Completed
Push — master ( 4fcc05...a85859 )
by Peter
05:13
created

Builder::paginateRequest()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 16
Code Lines 12

Duplication

Lines 16
Ratio 100 %

Code Coverage

Tests 8
CRAP Score 2

Importance

Changes 0
Metric Value
dl 16
loc 16
ccs 8
cts 8
cp 1
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 12
nc 2
nop 4
crap 2
1
<?php
2
/**
3
 * GpsLab component.
4
 *
5
 * @author    Peter Gribanov <[email protected]>
6
 * @copyright Copyright (c) 2011, Peter Gribanov
7
 * @license   http://opensource.org/licenses/MIT
8
 */
9
10
namespace GpsLab\Bundle\PaginationBundle\Service;
11
12
use GpsLab\Bundle\PaginationBundle\Exception\IncorrectPageNumberException;
13
use GpsLab\Bundle\PaginationBundle\Exception\OutOfRangeException;
14
use Doctrine\ORM\QueryBuilder;
15
use Symfony\Bundle\FrameworkBundle\Routing\Router;
16
use Symfony\Component\HttpFoundation\Request;
17
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
18
19
class Builder
20
{
21
    /**
22
     * @var Router
23
     */
24
    private $router;
25
26
    /**
27
     * The number of pages displayed in the navigation.
28
     *
29
     * @var int
30
     */
31
    private $max_navigate = Configuration::DEFAULT_LIST_LENGTH;
32
33
    /**
34
     * Name of URL parameter for page number
35
     *
36
     * @var int
37
     */
38
    private $parameter_name = 'page';
39
40
    /**
41
     * @param Router $router         Router service
42
     * @param int    $max_navigate   Maximum showing navigation links in pagination
43
     * @param string $parameter_name Name of URL parameter for page number
44
     */
45 13
    public function __construct(Router $router, $max_navigate, $parameter_name)
46
    {
47 13
        $this->router = $router;
48 13
        $this->max_navigate = $max_navigate;
49 13
        $this->parameter_name = $parameter_name;
0 ignored issues
show
Documentation Bug introduced by
The property $parameter_name was declared of type integer, but $parameter_name is of type string. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
50 13
    }
51
52
    /**
53
     * @param int $total_pages  Total available pages
54
     * @param int $current_page The current page number
55
     *
56
     * @return Configuration
57
     */
58 6
    public function paginate($total_pages = 1, $current_page = 1)
59
    {
60 6
        return (new Configuration($total_pages, $current_page))
61 6
            ->setMaxNavigate($this->max_navigate)
62 6
        ;
63
    }
64
65
    /**
66
     * @param QueryBuilder $query        Query for select entities
67
     * @param int          $per_page     Entities per page
68
     * @param int          $current_page The current page number
69
     *
70
     * @return Configuration
71
     */
72 7
    public function paginateQuery(QueryBuilder $query, $per_page, $current_page = 1)
73
    {
74 7
        $counter = clone $query;
75
        $total = $counter
76 7
            ->select(sprintf('COUNT(%s)', current($query->getRootAliases())))
77 7
            ->getQuery()
78 7
            ->getSingleScalarResult()
79 7
        ;
80
81 7
        $total_pages = ceil($total / $per_page);
82 7
        $current_page = $this->validateCurrentPage($current_page, $total_pages);
83
84
        $query
85 3
            ->setFirstResult(($current_page - 1) * $per_page)
86 3
            ->setMaxResults($per_page)
87
        ;
88
89 3
        return $this->paginate($total_pages, $current_page);
90
    }
91
92
    /**
93
     * @param Request $request        Current HTTP request
94
     * @param int     $total_pages    Total available pages
95
     * @param string  $parameter_name Name of URL parameter for page number
96
     * @param int     $reference_type The type of reference (one of the constants in UrlGeneratorInterface)
97
     *
98
     * @return Configuration
99
     */
100 4 View Code Duplication
    public function paginateRequest(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
101
        Request $request,
102
        $total_pages,
103
        $parameter_name = '',
104
        $reference_type = UrlGeneratorInterface::ABSOLUTE_PATH
105
    ) {
106 4
        $parameter_name = $parameter_name ?: $this->parameter_name;
107 4
        $current_page = $this->validateCurrentPage($request->get($parameter_name), $total_pages);
108
109 1
        return $this->configureFromRequest(
110 1
            $request,
111 1
            $this->paginate($total_pages, $current_page),
112 1
            $parameter_name,
113
            $reference_type
114 1
        );
115
    }
116
117
    /**
118
     * @param Request      $request        Current HTTP request
119
     * @param QueryBuilder $query          Query for select entities
120
     * @param int          $per_page       Entities per page
121
     * @param string       $parameter_name Name of URL parameter for page number
122
     * @param int          $reference_type The type of reference (one of the constants in UrlGeneratorInterface)
123
     *
124
     * @return Configuration
125
     */
126 4 View Code Duplication
    public function paginateRequestQuery(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
127
        Request $request,
128
        QueryBuilder $query,
129
        $per_page,
130
        $parameter_name = 'page',
131
        $reference_type = UrlGeneratorInterface::ABSOLUTE_PATH
132
    ) {
133 4
        $parameter_name = $parameter_name ?: $this->parameter_name;
134
135 4
        return $this->configureFromRequest(
136 4
            $request,
137 4
            $this->paginateQuery($query, $per_page, $request->get($parameter_name)),
138 1
            $parameter_name,
139
            $reference_type
140 1
        );
141
    }
142
143
    /**
144
     * @param mixed $current_page
145
     * @param int   $total_pages
146
     *
147
     * @return int
148
     */
149 11
    private function validateCurrentPage($current_page, $total_pages)
150
    {
151 11
        if (is_null($current_page)) {
152 1
            return 1;
153 10
        } elseif (!is_numeric($current_page)) {
154 2
            throw IncorrectPageNumberException::incorrect($current_page);
155 8
        } elseif ($current_page < 1 || $current_page > $total_pages) {
156 5
            throw OutOfRangeException::out($current_page, $total_pages);
157
        } else {
158 3
            return (int) $current_page;
159
        }
160
    }
161
162
    /**
163
     * @param Request       $request
164
     * @param Configuration $configuration
165
     * @param string        $parameter_name
166
     * @param int           $reference_type
167
     *
168
     * @return Configuration
169
     */
170 2
    private function configureFromRequest(
171
        Request $request,
172
        Configuration $configuration,
173
        $parameter_name,
174
        $reference_type
175
    ) {
176 2
        $route = $request->get('_route');
177 2
        $route_params = $request->get('_route_params');
178
179
        return $configuration
180 2
            ->setPageLink(function ($number) use ($route, $route_params, $parameter_name, $reference_type) {
181 2
                $params = array_merge($route_params, [$parameter_name => $number]);
182
183 2
                return $this->router->generate($route, $params, $reference_type);
184 2
            })
185 2
            ->setFirstPageLink($this->router->generate($route, $route_params, $reference_type))
186 2
        ;
187
    }
188
}
189