diff options
Diffstat (limited to 'src/Wallabag/CoreBundle/Repository')
-rw-r--r-- | src/Wallabag/CoreBundle/Repository/EntryRepository.php | 99 |
1 files changed, 88 insertions, 11 deletions
diff --git a/src/Wallabag/CoreBundle/Repository/EntryRepository.php b/src/Wallabag/CoreBundle/Repository/EntryRepository.php index cebce714..880e7c65 100644 --- a/src/Wallabag/CoreBundle/Repository/EntryRepository.php +++ b/src/Wallabag/CoreBundle/Repository/EntryRepository.php | |||
@@ -3,11 +3,13 @@ | |||
3 | namespace Wallabag\CoreBundle\Repository; | 3 | namespace Wallabag\CoreBundle\Repository; |
4 | 4 | ||
5 | use Doctrine\ORM\EntityRepository; | 5 | use Doctrine\ORM\EntityRepository; |
6 | use Doctrine\ORM\NoResultException; | ||
6 | use Doctrine\ORM\QueryBuilder; | 7 | use Doctrine\ORM\QueryBuilder; |
7 | use Pagerfanta\Adapter\DoctrineORMAdapter; | 8 | use Pagerfanta\Adapter\DoctrineORMAdapter; |
8 | use Pagerfanta\Pagerfanta; | 9 | use Pagerfanta\Pagerfanta; |
9 | use Wallabag\CoreBundle\Entity\Entry; | 10 | use Wallabag\CoreBundle\Entity\Entry; |
10 | use Wallabag\CoreBundle\Entity\Tag; | 11 | use Wallabag\CoreBundle\Entity\Tag; |
12 | use Wallabag\CoreBundle\Helper\UrlHasher; | ||
11 | 13 | ||
12 | class EntryRepository extends EntityRepository | 14 | class EntryRepository extends EntityRepository |
13 | { | 15 | { |
@@ -50,7 +52,7 @@ class EntryRepository extends EntityRepository | |||
50 | public function getBuilderForArchiveByUser($userId) | 52 | public function getBuilderForArchiveByUser($userId) |
51 | { | 53 | { |
52 | return $this | 54 | return $this |
53 | ->getSortedQueryBuilderByUser($userId) | 55 | ->getSortedQueryBuilderByUser($userId, 'archivedAt', 'desc') |
54 | ->andWhere('e.isArchived = true') | 56 | ->andWhere('e.isArchived = true') |
55 | ; | 57 | ; |
56 | } | 58 | } |
@@ -110,8 +112,7 @@ class EntryRepository extends EntityRepository | |||
110 | */ | 112 | */ |
111 | public function getBuilderForUntaggedByUser($userId) | 113 | public function getBuilderForUntaggedByUser($userId) |
112 | { | 114 | { |
113 | return $this | 115 | return $this->sortQueryBuilder($this->getRawBuilderForUntaggedByUser($userId)); |
114 | ->sortQueryBuilder($this->getRawBuilderForUntaggedByUser($userId)); | ||
115 | } | 116 | } |
116 | 117 | ||
117 | /** | 118 | /** |
@@ -139,15 +140,30 @@ class EntryRepository extends EntityRepository | |||
139 | * @param string $order | 140 | * @param string $order |
140 | * @param int $since | 141 | * @param int $since |
141 | * @param string $tags | 142 | * @param string $tags |
143 | * @param string $detail 'metadata' or 'full'. Include content field if 'full' | ||
144 | * | ||
145 | * @todo Breaking change: replace default detail=full by detail=metadata in a future version | ||
142 | * | 146 | * |
143 | * @return Pagerfanta | 147 | * @return Pagerfanta |
144 | */ | 148 | */ |
145 | public function findEntries($userId, $isArchived = null, $isStarred = null, $isPublic = null, $sort = 'created', $order = 'asc', $since = 0, $tags = '') | 149 | public function findEntries($userId, $isArchived = null, $isStarred = null, $isPublic = null, $sort = 'created', $order = 'asc', $since = 0, $tags = '', $detail = 'full') |
146 | { | 150 | { |
151 | if (!\in_array(strtolower($detail), ['full', 'metadata'], true)) { | ||
152 | throw new \Exception('Detail "' . $detail . '" parameter is wrong, allowed: full or metadata'); | ||
153 | } | ||
154 | |||
147 | $qb = $this->createQueryBuilder('e') | 155 | $qb = $this->createQueryBuilder('e') |
148 | ->leftJoin('e.tags', 't') | 156 | ->leftJoin('e.tags', 't') |
149 | ->where('e.user = :userId')->setParameter('userId', $userId); | 157 | ->where('e.user = :userId')->setParameter('userId', $userId); |
150 | 158 | ||
159 | if ('metadata' === $detail) { | ||
160 | $fieldNames = $this->getClassMetadata()->getFieldNames(); | ||
161 | $fields = array_filter($fieldNames, function ($k) { | ||
162 | return 'content' !== $k; | ||
163 | }); | ||
164 | $qb->select(sprintf('partial e.{%s}', implode(',', $fields))); | ||
165 | } | ||
166 | |||
151 | if (null !== $isArchived) { | 167 | if (null !== $isArchived) { |
152 | $qb->andWhere('e.isArchived = :isArchived')->setParameter('isArchived', (bool) $isArchived); | 168 | $qb->andWhere('e.isArchived = :isArchived')->setParameter('isArchived', (bool) $isArchived); |
153 | } | 169 | } |
@@ -193,6 +209,8 @@ class EntryRepository extends EntityRepository | |||
193 | $qb->orderBy('e.id', $order); | 209 | $qb->orderBy('e.id', $order); |
194 | } elseif ('updated' === $sort) { | 210 | } elseif ('updated' === $sort) { |
195 | $qb->orderBy('e.updatedAt', $order); | 211 | $qb->orderBy('e.updatedAt', $order); |
212 | } elseif ('archived' === $sort) { | ||
213 | $qb->orderBy('e.archivedAt', $order); | ||
196 | } | 214 | } |
197 | 215 | ||
198 | $pagerAdapter = new DoctrineORMAdapter($qb, true, false); | 216 | $pagerAdapter = new DoctrineORMAdapter($qb, true, false); |
@@ -324,15 +342,32 @@ class EntryRepository extends EntityRepository | |||
324 | * Find an entry by its url and its owner. | 342 | * Find an entry by its url and its owner. |
325 | * If it exists, return the entry otherwise return false. | 343 | * If it exists, return the entry otherwise return false. |
326 | * | 344 | * |
327 | * @param $url | 345 | * @param string $url |
328 | * @param $userId | 346 | * @param int $userId |
329 | * | 347 | * |
330 | * @return Entry|bool | 348 | * @return Entry|bool |
331 | */ | 349 | */ |
332 | public function findByUrlAndUserId($url, $userId) | 350 | public function findByUrlAndUserId($url, $userId) |
333 | { | 351 | { |
352 | return $this->findByHashedUrlAndUserId( | ||
353 | UrlHasher::hashUrl($url), | ||
354 | $userId | ||
355 | ); | ||
356 | } | ||
357 | |||
358 | /** | ||
359 | * Find an entry by its hashed url and its owner. | ||
360 | * If it exists, return the entry otherwise return false. | ||
361 | * | ||
362 | * @param string $hashedUrl Url hashed using sha1 | ||
363 | * @param int $userId | ||
364 | * | ||
365 | * @return Entry|bool | ||
366 | */ | ||
367 | public function findByHashedUrlAndUserId($hashedUrl, $userId) | ||
368 | { | ||
334 | $res = $this->createQueryBuilder('e') | 369 | $res = $this->createQueryBuilder('e') |
335 | ->where('e.url = :url')->setParameter('url', urldecode($url)) | 370 | ->where('e.hashedUrl = :hashed_url')->setParameter('hashed_url', $hashedUrl) |
336 | ->andWhere('e.user = :user_id')->setParameter('user_id', $userId) | 371 | ->andWhere('e.user = :user_id')->setParameter('user_id', $userId) |
337 | ->getQuery() | 372 | ->getQuery() |
338 | ->getResult(); | 373 | ->getResult(); |
@@ -416,8 +451,8 @@ class EntryRepository extends EntityRepository | |||
416 | /** | 451 | /** |
417 | * Find all entries by url and owner. | 452 | * Find all entries by url and owner. |
418 | * | 453 | * |
419 | * @param $url | 454 | * @param string $url |
420 | * @param $userId | 455 | * @param int $userId |
421 | * | 456 | * |
422 | * @return array | 457 | * @return array |
423 | */ | 458 | */ |
@@ -431,6 +466,49 @@ class EntryRepository extends EntityRepository | |||
431 | } | 466 | } |
432 | 467 | ||
433 | /** | 468 | /** |
469 | * Returns a random entry, filtering by status. | ||
470 | * | ||
471 | * @param int $userId | ||
472 | * @param string $type Can be unread, archive, starred, etc | ||
473 | * | ||
474 | * @throws NoResultException | ||
475 | * | ||
476 | * @return Entry | ||
477 | */ | ||
478 | public function getRandomEntry($userId, $type = '') | ||
479 | { | ||
480 | $qb = $this->getQueryBuilderByUser($userId) | ||
481 | ->select('e.id'); | ||
482 | |||
483 | switch ($type) { | ||
484 | case 'unread': | ||
485 | $qb->andWhere('e.isArchived = false'); | ||
486 | break; | ||
487 | case 'archive': | ||
488 | $qb->andWhere('e.isArchived = true'); | ||
489 | break; | ||
490 | case 'starred': | ||
491 | $qb->andWhere('e.isStarred = true'); | ||
492 | break; | ||
493 | case 'untagged': | ||
494 | $qb->leftJoin('e.tags', 't'); | ||
495 | $qb->andWhere('t.id is null'); | ||
496 | break; | ||
497 | } | ||
498 | |||
499 | $ids = $qb->getQuery()->getArrayResult(); | ||
500 | |||
501 | if (empty($ids)) { | ||
502 | throw new NoResultException(); | ||
503 | } | ||
504 | |||
505 | // random select one in the list | ||
506 | $randomId = $ids[mt_rand(0, \count($ids) - 1)]['id']; | ||
507 | |||
508 | return $this->find($randomId); | ||
509 | } | ||
510 | |||
511 | /** | ||
434 | * Return a query builder to be used by other getBuilderFor* method. | 512 | * Return a query builder to be used by other getBuilderFor* method. |
435 | * | 513 | * |
436 | * @param int $userId | 514 | * @param int $userId |
@@ -468,7 +546,6 @@ class EntryRepository extends EntityRepository | |||
468 | */ | 546 | */ |
469 | private function sortQueryBuilder(QueryBuilder $qb, $sortBy = 'createdAt', $direction = 'desc') | 547 | private function sortQueryBuilder(QueryBuilder $qb, $sortBy = 'createdAt', $direction = 'desc') |
470 | { | 548 | { |
471 | return $qb | 549 | return $qb->orderBy(sprintf('e.%s', $sortBy), $direction); |
472 | ->orderBy(sprintf('e.%s', $sortBy), $direction); | ||
473 | } | 550 | } |
474 | } | 551 | } |