* * 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 ]; } }