From 863d7cd4e4fa5ff8935b8575f219be5cfabc0e98 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Rapha=C3=ABl=20Gertz?= Date: Thu, 14 Nov 2024 08:47:35 +0100 Subject: [PATCH 1/1] Add element repository class with findOneByUidIdPathAsArray method --- Repository/ElementRepository.php | 197 +++++++++++++++++++++++++++++++ config/doctrine/Element.orm.yml | 2 +- 2 files changed, 198 insertions(+), 1 deletion(-) create mode 100644 Repository/ElementRepository.php diff --git a/Repository/ElementRepository.php b/Repository/ElementRepository.php new file mode 100644 index 0000000..c341517 --- /dev/null +++ b/Repository/ElementRepository.php @@ -0,0 +1,197 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Rapsys\TreeBundle\Repository; + +use Doctrine\ORM\Query\ResultSetMapping; + +use Rapsys\TreeBundle\Repository; + +/** + * Element repository + */ +class ElementRepository extends Repository { + /** + * Find element as array + * + * @param ?integer $uid The user id + * @param integer $id The element id + * @param string $path The element path + * @return ?array The element array + */ + public function findOneByUidIdPathAsArray(?int $uid, int $id, string $path): ?array { + //Set the request + $req = <<replace($req); + + //Get result set mapping instance + $rsm = new ResultSetMapping(); + + //Declare all fields + //XXX: see vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/Types.php + //addScalarResult($sqlColName, $resColName, $type = 'string'); + $rsm->addScalarResult('id', 'id', 'integer') + ->addScalarResult('path', 'path', 'string') + ->addScalarResult('created', 'created', 'datetime') + ->addScalarResult('updated', 'updated', 'datetime') + ->addScalarResult('modified', 'modified', 'datetime') + ->addScalarResult('a_id', 'a_id', 'integer') + ->addScalarResult('a_path', 'a_path', 'string') + ->addScalarResult('a_slug', 'a_slug', 'string') + ->addIndexByScalar('id'); + + //Get result + $result = $this->_em + ->createNativeQuery($req, $rsm) + ->setParameter('uid', $uid) + ->setParameter('id', $id) + ->setParameter('path', $path) + ->getOneOrNullResult(); + + //Check result + if ( + //Without result + $result === null || + //Without realpath + !($realpath = realpath($result['a_path'].($path?DIRECTORY_SEPARATOR.$path:''))) || + //Realpath not matching element path + $result['a_path'].($result['path']?DIRECTORY_SEPARATOR.$result['path']:'') !== substr($realpath, 0, strlen($result['a_path'].($result['path']?DIRECTORY_SEPARATOR.$result['path']:''))) + ) { + //Return null + return null; + } + + //Set breadcrumbs + $breadcrumbs = [ + //Add album + [ + 'name' => ucfirst($result['a_slug']), + 'link' => $alink = $this->router->generate('rapsystree_album', [ 'id' => $result['a_id'], 'path' => '', 'slug' => $result['a_slug'] ]) + ], + //Add element + [ + 'name' => $name = trim(str_replace('/', ' / ', '/'.$result['path'])), + 'link' => $link = $this->router->generate('rapsystree_element', [ 'id' => $result['id'], 'path' => $result['path'] ]) + ] + ]; + + //Set base + $base = $result['path']; + + //Iterate on intermediate breadcrumbs + foreach(array_slice(explode('/', substr($realpath, strlen($result['a_path'].($result['path']?DIRECTORY_SEPARATOR.$result['path']:'')))), 1) as $value) { + //Add breadcrumb + $breadcrumbs[] = [ + 'name' => ($base == '' ? '' : '/ ').$value, + 'link' => $this->router->generate('rapsystree_element', [ 'id' => $result['id'], 'path' => ($base .= ($base == '' ? '' : '/').$value) ]) + ]; + } + + //Set directories + $directories = []; + + //Set files + $files = []; + + //Set file + $file = []; + + //With directory + if (is_dir($realpath)) { + //Iterate on directory + foreach(array_diff(scandir($realpath), ['.', '..']) as $item) { + //TODO: exclude .svn, .git, .passwd, .*.un~, etc... (if not already protected by haproxy/apache) + + //Check item + if ( + //Without item realpath + !($itempath = realpath($realpath.DIRECTORY_SEPARATOR.$item)) || + //Item realpath not matching element path + $result['a_path'].($result['path']?DIRECTORY_SEPARATOR.$result['path']:'') !== substr($itempath, 0, strlen($result['a_path'].($result['path']?DIRECTORY_SEPARATOR.$result['path']:''))) + ) { + //Skip + continue; + } + + //With directory + if (is_dir($itempath)) { + //Append directory + $directories[$item.'/'] = $this->router->generate('rapsystree_element', [ 'id' => $result['id'], 'path' => $path.'/'.$item ]); + //With file + } elseif (is_file($itempath)) { + //Get file infos + $fileinfos = $this->file->infos($itempath); + + //Append file + $files[$fileinfos['name']] = [ + //Set link + 'link' => $this->router->generate('rapsystree_element', [ 'id' => $result['id'], 'path' => $path.'/'.$item ]) + ]+$fileinfos; + //With unknown type + } else { + //Throw 404 + throw new \Exception('Unknown element item type'); + } + } + //With file + } elseif (is_file($realpath)) { + //Get file infos + $fileinfos = $this->file->infos($realpath); + + //Append file + $file = [ + //Set link + 'link' => $this->router->generate('rapsystree_element', [ 'id' => $result['id'], 'path' => $path ]) + ]+$fileinfos; + //With unknown type + } else { + //Throw 404 + throw new \Exception('Unknown element type'); + } + + //Return element + return [ + 'id' => $result['id'], + 'name' => $name, + 'path' => $result['path'], + 'realpath' => $realpath, + 'link' => $link, + 'created' => $result['created'], + 'updated' => $result['updated'], + 'modified' => $result['modified'], + 'album' => [ + 'id' => $result['a_id'], + 'path' => $result['a_path'], + 'slug' => $result['a_slug'], + 'link' => $alink + ], + 'breadcrumbs' => $breadcrumbs, + 'directories' => $directories, + 'files' => $files, + 'file' => $file + ]; + } +} diff --git a/config/doctrine/Element.orm.yml b/config/doctrine/Element.orm.yml index bfd9d7b..208d299 100644 --- a/config/doctrine/Element.orm.yml +++ b/config/doctrine/Element.orm.yml @@ -1,6 +1,6 @@ Rapsys\TreeBundle\Entity\Element: type: entity - #repositoryClass: Rapsys\TreeBundle\Repository\ElementRepository + repositoryClass: Rapsys\TreeBundle\Repository\ElementRepository table: elements id: id: -- 2.41.1