* * 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; /** * Album repository */ class AlbumRepository extends Repository { /** * Find album count as int * * @param ?integer $uid The user id * @return integer The albums count */ public function countByUidAsInt(?int $uid): int { //Set user sql $userSql = <<replace($req); //Get result set mapping instance //XXX: DEBUG: see ../blog.orig/src/Rapsys/BlogBundle/Repository/ArticleRepository.php $rsm = new ResultSetMapping(); //Declare all fields //XXX: see vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/Types.php //addScalarResult($sqlColName, $resColName, $type = 'string'); $rsm->addScalarResult('count', 'count', 'integer'); //Get result return $this->_em ->createNativeQuery($req, $rsm) ->setParameter('uid', $uid) ->getSingleScalarResult(); } /** * Find albums as array * * @param ?integer $uid The user id * @param integer $page The page * @param integer $count The count * @return array The albums array */ public function findByUidAsArray(?int $uid, int $page, int $count): 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('slug', 'slug', 'string') ->addScalarResult('created', 'created', 'datetime') ->addScalarResult('updated', 'updated', 'datetime') ->addScalarResult('modified', 'modified', 'datetime') ->addScalarResult('e_ids', 'e_ids', 'string') ->addScalarResult('e_paths', 'e_paths', 'string') ->addIndexByScalar('id'); //Get result $result = $this->_em ->createNativeQuery($req, $rsm) ->setParameter('offset', $page * $count) ->setParameter('count', $count) ->setParameter('uid', $uid) ->getArrayResult(); //Set return $return = []; //Iterate on each album foreach($result as $data) { //Append album $return[$data['id']] = [ 'id' => $id = $data['id'], 'slug' => $slug = $data['slug'], 'path' => $data['path'], 'created' => $data['created'], 'updated' => $data['updated'], 'modified' => $data['modified'], 'link' => $this->router->generate('rapsystree_album', [ 'id' => $id, 'slug' => $slug ]), 'elements' => [] ]; //Explode element ids $data['e_ids'] = explode("\n", $data['e_ids']); //Explode element paths $data['e_paths'] = explode("\n", $data['e_paths']); foreach($data['e_ids'] as $e => $eid) { $return[$data['id']]['elements'][$eid] = [ 'id' => $eid, 'name' => trim(str_replace('/', ' / ', '/'.($path = $data['e_paths'][$e]))), 'path' => $path, 'link' => $this->router->generate('rapsystree_element', [ 'id' => $eid, 'path' => $path ]), ]; } } //Return return return $return; } /** * Find album as array * * @param integer $id The album id * @param string $path The album path * @return ?array The album array */ public function findOneByIdPathAsArray(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('slug', 'slug', 'string') ->addScalarResult('created', 'created', 'datetime') ->addScalarResult('updated', 'updated', 'datetime') ->addScalarResult('modified', 'modified', 'datetime') ->addScalarResult('e_ids', 'e_ids', 'string') ->addScalarResult('e_paths', 'e_paths', 'string') ->addScalarResult('e_uids', 'e_uids', 'string') ->addIndexByScalar('id'); //Get result $result = $this->_em ->createNativeQuery($req, $rsm) ->setParameter('id', $id) ->getOneOrNullResult(); //Check result if ( //Without result $result === null || //Without realpath !($realpath = realpath($result['path'].($path?DIRECTORY_SEPARATOR.$path:''))) || //Realpath not matching element path $result['path'] !== substr($realpath, 0, strlen($result['path'])) ) { //Return null return null; } //Set breadcrumbs $breadcrumbs = [ //Add album [ 'name' => $name = ucfirst($slug = $result['slug']), 'link' => $link = $this->router->generate('rapsystree_album', [ 'id' => $result['id'], 'path' => '', 'slug' => $slug ]) ] ]; //Set base $base = ''; //Iterate on intermediate breadcrumbs foreach(array_slice(explode('/', substr($realpath, strlen($result['path']))), 1) as $value) { //Add breadcrumb $breadcrumbs[] = [ 'name' => '/ '.$value, 'link' => $this->router->generate('rapsystree_album', [ 'id' => $result['id'], 'path' => ($base .= ($base == '' ? '' : '/').$value), 'slug' => $slug ]) ]; } //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 album path $result['path'] !== substr($itempath, 0, strlen($result['path'])) ) { //Skip continue; } //With directory if (is_dir($itempath)) { //Append directory $directories[$item.'/'] = $this->router->generate('rapsystree_album', [ 'id' => $result['id'], 'path' => ($path ? $path.'/' : '').$item, 'slug' => $slug ]); //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_album', [ 'id' => $result['id'], 'path' => ($path ? $path.'/' : '').$item, 'slug' => $slug ]) ]+$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_album', [ 'id' => $result['id'], 'path' => $path, 'slug' => $slug ]) ]+$fileinfos; //With unknown type } else { //Throw 404 throw new \Exception('Unknown element type'); } //Set album $album = [ 'id' => $result['id'], 'name' => $name, 'path' => $result['path'], 'slug' => $slug, 'created' => $result['created'], 'updated' => $result['updated'], 'modified' => $result['modified'], 'link' => $link, 'elements' => [], 'breadcrumbs' => $breadcrumbs, 'directories' => $directories, 'files' => $files, 'file' => $file ]; //Explode element ids $result['e_ids'] = explode("\n", $result['e_ids']); //Explode element paths $result['e_paths'] = explode("\n", $result['e_paths']); //Explode element uids $result['e_uids'] = explode("\n", $result['e_uids']); //Iterate on elements foreach($result['e_ids'] as $e => $eid) { //Append element $album['elements'][$eid] = [ 'id' => $eid, 'name' => trim(str_replace('/', ' / ', '/'.($epath = $result['e_paths'][$e]))), 'path' => $epath, 'uid' => $result['e_uids'][$e], 'link' => $this->router->generate('rapsystree_album', ['id' => $result['id'], 'path' => $epath, 'slug' => $slug]), ]; } //Return album return $album; } }