Passed
Push — master ( a5a2c7...2fcb6d )
by Roeland
10:48
created
apps/files_sharing/appinfo/app.php 2 patches
Indentation   +57 added lines, -57 removed lines patch added patch discarded remove patch
@@ -40,13 +40,13 @@  discard block
 block discarded – undo
40 40
 
41 41
 $eventDispatcher = \OC::$server->getEventDispatcher();
42 42
 $eventDispatcher->addListener(
43
-	'OCA\Files::loadAdditionalScripts',
44
-	function() {
45
-		\OCP\Util::addScript('files_sharing', 'dist/additionalScripts');
46
-	}
43
+    'OCA\Files::loadAdditionalScripts',
44
+    function() {
45
+        \OCP\Util::addScript('files_sharing', 'dist/additionalScripts');
46
+    }
47 47
 );
48 48
 \OC::$server->getEventDispatcher()->addListener('\OCP\Collaboration\Resources::loadAdditionalScripts', function () {
49
-	\OCP\Util::addScript('files_sharing', 'dist/collaboration');
49
+    \OCP\Util::addScript('files_sharing', 'dist/collaboration');
50 50
 });
51 51
 
52 52
 $config = \OC::$server->getConfig();
@@ -56,62 +56,62 @@  discard block
 block discarded – undo
56 56
 
57 57
 if ($config->getAppValue('core', 'shareapi_enabled', 'yes') === 'yes') {
58 58
 
59
-	$sharingSublistArray = [];
59
+    $sharingSublistArray = [];
60 60
 
61
-	if (\OCP\Util::isSharingDisabledForUser() === false) {
62
-		array_push($sharingSublistArray, [
63
-			'id' => 'sharingout',
64
-			'appname' => 'files_sharing',
65
-			'script' => 'list.php',
66
-			'order' => 16,
67
-			'name' => $l->t('Shared with others'),
68
-		]);
69
-	}
61
+    if (\OCP\Util::isSharingDisabledForUser() === false) {
62
+        array_push($sharingSublistArray, [
63
+            'id' => 'sharingout',
64
+            'appname' => 'files_sharing',
65
+            'script' => 'list.php',
66
+            'order' => 16,
67
+            'name' => $l->t('Shared with others'),
68
+        ]);
69
+    }
70 70
 
71
-	array_push($sharingSublistArray, [
72
-		'id' => 'sharingin',
73
-		'appname' => 'files_sharing',
74
-		'script' => 'list.php',
75
-		'order' => 15,
76
-		'name' => $l->t('Shared with you'),
77
-	]);
71
+    array_push($sharingSublistArray, [
72
+        'id' => 'sharingin',
73
+        'appname' => 'files_sharing',
74
+        'script' => 'list.php',
75
+        'order' => 15,
76
+        'name' => $l->t('Shared with you'),
77
+    ]);
78 78
 
79
-	if (\OCP\Util::isSharingDisabledForUser() === false) {
80
-		// Check if sharing by link is enabled
81
-		if ($config->getAppValue('core', 'shareapi_allow_links', 'yes') === 'yes') {
82
-			array_push($sharingSublistArray, [
83
-				'id' => 'sharinglinks',
84
-				'appname' => 'files_sharing',
85
-				'script' => 'list.php',
86
-				'order' => 17,
87
-				'name' => $l->t('Shared by link'),
88
-			]);
89
-		}
90
-	}
79
+    if (\OCP\Util::isSharingDisabledForUser() === false) {
80
+        // Check if sharing by link is enabled
81
+        if ($config->getAppValue('core', 'shareapi_allow_links', 'yes') === 'yes') {
82
+            array_push($sharingSublistArray, [
83
+                'id' => 'sharinglinks',
84
+                'appname' => 'files_sharing',
85
+                'script' => 'list.php',
86
+                'order' => 17,
87
+                'name' => $l->t('Shared by link'),
88
+            ]);
89
+        }
90
+    }
91 91
 
92
-	array_push($sharingSublistArray, [
93
-		'id' => 'deletedshares',
94
-		'appname' => 'files_sharing',
95
-		'script' => 'list.php',
96
-		'order' => 19,
97
-		'name' => $l->t('Deleted shares'),
98
-	]);
92
+    array_push($sharingSublistArray, [
93
+        'id' => 'deletedshares',
94
+        'appname' => 'files_sharing',
95
+        'script' => 'list.php',
96
+        'order' => 19,
97
+        'name' => $l->t('Deleted shares'),
98
+    ]);
99 99
 
100
-	// show_Quick_Access stored as string
101
-	$user = $userSession->getUser();
102
-	$defaultExpandedState = true;
103
-	if ($user instanceof \OCP\IUser) {
104
-		$defaultExpandedState = $config->getUserValue($userSession->getUser()->getUID(), 'files', 'show_sharing_menu', '0') === '1';
105
-	}
100
+    // show_Quick_Access stored as string
101
+    $user = $userSession->getUser();
102
+    $defaultExpandedState = true;
103
+    if ($user instanceof \OCP\IUser) {
104
+        $defaultExpandedState = $config->getUserValue($userSession->getUser()->getUID(), 'files', 'show_sharing_menu', '0') === '1';
105
+    }
106 106
 
107
-	\OCA\Files\App::getNavigationManager()->add([
108
-		'id' => 'shareoverview',
109
-		'appname' => 'files_sharing',
110
-		'script' => 'list.php',
111
-		'order' => 18,
112
-		'name' => $l->t('Shares'),
113
-		'classes' => 'collapsible',
114
-		'sublist' => $sharingSublistArray,
115
-		'expandedState' => 'show_sharing_menu'
116
-	]);
107
+    \OCA\Files\App::getNavigationManager()->add([
108
+        'id' => 'shareoverview',
109
+        'appname' => 'files_sharing',
110
+        'script' => 'list.php',
111
+        'order' => 18,
112
+        'name' => $l->t('Shares'),
113
+        'classes' => 'collapsible',
114
+        'sublist' => $sharingSublistArray,
115
+        'expandedState' => 'show_sharing_menu'
116
+    ]);
117 117
 }
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -45,7 +45,7 @@
 block discarded – undo
45 45
 		\OCP\Util::addScript('files_sharing', 'dist/additionalScripts');
46 46
 	}
47 47
 );
