Completed
Push — 3.x ( 733455...aa9981 )
by Grégoire
02:00
created

CommentManager::getPager()   A

Complexity

Conditions 5
Paths 12

Size

Total Lines 33

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 33
rs 9.0808
c 0
b 0
f 0
cc 5
nc 12
nop 4
1
<?php
2
3
/*
4
 * This file is part of the Sonata Project package.
5
 *
6
 * (c) Thomas Rabaix <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Sonata\NewsBundle\Entity;
13
14
use Doctrine\Common\Persistence\ManagerRegistry;
15
use Sonata\CoreBundle\Model\BaseEntityManager;
16
use Sonata\CoreBundle\Model\ManagerInterface;
17
use Sonata\DatagridBundle\Pager\Doctrine\Pager;
18
use Sonata\DatagridBundle\ProxyQuery\Doctrine\ProxyQuery;
19
use Sonata\NewsBundle\Model\CommentInterface;
20
use Sonata\NewsBundle\Model\CommentManagerInterface;
21
use Sonata\NewsBundle\Model\PostInterface;
22
23
class CommentManager extends BaseEntityManager implements CommentManagerInterface
24
{
25
    /**
26
     * @var ManagerInterface
27
     */
28
    protected $postManager;
29
30
    /**
31
     * @param string           $class
32
     * @param ManagerRegistry  $registry
33
     * @param ManagerInterface $postManager
34
     */
35
    public function __construct($class, ManagerRegistry $registry, ManagerInterface $postManager)
36
    {
37
        parent::__construct($class, $registry);
38
39
        $this->postManager = $postManager;
40
    }
41
42
    /**
43
     * {@inheritdoc}
44
     */
45
    public function save($comment, $andFlush = true)
46
    {
47
        parent::save($comment, $andFlush);
48
49
        $this->updateCommentsCount($comment->getPost());
50
    }
51
52
    /**
53
     * Update the number of comment for a comment.
54
     *
55
     * @param null|\Sonata\NewsBundle\Model\PostInterface $post
56
     */
57
    public function updateCommentsCount(PostInterface $post = null)
58
    {
59
        $commentTableName = $this->getObjectManager()->getClassMetadata($this->getClass())->table['name'];
0 ignored issues
show
Bug introduced by
Accessing table on the interface Doctrine\Common\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...
60
        $postTableName = $this->getObjectManager()->getClassMetadata($this->postManager->getClass())->table['name'];
0 ignored issues
show
Bug introduced by
Accessing table on the interface Doctrine\Common\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...
61
62
        $this->getConnection()->beginTransaction();
63
        $this->getConnection()->query($this->getCommentsCountResetQuery($postTableName));
64
65
        $this->getConnection()->query($this->getCommentsCountQuery($postTableName, $commentTableName));
66
67
        $this->getConnection()->commit();
68
    }
69
70
    /**
71
     * {@inheritdoc}
72
     */
73
    public function delete($comment, $andFlush = true)
74
    {
75
        $post = $comment->getPost();
76
77
        parent::delete($comment, $andFlush);
78
79
        $this->updateCommentsCount($post);
80
    }
81
82
    /**
83
     * {@inheritdoc}
84
     */
85
    public function getPager(array $criteria, $page, $limit = 10, array $sort = [])
86
    {
87
        if (!isset($criteria['mode'])) {
88
            $criteria['mode'] = 'public';
89
        }
90
91
        $parameters = [];
92
93
        $query = $this->getRepository()
94
            ->createQueryBuilder('c')
95
            ->orderby('c.createdAt', 'DESC');
96
97
        if ('public' == $criteria['mode']) {
98
            $criteria['status'] = isset($criteria['status']) ? $criteria['status'] : CommentInterface::STATUS_VALID;
99
            $query->andWhere('c.status = :status');
100
            $parameters['status'] = $criteria['status'];
101
        }
102
103
        if (isset($criteria['postId'])) {
104
            $query->andWhere('c.post = :postId');
105
            $parameters['postId'] = $criteria['postId'];
106
        }
107
108
        $query->setParameters($parameters);
109
110
        $pager = new Pager();
111
        $pager->setMaxPerPage($limit);
112
        $pager->setQuery(new ProxyQuery($query));
113
        $pager->setPage($page);
114
        $pager->init();
115
116
        return $pager;
117
    }
118
119
    /**
120
     * @param string $postTableName
121
     *
122
     * @return string
123
     */
124
    private function getCommentsCountResetQuery($postTableName)
125
    {
126
        switch ($this->getConnection()->getDriver()->getDatabasePlatform()->getName()) {
127
            case 'postgresql':
128
                return sprintf('UPDATE %s SET comments_count = 0', $postTableName);
129
130
            default:
131
                return sprintf('UPDATE %s p SET p.comments_count = 0', $postTableName);
132
        }
133
    }
134
135
    /**
136
     * @param string $postTableName
137
     * @param string $commentTableName
138
     *
139
     * @return string
140
     */
141
    private function getCommentsCountQuery($postTableName, $commentTableName)
142
    {
143
        switch ($this->getConnection()->getDriver()->getDatabasePlatform()->getName()) {
144
            case 'postgresql':
145
                return sprintf(
146
            'UPDATE %s SET comments_count = count_comment.total
147
            FROM (SELECT c.post_id, count(*) AS total FROM %s AS c WHERE c.status = 1 GROUP BY c.post_id) count_comment
148
            WHERE %s.id = count_comment.post_id', $postTableName, $commentTableName, $postTableName);
149
150
            default:
151
                return sprintf(
152
            '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
153
            SET p.comments_count = count_comment.total
154
            WHERE p.id = count_comment.post_id', $postTableName, $commentTableName);
155
        }
156
    }
157
}
158