diff --git a/public/js/pimcore/asset/tree.js b/public/js/pimcore/asset/tree.js index 8e9b289c4..15370b72e 100644 --- a/public/js/pimcore/asset/tree.js +++ b/public/js/pimcore/asset/tree.js @@ -277,7 +277,8 @@ url: Routing.generate('pimcore_admin_asset_exists'), params: { parentId: parentNode.id, - filename: file.name + filename: file.name, + dir: path }, async: false, success: function (response) { diff --git a/public/js/pimcore/document/editables/video.js b/public/js/pimcore/document/editables/video.js index 0153d9ae3..a7074d889 100644 --- a/public/js/pimcore/document/editables/video.js +++ b/public/js/pimcore/document/editables/video.js @@ -20,7 +20,6 @@ pimcore.document.editables.video = Class.create(pimcore.document.editable, { initialize: function($super, id, name, config, data, inherited) { $super(id, name, config, data, inherited); - data.allowedTypes = config.allowedTypes; this.data = data; }, diff --git a/src/Controller/Admin/Asset/AssetController.php b/src/Controller/Admin/Asset/AssetController.php index cf0434167..ac0fc8244 100644 --- a/src/Controller/Admin/Asset/AssetController.php +++ b/src/Controller/Admin/Asset/AssetController.php @@ -401,8 +401,20 @@ public function existsAction(Request $request): JsonResponse { $parentAsset = \Pimcore\Model\Asset::getById((int)$request->get('parentId')); + $dir = $request->get('dir', ''); + if ($dir) { + // this is for uploading folders with Drag&Drop + // param "dir" contains the relative path of the file + if (strpos($dir, '..') !== false) { + throw new \Exception('not allowed'); + } + $dir = '/' . trim($dir, '/ '); + } + + $assetPath = $parentAsset->getRealFullPath() . $dir . '/' . $request->get('filename'); + return new JsonResponse([ - 'exists' => Asset\Service::pathExists($parentAsset->getRealFullPath().'/'.$request->get('filename')), + 'exists' => Asset\Service::pathExists($assetPath), ]); } diff --git a/src/Helper/GridHelperService.php b/src/Helper/GridHelperService.php index 45ae42b87..9bab4b4d0 100644 --- a/src/Helper/GridHelperService.php +++ b/src/Helper/GridHelperService.php @@ -926,14 +926,20 @@ public function createXlsxExportFile(FilesystemOperator $storage, string $fileHa /** * A more performant alternative to "CONCAT(`path`,`key`) LIKE $fullpath" */ - private function optimizedConcatLike(string $fullpath): string + private function optimizedConcatLike(string $fullpath, string $type = 'object'): string { + //special case for the root folder + if ($fullpath === '/') { + return '`path` LIKE "/%"'; + } + $pathParts = explode('/', $fullpath); $leaf = array_pop($pathParts); $path = implode('/', $pathParts); + $queryColumn = $type === 'asset' ? '`filename`' : '`key`'; return '( - (`path` = "' . $path . '/" AND `key` = "' . $leaf . '") + (`path` = "' . $path . '/" AND ' . $queryColumn . ' = "' . $leaf . '") OR `path` LIKE "' . $fullpath . '/%" )'; @@ -943,18 +949,22 @@ private function optimizedConcatLike(string $fullpath): string * A more performant alternative to "CONCAT(`path`,`key`) NOT LIKE $fullpath" * Set $onlyChildren to true when you want to exclude the folder/element itself */ - private function optimizedConcatNotLike(string $fullpath, bool $onlyChildren = false): string - { + private function optimizedConcatNotLike( + string $fullpath, + bool $onlyChildren = false, + string $type = 'object' + ): string { $pathParts = explode('/', $fullpath); $leaf = array_pop($pathParts); $path = implode('/', $pathParts); + $queryColumn = $type === 'asset' ? '`filename`' : '`key`'; if ($onlyChildren) { return '`path` NOT LIKE "' . $fullpath . '/%"'; } return '( - (`path` != "' . $path . '/" AND `key` != "' . $leaf . '") + NOT (`path` = "' . $path . '/" AND ' . $queryColumn . ' = "' . $leaf . '") AND `path` NOT LIKE "' . $fullpath . '/%" )'; @@ -983,27 +993,29 @@ protected function getPermittedPathsByUser(string $type, User $user): string if ($exceptionsConcat !== '') { $exceptionsConcat.= ' OR '; } - $exceptionsConcat.= $this->optimizedConcatLike($path); + $exceptionsConcat.= $this->optimizedConcatLike($path, $type); } $exceptions = ' OR (' . $exceptionsConcat . ')'; //if any allowed child is found, the current folder can be listed but its content is still blocked $onlyChildren = true; } - $forbiddenPathSql[] = $this->optimizedConcatNotLike($forbiddenPath, $onlyChildren) . $exceptions; + $forbiddenPathSql[] = + '(' . $this->optimizedConcatNotLike($forbiddenPath, $onlyChildren, $type) . $exceptions . ')' + ; } foreach ($elementPaths['allowed'] as $allowedPaths) { - $allowedPathSql[] = $this->optimizedConcatLike($allowedPaths); + $allowedPathSql[] = $this->optimizedConcatLike($allowedPaths, $type); } // this is to avoid query error when implode is empty. // the result would be like `(((path1 OR path2) AND (not_path3 AND not_path4)))` $forbiddenAndAllowedSql = '('; - if ($allowedPathSql || $forbiddenPathSql) { + if (!empty($allowedPathSql) || !empty($forbiddenPathSql)) { $forbiddenAndAllowedSql .= '('; $forbiddenAndAllowedSql .= $allowedPathSql ? '( ' . implode(' OR ', $allowedPathSql) . ' )' : ''; - if ($forbiddenPathSql) { + if (!empty($forbiddenPathSql)) { //if $allowedPathSql "implosion" is present, we need `AND` in between $forbiddenAndAllowedSql .= $allowedPathSql ? ' AND ' : ''; $forbiddenAndAllowedSql .= implode(' AND ', $forbiddenPathSql);