Completed
Push — master ( 4d0c63...2378fd )
by Jeremy
17s queued 10s
created

TagRepository::getQueryBuilderByUser()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 5
nc 1
nop 1
dl 0
loc 7
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Wallabag\CoreBundle\Repository;
4
5
use Doctrine\ORM\EntityRepository;
6
use Doctrine\ORM\QueryBuilder;
7
use Wallabag\CoreBundle\Entity\Tag;
8
9
class TagRepository extends EntityRepository
10
{
11
    /**
12
     * Count all tags per user.
13
     *
14
     * @param int $userId
15
     * @param int $cacheLifeTime Duration of the cache for this query
16
     *
17
     * @return int
18
     */
19
    public function countAllTags($userId, $cacheLifeTime = null)
20
    {
21
        $query = $this->createQueryBuilder('t')
22
            ->select('t.slug')
23
            ->leftJoin('t.entries', 'e')
24
            ->where('e.user = :userId')->setParameter('userId', $userId)
25
            ->groupBy('t.slug')
26
            ->getQuery();
27
28
        if (null !== $cacheLifeTime) {
29
            $query->useQueryCache(true);
30
            $query->useResultCache(true);
31
            $query->setResultCacheLifetime($cacheLifeTime);
32
        }
33
34
        return \count($query->getArrayResult());
35
    }
36
37
    /**
38
     * Find all tags per user.
39
     * Instead of just left joined on the Entry table, we select only id and group by id to avoid tag multiplication in results.
40
     * Once we have all tags id, we can safely request them one by one.
41
     * This'll still be fastest than the previous query.
42
     *
43
     * @param int $userId
44
     *
45
     * @return array
46
     */
47
    public function findAllTags($userId)
48
    {
49
        $ids = $this->getQueryBuilderByUser($userId)
50
            ->select('t.id')
51
            ->getQuery()
52
            ->getArrayResult();
53
54
        $tags = [];
55
        foreach ($ids as $id) {
56
            $tags[] = $this->find($id);
57
        }
58
59
        return $tags;
60
    }
61
62
    /**
63
     * Find all tags (flat) per user with nb entries.
64
     *
65
     * @param int $userId
66
     *
67
     * @return array
68
     */
69
    public function findAllFlatTagsWithNbEntries($userId)
70
    {
71
        return $this->getQueryBuilderByUser($userId)
72
            ->select('t.id, t.label, t.slug, count(e.id) as nbEntries')
73
            ->distinct(true)
74
            ->getQuery()
75
            ->getArrayResult();
76
    }
77
78
    public function findByLabelsAndUser($labels, $userId)
79
    {
80
        $qb = $this->getQueryBuilderByUser($userId)
81
            ->select('t.id');
82
83
        $ids = $qb->andWhere($qb->expr()->in('t.label', $labels))
84
            ->getQuery()
85
            ->getArrayResult();
86
87
        $tags = [];
88
        foreach ($ids as $id) {
89
            $tags[] = $this->find($id);
90
        }
91
92
        return $tags;
93
    }
94
95
    /**
96
     * Used only in test case to get a tag for our entry.
97
     *
98
     * @return Tag
99
     */
100
    public function findOneByEntryAndTagLabel($entry, $label)
101
    {
102
        return $this->createQueryBuilder('t')
103
            ->leftJoin('t.entries', 'e')
104
            ->where('e.id = :entryId')->setParameter('entryId', $entry->getId())
105
            ->andWhere('t.label = :label')->setParameter('label', $label)
106
            ->setMaxResults(1)
107
            ->getQuery()
108
            ->getSingleResult();
109
    }
110
111
    public function findForArchivedArticlesByUser($userId)
112
    {
113
        $ids = $this->getQueryBuilderByUser($userId)
114
            ->select('t.id')
115
            ->andWhere('e.isArchived = true')
116
            ->getQuery()
117
            ->getArrayResult();
118
119
        $tags = [];
120
        foreach ($ids as $id) {
121
            $tags[] = $this->find($id);
122
        }
123
124
        return $tags;
125
    }
126
127
    /**
128
     * Retrieve a sorted list of tags used by a user.
129
     *
130
     * @param int $userId
131
     *
132
     * @return QueryBuilder
133
     */
134
    private function getQueryBuilderByUser($userId)
135
    {
136
        return $this->createQueryBuilder('t')
137
            ->leftJoin('t.entries', 'e')
138
            ->where('e.user = :userId')->setParameter('userId', $userId)
139
            ->groupBy('t.id')
140
            ->orderBy('t.slug');
141
    }
142
}
143