48
-\OC::$server->getEventDispatcher()->addListener('\OCP\Collaboration\Resources::loadAdditionalScripts', function () {
48
+\OC::$server->getEventDispatcher()->addListener('\OCP\Collaboration\Resources::loadAdditionalScripts', function() {
49 49
 	\OCP\Util::addScript('files_sharing', 'dist/collaboration');
50 50
 });
51 51
 
Please login to merge, or discard this patch.
apps/files/lib/Collaboration/Resources/ResourceProvider.php 1 patch
Indentation   +96 added lines, -96 removed lines patch added patch discarded remove patch
@@ -34,100 +34,100 @@
 block discarded – undo
34 34
 
35 35
 class ResourceProvider implements IProvider {
36 36
 
37
-	public const RESOURCE_TYPE = 'file';
38
-
39
-	/** @var IRootFolder */
40
-	protected $rootFolder;
41
-	/** @var IPreview */
42
-	private $preview;
43
-	/** @var IURLGenerator */
44
-	private $urlGenerator;
45
-
46
-	/** @var array */
47
-	protected $nodes = [];
48
-
49
-	public function __construct(IRootFolder $rootFolder,
50
-								IPreview $preview,
51
-								IURLGenerator $urlGenerator) {
52
-		$this->rootFolder = $rootFolder;
53
-		$this->preview = $preview;
54
-		$this->urlGenerator = $urlGenerator;
55
-	}
56
-
57
-	private function getNode(IResource $resource): ?Node {
58
-		if (isset($this->nodes[(int) $resource->getId()])) {
59
-			return $this->nodes[(int) $resource->getId()];
60
-		}
61
-		$nodes = $this->rootFolder->getById((int) $resource->getId());
62
-		if (!empty($nodes)) {
63
-			$this->nodes[(int) $resource->getId()] = array_shift($nodes);
64
-			return $this->nodes[(int) $resource->getId()];
65
-		}
66
-		return null;
67
-	}
68
-
69
-	/**
70
-	 * @param IResource $resource
71
-	 * @return array
72
-	 * @since 16.0.0
73
-	 */
74
-	public function getResourceRichObject(IResource $resource): array {
75
-		if (isset($this->nodes[(int) $resource->getId()])) {
76
-			$node = $this->nodes[(int) $resource->getId()]->getPath();
77
-		} else {
78
-			$node = $this->getNode($resource);
79
-		}
80
-
81
-		if ($node instanceof Node) {
82
-			$link = $this->urlGenerator->linkToRouteAbsolute(
83
-				'files.viewcontroller.showFile',
84
-				['fileid' => $resource->getId()]
85
-			);
86
-			return [
87
-				'type' => 'file',
88
-				'id' => $resource->getId(),
89
-				'name' => $node->getName(),
90
-				'path' => $node->getInternalPath(),
91
-				'link' => $link,
92
-				'mimetype' => $node->getMimetype(),
93
-				'preview-available' => $this->preview->isAvailable($node),
94
-			];
95
-		}
96
-
97
-		throw new ResourceException('File not found');
98
-	}
99
-
100
-	/**
101
-	 * Can a user/guest access the collection
102
-	 *
103
-	 * @param IResource $resource
104
-	 * @param IUser $user
105
-	 * @return bool
106
-	 * @since 16.0.0
107
-	 */
108
-	public function canAccessResource(IResource $resource, IUser $user = null): bool {
109
-		if (!$user instanceof IUser) {
110
-			return false;
111
-		}
112
-
113
-		$userFolder = $this->rootFolder->getUserFolder($user->getUID());
114
-		$nodes = $userFolder->getById((int) $resource->getId());
115
-
116
-		if (!empty($nodes)) {
117
-			$this->nodes[(int) $resource->getId()] = array_shift($nodes);
118
-			return true;
119
-		}
120
-
121
-		return false;
122
-	}
123
-
124
-	/**
125
-	 * Get the resource type of the provider
126
-	 *
127
-	 * @return string
128
-	 * @since 16.0.0
129
-	 */
130
-	public function getType(): string {
131
-		return self::RESOURCE_TYPE;
132
-	}
37
+    public const RESOURCE_TYPE = 'file';
38
+
39
+    /** @var IRootFolder */
40
+    protected $rootFolder;
41
+    /** @var IPreview */
42
+    private $preview;
43
+    /** @var IURLGenerator */
44
+    private $urlGenerator;
45
+
46
+    /** @var array */
47
+    protected $nodes = [];
48
+
49
+    public function __construct(IRootFolder $rootFolder,
50
+                                IPreview $preview,
51
+                                IURLGenerator $urlGenerator) {
52
+        $this->rootFolder = $rootFolder;
53
+        $this->preview = $preview;
54
+        $this->urlGenerator = $urlGenerator;
55
+    }
56
+
57
+    private function getNode(IResource $resource): ?Node {
58
+        if (isset($this->nodes[(int) $resource->getId()])) {
59
+            return $this->nodes[(int) $resource->getId()];
60
+        }
61
+        $nodes = $this->rootFolder->getById((int) $resource->getId());
62
+        if (!empty($nodes)) {
63
+            $this->nodes[(int) $resource->getId()] = array_shift($nodes);
64
+            return $this->nodes[(int) $resource->getId()];
65
+        }
66
+        return null;
67
+    }
68
+
69
+    /**
70
+     * @param IResource $resource
71
+     * @return array
72
+     * @since 16.0.0
73
+     */
74
+    public function getResourceRichObject(IResource $resource): array {
75
+        if (isset($this->nodes[(int) $resource->getId()])) {
76
+            $node = $this->nodes[(int) $resource->getId()]->getPath();
77
+        } else {
78
+            $node = $this->getNode($resource);
79
+        }
80
+
81
+        if ($node instanceof Node) {
82
+            $link = $this->urlGenerator->linkToRouteAbsolute(
83
+                'files.viewcontroller.showFile',
84
+                ['fileid' => $resource->getId()]
85
+            );
86
+            return [
87
+                'type' => 'file',
88
+                'id' => $resource->getId(),
89
+                'name' => $node->getName(),
90
+                'path' => $node->getInternalPath(),
91
+                'link' => $link,
92
+                'mimetype' => $node->getMimetype(),
93
+                'preview-available' => $this->preview->isAvailable($node),
94
+            ];
95
+        }
96
+
97
+        throw new ResourceException('File not found');
98
+    }
99
+
100
+    /**
101
+     * Can a user/guest access the collection
102
+     *
103
+     * @param IResource $resource
104
+     * @param IUser $user
105
+     * @return bool
106
+     * @since 16.0.0
107
+     */
108
+    public function canAccessResource(IResource $resource, IUser $user = null): bool {
109
+        if (!$user instanceof IUser) {
110
+            return false;
111
+        }
112
+
113
+        $userFolder = $this->rootFolder->getUserFolder($user->getUID());
114
+        $nodes = $userFolder->getById((int) $resource->getId());
115
+
116
+        if (!empty($nodes)) {
117
+            $this->nodes[(int) $resource->getId()] = array_shift($nodes);
118
+            return true;
119
+        }
120
+
121
+        return false;
122
+    }
123
+
124
+    /**
125
+     * Get the resource type of the provider
126
+     *
127
+     * @return string
128
+     * @since 16.0.0
129
+     */
130
+    public function getType(): string {
131
+        return self::RESOURCE_TYPE;
132
+    }
133 133
 }
Please login to merge, or discard this patch.
lib/private/Collaboration/Resources/Resource.php 1 patch
Indentation   +125 added lines, -125 removed lines patch added patch discarded remove patch
@@ -31,129 +31,129 @@
 block discarded – undo
31 31
 
32 32
 class Resource implements IResource {
33 33
 
34
-	/** @var IManager */
35
-	protected $manager;
36
-
37
-	/** @var IDBConnection */
38
-	protected $connection;
39
-
40
-	/** @var string */
41
-	protected $type;
42
-
43
-	/** @var string */
44
-	protected $id;
45
-
46
-	/** @var IUser|null */
47
-	protected $userForAccess;
48
-
49
-	/** @var bool|null */
50
-	protected $access;
51
-
52
-	/** @var array|null */
53
-	protected $data;
54
-
55
-	public function __construct(
56
-		IManager $manager,
57
-		IDBConnection $connection,
58
-		string $type,
59
-		string $id,
60
-		?IUser $userForAccess = null,
61
-		?bool $access = null
62
-	) {
63
-		$this->manager = $manager;
64
-		$this->connection = $connection;
65
-		$this->type = $type;
66
-		$this->id = $id;
67
-		$this->userForAccess = $userForAccess;
68
-		$this->access = $access;
69
-	}
70
-
71
-	/**
72
-	 * @return string
73
-	 * @since 16.0.0
74
-	 */
75
-	public function getType(): string {
76
-		return $this->type;
77
-	}
78
-
79
-	/**
80
-	 * @return string
81
-	 * @since 16.0.0
82
-	 */
83
-	public function getId(): string {
84
-		return $this->id;
85
-	}
86
-
87
-	/**
88
-	 * @return array
89
-	 * @since 16.0.0
90
-	 */
91
-	public function getRichObject(): array {
92
-		if ($this->data === null) {
93
-			$this->data = $this->manager->getResourceRichObject($this);
94
-		}
95
-
96
-		return $this->data;
97
-	}
98
-
99
-	/**
100
-	 * Can a user/guest access the resource
101
-	 *
102
-	 * @param IUser|null $user
103
-	 * @return bool
104
-	 * @since 16.0.0
105
-	 */
106
-	public function canAccess(?IUser $user): bool {
107
-		if ($user instanceof IUser) {
108
-			return $this->canUserAccess($user);
109
-		}
110
-		return $this->canGuestAccess();
111
-	}
112
-
113
-	protected function canUserAccess(IUser $user): bool {
114
-		if (\is_bool($this->access) && $this->userForAccess instanceof IUser && $user->getUID() === $this->userForAccess->getUID()) {
115
-			return $this->access;
116
-		}
117
-
118
-		$access = $this->manager->canAccessResource($this, $user);
119
-		if ($this->userForAccess instanceof IUser && $user->getUID() === $this->userForAccess->getUID()) {
120
-			$this->access = $access;
121
-		}
122
-		return $access;
123
-	}
124
-
125
-	protected function canGuestAccess(): bool {
126
-		if (\is_bool($this->access) && !$this->userForAccess instanceof IUser) {
127
-			return $this->access;
128
-		}
129
-
130
-		$access = $this->manager->canAccessResource($this, null);
131
-		if (!$this->userForAccess instanceof IUser) {
132
-			$this->access = $access;
133
-		}
134
-		return $access;
135
-	}
136
-
137
-	/**
138
-	 * @return ICollection[]
139
-	 * @since 16.0.0
140
-	 */
141
-	public function getCollections(): array {
142
-		$collections = [];
143
-
144
-		$query = $this->connection->getQueryBuilder();
145
-
146
-		$query->select('collection_id')
147
-			->from('collres_resources')
148
-			->where($query->expr()->eq('resource_type', $query->createNamedParameter($this->getType())))
149
-			->andWhere($query->expr()->eq('resource_id', $query->createNamedParameter($this->getId())));
150
-
151
-		$result = $query->execute();
152
-		while ($row = $result->fetch()) {
153
-			$collections[] = $this->manager->getCollection((int) $row['collection_id']);
154
-		}
155
-		$result->closeCursor();
156
-
157
-		return $collections;
158
-	}
34
+    /** @var IManager */
35
+    protected $manager;
36
+
37
+    /** @var IDBConnection */
38
+    protected $connection;
39
+
40
+    /** @var string */
41
+    protected $type;
42
+
43
+    /** @var string */
44
+    protected $id;
45
+
46
+    /** @var IUser|null */
47
+    protected $userForAccess;
48
+
49
+    /** @var bool|null */
50
+    protected $access;
51
+
52
+    /** @var array|null */
53
+    protected $data;
54
+
55
+    public function __construct(
56
+        IManager $manager,
57
+        IDBConnection $connection,
58
+        string $type,
59
+        string $id,
60
+        ?IUser $userForAccess = null,
61
+        ?bool $access = null
62
+    ) {
63
+        $this->manager = $manager;
64
+        $this->connection = $connection;
65
+        $this->type = $type;
66
+        $this->id = $id;
67
+        $this->userForAccess = $userForAccess;
68
+        $this->access = $access;
69
+    }
70
+
71
+    /**
72
+     * @return string
73
+     * @since 16.0.0
74
+     */
75
+    public function getType(): string {
76
+        return $this->type;
77
+    }
78
+
79
+    /**
80
+     * @return string
81
+     * @since 16.0.0
82
+     */
83
+    public function getId(): string {
84
+        return $this->id;
85
+    }
86
+
87
+    /**
88
+     * @return array
89
+     * @since 16.0.0
90
+     */
91
+    public function getRichObject(): array {
92
+        if ($this->data === null) {
93
+            $this->data = $this->manager->getResourceRichObject($this);
94
+        }
95
+
96
+        return $this->data;
97
+    }
98
+
99
+    /**
100
+     * Can a user/guest access the resource
101
+     *
102
+     * @param IUser|null $user
103
+     * @return bool
104
+     * @since 16.0.0
105
+     */
106
+    public function canAccess(?IUser $user): bool {
107
+        if ($user instanceof IUser) {
108
+            return $this->canUserAccess($user);
109
+        }
110
+        return $this->canGuestAccess();
111
+    }
112
+
113
+    protected function canUserAccess(IUser $user): bool {
114
+        if (\is_bool($this->access) && $this->userForAccess instanceof IUser && $user->getUID() === $this->userForAccess->getUID()) {
115
+            return $this->access;
116
+        }
117
+
118
+        $access = $this->manager->canAccessResource($this, $user);
119
+        if ($this->userForAccess instanceof IUser && $user->getUID() === $this->userForAccess->getUID()) {
120
+            $this->access = $access;
121
+        }
122
+        return $access;
123
+    }
124
+
125
+    protected function canGuestAccess(): bool {
126
+        if (\is_bool($this->access) && !$this->userForAccess instanceof IUser) {
127
+            return $this->access;
128
+        }
129
+
130
+        $access = $this->manager->canAccessResource($this, null);
131
+        if (!$this->userForAccess instanceof IUser) {
132
+            $this->access = $access;
133
+        }
134
+        return $access;
135
+    }
136
+
137
+    /**
138
+     * @return ICollection[]
139
+     * @since 16.0.0
140
+     */
141
+    public function getCollections(): array {
142
+        $collections = [];
143
+
144
+        $query = $this->connection->getQueryBuilder();
145
+
146
+        $query->select('collection_id')
147
+            ->from('collres_resources')
148
+            ->where($query->expr()->eq('resource_type', $query->createNamedParameter($this->getType())))
149
+            ->andWhere($query->expr()->eq('resource_id', $query->createNamedParameter($this->getId())));
150
+
151
+        $result = $query->execute();
152
+        while ($row = $result->fetch()) {
153
+            $collections[] = $this->manager->getCollection((int) $row['collection_id']);
154
+        }
155
+        $result->closeCursor();
156
+
157
+        return $collections;
158
+    }
159 159
 }
Please login to merge, or discard this patch.
lib/private/Collaboration/Resources/Manager.php 1 patch
Indentation   +485 added lines, -485 removed lines patch added patch discarded remove patch
@@ -38,489 +38,489 @@
 block discarded – undo
38 38
 
39 39
 class Manager implements IManager {
40 40
 
41
-	public const TABLE_COLLECTIONS = 'collres_collections';
42
-	public const TABLE_RESOURCES = 'collres_resources';
43
-	public const TABLE_ACCESS_CACHE = 'collres_accesscache';
44
-
45
-	/** @var IDBConnection */
46
-	protected $connection;
47
-	/** @var ILogger */
48
-	protected $logger;
49
-
50
-	/** @var string[] */
51
-	protected $providers = [];
52
-
53
-	/** @var IProvider[] */
54
-	protected $providerInstances = [];
55
-
56
-	public function __construct(IDBConnection $connection, ILogger $logger) {
57
-		$this->connection = $connection;
58
-		$this->logger = $logger;
59
-	}
60
-
61
-	/**
62
-	 * @param int $id
63
-	 * @return ICollection
64
-	 * @throws CollectionException when the collection could not be found
65
-	 * @since 16.0.0
66
-	 */
67
-	public function getCollection(int $id): ICollection {
68
-		$query = $this->connection->getQueryBuilder();
69
-		$query->select('*')
70
-			->from(self::TABLE_COLLECTIONS)
71
-			->where($query->expr()->eq('id', $query->createNamedParameter($id, IQueryBuilder::PARAM_INT)));
72
-		$result = $query->execute();
73
-		$row = $result->fetch();
74
-		$result->closeCursor();
75
-
76
-		if (!$row) {
77
-			throw new CollectionException('Collection not found');
78
-		}
79
-
80
-		return new Collection($this, $this->connection, (int) $row['id'], (string) $row['name']);
81
-	}
82
-
83
-	/**
84
-	 * @param int $id
85
-	 * @param IUser|null $user
86
-	 * @return ICollection
87
-	 * @throws CollectionException when the collection could not be found
88
-	 * @since 16.0.0
89
-	 */
90
-	public function getCollectionForUser(int $id, ?IUser $user): ICollection {
91
-		$query = $this->connection->getQueryBuilder();
92
-		$userId = $user instanceof IUser ? $user->getUID() : '';
93
-
94
-		$query->select('*')
95
-			->from(self::TABLE_COLLECTIONS, 'c')
96
-			->leftJoin(
97
-				'c', self::TABLE_ACCESS_CACHE, 'a',
98
-				$query->expr()->andX(
99
-					$query->expr()->eq('c.id', 'a.collection_id'),
100
-					$query->expr()->eq('a.user_id', $query->createNamedParameter($userId, IQueryBuilder::PARAM_STR))
101
-				)
102
-			)
103
-			->where($query->expr()->eq('c.id', $query->createNamedParameter($id, IQueryBuilder::PARAM_INT)));
104
-		$result = $query->execute();
105
-		$row = $result->fetch();
106
-		$result->closeCursor();
107
-
108
-		if (!$row) {
109
-			throw new CollectionException('Collection not found');
110
-		}
111
-
112
-		$access = $row['access'] === null ? null : (bool) $row['access'];
113
-		if ($user instanceof IUser) {
114
-			return new Collection($this, $this->connection, (int) $row['id'], (string) $row['name'], $user, $access);
115
-		}
116
-
117
-		return new Collection($this, $this->connection, (int) $row['id'], (string) $row['name'], $user, $access);
118
-	}
119
-
120
-	/**
121
-	 * @param IUser $user
122
-	 * @param string $filter
123
-	 * @param int $limit
124
-	 * @param int $start
125
-	 * @return ICollection[]
126
-	 * @since 16.0.0
127
-	 */
128
-	public function searchCollections(IUser $user, string $filter, int $limit = 50, int $start = 0): array {
129
-		$query = $this->connection->getQueryBuilder();
130
-		$userId = $user instanceof IUser ? $user->getUID() : '';
131
-
132
-		$query->select('c.*', 'a.access')
133
-			->from(self::TABLE_COLLECTIONS, 'c')
134
-			->leftJoin(
135
-				'c', self::TABLE_ACCESS_CACHE, 'a',
136
-				$query->expr()->andX(
137
-					$query->expr()->eq('c.id', 'a.collection_id'),
138
-					$query->expr()->eq('a.user_id', $query->createNamedParameter($userId, IQueryBuilder::PARAM_STR))
139
-				)
140
-			)
141
-			->where($query->expr()->iLike('c.name', $query->createNamedParameter($filter, IQueryBuilder::PARAM_STR)))
142
-			->andWhere($query->expr()->eq('a.access', $query->createNamedParameter(1, IQueryBuilder::PARAM_INT)))
143
-			->orderBy('c.id')
144
-			->setMaxResults($limit)
145
-			->setFirstResult($start);
146
-		$result = $query->execute();
147
-		$collections = [];
148
-
149
-		$foundResults = 0;
150
-		while ($row = $result->fetch()) {
151
-			$foundResults++;
152
-			$access = $row['access'] === null ? null : (bool) $row['access'];
153
-			$collection = new Collection($this, $this->connection, (int)$row['id'], (string)$row['name'], $user, $access);
154
-			if ($collection->canAccess($user)) {
155
-				$collections[] = $collection;
156
-			}
157
-		}
158
-		$result->closeCursor();
159
-
160
-		if (empty($collections) && $foundResults === $limit) {
161
-			$this->searchCollections($user, $filter, $limit, $start + $limit);
162
-		}
163
-
164
-		return $collections;
165
-	}
166
-
167
-	/**
168
-	 * @param string $name
169
-	 * @return ICollection
170
-	 * @since 16.0.0
171
-	 */
172
-	public function newCollection(string $name): ICollection {
173
-		$query = $this->connection->getQueryBuilder();
174
-		$query->insert(self::TABLE_COLLECTIONS)
175
-			->values([
176
-				'name' => $query->createNamedParameter($name),
177
-			]);
178
-		$query->execute();
179
-
180
-		return new Collection($this, $this->connection, $query->getLastInsertId(), $name);
181
-	}
182
-
183
-	/**
184
-	 * @param string $type
185
-	 * @param string $id
186
-	 * @return IResource
187
-	 * @since 16.0.0
188
-	 */
189
-	public function createResource(string $type, string $id): IResource {
190
-		return new Resource($this, $this->connection, $type, $id);
191
-	}
192
-
193
-	/**
194
-	 * @param string $type
195
-	 * @param string $id
196
-	 * @param IUser|null $user
197
-	 * @return IResource
198
-	 * @throws ResourceException
199
-	 * @since 16.0.0
200
-	 */
201
-	public function getResourceForUser(string $type, string $id, ?IUser $user): IResource {
202
-		$query = $this->connection->getQueryBuilder();
203
-		$userId = $user instanceof IUser ? $user->getUID() : '';
204
-
205
-		$query->select('r.*', 'a.access')
206
-			->from(self::TABLE_RESOURCES, 'r')
207
-			->leftJoin(
208
-				'r', self::TABLE_ACCESS_CACHE, 'a',
209
-				$query->expr()->andX(
210
-					$query->expr()->eq('r.resource_id', 'a.resource_id'),
211
-					$query->expr()->eq('r.resource_type', 'a.resource_type'),
212
-					$query->expr()->eq('a.user_id', $query->createNamedParameter($userId, IQueryBuilder::PARAM_STR))
213
-				)
214
-			)
215
-			->where($query->expr()->eq('r.resource_type', $query->createNamedParameter($type, IQueryBuilder::PARAM_STR)))
216
-			->andWhere($query->expr()->eq('r.resource_id', $query->createNamedParameter($id, IQueryBuilder::PARAM_STR)));
217
-		$result = $query->execute();
218
-		$row = $result->fetch();
219
-		$result->closeCursor();
220
-
221
-		if (!$row) {
222
-			throw new ResourceException('Resource not found');
223
-		}
224
-
225
-		$access = $row['access'] === null ? null : (bool) $row['access'];
226
-		if ($user instanceof IUser) {
227
-			return new Resource($this, $this->connection, $type, $id, $user, $access);
228
-		}
229
-
230
-		return new Resource($this, $this->connection, $type, $id, null, $access);
231
-	}
232
-
233
-	/**
234
-	 * @param ICollection $collection
235
-	 * @param IUser|null $user
236
-	 * @return IResource[]
237
-	 * @since 16.0.0
238
-	 */
239
-	public function getResourcesByCollectionForUser(ICollection $collection, ?IUser $user): array {
240
-		$query = $this->connection->getQueryBuilder();
241
-		$userId = $user instanceof IUser ? $user->getUID() : '';
242
-
243
-		$query->select('r.*', 'a.access')
244
-			->from(self::TABLE_RESOURCES, 'r')
245
-			->leftJoin(
246
-				'r', self::TABLE_ACCESS_CACHE, 'a',
247
-				$query->expr()->andX(
248
-					$query->expr()->eq('r.resource_id', 'a.resource_id'),
249
-					$query->expr()->eq('r.resource_type', 'a.resource_type'),
250
-					$query->expr()->eq('a.user_id', $query->createNamedParameter($userId, IQueryBuilder::PARAM_STR))
251
-				)
252
-			)
253
-			->where($query->expr()->eq('r.collection_id', $query->createNamedParameter($collection->getId(), IQueryBuilder::PARAM_INT)));
254
-
255
-		$resources = [];
256
-		$result = $query->execute();
257
-		while ($row = $result->fetch()) {
258
-			$access = $row['access'] === null ? null : (bool) $row['access'];
259
-			$resources[] = new Resource($this, $this->connection, $row['resource_type'], $row['resource_id'], $user, $access);
260
-		}
261
-		$result->closeCursor();
262
-
263
-		return $resources;
264
-	}
265
-
266
-	/**
267
-	 * @return IProvider[]
268
-	 * @since 16.0.0
269
-	 */
270
-	public function getProviders(): array {
271
-		if (!empty($this->providers)) {
272
-			foreach ($this->providers as $provider) {
273
-				try {
274
-					$this->providerInstances[] = \OC::$server->query($provider);
275
-				} catch (QueryException $e) {
276
-					$this->logger->logException($e, [
277
-						'message' => 'Error when instantiating resource provider'
278
-					]);
279
-				}
280
-			}
281
-			$this->providers = [];
282
-		}
283
-
284
-		return $this->providerInstances;
285
-	}
286
-
287
-	/**
288
-	 * Get the rich object data of a resource
289
-	 *
290
-	 * @param IResource $resource
291
-	 * @return array
292
-	 * @since 16.0.0
293
-	 */
294
-	public function getResourceRichObject(IResource $resource): array {
295
-		foreach ($this->getProviders() as $provider) {
296
-			if ($provider->getType() === $resource->getType()) {
297
-				try {
298
-					return $provider->getResourceRichObject($resource);
299
-				} catch (ResourceException $e) {
300
-				}
301
-			}
302
-		}
303
-
304
-		return [];
305
-	}
306
-
307
-	/**
308
-	 * Can a user/guest access the collection
309
-	 *
310
-	 * @param IResource $resource
311
-	 * @param IUser|null $user
312
-	 * @return bool
313
-	 * @since 16.0.0
314
-	 */
315
-	public function canAccessResource(IResource $resource, ?IUser $user): bool {
316
-		$access = $this->checkAccessCacheForUserByResource($resource, $user);
317
-		if (\is_bool($access)) {
318
-			return $access;
319
-		}
320
-
321
-		$access = false;
322
-		foreach ($this->getProviders() as $provider) {
323
-			if ($provider->getType() === $resource->getType()) {
324
-				try {
325
-					if ($provider->canAccessResource($resource, $user)) {
326
-						$access = true;
327
-						break;
328
-					}
329
-				} catch (ResourceException $e) {
330
-				}
331
-			}
332
-		}
333
-
334
-		$this->cacheAccessForResource($resource, $user, $access);
335
-		return $access;
336
-	}
337
-
338
-	/**
339
-	 * Can a user/guest access the collection
340
-	 *
341
-	 * @param ICollection $collection
342
-	 * @param IUser|null $user
343
-	 * @return bool
344
-	 * @since 16.0.0
345
-	 */
346
-	public function canAccessCollection(ICollection $collection, ?IUser $user): bool {
347
-		$access = $this->checkAccessCacheForUserByCollection($collection, $user);
348
-		if (\is_bool($access)) {
349
-			return $access;
350
-		}
351
-
352
-		$access = false;
353
-		foreach ($collection->getResources() as $resource) {
354
-			if ($resource->canAccess($user)) {
355
-				$access = true;
356
-				break;
357
-			}
358
-		}
359
-
360
-		$this->cacheAccessForCollection($collection, $user, $access);
361
-		return $access;
362
-	}
363
-
364
-	protected function checkAccessCacheForUserByResource(IResource $resource, ?IUser $user): ?bool {
365
-		$query = $this->connection->getQueryBuilder();
366
-		$userId = $user instanceof IUser ? $user->getUID() : '';
367
-
368
-		$query->select('access')
369
-			->from(self::TABLE_ACCESS_CACHE)
370
-			->where($query->expr()->eq('resource_id', $query->createNamedParameter($resource->getId(), IQueryBuilder::PARAM_STR)))
371
-			->andWhere($query->expr()->eq('resource_type', $query->createNamedParameter($resource->getType(), IQueryBuilder::PARAM_STR)))
372
-			->andWhere($query->expr()->eq('user_id', $query->createNamedParameter($userId, IQueryBuilder::PARAM_STR)))
373
-			->setMaxResults(1);
374
-
375
-		$hasAccess = null;
376
-		$result = $query->execute();
377
-		if ($row = $result->fetch()) {
378
-			$hasAccess = (bool) $row['access'];
379
-		}
380
-		$result->closeCursor();
381
-
382
-		return $hasAccess;
383
-	}
384
-
385
-	protected function checkAccessCacheForUserByCollection(ICollection $collection, ?IUser $user): ?bool {
386
-		$query = $this->connection->getQueryBuilder();
387
-		$userId = $user instanceof IUser ? $user->getUID() : '';
388
-
389
-		$query->select('access')
390
-			->from(self::TABLE_ACCESS_CACHE)
391
-			->where($query->expr()->eq('collection_id', $query->createNamedParameter($collection->getId(), IQueryBuilder::PARAM_INT)))
392
-			->andWhere($query->expr()->eq('user_id', $query->createNamedParameter($userId, IQueryBuilder::PARAM_STR)))
393
-			->setMaxResults(1);
394
-
395
-		$hasAccess = null;
396
-		$result = $query->execute();
397
-		if ($row = $result->fetch()) {
398
-			$hasAccess = (bool) $row['access'];
399
-		}
400
-		$result->closeCursor();
401
-
402
-		return $hasAccess;
403
-	}
404
-
405
-	public function cacheAccessForResource(IResource $resource, ?IUser $user, bool $access): void {
406
-		$query = $this->connection->getQueryBuilder();
407
-		$userId = $user instanceof IUser ? $user->getUID() : '';
408
-
409
-		$query->insert(self::TABLE_ACCESS_CACHE)
410
-			->values([
411
-				'user_id' => $query->createNamedParameter($userId),
412
-				'resource_id' => $query->createNamedParameter($resource->getId()),
413
-				'resource_type' => $query->createNamedParameter($resource->getType()),
414
-				'access' => $query->createNamedParameter($access),
415
-			]);
416
-		try {
417
-			$query->execute();
418
-		} catch (UniqueConstraintViolationException $e) {
419
-		}
420
-	}
421
-
422
-	public function cacheAccessForCollection(ICollection $collection, ?IUser $user, bool $access): void {
423
-		$query = $this->connection->getQueryBuilder();
424
-		$userId = $user instanceof IUser ? $user->getUID() : '';
425
-
426
-		$query->insert(self::TABLE_ACCESS_CACHE)
427
-			->values([
428
-				'user_id' => $query->createNamedParameter($userId),
429
-				'collection_id' => $query->createNamedParameter($collection->getId()),
430
-				'access' => $query->createNamedParameter($access),
431
-			]);
432
-		try {
433
-			$query->execute();
434
-		} catch (UniqueConstraintViolationException $e) {
435
-		}
436
-	}
437
-
438
-	public function invalidateAccessCacheForUser(?IUser $user): void {
439
-		$query = $this->connection->getQueryBuilder();
440
-		$userId = $user instanceof IUser ? $user->getUID() : '';
441
-
442
-		$query->delete(self::TABLE_ACCESS_CACHE)
443
-			->where($query->expr()->eq('user_id', $query->createNamedParameter($userId)));
444
-		$query->execute();
445
-	}
446
-
447
-	public function invalidateAccessCacheForResource(IResource $resource): void {
448
-		$query = $this->connection->getQueryBuilder();
449
-
450
-		$query->delete(self::TABLE_ACCESS_CACHE)
451
-			->where($query->expr()->eq('resource_id', $query->createNamedParameter($resource->getId())))
452
-			->andWhere($query->expr()->eq('resource_type', $query->createNamedParameter($resource->getType(), IQueryBuilder::PARAM_STR)));
453
-		$query->execute();
454
-
455
-		foreach ($resource->getCollections() as $collection) {
456
-			$this->invalidateAccessCacheForCollection($collection);
457
-		}
458
-	}
459
-
460
-	public function invalidateAccessCacheForCollection(ICollection $collection): void {
461
-		$query = $this->connection->getQueryBuilder();
462
-
463
-		$query->delete(self::TABLE_ACCESS_CACHE)
464
-			->where($query->expr()->eq('collection_id', $query->createNamedParameter($collection->getId())));
465
-		$query->execute();
466
-	}
467
-
468
-	public function invalidateAccessCacheForProvider(IProvider $provider): void {
469
-		$query = $this->connection->getQueryBuilder();
470
-
471
-		$query->delete(self::TABLE_ACCESS_CACHE)
472
-			->where($query->expr()->eq('resource_type', $query->createNamedParameter($provider->getType(), IQueryBuilder::PARAM_STR)));
473
-		$query->execute();
474
-	}
475
-
476
-	public function invalidateAccessCacheForResourceByUser(IResource $resource, ?IUser $user): void {
477
-		$query = $this->connection->getQueryBuilder();
478
-		$userId = $user instanceof IUser ? $user->getUID() : '';
479
-
480
-		$query->delete(self::TABLE_ACCESS_CACHE)
481
-			->where($query->expr()->eq('resource_id', $query->createNamedParameter($resource->getId())))
482
-			->andWhere($query->expr()->eq('user_id', $query->createNamedParameter($userId)));
483
-		$query->execute();
484
-
485
-		foreach ($resource->getCollections() as $collection) {
486
-			$this->invalidateAccessCacheForCollectionByUser($collection, $user);
487
-		}
488
-	}
489
-
490
-	protected function invalidateAccessCacheForCollectionByUser(ICollection $collection, ?IUser $user): void {
491
-		$query = $this->connection->getQueryBuilder();
492
-		$userId = $user instanceof IUser ? $user->getUID() : '';
493
-
494
-		$query->delete(self::TABLE_ACCESS_CACHE)
495
-			->where($query->expr()->eq('collection_id', $query->createNamedParameter($collection->getId())))
496
-			->andWhere($query->expr()->eq('user_id', $query->createNamedParameter($userId)));
497
-		$query->execute();
498
-	}
499
-
500
-	public function invalidateAccessCacheForProviderByUser(IProvider $provider, ?IUser $user): void {
501
-		$query = $this->connection->getQueryBuilder();
502
-		$userId = $user instanceof IUser ? $user->getUID() : '';
503
-
504
-		$query->delete(self::TABLE_ACCESS_CACHE)
505
-			->where($query->expr()->eq('resource_type', $query->createNamedParameter($provider->getType(), IQueryBuilder::PARAM_STR)))
506
-			->andWhere($query->expr()->eq('user_id', $query->createNamedParameter($userId)));
507
-		$query->execute();
508
-	}
509
-
510
-	/**
511
-	 * @param string $provider
512
-	 */
513
-	public function registerResourceProvider(string $provider): void {
514
-		$this->providers[] = $provider;
515
-	}
516
-
517
-	/**
518
-	 * Get the resource type of the provider
519
-	 *
520
-	 * @return string
521
-	 * @since 16.0.0
522
-	 */
523
-	public function getType(): string {
524
-		return '';
525
-	}
41
+    public const TABLE_COLLECTIONS = 'collres_collections';
42
+    public const TABLE_RESOURCES = 'collres_resources';
43
+    public const TABLE_ACCESS_CACHE = 'collres_accesscache';
44
+
45
+    /** @var IDBConnection */
46
+    protected $connection;
47
+    /** @var ILogger */
48
+    protected $logger;
49
+
50
+    /** @var string[] */
51
+    protected $providers = [];
52
+
53
+    /** @var IProvider[] */
54
+    protected $providerInstances = [];
55
+
56
+    public function __construct(IDBConnection $connection, ILogger $logger) {
57
+        $this->connection = $connection;
58
+        $this->logger = $logger;
59
+    }
60
+
61
+    /**
62
+     * @param int $id
63
+     * @return ICollection
64
+     * @throws CollectionException when the collection could not be found
65
+     * @since 16.0.0
66
+     */
67
+    public function getCollection(int $id): ICollection {
68
+        $query = $this->connection->getQueryBuilder();
69
+        $query->select('*')
70
+            ->from(self::TABLE_COLLECTIONS)
71
+            ->where($query->expr()->eq('id', $query->createNamedParameter($id, IQueryBuilder::PARAM_INT)));
72
+        $result = $query->execute();
73
+        $row = $result->fetch();
74
+        $result->closeCursor();
75
+
76
+        if (!$row) {
77
+            throw new CollectionException('Collection not found');
78
+        }
79
+
80
+        return new Collection($this, $this->connection, (int) $row['id'], (string) $row['name']);
81
+    }
82
+
83
+    /**
84
+     * @param int $id
85
+     * @param IUser|null $user
86
+     * @return ICollection
87
+     * @throws CollectionException when the collection could not be found
88
+     * @since 16.0.0
89
+     */
90
+    public function getCollectionForUser(int $id, ?IUser $user): ICollection {
91
+        $query = $this->connection->getQueryBuilder();
92
+        $userId = $user instanceof IUser ? $user->getUID() : '';
93
+
94
+        $query->select('*')
95
+            ->from(self::TABLE_COLLECTIONS, 'c')
96
+            ->leftJoin(
97
+                'c', self::TABLE_ACCESS_CACHE, 'a',
98
+                $query->expr()->andX(
99
+                    $query->expr()->eq('c.id', 'a.collection_id'),
100
+                    $query->expr()->eq('a.user_id', $query->createNamedParameter($userId, IQueryBuilder::PARAM_STR))
101
+                )
102
+            )
103
+            ->where($query->expr()->eq('c.id', $query->createNamedParameter($id, IQueryBuilder::PARAM_INT)));
104
+        $result = $query->execute();
105
+        $row = $result->fetch();
106
+        $result->closeCursor();
107
+
108
+        if (!$row) {
109
+            throw new CollectionException('Collection not found');
110
+        }
111
+
112
+        $access = $row['access'] === null ? null : (bool) $row['access'];
113
+        if ($user instanceof IUser) {
114
+            return new Collection($this, $this->connection, (int) $row['id'], (string) $row['name'], $user, $access);
115
+        }
116
+
117
+        return new Collection($this, $this->connection, (int) $row['id'], (string) $row['name'], $user, $access);
118
+    }
119
+
120
+    /**
121
+     * @param IUser $user
122
+     * @param string $filter
123
+     * @param int $limit
124
+     * @param int $start
125
+     * @return ICollection[]
126
+     * @since 16.0.0
127
+     */
128
+    public function searchCollections(IUser $user, string $filter, int $limit = 50, int $start = 0): array {
129
+        $query = $this->connection->getQueryBuilder();
130
+        $userId = $user instanceof IUser ? $user->getUID() : '';
131
+
132
+        $query->select('c.*', 'a.access')
133
+            ->from(self::TABLE_COLLECTIONS, 'c')
134
+            ->leftJoin(
135
+                'c', self::TABLE_ACCESS_CACHE, 'a',
136
+                $query->expr()->andX(
137
+                    $query->expr()->eq('c.id', 'a.collection_id'),
138
+                    $query->expr()->eq('a.user_id', $query->createNamedParameter($userId, IQueryBuilder::PARAM_STR))
139
+                )
140
+            )
141
+            ->where($query->expr()->iLike('c.name', $query->createNamedParameter($filter, IQueryBuilder::PARAM_STR)))
142
+            ->andWhere($query->expr()->eq('a.access', $query->createNamedParameter(1, IQueryBuilder::PARAM_INT)))
143
+            ->orderBy('c.id')
144
+            ->setMaxResults($limit)
145
+            ->setFirstResult($start);
146
+        $result = $query->execute();
147
+        $collections = [];
148
+
149
+        $foundResults = 0;
150
+        while ($row = $result->fetch()) {
151
+            $foundResults++;
152
+            $access = $row['access'] === null ? null : (bool) $row['access'];
153
+            $collection = new Collection($this, $this->connection, (int)$row['id'], (string)$row['name'], $user, $access);
154
+            if ($collection->canAccess($user)) {
155
+                $collections[] = $collection;
156
+            }
157
+        }
158
+        $result->closeCursor();
159
+
160
+        if (empty($collections) && $foundResults === $limit) {
161
+            $this->searchCollections($user, $filter, $limit, $start + $limit);
162
+        }
163
+
164
+        return $collections;
165
+    }
166
+
167
+    /**
168
+     * @param string $name
169
+     * @return ICollection
170
+     * @since 16.0.0
171
+     */
172
+    public function newCollection(string $name): ICollection {
173
+        $query = $this->connection->getQueryBuilder();
174
+        $query->insert(self::TABLE_COLLECTIONS)
175
+            ->values([
176
+                'name' => $query->createNamedParameter($name),
177
+            ]);
178
+        $query->execute();
179
+
180
+        return new Collection($this, $this->connection, $query->getLastInsertId(), $name);
181
+    }
182
+
183
+    /**
184
+     * @param string $type
185
+     * @param string $id
186
+     * @return IResource
187
+     * @since 16.0.0
188
+     */
189
+    public function createResource(string $type, string $id): IResource {
190
+        return new Resource($this, $this->connection, $type, $id);
191
+    }
192
+
193
+    /**
194
+     * @param string $type
195
+     * @param string $id
196
+     * @param IUser|null $user
197
+     * @return IResource
198
+     * @throws ResourceException
199
+     * @since 16.0.0
200
+     */
201
+    public function getResourceForUser(string $type, string $id, ?IUser $user): IResource {
202
+        $query = $this->connection->getQueryBuilder();
203
+        $userId = $user instanceof IUser ? $user->getUID() : '';
204
+
205
+        $query->select('r.*', 'a.access')
206
+            ->from(self::TABLE_RESOURCES, 'r')
207
+            ->leftJoin(
208
+                'r', self::TABLE_ACCESS_CACHE, 'a',
209
+                $query->expr()->andX(
210
+                    $query->expr()->eq('r.resource_id', 'a.resource_id'),
211
+                    $query->expr()->eq('r.resource_type', 'a.resource_type'),
212
+                    $query->expr()->eq('a.user_id', $query->createNamedParameter($userId, IQueryBuilder::PARAM_STR))
213
+                )
214
+            )
215
+            ->where($query->expr()->eq('r.resource_type', $query->createNamedParameter($type, IQueryBuilder::PARAM_STR)))
216
+            ->andWhere($query->expr()->eq('r.resource_id', $query->createNamedParameter($id, IQueryBuilder::PARAM_STR)));
217
+        $result = $query->execute();
218
+        $row = $result->fetch();
219
+        $result->closeCursor();
220
+
221
+        if (!$row) {
222
+            throw new ResourceException('Resource not found');
223
+        }
224
+
225
+        $access = $row['access'] === null ? null : (bool) $row['access'];
226
+        if ($user instanceof IUser) {
227
+            return new Resource($this, $this->connection, $type, $id, $user, $access);
228
+        }
229
+
230
+        return new Resource($this, $this->connection, $type, $id, null, $access);
231
+    }
232
+
233
+    /**
234
+     * @param ICollection $collection
235
+     * @param IUser|null $user
236
+     * @return IResource[]
237
+     * @since 16.0.0
238
+     */
239
+    public function getResourcesByCollectionForUser(ICollection $collection, ?IUser $user): array {
240
+        $query = $this->connection->getQueryBuilder();
241
+        $userId = $user instanceof IUser ? $user->getUID() : '';
242
+
243
+        $query->select('r.*', 'a.access')
244
+            ->from(self::TABLE_RESOURCES, 'r')
245
+            ->leftJoin(
246
+                'r', self::TABLE_ACCESS_CACHE, 'a',
247
+                $query->expr()->andX(
248
+                    $query->expr()->eq('r.resource_id', 'a.resource_id'),
249
+                    $query->expr()->eq('r.resource_type', 'a.resource_type'),
250
+                    $query->expr()->eq('a.user_id', $query->createNamedParameter($userId, IQueryBuilder::PARAM_STR))
251
+                )
252
+            )
253
+            ->where($query->expr()->eq('r.collection_id', $query->createNamedParameter($collection->getId(), IQueryBuilder::PARAM_INT)));
254
+
255
+        $resources = [];
256
+        $result = $query->execute();
257
+        while ($row = $result->fetch()) {
258
+            $access = $row['access'] === null ? null : (bool) $row['access'];
259
+            $resources[] = new Resource($this, $this->connection, $row['resource_type'], $row['resource_id'], $user, $access);
260
+        }
261
+        $result->closeCursor();
262
+
263
+        return $resources;
264
+    }
265
+
266
+    /**
267
+     * @return IProvider[]
268
+     * @since 16.0.0
269
+     */
270
+    public function getProviders(): array {
271
+        if (!empty($this->providers)) {
272
+            foreach ($this->providers as $provider) {
273
+                try {
274
+                    $this->providerInstances[] = \OC::$server->query($provider);
275
+                } catch (QueryException $e) {
276
+                    $this->logger->logException($e, [
277
+                        'message' => 'Error when instantiating resource provider'
278
+                    ]);
279
+                }
280
+            }
281
+            $this->providers = [];
282
+        }
283
+
284
+        return $this->providerInstances;
285
+    }
286
+
287
+    /**
288
+     * Get the rich object data of a resource
289
+     *
290
+     * @param IResource $resource
291
+     * @return array
292
+     * @since 16.0.0
293
+     */
294
+    public function getResourceRichObject(IResource $resource): array {
295
+        foreach ($this->getProviders() as $provider) {
296
+            if ($provider->getType() === $resource->getType()) {
297
+                try {
298
+                    return $provider->getResourceRichObject($resource);
299
+                } catch (ResourceException $e) {
300
+                }
301
+            }
302
+        }
303
+
304
+        return [];
305
+    }
306
+
307
+    /**
308
+     * Can a user/guest access the collection
309
+     *
310
+     * @param IResource $resource
311
+     * @param IUser|null $user
312
+     * @return bool
313
+     * @since 16.0.0
314
+     */
315
+    public function canAccessResource(IResource $resource, ?IUser $user): bool {
316
+        $access = $this->checkAccessCacheForUserByResource($resource, $user);
317
+        if (\is_bool($access)) {
318
+            return $access;
319
+        }
320
+
321
+        $access = false;
322
+        foreach ($this->getProviders() as $provider) {
323
+            if ($provider->getType() === $resource->getType()) {
324
+                try {
325
+                    if ($provider->canAccessResource($resource, $user)) {
326
+                        $access = true;
327
+                        break;
328
+                    }
329
+                } catch (ResourceException $e) {
330
+                }
331
+            }
332
+        }
333
+
334
+        $this->cacheAccessForResource($resource, $user, $access);
335
+        return $access;
336
+    }
337
+
338
+    /**
339
+     * Can a user/guest access the collection
340
+     *
341
+     * @param ICollection $collection
342
+     * @param IUser|null $user
343
+     * @return bool
344
+     * @since 16.0.0
345
+     */
346
+    public function canAccessCollection(ICollection $collection, ?IUser $user): bool {
347
+        $access = $this->checkAccessCacheForUserByCollection($collection, $user);
348
+        if (\is_bool($access)) {
349
+            return $access;
350
+        }
351
+
352
+        $access = false;
353
+        foreach ($collection->getResources() as $resource) {
354
+            if ($resource->canAccess($user)) {
355
+                $access = true;
356
+                break;
357
+            }
358
+        }
359
+
360
+        $this->cacheAccessForCollection($collection, $user, $access);
361
+        return $access;
362
+    }
363
+
364
+    protected function checkAccessCacheForUserByResource(IResource $resource, ?IUser $user): ?bool {
365
+        $query = $this->connection->getQueryBuilder();
366
+        $userId = $user instanceof IUser ? $user->getUID() : '';
367
+
368
+        $query->select('access')
369
+            ->from(self::TABLE_ACCESS_CACHE)
370
+            ->where($query->expr()->eq('resource_id', $query->createNamedParameter($resource->getId(), IQueryBuilder::PARAM_STR)))
371
+            ->andWhere($query->expr()->eq('resource_type', $query->createNamedParameter($resource->getType(), IQueryBuilder::PARAM_STR)))
372
+            ->andWhere($query->expr()->eq('user_id', $query->createNamedParameter($userId, IQueryBuilder::PARAM_STR)))
373
+            ->setMaxResults(1);
374
+
375
+        $hasAccess = null;
376
+        $result = $query->execute();
377
+        if ($row = $result->fetch()) {
378
+            $hasAccess = (bool) $row['access'];
379
+        }
380
+        $result->closeCursor();
381
+
382
+        return $hasAccess;
383
+    }
384
+
385
+    protected function checkAccessCacheForUserByCollection(ICollection $collection, ?IUser $user): ?bool {
386
+        $query = $this->connection->getQueryBuilder();
387
+        $userId = $user instanceof IUser ? $user->getUID() : '';
388
+
389
+        $query->select('access')
390
+            ->from(self::TABLE_ACCESS_CACHE)
391
+            ->where($query->expr()->eq('collection_id', $query->createNamedParameter($collection->getId(), IQueryBuilder::PARAM_INT)))
392
+            ->andWhere($query->expr()->eq('user_id', $query->createNamedParameter($userId, IQueryBuilder::PARAM_STR)))
393
+            ->setMaxResults(1);
394
+
395
+        $hasAccess = null;
396
+        $result = $query->execute();
397
+        if ($row = $result->fetch()) {
398
+            $hasAccess = (bool) $row['access'];
399
+        }
400
+        $result->closeCursor();
401
+
402
+        return $hasAccess;
403
+    }
404
+
405
+    public function cacheAccessForResource(IResource $resource, ?IUser $user, bool $access): void {
406
+        $query = $this->connection->getQueryBuilder();
407
+        $userId = $user instanceof IUser ? $user->getUID() : '';
408
+
409
+        $query->insert(self::TABLE_ACCESS_CACHE)
410
+            ->values([
411
+                'user_id' => $query->createNamedParameter($userId),
412
+                'resource_id' => $query->createNamedParameter($resource->getId()),
413
+                'resource_type' => $query->createNamedParameter($resource->getType()),
414
+                'access' => $query->createNamedParameter($access),
415
+            ]);
416
+        try {
417
+            $query->execute();
418
+        } catch (UniqueConstraintViolationException $e) {
419
+        }
420
+    }
421
+
422
+    public function cacheAccessForCollection(ICollection $collection, ?IUser $user, bool $access): void {
423
+        $query = $this->connection->getQueryBuilder();
424
+        $userId = $user instanceof IUser ? $user->getUID() : '';
425
+
426
+        $query->insert(self::TABLE_ACCESS_CACHE)
427
+            ->values([
428
+                'user_id' => $query->createNamedParameter($userId),
429
+                'collection_id' => $query->createNamedParameter($collection->getId()),
430
+                'access' => $query->createNamedParameter($access),
431
+            ]);
432
+        try {
433
+            $query->execute();
434
+        } catch (UniqueConstraintViolationException $e) {
435
+        }
436
+    }
437
+
438
+    public function invalidateAccessCacheForUser(?IUser $user): void {
439
+        $query = $this->connection->getQueryBuilder();
440
+        $userId = $user instanceof IUser ? $user->getUID() : '';
441
+
442
+        $query->delete(self::TABLE_ACCESS_CACHE)
443
+            ->where($query->expr()->eq('user_id', $query->createNamedParameter($userId)));
444
+        $query->execute();
445
+    }
446
+
447
+    public function invalidateAccessCacheForResource(IResource $resource): void {
448
+        $query = $this->connection->getQueryBuilder();
449
+
450
+        $query->delete(self::TABLE_ACCESS_CACHE)
451
+            ->where($query->expr()->eq('resource_id', $query->createNamedParameter($resource->getId())))
452
+            ->andWhere($query->expr()->eq('resource_type', $query->createNamedParameter($resource->getType(), IQueryBuilder::PARAM_STR)));
453
+        $query->execute();
454
+
455
+        foreach ($resource->getCollections() as $collection) {
456
+            $this->invalidateAccessCacheForCollection($collection);
457
+        }
458
+    }
459
+
460
+    public function invalidateAccessCacheForCollection(ICollection $collection): void {
461
+        $query = $this->connection->getQueryBuilder();
462
+
463
+        $query->delete(self::TABLE_ACCESS_CACHE)
464
+            ->where($query->expr()->eq('collection_id', $query->createNamedParameter($collection->getId())));
465
+        $query->execute();
466
+    }
467
+
468
+    public function invalidateAccessCacheForProvider(IProvider $provider): void {
469
+        $query = $this->connection->getQueryBuilder();
470
+
471
+        $query->delete(self::TABLE_ACCESS_CACHE)
472
+            ->where($query->expr()->eq('resource_type', $query->createNamedParameter($provider->getType(), IQueryBuilder::PARAM_STR)));
473
+        $query->execute();
474
+    }
475
+
476
+    public function invalidateAccessCacheForResourceByUser(IResource $resource, ?IUser $user): void {
477
+        $query = $this->connection->getQueryBuilder();
478
+        $userId = $user instanceof IUser ? $user->getUID() : '';
479
+
480
+        $query->delete(self::TABLE_ACCESS_CACHE)
481
+            ->where($query->expr()->eq('resource_id', $query->createNamedParameter($resource->getId())))
482
+            ->andWhere($query->expr()->eq('user_id', $query->createNamedParameter($userId)));
483
+        $query->execute();
484
+
485
+        foreach ($resource->getCollections() as $collection) {
486
+            $this->invalidateAccessCacheForCollectionByUser($collection, $user);
487
+        }
488
+    }
489
+
490
+    protected function invalidateAccessCacheForCollectionByUser(ICollection $collection, ?IUser $user): void {
491
+        $query = $this->connection->getQueryBuilder();
492
+        $userId = $user instanceof IUser ? $user->getUID() : '';
493
+
494
+        $query->delete(self::TABLE_ACCESS_CACHE)
495
+            ->where($query->expr()->eq('collection_id', $query->createNamedParameter($collection->getId())))
496
+            ->andWhere($query->expr()->eq('user_id', $query->createNamedParameter($userId)));
497
+        $query->execute();
498
+    }
499
+
500
+    public function invalidateAccessCacheForProviderByUser(IProvider $provider, ?IUser $user): void {
501
+        $query = $this->connection->getQueryBuilder();
502
+        $userId = $user instanceof IUser ? $user->getUID() : '';
503
+
504
+        $query->delete(self::TABLE_ACCESS_CACHE)
505
+            ->where($query->expr()->eq('resource_type', $query->createNamedParameter($provider->getType(), IQueryBuilder::PARAM_STR)))
506
+            ->andWhere($query->expr()->eq('user_id', $query->createNamedParameter($userId)));
507
+        $query->execute();
508
+    }
509
+
510
+    /**
511
+     * @param string $provider
512
+     */
513
+    public function registerResourceProvider(string $provider): void {
514
+        $this->providers[] = $provider;
515
+    }
516
+
517
+    /**
518
+     * Get the resource type of the provider
519
+     *
520
+     * @return string
521
+     * @since 16.0.0
522
+     */
523
+    public function getType(): string {
524
+        return '';
525
+    }
526 526
 }
Please login to merge, or discard this patch.
lib/public/Collaboration/Resources/IResource.php 1 patch
Indentation   +28 added lines, -28 removed lines patch added patch discarded remove patch
@@ -29,36 +29,36 @@
 block discarded – undo
29 29
  */
30 30
 interface IResource {
31 31
 
32
-	/**
33
-	 * @return string
34
-	 * @since 16.0.0
35
-	 */
36
-	public function getType(): string;
32
+    /**
33
+     * @return string
34
+     * @since 16.0.0
35
+     */
36
+    public function getType(): string;
37 37
 
38
-	/**
39
-	 * @return string
40
-	 * @since 16.0.0
41
-	 */
42
-	public function getId(): string;
38
+    /**
39
+     * @return string
40
+     * @since 16.0.0
41
+     */
42
+    public function getId(): string;
43 43
 
44
-	/**
45
-	 * @return array
46
-	 * @since 16.0.0
47
-	 */
48
-	public function getRichObject(): array;
44
+    /**
45
+     * @return array
46
+     * @since 16.0.0
47
+     */
48
+    public function getRichObject(): array;
49 49
 
50
-	/**
51
-	 * Can a user/guest access the resource
52
-	 *
53
-	 * @param IUser|null $user
54
-	 * @return bool
55
-	 * @since 16.0.0
56
-	 */
57
-	public function canAccess(?IUser $user): bool;
50
+    /**
51
+     * Can a user/guest access the resource
52
+     *
53
+     * @param IUser|null $user
54
+     * @return bool
55
+     * @since 16.0.0
56
+     */
57
+    public function canAccess(?IUser $user): bool;
58 58
 
59
-	/**
60
-	 * @return ICollection[]
61
-	 * @since 16.0.0
62
-	 */
63
-	public function getCollections(): array;
59
+    /**
60
+     * @return ICollection[]
61
+     * @since 16.0.0
62
+     */
63
+    public function getCollections(): array;
64 64
 }
Please login to merge, or discard this patch.
lib/public/Collaboration/Resources/IProvider.php 1 patch
Indentation   +24 added lines, -24 removed lines patch added patch discarded remove patch
@@ -29,31 +29,31 @@
 block discarded – undo
29 29
  */
30 30
 interface IProvider {
31 31
 
32
-	/**
33
-	 * Get the resource type of the provider
34
-	 *
35
-	 * @return string
36
-	 * @since 16.0.0
37
-	 */
38
-	public function getType(): string;
32
+    /**
33
+     * Get the resource type of the provider
34
+     *
35
+     * @return string
36
+     * @since 16.0.0
37
+     */
38
+    public function getType(): string;
39 39
 
40
-	/**
41
-	 * Get the rich object data of a resource
42
-	 *
43
-	 * @param IResource $resource
44
-	 * @return array
45
-	 * @since 16.0.0
46
-	 */
47
-	public function getResourceRichObject(IResource $resource): array;
40
+    /**
41
+     * Get the rich object data of a resource
42
+     *
43
+     * @param IResource $resource
44
+     * @return array
45
+     * @since 16.0.0
46
+     */
47
+    public function getResourceRichObject(IResource $resource): array;
48 48
 
49
-	/**
50
-	 * Can a user/guest access the collection
51
-	 *
52
-	 * @param IResource $resource
53
-	 * @param IUser|null $user
54
-	 * @return bool
55
-	 * @since 16.0.0
56
-	 */
57
-	public function canAccessResource(IResource $resource, ?IUser $user): bool;
49
+    /**
50
+     * Can a user/guest access the collection
51
+     *
52
+     * @param IResource $resource
53
+     * @param IUser|null $user
54
+     * @return bool
55
+     * @since 16.0.0
56
+     */
57
+    public function canAccessResource(IResource $resource, ?IUser $user): bool;
58 58
 
59 59
 }
Please login to merge, or discard this patch.
core/Controller/CollaborationResourcesController.php 1 patch
Indentation   +208 added lines, -208 removed lines patch added patch discarded remove patch
@@ -35,212 +35,212 @@
 block discarded – undo
35 35
 
36 36
 class CollaborationResourcesController extends OCSController {
37 37
 
38
-	/** @var IManager */
39
-	private $manager;
40
-
41
-	/** @var IUserSession */
42
-	private $userSession;
43
-
44
-	public function __construct(
45
-		string $appName,
46
-		IRequest $request,
47
-		IManager $manager,
48
-		IUserSession $userSession
49
-	) {
50
-		parent::__construct($appName, $request);
51
-
52
-		$this->manager = $manager;
53
-		$this->userSession = $userSession;
54
-	}
55
-
56
-	/**
57
-	 * @param int $collectionId
58
-	 * @return ICollection
59
-	 * @throws CollectionException when the collection was not found for the user
60
-	 */
61
-	protected function getCollection(int $collectionId): ICollection {
62
-		$collection = $this->manager->getCollectionForUser($collectionId, $this->userSession->getUser());
63
-
64
-		if (!$collection->canAccess($this->userSession->getUser())) {
65
-			throw new CollectionException('Not found');
66
-		}
67
-
68
-		return $collection;
69
-	}
70
-
71
-	/**
72
-	 * @NoAdminRequired
73
-	 *
74
-	 * @param int $collectionId
75
-	 * @return DataResponse
76
-	 */
77
-	public function listCollection(int $collectionId): DataResponse {
78
-		try {
79
-			$collection = $this->getCollection($collectionId);
80
-		} catch (CollectionException $e) {
81
-			return new DataResponse([], Http::STATUS_NOT_FOUND);
82
-		}
83
-
84
-		return new DataResponse($this->prepareCollection($collection));
85
-	}
86
-
87
-	/**
88
-	 * @NoAdminRequired
89
-	 *
90
-	 * @param string $filter
91
-	 * @return DataResponse
92
-	 */
93
-	public function searchCollections(string $filter): DataResponse {
94
-		try {
95
-			$collections = $this->manager->searchCollections($this->userSession->getUser(), $filter);
96
-		} catch (CollectionException $e) {
97
-			return new DataResponse([], Http::STATUS_NOT_FOUND);
98
-		}
99
-
100
-		return new DataResponse(array_map([$this, 'prepareCollection'], $collections));
101
-	}
102
-
103
-	/**
104
-	 * @NoAdminRequired
105
-	 *
106
-	 * @param int $collectionId
107
-	 * @param string $resourceType
108
-	 * @param string $resourceId
109
-	 * @return DataResponse
110
-	 */
111
-	public function addResource(int $collectionId, string $resourceType, string $resourceId): DataResponse {
112
-		try {
113
-			$collection = $this->getCollection($collectionId);
114
-		} catch (CollectionException $e) {
115
-			return new DataResponse([], Http::STATUS_NOT_FOUND);
116
-		}
117
-
118
-		$resource = $this->manager->createResource($resourceType, $resourceId);
119
-
120
-		if (!$resource->canAccess($this->userSession->getUser())) {
121
-			return new DataResponse([], Http::STATUS_NOT_FOUND);
122
-		}
123
-
124
-		try {
125
-			$collection->addResource($resource);
126
-		} catch (ResourceException $e) {
127
-		}
128
-
129
-		return new DataResponse($this->prepareCollection($collection));
130
-	}
131
-
132
-	/**
133
-	 * @NoAdminRequired
134
-	 *
135
-	 * @param int $collectionId
136
-	 * @param string $resourceType
137
-	 * @param string $resourceId
138
-	 * @return DataResponse
139
-	 */
140
-	public function removeResource(int $collectionId, string $resourceType, string $resourceId): DataResponse {
141
-		try {
142
-			$collection = $this->getCollection($collectionId);
143
-		} catch (CollectionException $e) {
144
-			return new DataResponse([], Http::STATUS_NOT_FOUND);
145
-		}
146
-
147
-		try {
148
-			$resource = $this->manager->getResourceForUser($resourceType, $resourceId, $this->userSession->getUser());
149
-		} catch (CollectionException $e) {
150
-			return new DataResponse([], Http::STATUS_NOT_FOUND);
151
-		}
152
-
153
-		$collection->removeResource($resource);
154
-
155
-		return new DataResponse($this->prepareCollection($collection));
156
-	}
157
-
158
-	/**
159
-	 * @NoAdminRequired
160
-	 *
161
-	 * @param string $resourceType
162
-	 * @param string $resourceId
163
-	 * @return DataResponse
164
-	 */
165
-	public function getCollectionsByResource(string $resourceType, string $resourceId): DataResponse {
166
-		try {
167
-			$resource = $this->manager->getResourceForUser($resourceType, $resourceId, $this->userSession->getUser());
168
-		} catch (ResourceException $e) {
169
-			$resource = $this->manager->createResource($resourceType, $resourceId);
170
-		}
171
-
172
-		if (!$resource->canAccess($this->userSession->getUser())) {
173
-			return new DataResponse([], Http::STATUS_NOT_FOUND);
174
-		}
175
-
176
-		return new DataResponse(array_map([$this, 'prepareCollection'], $resource->getCollections()));
177
-	}
178
-
179
-	/**
180
-	 * @NoAdminRequired
181
-	 *
182
-	 * @param string $baseResourceType
183
-	 * @param string $baseResourceId
184
-	 * @param string $name
185
-	 * @return DataResponse
186
-	 */
187
-	public function createCollectionOnResource(string $baseResourceType, string $baseResourceId, string $name): DataResponse {
188
-		if (!isset($name[0]) || isset($name[64])) {
189
-			return new DataResponse([], Http::STATUS_BAD_REQUEST);
190
-		}
191
-
192
-		try {
193
-			$resource = $this->manager->createResource($baseResourceType, $baseResourceId);
194
-		} catch (CollectionException $e) {
195
-			return new DataResponse([], Http::STATUS_NOT_FOUND);
196
-		}
197
-
198
-		if (!$resource->canAccess($this->userSession->getUser())) {
199
-			return new DataResponse([], Http::STATUS_NOT_FOUND);
200
-		}
201
-
202
-		$collection = $this->manager->newCollection($name);
203
-		$collection->addResource($resource);
204
-
205
-		return new DataResponse($this->prepareCollection($collection));
206
-	}
207
-
208
-	/**
209
-	 * @NoAdminRequired
210
-	 *
211
-	 * @param int $collectionId
212
-	 * @param string $collectionName
213
-	 * @return DataResponse
214
-	 */
215
-	public function renameCollection(int $collectionId, string $collectionName): DataResponse {
216
-		try {
217
-			$collection = $this->getCollection($collectionId);
218
-		} catch (CollectionException $exception) {
219
-			return new DataResponse([], Http::STATUS_NOT_FOUND);
220
-		}
221
-
222
-		$collection->setName($collectionName);
223
-
224
-		return new DataResponse($this->prepareCollection($collection));
225
-	}
226
-
227
-	protected function prepareCollection(ICollection $collection): array {
228
-		if (!$collection->canAccess($this->userSession->getUser())) {
229
-			return null;
230
-		}
231
-
232
-		return [
233
-			'id' => $collection->getId(),
234
-			'name' => $collection->getName(),
235
-			'resources' => array_values(array_filter(array_map([$this, 'prepareResources'], $collection->getResources()))),
236
-		];
237
-	}
238
-
239
-	protected function prepareResources(IResource $resource): ?array {
240
-		if (!$resource->canAccess($this->userSession->getUser())) {
241
-			return null;
242
-		}
243
-
244
-		return $resource->getRichObject();
245
-	}
38
+    /** @var IManager */
39
+    private $manager;
40
+
41
+    /** @var IUserSession */
42
+    private $userSession;
43
+
44
+    public function __construct(
45
+        string $appName,
46
+        IRequest $request,
47
+        IManager $manager,
48
+        IUserSession $userSession
49
+    ) {
50
+        parent::__construct($appName, $request);
51
+
52
+        $this->manager = $manager;
53
+        $this->userSession = $userSession;
54
+    }
55
+
56
+    /**
57
+     * @param int $collectionId
58
+     * @return ICollection
59
+     * @throws CollectionException when the collection was not found for the user
60
+     */
61
+    protected function getCollection(int $collectionId): ICollection {
62
+        $collection = $this->manager->getCollectionForUser($collectionId, $this->userSession->getUser());
63
+
64
+        if (!$collection->canAccess($this->userSession->getUser())) {
65
+            throw new CollectionException('Not found');
66
+        }
67
+
68
+        return $collection;
69
+    }
70
+
71
+    /**
72
+     * @NoAdminRequired
73
+     *
74
+     * @param int $collectionId
75
+     * @return DataResponse
76
+     */
77
+    public function listCollection(int $collectionId): DataResponse {
78
+        try {
79
+            $collection = $this->getCollection($collectionId);
80
+        } catch (CollectionException $e) {
81
+            return new DataResponse([], Http::STATUS_NOT_FOUND);
82
+        }
83
+
84
+        return new DataResponse($this->prepareCollection($collection));
85
+    }
86
+
87
+    /**
88
+     * @NoAdminRequired
89
+     *
90
+     * @param string $filter
91
+     * @return DataResponse
92
+     */
93
+    public function searchCollections(string $filter): DataResponse {
94
+        try {
95
+            $collections = $this->manager->searchCollections($this->userSession->getUser(), $filter);
96
+        } catch (CollectionException $e) {
97
+            return new DataResponse([], Http::STATUS_NOT_FOUND);
98
+        }
99
+
100
+        return new DataResponse(array_map([$this, 'prepareCollection'], $collections));
101
+    }
102
+
103
+    /**
104
+     * @NoAdminRequired
105
+     *
106
+     * @param int $collectionId
107
+     * @param string $resourceType
108
+     * @param string $resourceId
109
+     * @return DataResponse
110
+     */
111
+    public function addResource(int $collectionId, string $resourceType, string $resourceId): DataResponse {
112
+        try {
113
+            $collection = $this->getCollection($collectionId);
114
+        } catch (CollectionException $e) {
115
+            return new DataResponse([], Http::STATUS_NOT_FOUND);
116
+        }
117
+
118
+        $resource = $this->manager->createResource($resourceType, $resourceId);
119
+
120
+        if (!$resource->canAccess($this->userSession->getUser())) {
121
+            return new DataResponse([], Http::STATUS_NOT_FOUND);
122
+        }
123
+
124
+        try {
125
+            $collection->addResource($resource);
126
+        } catch (ResourceException $e) {
127
+        }
128
+
129
+        return new DataResponse($this->prepareCollection($collection));
130
+    }
131
+
132
+    /**
133
+     * @NoAdminRequired
134
+     *
135
+     * @param int $collectionId
136
+     * @param string $resourceType
137
+     * @param string $resourceId
138
+     * @return DataResponse
139
+     */
140
+    public function removeResource(int $collectionId, string $resourceType, string $resourceId): DataResponse {
141
+        try {
142
+            $collection = $this->getCollection($collectionId);
143
+        } catch (CollectionException $e) {
144
+            return new DataResponse([], Http::STATUS_NOT_FOUND);
145
+        }
146
+
147
+        try {
148
+            $resource = $this->manager->getResourceForUser($resourceType, $resourceId, $this->userSession->getUser());
149
+        } catch (CollectionException $e) {
150
+            return new DataResponse([], Http::STATUS_NOT_FOUND);
151
+        }
152
+
153
+        $collection->removeResource($resource);
154
+
155
+        return new DataResponse($this->prepareCollection($collection));
156
+    }
157
+
158
+    /**
159
+     * @NoAdminRequired
160
+     *
161
+     * @param string $resourceType
162
+     * @param string $resourceId
163
+     * @return DataResponse
164
+     */
165
+    public function getCollectionsByResource(string $resourceType, string $resourceId): DataResponse {
166
+        try {
167
+            $resource = $this->manager->getResourceForUser($resourceType, $resourceId, $this->userSession->getUser());
168
+        } catch (ResourceException $e) {
169
+            $resource = $this->manager->createResource($resourceType, $resourceId);
170
+        }
171
+
172
+        if (!$resource->canAccess($this->userSession->getUser())) {
173
+            return new DataResponse([], Http::STATUS_NOT_FOUND);
174
+        }
175
+
176
+        return new DataResponse(array_map([$this, 'prepareCollection'], $resource->getCollections()));
177
+    }
178
+
179
+    /**
180
+     * @NoAdminRequired
181
+     *
182
+     * @param string $baseResourceType
183
+     * @param string $baseResourceId
184
+     * @param string $name
185
+     * @return DataResponse
186
+     */
187
+    public function createCollectionOnResource(string $baseResourceType, string $baseResourceId, string $name): DataResponse {
188
+        if (!isset($name[0]) || isset($name[64])) {
189
+            return new DataResponse([], Http::STATUS_BAD_REQUEST);
190
+        }
191
+
192
+        try {
193
+            $resource = $this->manager->createResource($baseResourceType, $baseResourceId);
194
+        } catch (CollectionException $e) {
195
+            return new DataResponse([], Http::STATUS_NOT_FOUND);
196
+        }
197
+
198
+        if (!$resource->canAccess($this->userSession->getUser())) {
199
+            return new DataResponse([], Http::STATUS_NOT_FOUND);
200
+        }
201
+
202
+        $collection = $this->manager->newCollection($name);
203
+        $collection->addResource($resource);
204
+
205
+        return new DataResponse($this->prepareCollection($collection));
206
+    }
207
+
208
+    /**
209
+     * @NoAdminRequired
210
+     *
211
+     * @param int $collectionId
212
+     * @param string $collectionName
213
+     * @return DataResponse
214
+     */
215
+    public function renameCollection(int $collectionId, string $collectionName): DataResponse {
216
+        try {
217
+            $collection = $this->getCollection($collectionId);
218
+        } catch (CollectionException $exception) {
219
+            return new DataResponse([], Http::STATUS_NOT_FOUND);
220
+        }
221
+
222
+        $collection->setName($collectionName);
223
+
224
+        return new DataResponse($this->prepareCollection($collection));
225
+    }
226
+
227
+    protected function prepareCollection(ICollection $collection): array {
228
+        if (!$collection->canAccess($this->userSession->getUser())) {
229
+            return null;
230
+        }
231
+
232
+        return [
233
+            'id' => $collection->getId(),
234
+            'name' => $collection->getName(),
235
+            'resources' => array_values(array_filter(array_map([$this, 'prepareResources'], $collection->getResources()))),
236
+        ];
237
+    }
238
+
239
+    protected function prepareResources(IResource $resource): ?array {
240
+        if (!$resource->canAccess($this->userSession->getUser())) {
241
+            return null;
242
+        }
243
+
244
+        return $resource->getRichObject();
245
+    }
246 246
 }
Please login to merge, or discard this patch.