Completed
Push — 3.x-dev-kit ( 34f108...1154cd )
by Grégoire
01:42
created

CommentManager::getCommentsCountResetQuery()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 10
rs 9.9332
c 0
b 0
f 0
cc 2
nc 2
nop 1
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the Sonata Project package.
7
 *
8
 * (c) Thomas Rabaix <[email protected]>
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Sonata\NewsBundle\Entity;
15
16
use Doctrine\Common\Persistence\ManagerRegistry;
17
use Sonata\DatagridBundle\Pager\Doctrine\Pager;
18
use Sonata\DatagridBundle\ProxyQuery\Doctrine\ProxyQuery;
19
use Sonata\Doctrine\Entity\BaseEntityManager;
20
use Sonata\Doctrine\Model\ManagerInterface;
21
use Sonata\NewsBundle\Model\CommentInterface;
22
use Sonata\NewsBundle\Model\CommentManagerInterface;
23
use Sonata\NewsBundle\Model\PostInterface;
24
25
class CommentManager extends BaseEntityManager implements CommentManagerInterface
26
{
27
    /**
28
     * @var ManagerInterface
29
     */
30
    protected $postManager;
31
32
    /**
33
     * @param string $class
34
     */
35
    public function __construct($class, ManagerRegistry $registry, ManagerInterface $postManager)
36
    {
37
        parent::__construct($class, $registry);
38
39
        $this->postManager = $postManager;
40
    }
41
42
    public function save($comment, $andFlush = true)
43
    {
44
        parent::save($comment, $andFlush);
45
46
        $this->updateCommentsCount($comment->getPost());
47
    }
48
49
    /**
50
     * Update the number of comment for a comment.
51
     */
52
    public function updateCommentsCount(PostInterface $post = null)
53
    {
54
        $commentTableName = $this->getObjectManager()->getClassMetadata($this->getClass())->table['name'];
0 ignored issues
show
Bug introduced by
Accessing table on the interface Doctrine\Persistence\Mapping\ClassMetadata suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
55
        $postTableName = $this->getObjectManager()->getClassMetadata($this->postManager->getClass())->table['name'];
0 ignored issues
show
Bug introduced by
Accessing table on the interface Doctrine\Persistence\Mapping\ClassMetadata suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
56
57
        $this->getConnection()->beginTransaction();
58
        $this->getConnection()->query($this->getCommentsCountResetQuery($postTableName));
59
60
        $this->getConnection()->query($this->getCommentsCountQuery($postTableName, $commentTableName));
61
62
        $this->getConnection()->commit();
63
    }
64
65
    public function delete($comment, $andFlush = true)
66
    {
67
        $post = $comment->getPost();
68
69
        parent::delete($comment, $andFlush);
70
71
        $this->updateCommentsCount($post);
72
    }
73
74
    public function getPager(array $criteria, $page, $limit = 10, array $sort = [])
75
    {
76
        if (!isset($criteria['mode'])) {
77
            $criteria['mode'] = 'public';
78
        }
79
80
        $parameters = [];
81
82
        $query = $this->getRepository()
83
            ->createQueryBuilder('c')
84
            ->orderby('c.createdAt', 'DESC');
85
86
        if ('public' === $criteria['mode']) {
87
            $criteria['status'] = $criteria['status'] ?? CommentInterface::STATUS_VALID;
88
            $query->andWhere('c.status = :status');
89
            $parameters['status'] = $criteria['status'];
90
        }
91
92
        if (isset($criteria['postId'])) {
93
            $query->andWhere('c.post = :postId');
94
            $parameters['postId'] = $criteria['postId'];
95
        }
96
97
        $query->setParameters($parameters);
98
99
        $pager = new Pager();
100
        $pager->setMaxPerPage($limit);
101
        $pager->setQuery(new ProxyQuery($query));
102
        $pager->setPage($page);
103
        $pager->init();
104
105
        return $pager;
106
    }
107
108
    /**
109
     * @param string $postTableName
110
     *
111
     * @return string
112
     */
113
    private function getCommentsCountResetQuery($postTableName)
114
    {
115
        switch ($this->getConnection()->getDriver()->getDatabasePlatform()->getName()) {
116
            case 'postgresql':
117
                return sprintf('UPDATE %s SET comments_count = 0', $postTableName);
118
119
            default:
120
                return sprintf('UPDATE %s p SET p.comments_count = 0', $postTableName);
121
        }
122
    }
123
124
    /**
125
     * @param string $postTableName
126
     * @param string $commentTableName
127
     *
128
     * @return string
129
     */
130
    private function getCommentsCountQuery($postTableName, $commentTableName)
131
    {
132
        switch ($this->getConnection()->getDriver()->getDatabasePlatform()->getName()) {
133
            case 'postgresql':
134
                return sprintf(
135
                    <<<'SQL'
136
UPDATE %s SET comments_count = count_comment.total
137
FROM (SELECT c.post_id, count(*) AS total FROM %s AS c WHERE c.status = 1 GROUP BY c.post_id) count_comment
138
WHERE %s.id = count_comment.post_id
139
SQL
140
                    ,
141
                    $postTableName,
142
                    $commentTableName,
143
                    $postTableName
144
                );
145
146
            default:
147
                return sprintf(
148
                    <<<'SQL'
149
UPDATE %s p, (SELECT c.post_id, count(*) as total FROM %s as c WHERE c.status = 1 GROUP BY c.post_id) as count_comment
150
SET p.comments_count = count_comment.total
151
WHERE p.id = count_comment.post_id
152
SQL
153
                    ,
154
                    $postTableName,
155
                    $commentTableName
156
                );
157
        }
158
    }
159
}
160