Completed
Push — master ( 9684f5...5d31f9 )
by Sander
36:56 queued 12:48
created

src/Kunstmaan/TaggingBundle/Entity/TagManager.php (1 issue)

Checks whether return doc types can be made more specific.

Documentation Informational

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
namespace Kunstmaan\TaggingBundle\Entity;
4
5
use Doctrine\ORM\Query\Expr;
6
use Doctrine\ORM\Query\ResultSetMappingBuilder;
7
use DoctrineExtensions\Taggable\Taggable as BaseTaggable;
8
use DoctrineExtensions\Taggable\TagManager as BaseTagManager;
9
use Kunstmaan\NodeBundle\Entity\AbstractPage;
10
11
class TagManager extends BaseTagManager
12
{
13
    const TAGGING_HYDRATOR = 'taggingHydrator';
14
15
    /**
16
     * @param BaseTaggable $resource
17
     */
18
    public function loadTagging(BaseTaggable $resource)
19
    {
20
        if ($resource instanceof LazyLoadingTaggableInterface) {
21
            $resource->setTagLoader(function (Taggable $taggable) {
22
                parent::loadTagging($taggable);
23
            });
24
25
            return;
26
        }
27
28
        parent::loadTagging($resource);
29
    }
30
31
    /**
32
     * @param BaseTaggable $resource
33
     */
34
    public function saveTagging(BaseTaggable $resource)
35
    {
36
        $tags = clone $resource->getTags();
37
        parent::saveTagging($resource);
38
        if (count($tags) !== count($resource->getTags())) {
39
            // parent::saveTagging uses getTags by reference and removes elements, so it ends up empty :-/
40
            // this causes all tags to be deleted when an entity is persisted more than once in a request
41
            // Restore:
42
            $this->replaceTags($tags->toArray(), $resource);
43
        }
44
    }
45
46
    /**
47
     * Gets all tags for the given taggable resource
48
     *
49
     * @param BaseTaggable $resource Taggable resource
50
     *
51
     * @return array
52
     */
53
    public function getTagging(BaseTaggable $resource)
54
    {
55
        $em = $this->em;
56
57
        $config = $em->getConfiguration();
58
        if (is_null($config->getCustomHydrationMode(self::TAGGING_HYDRATOR))) {
59
            $config->addCustomHydrationMode(self::TAGGING_HYDRATOR, 'Doctrine\ORM\Internal\Hydration\ObjectHydrator');
60
        }
61
62
        return $em
63
            ->createQueryBuilder()
64
65
            ->select('t')
66
            ->from($this->tagClass, 't')
67
68
            ->innerJoin('t.tagging', 't2', Expr\Join::WITH, 't2.resourceId = :id AND t2.resourceType = :type')
69
            ->setParameter('id', $resource->getTaggableId())
70
            ->setParameter('type', $resource->getTaggableType())
71
72
            ->getQuery()
73
            ->getResult(self::TAGGING_HYDRATOR);
74
    }
75
76
    /**
77
     * @param $id
78
     *
79
     * @return mixed|null
80
     *
81
     * @throws \Doctrine\ORM\NonUniqueResultException
82
     */
83
    public function findById($id)
84
    {
85
        if (!isset($id) || is_null($id)) {
86
            return null;
87
        }
88
        $builder = $this->em->createQueryBuilder();
89
90
        $tag = $builder
91
            ->select('t')
92
            ->from($this->tagClass, 't')
93
94
            ->where($builder->expr()->eq('t.id', $id))
95
96
            ->getQuery()
97
            ->getOneOrNullResult();
98
99
        return $tag;
100
    }
101
102
    /**
103
     * @return array
0 ignored issues
show
Consider making the return type a bit more specific; maybe use object[].

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
104
     */
105
    public function findAll()
106
    {
107
        $tagsRepo = $this->em->getRepository('KunstmaanTaggingBundle:Tag');
108
109
        return $tagsRepo->findAll();
110
    }
111
112
    /**
113
     * @param Taggable $item
114
     * @param $class
115
     * @param $locale
116
     * @param int $nbOfItems
117
     *
118
     * @return array|null
119
     */
120
    public function findRelatedItems(Taggable $item, $class, $locale, $nbOfItems = 1)
121
    {
122
        $instance = new $class();
123
        if (!($instance instanceof Taggable)) {
124
            return null;
125
        }
126
127
        $em = $this->em;
128
        $rsm = new ResultSetMappingBuilder($em);
129
        $rsm->addRootEntityFromClassMetadata($class, 'i');
130
131
        $meta = $em->getClassMetadata($class);
132
        $tableName = $meta->getTableName();
133
134
        $escapedClass = str_replace('\\', '\\\\', $class);
135
136
        $query = <<<EOD
137
            SELECT i.*, COUNT(i.id) as number
138
            FROM {$tableName} i
139
            LEFT JOIN kuma_taggings t
140
            ON t.resource_id = i.id
141
            AND t.resource_type = '{$instance->getTaggableType()}'
142
            WHERE t.tag_id IN (
143
                SELECT tg.tag_id
144
                FROM kuma_taggings tg
145
                WHERE tg.resource_id = {$item->getId()}
146
                AND tg.resource_type = '{$item->getTaggableType()}'
147
            )
148
            AND i.id <> {$item->getId()}
149
EOD;
150
151
        if ($item instanceof AbstractPage) {
152
            $query .= <<< EOD
153
                AND i.id IN (
154
                    SELECT nodeversion.refId
155
                    FROM kuma_nodes as node
156
                    INNER JOIN kuma_node_translations as nodetranslation
157
                    ON node.id = nodetranslation.node
158
                    AND nodetranslation.lang = '{$locale}'
159
                    INNER JOIN kuma_node_versions as nodeversion
160
                    ON nodetranslation.publicNodeVersion = nodeversion.id
161
                    AND nodeversion.refEntityname = '{$escapedClass}'
162
                    AND node.deleted = 0
163
                    AND nodetranslation.online = 1
164
                )
165
EOD;
166
        }
167
168
        $query .= <<<EOD
169
            GROUP BY
170
                i.id
171
            HAVING
172
                number > 0
173
            ORDER BY
174
                number DESC
175
            LIMIT {$nbOfItems};
176
EOD;
177
178
        $items = $em->createNativeQuery($query, $rsm)->getResult();
179
180
        return $items;
181
    }
182
}
183