Completed
Push — master ( e03925...d40975 )
by Matt
17s queued 12s
created

src/Pagination/DoctrinePaginatorAdapter.php (1 issue)

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
 * This file is part of the League\Fractal package.
4
 *
5
 * (c) Phil Sturgeon <[email protected]>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
11
namespace League\Fractal\Pagination;
12
13
use Doctrine\ORM\Tools\Pagination\Paginator;
14
15
/**
16
 * A paginator adapter for doctrine pagination.
17
 *
18
 * @author Fraser Stockley <[email protected]>
19
 */
20
class DoctrinePaginatorAdapter implements PaginatorInterface
21
{
22
    /**
23
     * The paginator instance.
24
     * @var  Paginator
25
     */
26
    private $paginator;
27
28
    /**
29
     * The route generator.
30
     *
31
     * @var callable
32
     */
33
    private $routeGenerator;
34
35
    /**
36
     * Create a new DoctrinePaginatorAdapter.
37
     * @param Paginator $paginator
38
     * @param callable $routeGenerator
39
     *
40
     */
41 1
    public function __construct(Paginator $paginator, callable $routeGenerator)
42
    {
43 1
        $this->paginator = $paginator;
44 1
        $this->routeGenerator = $routeGenerator;
45 1
    }
46
47
    /**
48
     * Get the current page.
49
     *
50
     * @return int
51
     */
52 1
    public function getCurrentPage()
53
    {
54 1
        return ($this->paginator->getQuery()->getFirstResult() / $this->paginator->getQuery()->getMaxResults()) + 1;
55
    }
56
57
    /**
58
     * Get the last page.
59
     *
60
     * @return int
61
     */
62 1
    public function getLastPage()
63
    {
64 1
        return (int) ceil($this->getTotal() / $this->paginator->getQuery()->getMaxResults());
65
    }
66
67
    /**
68
     * Get the total.
69
     *
70
     * @return int
71
     */
72 1
    public function getTotal()
73
    {
74 1
        return count($this->paginator);
75
    }
76
77
    /**
78
     * Get the count.
79
     *
80
     * @return int
81
     */
82 1
    public function getCount()
83
    {
84 1
        return $this->paginator->getIterator()->count();
0 ignored issues
show
It seems like you code against a concrete implementation and not the interface Traversable as the method count() does only exist in the following implementations of said interface: ArrayIterator, ArrayObject, CachingIterator, Doctrine\Common\Collections\AbstractLazyCollection, Doctrine\Common\Collections\ArrayCollection, Doctrine\ORM\LazyCriteriaCollection, Doctrine\ORM\PersistentCollection, Doctrine\ORM\Tools\Console\MetadataFilter, Doctrine\ORM\Tools\Pagination\Paginator, GlobIterator, HttpMessage, HttpRequestPool, Issue523, MongoCursor, MongoGridFSCursor, PHPUnit\Framework\DataProviderTestSuite, PHPUnit\Framework\TestSuite, PHP_CodeSniffer\Files\FileList, PHP_Token_Stream, Pagerfanta\Pagerfanta, Phar, PharData, PharIo\Manifest\AuthorCollection, PharIo\Manifest\BundledComponentCollection, PharIo\Manifest\RequirementCollection, RecursiveArrayIterator, RecursiveCachingIterator, SQLiteResult, SebastianBergmann\CodeCoverage\Node\Directory, SimpleXMLElement, SimpleXMLIterator, SplDoublyLinkedList, SplFixedArray, SplHeap, SplMaxHeap, SplMinHeap, SplObjectStorage, SplPriorityQueue, SplQueue, SplStack, TheSeer\Tokenizer\TokenCollection, Zend\Paginator\Paginator, Zend\Stdlib\ArrayObject, Zend\Stdlib\ArrayStack, Zend\Stdlib\FastPriorityQueue, Zend\Stdlib\Parameters, Zend\Stdlib\PriorityList, Zend\Stdlib\PriorityQueue, Zend\Stdlib\SplPriorityQueue, Zend\Stdlib\SplQueue, Zend\Stdlib\SplStack.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
85
    }
86
87
    /**
88
     * Get the number per page.
89
     *
90
     * @return int
91
     */
92 1
    public function getPerPage()
93
    {
94 1
        return $this->paginator->getQuery()->getMaxResults();
95
    }
96
97
    /**
98
     * Get the url for the given page.
99
     *
100
     * @param int $page
101
     *
102
     * @return string
103
     */
104 1
    public function getUrl($page)
105
    {
106 1
        return call_user_func($this->getRouteGenerator(), $page);
107
    }
108
109
    /**
110
     * Get the the route generator.
111
     *
112
     * @return callable
113
     */
114 1
    private function getRouteGenerator()
115
    {
116 1
        return $this->routeGenerator;
117
    }
118
}
119