1414use OCP \ICacheFactory ;
1515use OCP \IDBConnection ;
1616use OCP \Security \ISecureRandom ;
17+ use Sabre \DAV \Xml \Property \ResourceType ;
1718
1819class PaginateCache {
1920 public const TTL = 60 * 60 ;
2021 private const CACHE_COUNT_SUFFIX = 'count ' ;
2122
23+ private const RESOURCE_TYPE_PROPERTY = '{DAV:}resourcetype ' ;
24+
2225 private ICache $ cache ;
2326
2427 public function __construct (
@@ -40,6 +43,7 @@ public function store(string $uri, \Iterator $items): array {
4043
4144 $ count = 0 ;
4245 foreach ($ items as $ item ) {
46+ $ this ->serializeResourceType ($ item );
4347 // Add small margin to avoid fetching valid count and then expired entries
4448 $ this ->cache ->set ($ cacheKey . $ count , $ item , self ::TTL + 60 );
4549 ++$ count ;
@@ -61,7 +65,49 @@ public function get(string $uri, string $token, int $offset, int $count): Genera
6165
6266 $ lastItem = min ($ nbItems , $ offset + $ count );
6367 for ($ i = $ offset ; $ i < $ lastItem ; ++$ i ) {
64- yield $ this ->cache ->get ($ cacheKey . $ i );
68+ $ element = $ this ->cache ->get ($ cacheKey . $ i );
69+ $ this ->deserializeResourceType ($ element );
70+ yield $ element ;
71+ }
72+ }
73+
74+ /**
75+ * The ResourceType class is lost when json_encode is used.
76+ * This function serializes it in place so that this does not happen.
77+ *
78+ * @param array $item
79+ * @return void
80+ */
81+ private function serializeResourceType (array &$ item ): void {
82+ foreach ($ item as &$ responseProperties ) {
83+ if (!is_array ($ responseProperties )) {
84+ continue ;
85+ }
86+ foreach ($ responseProperties as &$ propertyValue ) {
87+ if ($ propertyValue instanceof ResourceType) {
88+ $ propertyValue = serialize ($ propertyValue );
89+ }
90+ }
91+ }
92+ }
93+
94+ /**
95+ * The ResourceType class in the cache is serialized. This function will
96+ * deserialize it in place.
97+ *
98+ * @param array $item
99+ * @return void
100+ */
101+ private function deserializeResourceType (array &$ item ): void {
102+ foreach ($ item as &$ responseProperties ) {
103+ foreach ($ responseProperties as $ propertyName => &$ propertyValue ) {
104+ if ($ propertyName === self ::RESOURCE_TYPE_PROPERTY ) {
105+ $ propertyValue = unserialize (
106+ $ propertyValue ,
107+ [ 'allowed_classes ' => [ResourceType::class]]
108+ );
109+ }
110+ }
65111 }
66112 }
67113
0 commit comments