Code Coverage
 
Classes and Traits
Functions and Methods
Lines
Total
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
12 / 12
CRAP
100.00% covered (success)
100.00%
84 / 84
AlexisLefebvre\Bundle\AsyncTweetsBundle\Entity\TweetRepository
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
12 / 12
20
100.00% covered (success)
100.00%
84 / 84
 getWithUsers
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
11 / 11
 getWithUsersAndMediasQuery
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
10 / 10
 getWithUsersAndMedias
100.00% covered (success)
100.00%
1 / 1
2
100.00% covered (success)
100.00%
6 / 6
 getTweetId
100.00% covered (success)
100.00%
1 / 1
2
100.00% covered (success)
100.00%
10 / 10
 getPreviousTweetId
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 getNextTweetId
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 countPendingTweets
100.00% covered (success)
100.00%
1 / 1
2
100.00% covered (success)
100.00%
8 / 8
 getLastTweet
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
5 / 5
 getTweetsLessThanId
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
12 / 12
 removeOrphanMedias
100.00% covered (success)
100.00%
1 / 1
2
100.00% covered (success)
100.00%
3 / 3
 removeTweet
100.00% covered (success)
100.00%
1 / 1
3
100.00% covered (success)
100.00%
8 / 8
 deleteAndHideTweetsLessThanId
100.00% covered (success)
100.00%
1 / 1
3
100.00% covered (success)
100.00%
9 / 9
<?php
namespace AlexisLefebvre\Bundle\AsyncTweetsBundle\Entity;
use Doctrine\ORM\EntityRepository;
/**
 * TweetRepository.
 *
 * This class was generated by the Doctrine ORM. Add your own custom
 * repository methods below.
 */
