diff --git a/lib/Service/GroupFoldersService.php b/lib/Service/GroupFoldersService.php index 620b595..bc5a62f 100644 --- a/lib/Service/GroupFoldersService.php +++ b/lib/Service/GroupFoldersService.php @@ -2,7 +2,6 @@ declare(strict_types=1); - /** * Files_FullTextSearch - Index the content of your files * @@ -28,105 +27,67 @@ * */ - namespace OCA\Files_FullTextSearch\Service; -use ArtificialOwl\MySmallPhpTools\Traits\Nextcloud\nc22\TNC22Logger; -use ArtificialOwl\MySmallPhpTools\Traits\TArrayTools; use Exception; -use OCA\Files_FullTextSearch\AppInfo\Application; use OCA\Files_FullTextSearch\Exceptions\FileIsNotIndexableException; use OCA\Files_FullTextSearch\Exceptions\GroupFolderNotFoundException; use OCA\Files_FullTextSearch\Exceptions\KnownFileSourceException; use OCA\Files_FullTextSearch\Model\FilesDocument; use OCA\Files_FullTextSearch\Model\MountPoint; +use OCA\Files_FullTextSearch\Tools\Traits\TArrayTools; use OCA\GroupFolders\Folder\FolderManager; use OCP\App\IAppManager; +use OCP\Files\IMimeTypeLoader; use OCP\Files\Node; use OCP\FullTextSearch\Model\IIndex; use OCP\IDBConnection; use OCP\IGroupManager; -use OCP\Share\IManager; +use Psr\Log\LoggerInterface; -/** - * Class GroupFoldersService - * - * @package OCA\Files_FullTextSearch\Service - */ class GroupFoldersService { - use TNC22Logger; use TArrayTools; - - /** @var IManager */ - private $shareManager; - - /** @var IGroupManager */ - private $groupManager; - - /** @var FolderManager */ - private $folderManager; - - /** @var LocalFilesService */ - private $localFilesService; - - /** @var ConfigService */ - private $configService; - - /** @var MiscService */ - private $miscService; - - + private ?FolderManager $folderManager = null; /** @var MountPoint[] */ - private $groupFolders = []; - + private array $groupFolders = []; - /** - * GroupFoldersService constructor. - * - * @param string $userId - * @param IDBConnection $dbConnection - * @param IAppManager $appManager - * @param IManager $shareManager - * @param IGroupManager $groupManager - * @param LocalFilesService $localFilesService - * @param ConfigService $configService - * @param MiscService $miscService - */ public function __construct( - IDBConnection $dbConnection, IAppManager $appManager, IManager $shareManager, - IGroupManager $groupManager, LocalFilesService $localFilesService, - ConfigService $configService, MiscService $miscService + IDBConnection $dbConnection, + IAppManager $appManager, + IMimeTypeLoader $mimeTypeLoader, + private IGroupManager $groupManager, + private LocalFilesService $localFilesService, + ConfigService $configService, + private LoggerInterface $logger ) { if ($configService->getAppValue(ConfigService::FILES_GROUP_FOLDERS) === '1' && $appManager->isEnabledForUser('groupfolders')) { try { - $this->folderManager = new FolderManager($dbConnection); + $this->folderManager = new FolderManager( + $dbConnection, + $groupManager, + $mimeTypeLoader, + $logger + ); } catch (Exception $e) { return; } } - - $this->shareManager = $shareManager; - $this->groupManager = $groupManager; - $this->localFilesService = $localFilesService; - $this->configService = $configService; - $this->miscService = $miscService; - $this->setup('app', Application::APP_ID); } /** * @param string $userId */ - public function initGroupSharesForUser(string $userId) { + public function initGroupSharesForUser(string $userId): void { if ($this->folderManager === null) { return; } - $this->debug('initGroupSharesForUser request', ['userId' => $userId]); + $this->logger->debug('initGroupSharesForUser request', ['userId' => $userId]); $this->groupFolders = $this->getMountPoints($userId); - $this->debug('initGroupSharesForUser result', ['groupFolders' => $this->groupFolders]); + $this->logger->debug('initGroupSharesForUser result', ['groupFolders' => $this->groupFolders]); } @@ -136,7 +97,7 @@ public function initGroupSharesForUser(string $userId) { * * @throws KnownFileSourceException */ - public function getFileSource(Node $file, string &$source) { + public function getFileSource(Node $file, string &$source): void { if ($file->getMountPoint() ->getMountType() !== 'group' || $this->folderManager === null) { @@ -158,7 +119,7 @@ public function getFileSource(Node $file, string &$source) { * @param FilesDocument $document * @param Node $file */ - public function updateDocumentAccess(FilesDocument &$document, Node $file) { + public function updateDocumentAccess(FilesDocument $document, Node $file): void { if ($document->getSource() !== ConfigService::FILES_GROUP_FOLDERS) { return; } @@ -169,9 +130,14 @@ public function updateDocumentAccess(FilesDocument &$document, Node $file) { return; } - $access = $document->getAccess(); - $access->addGroups($mount->getGroups()); + foreach ($mount->getGroups() as $group) { + if ($this->groupManager->get($group) === null) { + $access->addCircle($group); + } else { + $access->addGroup($group); + } + } $document->getIndex() ->addOptionInt('group_folder_id', $mount->getId()); @@ -183,7 +149,7 @@ public function updateDocumentAccess(FilesDocument &$document, Node $file) { * @param FilesDocument $document * @param array $users */ - public function getShareUsers(FilesDocument $document, array &$users) { + public function getShareUsers(FilesDocument $document, array &$users): void { if ($document->getSource() !== ConfigService::FILES_GROUP_FOLDERS) { return; } @@ -200,7 +166,7 @@ public function getShareUsers(FilesDocument $document, array &$users) { */ private function getMountPoint(Node $file): MountPoint { foreach ($this->groupFolders as $mount) { - if (strpos($file->getPath(), $mount->getPath()) === 0) { + if (str_starts_with($file->getPath(), $mount->getPath())) { return $mount; } } @@ -233,7 +199,7 @@ private function getMountPoints(string $userId): array { /** * @param IIndex $index */ - public function impersonateOwner(IIndex $index) { + public function impersonateOwner(IIndex $index): void { if ($index->getSource() !== ConfigService::FILES_GROUP_FOLDERS) { return; } diff --git a/lib/Tools/Exceptions/ArrayNotFoundException.php b/lib/Tools/Exceptions/ArrayNotFoundException.php new file mode 100644 index 0000000..0a40afd --- /dev/null +++ b/lib/Tools/Exceptions/ArrayNotFoundException.php @@ -0,0 +1,10 @@ + + * @copyright 2018, Maxence Lange + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + + +namespace OCA\Files_FullTextSearch\Tools\Traits; + +use Exception; +use JsonSerializable; +use OCA\Files_FullTextSearch\Tools\Exceptions\ArrayNotFoundException; +use OCA\Files_FullTextSearch\Tools\Exceptions\ItemNotFoundException; +use OCA\Files_FullTextSearch\Tools\Exceptions\MalformedArrayException; +use OCA\Files_FullTextSearch\Tools\Exceptions\UnknownTypeException; + +trait TArrayTools { + public static $TYPE_NULL = 'Null'; + public static $TYPE_STRING = 'String'; + public static $TYPE_ARRAY = 'Array'; + public static $TYPE_BOOLEAN = 'Boolean'; + public static $TYPE_INTEGER = 'Integer'; + public static $TYPE_SERIALIZABLE = 'Serializable'; + + protected function get(string $k, array $arr, string $default = ''): string { + if (!array_key_exists($k, $arr)) { + $subs = explode('.', $k, 2); + if (sizeof($subs) > 1) { + if (!array_key_exists($subs[0], $arr)) { + return $default; + } + + $r = $arr[$subs[0]]; + if (!is_array($r)) { + return $default; + } + + return $this->get($subs[1], $r, $default); + } else { + return $default; + } + } + + if ($arr[$k] === null || !is_string($arr[$k]) && (!is_int($arr[$k]))) { + return $default; + } + + return (string)$arr[$k]; + } + + protected function getInt(string $k, array $arr, int $default = 0): int { + if (!array_key_exists($k, $arr)) { + $subs = explode('.', $k, 2); + if (sizeof($subs) > 1) { + if (!array_key_exists($subs[0], $arr)) { + return $default; + } + + $r = $arr[$subs[0]]; + if (!is_array($r)) { + return $default; + } + + return $this->getInt($subs[1], $r, $default); + } else { + return $default; + } + } + + if ($arr[$k] === null) { + return $default; + } + + return intval($arr[$k]); + } + + protected function getFloat(string $k, array $arr, float $default = 0): float { + if (!array_key_exists($k, $arr)) { + $subs = explode('.', $k, 2); + if (sizeof($subs) > 1) { + if (!array_key_exists($subs[0], $arr)) { + return $default; + } + + $r = $arr[$subs[0]]; + if (!is_array($r)) { + return $default; + } + + return $this->getFloat($subs[1], $r, $default); + } else { + return $default; + } + } + + if ($arr[$k] === null) { + return $default; + } + + return intval($arr[$k]); + } + + protected function getBool(string $k, array $arr, bool $default = false): bool { + if (!array_key_exists($k, $arr)) { + $subs = explode('.', $k, 2); + if (sizeof($subs) > 1) { + if (!array_key_exists($subs[0], $arr)) { + return $default; + } + + return $this->getBool($subs[1], $arr[$subs[0]], $default); + } else { + return $default; + } + } + + if ($arr[$k] === null) { + return $default; + } + + if (is_bool($arr[$k])) { + return $arr[$k]; + } + + $sk = (string)$arr[$k]; + if ($sk === '1' || strtolower($sk) === 'true') { + return true; + } + + if ($sk === '0' || strtolower($sk) === 'false') { + return false; + } + + return $default; + } + + protected function getObj(string $k, array $arr, ?JsonSerializable $default = null): ?JsonSerializable { + if (!array_key_exists($k, $arr)) { + $subs = explode('.', $k, 2); + if (sizeof($subs) > 1) { + if (!array_key_exists($subs[0], $arr)) { + return $default; + } + + return $this->getObj($subs[1], $arr[$subs[0]], $default); + } else { + return $default; + } + } + + return $arr[$k]; + } + + protected function getArray(string $k, array $arr, array $default = []): array { + if (!array_key_exists($k, $arr)) { + $subs = explode('.', $k, 2); + if (sizeof($subs) > 1) { + if (!array_key_exists($subs[0], $arr)) { + return $default; + } + + $r = $arr[$subs[0]]; + if (!is_array($r)) { + return $default; + } + + return $this->getArray($subs[1], $r, $default); + } else { + return $default; + } + } + + $r = $arr[$k]; + if ($r === null || (!is_array($r) && !is_string($r))) { + return $default; + } + + if (is_string($r)) { + $r = json_decode($r, true); + } + + if (!is_array($r)) { + return $default; + } + + return $r; + } + + public function validKey(string $k, array $arr): bool { + if (array_key_exists($k, $arr)) { + return true; + } + + $subs = explode('.', $k, 2); + if (sizeof($subs) > 1) { + if (!array_key_exists($subs[0], $arr)) { + return false; + } + + $r = $arr[$subs[0]]; + if (!is_array($r)) { + return false; + } + + return $this->validKey($subs[1], $r); + } + + return false; + } + + + /** + * @param string $k + * @param array $arr + * @param array $import + * @param array $default + * + * @return array + */ + protected function getList(string $k, array $arr, array $import, array $default = []): array { + $list = $this->getArray($k, $arr, $default); + + $r = []; + list($obj, $method) = $import; + foreach ($list as $item) { + try { + $o = new $obj(); + $o->$method($item); + + $r[] = $o; + } catch (Exception $e) { + } + } + + return $r; + } + + + /** + * @param string $k + * @param string $value + * @param array $list + * + * @return mixed + * @throws ArrayNotFoundException + */ + protected function extractArray(string $k, string $value, array $list) { + foreach ($list as $arr) { + if (!array_key_exists($k, $arr)) { + continue; + } + + if ($arr[$k] === $value) { + return $arr; + } + } + + throw new ArrayNotFoundException(); + } + + + /** + * @param string $key + * @param array $arr + * @param bool $root + * + * @return string + * @throws ItemNotFoundException + * @throws UnknownTypeException + */ + public function typeOf(string $key, array $arr, bool $root = true): string { + if (array_key_exists($key, $arr)) { + $item = $arr[$key]; + + if (is_null($item)) { + return self::$TYPE_NULL; + } + + if (is_string($item)) { + return self::$TYPE_STRING; + } + + if (is_array($item)) { + return self::$TYPE_ARRAY; + } + + if (is_bool($item)) { + return self::$TYPE_BOOLEAN; + } + + if (is_int($item)) { + return self::$TYPE_INTEGER; + } + + if ($item instanceof JsonSerializable) { + return self::$TYPE_SERIALIZABLE; + } + + throw new UnknownTypeException(); + } + + $subs = explode('.', $key, 2); + if (sizeof($subs) > 1) { + if (!array_key_exists($subs[0], $arr)) { + throw new ItemNotFoundException(); + } + + $r = $arr[$subs[0]]; + if (is_array($r)) { + return $this->typeOf($subs[1], $r); + } + } + + throw new ItemNotFoundException(); + } + + + /** + * @param array $keys + * @param array $arr + * + * @throws MalformedArrayException + */ + protected function mustContains(array $keys, array $arr) { + foreach ($keys as $key) { + if (!array_key_exists($key, $arr)) { + throw new MalformedArrayException( + 'source: ' . json_encode($arr) . ' - missing key: ' . $key + ); + } + } + } + + + /** + * @param array $arr + */ + protected function cleanArray(array &$arr) { + $arr = array_filter( + $arr, + function ($v) { + if (is_string($v)) { + return ($v !== ''); + } + if (is_array($v)) { + return !empty($v); + } + + return true; + } + ); + } +}