1 <?php 
declare(strict_types
=1); 
   4  * This file is part of the Rapsys TreeBundle package. 
   6  * (c) Raphaël Gertz <symfony@rapsys.eu> 
   8  * For the full copyright and license information, please view the LICENSE 
   9  * file that was distributed with this source code. 
  12 namespace Rapsys\TreeBundle\Repository
; 
  14 use Doctrine\ORM\Query\ResultSetMapping
; 
  16 use Rapsys\TreeBundle\Repository
; 
  21 class AlbumRepository 
extends Repository 
{ 
  23          * Find album count as int 
  25          * @param ?integer $uid The user id 
  26          * @return integer The albums count 
  28         public function countByUidAsInt(?int $uid): int { 
  44 SELECT COUNT(DISTINCT a.album_id) AS count 
  45 FROM Rapsys\TreeBundle\Entity\Element AS a 
  49                 //Get result set mapping instance 
  50                 $req = $this->replace($req); 
  52                 //Get result set mapping instance 
  53                 //XXX: DEBUG: see ../blog.orig/src/Rapsys/BlogBundle/Repository/ArticleRepository.php 
  54                 $rsm = new ResultSetMapping(); 
  57                 //XXX: see vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/Types.php 
  58                 //addScalarResult($sqlColName, $resColName, $type = 'string'); 
  59                 $rsm->addScalarResult('count', 'count', 'integer'); 
  63                         ->createNativeQuery($req, $rsm) 
  64                         ->setParameter('uid', $uid) 
  65                         ->getSingleScalarResult(); 
  69          * Find albums as array 
  71          * @param ?integer $uid The user id 
  72          * @param integer $page The page 
  73          * @param integer $count The count 
  74          * @return array The albums array 
  76         public function findByUidAsArray(?int $uid, int $page, int $count): array { 
  83         GREATEST(a.created, e.created) AS created, 
  84         GREATEST(a.updated, e.updated) AS updated, 
  85         GREATEST(a.created, e.created, a.updated, e.updated) AS modified, 
  86         GROUP_CONCAT(e.id ORDER BY e.id SEPARATOR "\\n") AS e_ids, 
  87         GROUP_CONCAT(e.path ORDER BY e.id SEPARATOR "\\n") AS e_paths 
  88 FROM Rapsys\TreeBundle\Entity\Album AS a 
  89 JOIN Rapsys\TreeBundle\Entity\Element AS e ON (e.album_id = a.id AND e.user_id IN (NULL, :uid)) 
  91 ORDER BY updated, created DESC, a.id 
  95                 //Replace bundle entity name by table name 
  96                 $req = $this->replace($req); 
  98                 //Get result set mapping instance 
  99                 $rsm = new ResultSetMapping(); 
 102                 //XXX: see vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/Types.php 
 103                 //addScalarResult($sqlColName, $resColName, $type = 'string'); 
 104                 $rsm->addScalarResult('id', 'id', 'integer') 
 105                         ->addScalarResult('path', 'path', 'string') 
 106                         ->addScalarResult('slug', 'slug', 'string') 
 107                         ->addScalarResult('created', 'created', 'datetime') 
 108                         ->addScalarResult('updated', 'updated', 'datetime') 
 109                         ->addScalarResult('modified', 'modified', 'datetime') 
 110                         ->addScalarResult('e_ids', 'e_ids', 'string') 
 111                         ->addScalarResult('e_paths', 'e_paths', 'string') 
 112                         ->addIndexByScalar('id'); 
 116                         ->createNativeQuery($req, $rsm) 
 117                         ->setParameter('offset', $page * $count) 
 118                         ->setParameter('count', $count) 
 119                         ->setParameter('uid', $uid) 
 125                 //Iterate on each album 
 126                 foreach($result as $data) { 
 128                         $return[$data['id']] = [ 
 129                                 'id' => $id = $data['id'], 
 130                                 'slug' => $slug = $data['slug'], 
 131                                 'path' => $data['path'], 
 132                                 'created' => $data['created'], 
 133                                 'updated' => $data['updated'], 
 134                                 'modified' => $data['modified'], 
 135                                 'link' => $this->router
->generate('rapsystree_album', [ 'id' => $id, 'slug' => $slug ]), 
 139                         //Explode element ids 
 140                         $data['e_ids'] = explode("\n", $data['e_ids']); 
 142                         //Explode element paths 
 143                         $data['e_paths'] = explode("\n", $data['e_paths']); 
 145                         foreach($data['e_ids'] as $e => $eid) { 
 146                                 $return[$data['id']]['elements'][$eid] = [ 
 148                                         'name' => trim(str_replace('/', ' / ', '/'.($path = $data['e_paths'][$e]))), 
 150                                         'link' => $this->router
->generate('rapsystree_element', [ 'id' => $eid, 'path' => $path ]), 
 160          * Find album as array 
 162          * @param integer $id The album id 
 163          * @param string $path The album path 
 164          * @return ?array The album array 
 166         public function findOneByIdPathAsArray(int $id, string $path): ?array { 
 173         GREATEST(a.created, e.created) AS created, 
 174         GREATEST(a.updated, e.updated) AS updated, 
 175         GREATEST(a.created, e.created, a.updated, e.updated) AS modified, 
 176         GROUP_CONCAT(e.id ORDER BY e.id SEPARATOR "\\n") AS e_ids, 
 177         GROUP_CONCAT(e.path ORDER BY e.id SEPARATOR "\\n") AS e_paths, 
 178         GROUP_CONCAT(e.user_id ORDER BY e.id SEPARATOR "\\n") AS e_uids 
 179 FROM Rapsys\TreeBundle\Entity\Album AS a 
 180 JOIN Rapsys\TreeBundle\Entity\Element AS e ON (e.album_id = a.id) 
 184                 //Replace bundle entity name by table name 
 185                 $req = $this->replace($req); 
 187                 //Get result set mapping instance 
 188                 $rsm = new ResultSetMapping(); 
 191                 //XXX: see vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/Types.php 
 192                 //addScalarResult($sqlColName, $resColName, $type = 'string'); 
 193                 $rsm->addScalarResult('id', 'id', 'integer') 
 194                         ->addScalarResult('path', 'path', 'string') 
 195                         ->addScalarResult('slug', 'slug', 'string') 
 196                         ->addScalarResult('created', 'created', 'datetime') 
 197                         ->addScalarResult('updated', 'updated', 'datetime') 
 198                         ->addScalarResult('modified', 'modified', 'datetime') 
 199                         ->addScalarResult('e_ids', 'e_ids', 'string') 
 200                         ->addScalarResult('e_paths', 'e_paths', 'string') 
 201                         ->addScalarResult('e_uids', 'e_uids', 'string') 
 202                         ->addIndexByScalar('id'); 
 206                         ->createNativeQuery($req, $rsm) 
 207                         ->setParameter('id', $id) 
 208                         ->getOneOrNullResult(); 
 215                         !($realpath = realpath($result['path'].($path?DIRECTORY_SEPARATOR
.$path:''))) || 
 216                         //Realpath not matching element path 
 217                         $result['path'] !== substr($realpath, 0, strlen($result['path'])) 
 227                                 'name' => $name = ucfirst($slug = $result['slug']), 
 228                                 'link' => $link = $this->router
->generate('rapsystree_album', [ 'id' => $result['id'], 'path' => '', 'slug' => $slug ]) 
 235                 //Iterate on intermediate breadcrumbs 
 236                 foreach(array_slice(explode('/', substr($realpath, strlen($result['path']))), 1) as $value) { 
 239                                 'name' => '/ '.$value, 
 240                                 'link' => $this->router
->generate('rapsystree_album', [ 'id' => $result['id'], 'path' => ($base .= ($base == '' ? '' : '/').$value), 'slug' => $slug ]) 
 254                 if (is_dir($realpath)) { 
 255                         //Iterate on directory 
 256                         foreach(array_diff(scandir($realpath), ['.', '..']) as $item) { 
 257                                 //TODO: exclude .svn, .git, .passwd, .*.un~, etc... (if not already protected by haproxy/apache) 
 261                                         //Without item realpath 
 262                                         !($itempath = realpath($realpath.DIRECTORY_SEPARATOR
.$item)) || 
 263                                         //Item realpath not matching album path 
 264                                         $result['path'] !== substr($itempath, 0, strlen($result['path'])) 
 271                                 if (is_dir($itempath)) { 
 273                                         $directories[$item.'/'] = $this->router
->generate('rapsystree_album', [ 'id' => $result['id'], 'path' => ($path ? $path.'/' : '').$item, 'slug' => $slug ]); 
 275                                 } elseif (is_file($itempath)) { 
 277                                         $fileinfos = $this->file
->infos($itempath); 
 280                                         $files[$fileinfos['name']] = [ 
 282                                                 'link' => $this->router
->generate('rapsystree_album', [ 'id' => $result['id'], 'path' => ($path ? $path.'/' : '').$item, 'slug' => $slug ]) 
 287                                         throw new \
Exception('Unknown element item type'); 
 291                 } elseif (is_file($realpath)) { 
 293                         $fileinfos = $this->file
->infos($realpath); 
 298                                 'link' => $this->router
->generate('rapsystree_album', [ 'id' => $result['id'], 'path' => $path, 'slug' => $slug ]) 
 303                         throw new \
Exception('Unknown element type'); 
 308                         'id' => $result['id'], 
 310                         'path' => $result['path'], 
 312                         'created' => $result['created'], 
 313                         'updated' => $result['updated'], 
 314                         'modified' => $result['modified'], 
 317                         'breadcrumbs' => $breadcrumbs, 
 318                         'directories' => $directories, 
 323                 //Explode element ids 
 324                 $result['e_ids'] = explode("\n", $result['e_ids']); 
 326                 //Explode element paths 
 327                 $result['e_paths'] = explode("\n", $result['e_paths']); 
 329                 //Explode element uids 
 330                 $result['e_uids'] = explode("\n", $result['e_uids']); 
 332                 //Iterate on elements 
 333                 foreach($result['e_ids'] as $e => $eid) { 
 335                         $album['elements'][$eid] = [ 
 337                                 'name' => trim(str_replace('/', ' / ', '/'.($epath = $result['e_paths'][$e]))), 
 339                                 'uid' => $result['e_uids'][$e], 
 340                                 'link' => $this->router
->generate('rapsystree_album', ['id' => $result['id'], 'path' => $epath, 'slug' => $slug]),