class TweetRepository extends EntityRepository
{
    private $nbTweets = 5;
    public function getWithUsers($page = 1)
    {
        $firstResult = (($page - 1) * $this->nbTweets);
        $qb = $this->createQueryBuilder('t');
        $query = $qb
            ->select('t, user, rt, rt_user')
            ->innerJoin('t.user', 'user')
            ->leftJoin('t.retweeted_status', 'rt')
            ->leftJoin('rt.user', 'rt_user')
            // Ignore tweets that were only retweeted
            ->where($qb->expr()->eq('t.in_timeline', 'true'))
            ->orderBy('t.id', 'DESC')
            ->setFirstResult($firstResult)
            ->setMaxResults($this->nbTweets);
        return $query->getQuery()->getResult();
    }
    /**
     * @param \Doctrine\ORM\QueryBuilder $qb
     *
     * @return \Doctrine\ORM\QueryBuilder $query
     */
    private function getWithUsersAndMediasQuery($qb)
    {
        $query = $qb
            ->select('t, user, medias, rt, rt_user')
            ->innerJoin('t.user', 'user')
            ->leftJoin('t.medias', 'medias')
            ->leftJoin('t.retweeted_status', 'rt')
            ->leftJoin('rt.user', 'rt_user')
            // Ignore tweets that were only retweeted
            ->where($qb->expr()->eq('t.in_timeline', 'true'))
            ->orderBy('t.id', 'ASC')
            ->setFirstResult(0)
            ->setMaxResults($this->nbTweets);
        return $query;
    }
    public function getWithUsersAndMedias($firstTweetId = null)
    {
        $qb = $this->createQueryBuilder('t');
        $query = $this->getWithUsersAndMediasQuery($qb);
        if (!is_null($firstTweetId)) {
            $query = $query->andWhere(
                $qb->expr()->gte('t.id', $firstTweetId)
            );
        }
        return $query->getQuery()->getResult();
    }
    /**
     * @param string $condition
     * @param string $order
     * @param int    $tweetId
     *
     * @return int|null
     */
    private function getTweetId($condition, $order, $tweetId)
    {
        $qb = $this->createQueryBuilder('t')
            ->select('t.id')
            ->where('t.id '.$condition.' :tweetId')
            ->setParameter(':tweetId', $tweetId)
            ->andWhere('t.in_timeline = true')
            ->orderBy('t.id', $order)
            ->setFirstResult($this->nbTweets - 1)
            ->setMaxResults(1);
        $result = $qb->getQuery()->getOneOrNullResult();
        return is_array($result) ? $result['id'] : null;
    }
    public function getPreviousTweetId($tweetId)
    {
        return $this->getTweetId('<', 'DESC', $tweetId);
    }
    public function getNextTweetId($tweetId)
    {
        return $this->getTweetId('>', 'ASC', $tweetId);
    }
    public function countPendingTweets($lastTweetId = null)
    {
        /** @var \Doctrine\ORM\QueryBuilder $qb */
        $qb = $this->createQueryBuilder('t');
        $query = $qb
            ->add('select', $qb->expr()->count('t.id'))
            // Ignore tweets that were only retweeted
            ->where(
                $qb->expr()->eq('t.in_timeline', 'true')
            );
        if (!is_null($lastTweetId)) {
            $query = $query->andWhere(
                $qb->expr()->gte('t.id', $lastTweetId)
            );
        }
        // return result of "COUNT()" query
        return $query->getQuery()->getSingleScalarResult();
    }
    public function getLastTweet()
    {
        $qb = $this->createQueryBuilder('t')
            ->addOrderBy('t.id', 'DESC')
            ->setFirstResult(0)
            ->setMaxResults(1);
        return $qb->getQuery()->getOneOrNullResult();
    }
    /**
     * @param int $tweetId
     *
     * @return array
     */
    private function getTweetsLessThanId($tweetId)
    {
        $qb = $this->createQueryBuilder('t')
            ->select('t, m')
            ->leftJoin('t.medias', 'm')
            ->where('t.id < :tweetId')
            ->setParameter(':tweetId', $tweetId)
            // Get retweeted tweets (it would break foreign keys)
            //  http://stackoverflow.com/questions/15087933/how-to-do-left-join-in-doctrine/15088250#15088250
            ->leftJoin(
                'AsyncTweetsBundle:Tweet',
                't2',
                'WITH',
                't.id = t2.retweeted_status'
            )
            ->orderBy('t.id', 'DESC');
        return $qb->getQuery()->getResult();
    }
    /**
     * Remove Media not associated to any Tweet.
     *
     * @param Media $media
     */
    private function removeOrphanMedias(Media $media)
    {
        if (count($media->getTweets()) == 0) {
            $this->_em->remove($media);
        }
    }
    /**
     * Remove the tweet and return 1 is the deleted tweet is not a
     *  retweet.
     *
     * @param Tweet $tweet
     *
     * @return int
     */
    protected function removeTweet($tweet)
    {
        $count = 0;
        foreach ($tweet->getMedias() as $media) {
            $tweet->removeMedia($media);
            $this->removeOrphanMedias($media);
        }
        // Don't count tweets that were only retweeted
        if ($tweet->isInTimeline()) {
            $count = 1;
        }
        $this->_em->remove($tweet);
        return $count;
    }
    /**
     * Delete tweets and return the number of deleted tweets (excluding
     *  retweeted-only tweets).
     *
     * @param int $tweetId
     *
     * @return int
     */
    public function deleteAndHideTweetsLessThanId($tweetId)
    {
        $count = 0;
        $tweets = $this->getTweetsLessThanId($tweetId);
        foreach ($tweets as $tweet) {
            if ($tweet->mustBeKept($tweetId)) {
                // The Tweet is still in the timeline, it can only be hidden
                $tweet->setInTimeline(false);
                $this->_em->persist($tweet);
            } else {
                // The Tweet has not been retweeted, it can be removed
                $count += $this->removeTweet($tweet);
            }
        }
        $this->_em->flush();
        return $count;
    }
}