Completed
Push — master ( e75a05...1230d5 )
by Alexis
07:31
created

TweetRepository::deleteAndHideTweetsLessThanId()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 22
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 3

Importance

Changes 3
Bugs 1 Features 0
Metric Value
c 3
b 1
f 0
dl 0
loc 22
ccs 12
cts 12
cp 1
rs 9.2
cc 3
eloc 11
nc 3
nop 1
crap 3
1
<?php
2
3
namespace AlexisLefebvre\Bundle\AsyncTweetsBundle\Entity;
4
5
use Doctrine\ORM\EntityRepository;
6
7
/**
8
 * TweetRepository
9
 *
10
 * This class was generated by the Doctrine ORM. Add your own custom
11
 * repository methods below.
12
 */
13
class TweetRepository extends EntityRepository
14
{
15
    private $nbTweets = 5;
16
    
17 3
    public function getWithUsers($page = 1)
18
    {
19 3
        $firstResult = (($page - 1) * $this->nbTweets);
20
                
21 3
        $qb = $this->createQueryBuilder('t');
22
        
23
        $query = $qb
24 3
            ->select('t, user, rt, rt_user')
25 3
            ->innerJoin('t.user', 'user')
26 3
            ->leftJoin('t.retweeted_status', 'rt')
27 3
            ->leftJoin('rt.user', 'rt_user')
28
            
29
            // Ignore tweets that were only retweeted
30 3
            ->where($qb->expr()->eq('t.in_timeline', 'true'))
31
            
32 3
            ->orderBy('t.id', 'DESC')
33
            
34 3
            ->setFirstResult($firstResult)
35 3
            ->setMaxResults($this->nbTweets)
36 3
        ;
37
        
38 3
        return $query->getQuery()->getResult();
39
    }
40
    
41
    /**
42
     * @param \Doctrine\ORM\QueryBuilder $qb
43
     */
44 8
    private function getWithUsersAndMediasQuery($qb)
45
    {
46
        $query = $qb
47 8
            ->select('t, user, medias, rt, rt_user')
48 8
            ->innerJoin('t.user', 'user')
49 8
            ->leftJoin('t.medias', 'medias')
50 8
            ->leftJoin('t.retweeted_status', 'rt')
51 8
            ->leftJoin('rt.user', 'rt_user')
52
            
53
            // Ignore tweets that were only retweeted
54 8
            ->where($qb->expr()->eq('t.in_timeline', 'true'))
55
            
56 8
            ->orderBy('t.id', 'ASC')
57
            
58 8
            ->setFirstResult(0)
59 8
            ->setMaxResults($this->nbTweets)
60 8
        ;
61
        
62 8
        return $query;
63
    }
64
    
65 8
    public function getWithUsersAndMedias($firstTweetId = null)
66
    {
67 8
        $qb = $this->createQueryBuilder('t');
68
        
69 8
        $query = $this->getWithUsersAndMediasQuery($qb);
70
        
71 8
        if (! is_null($firstTweetId))
72 8
        {
73 5
            $query = $query->andWhere(
74 5
                $qb->expr()->gte('t.id', $firstTweetId)
75 5
            );
76 5
        }
77
        
78 8
        return $query->getQuery()->getResult();
79
    }
80
    
81
    /**
82
     * @param string $condition
83
     * @param string $order
84
     */
85 6
    private function getTweetId($condition, $order, $tweetId)
86
    {
87 6
        $qb = $this->createQueryBuilder('t')
88 6
            ->select('t.id')
89
            
90 6
            ->where('t.id '.$condition.' :tweetId')
91 6
            ->setParameter(':tweetId', $tweetId)
92
            
93 6
            ->andWhere('t.in_timeline = true')
94
            
95 6
            ->orderBy('t.id', $order)
96
            
97 6
            ->setFirstResult($this->nbTweets - 1)
98 6
            ->setMaxResults(1)
99 6
        ;
100
        
101 6
        $result = $qb->getQuery()->getOneOrNullResult();
102
        
103 6
        return($this->getIdOrNull($result));
104
    }
105
    
106 6
    private function getIdOrNull($result)
107
    {
108 6
        return(is_array($result) ? $result['id'] : null);
109
    }
110
    
111 7
    public function getPreviousAndNextTweetId($tweetId)
112
    {
113
        return(array(
114 6
            $this->getTweetId('<', 'DESC', $tweetId),
115 6
            $this->getTweetId('>', 'ASC', $tweetId)
116 7
        ));
117
    }
118
    
119 7
    public function countPendingTweets($lastTweetId = null)
120
    {
121 7
        $qb = $this->createQueryBuilder('t');
122
        
123
        $query = $qb
124 7
            ->add('select', $qb->expr()->count('t.id'))
0 ignored issues
show
Documentation introduced by Alexis Lefebvre
$qb->expr()->count('t.id') is of type object<Doctrine\ORM\Query\Expr\Func>, but the function expects a object<Doctrine\ORM\Query\Expr\Base>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
125
            // Ignore tweets that were only retweeted
126 7
            ->where(
127 7
                $qb->expr()->eq('t.in_timeline', 'true')
128 7
            )
129 7
        ;
130
        
131 7
        if (! is_null($lastTweetId))
132 7
        {
133 7
            $query = $query->andWhere(
134 7
                $qb->expr()->gte('t.id', $lastTweetId)
135 7
            );
136 7
        }
137
        
138
        # return result of "COUNT()" query
139 7
        return $query->getQuery()->getSingleScalarResult();
140
    }
141
    
142 7
    public function getLastTweet()
143
    {
144 7
        $qb = $this->createQueryBuilder('t')
145 7
            ->addOrderBy('t.id', 'DESC')
146 7
            ->setFirstResult(0)
147 7
            ->setMaxResults(1)
148 7
        ;
149
        
150 7
        return $qb->getQuery()->getOneOrNullResult();
151
    }
152
    
153
    /**
154
     * @param integer $tweetId
155
     */
156 2
    private function getTweetsLessThanId($tweetId)
157
    {
158 2
        $qb = $this->createQueryBuilder('t')
159 2
            ->select('t, m')
160 2
            ->leftJoin('t.medias', 'm')
161 2
            ->where('t.id < :tweetId')
162 2
            ->setParameter(':tweetId', $tweetId)
163
            
164
            // Get retweeted tweets (it would break foreign keys)
165
            //  http://stackoverflow.com/questions/15087933/how-to-do-left-join-in-doctrine/15088250#15088250
166 2
            ->leftJoin(
167 2
                'AsyncTweetsBundle:Tweet',
168 2
                't2',
169 2
                'WITH',
170
                't.id = t2.retweeted_status'
171 2
            )
172
            
173 2
            ->orderBy('t.id', 'DESC')
174 2
        ;
175
        
176 2
        return($qb->getQuery()->getResult());
177
    }
178
    
179
    /**
180
     * Remove Media not associated to any Tweet
181
     */
182 1
    private function removeOrphanMedias(Media $media)
183
    {
184 1
        if (count($media->getTweets()) == 0)
185 1
        {
186 1
            $this->_em->remove($media);
187 1
        }
188 1
    }
189
    
190
    /**
191
     * Remove the tweet and return 1 is the deleted tweet is not a
192
     *  retweet
193
     * 
194
     * @param Tweet $tweet
195
     * 
196
     * @return integer
197
     */
198 2
    protected function removeTweet($tweet)
199
    {
200 2
        $count = 0;
201
        
202 2
        foreach ($tweet->getMedias() as $media) {
203 1
            $tweet->removeMedia($media);
204 1
            $this->removeOrphanMedias($media);
205 2
        }
206
        
207
        // Don't count tweets that were only retweeted
208 2
        if ($tweet->isInTimeline()) {
209 2
            $count = 1;
210 2
        }
211
        
212 2
        $this->_em->remove($tweet);
213
        
214 2
        return $count;
215
    }
216
    
217
    /**
218
     * Delete tweets and return the number of deleted tweets (excluding
219
     *  retweeted-only tweets)
220
     * 
221
     * @param integer $tweetId
222
     * 
223
     * @return integer
224
     */
225 2
    public function deleteAndHideTweetsLessThanId($tweetId)
226
    {
227 2
        $count = 0;
228
        
229 2
        $tweets = $this->getTweetsLessThanId($tweetId);
230
        
231 2
        foreach ($tweets as $tweet) {
232 2
            if ($tweet->mustBeKept($tweetId)) {
233
                // The Tweet is still in the timeline, it can only be hidden
234 1
                $tweet->setInTimeline(false);
235 1
                $this->_em->persist($tweet);
236 1
             }
237
             else {
238
                 // The Tweet has not been retweeted, it can be removed
239 2
                $count += $this->removeTweet($tweet);
240
            }
241 2
        }
242
        
243 2
        $this->_em->flush();
244
        
245 2
        return($count);
246
    }
247
}
248