Complex classes like PaginateRoute often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use PaginateRoute, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
13 | class PaginateRoute |
||
14 | { |
||
15 | /** |
||
16 | * @var \Illuminate\Translation\Translator |
||
17 | */ |
||
18 | protected $translator; |
||
19 | |||
20 | /** |
||
21 | * @var \Illuminate\Routing\Router |
||
22 | */ |
||
23 | protected $router; |
||
24 | |||
25 | /** |
||
26 | * @var \Illuminate\Contracts\Routing\UrlGenerator |
||
27 | */ |
||
28 | protected $urlGenerator; |
||
29 | |||
30 | /** |
||
31 | * @var string |
||
32 | */ |
||
33 | protected $pageKeyword; |
||
34 | |||
35 | /** |
||
36 | * @param \Illuminate\Translation\Translator $translator |
||
37 | * @param \Illuminate\Routing\Router $router |
||
38 | * @param \Illuminate\Contracts\Routing\UrlGenerator $urlGenerator |
||
39 | */ |
||
40 | public function __construct(Translator $translator, Router $router, UrlGenerator $urlGenerator) |
||
41 | { |
||
42 | $this->translator = $translator; |
||
43 | $this->router = $router; |
||
44 | $this->urlGenerator = $urlGenerator; |
||
45 | |||
46 | // Unfortunately we can't do this in the service provider since routes are booted first |
||
47 | $this->translator->addNamespace('paginateroute', __DIR__.'/../resources/lang'); |
||
48 | |||
49 | $this->pageKeyword = $this->translator->get('paginateroute::paginateroute.page'); |
||
50 | } |
||
51 | |||
52 | /** |
||
53 | * Return the current page. |
||
54 | * |
||
55 | * @return int |
||
56 | */ |
||
57 | public function currentPage() |
||
69 | |||
70 | /** |
||
71 | * Check if the given page is the current page. |
||
72 | * |
||
73 | * @param int $page |
||
74 | * |
||
75 | * @return bool |
||
76 | */ |
||
77 | public function isCurrentPage($page) |
||
81 | |||
82 | /** |
||
83 | * Get the next page number. |
||
84 | * |
||
85 | * @param \Illuminate\Contracts\Pagination\Paginator $paginator |
||
86 | * |
||
87 | * @return string|null |
||
88 | */ |
||
89 | public function nextPage(Paginator $paginator) |
||
97 | |||
98 | /** |
||
99 | * Determine wether there is a next page. |
||
100 | * |
||
101 | * @param \Illuminate\Contracts\Pagination\Paginator $paginator |
||
102 | * |
||
103 | * @return bool |
||
104 | */ |
||
105 | public function hasNextPage(Paginator $paginator) |
||
109 | |||
110 | /** |
||
111 | * Get the next page URL. |
||
112 | * |
||
113 | * @param \Illuminate\Contracts\Pagination\Paginator $paginator |
||
114 | * |
||
115 | * @return string|null |
||
116 | */ |
||
117 | public function nextPageUrl(Paginator $paginator) |
||
118 | { |
||
119 | $nextPage = $this->nextPage($paginator); |
||
120 | |||
121 | if ($nextPage === null) { |
||
122 | return; |
||
123 | } |
||
124 | |||
125 | return $this->pageUrl($nextPage); |
||
126 | } |
||
127 | |||
128 | /** |
||
129 | * Get the previous page number. |
||
130 | * |
||
131 | * @return string|null |
||
132 | */ |
||
133 | public function previousPage() |
||
141 | |||
142 | /** |
||
143 | * Determine wether there is a previous page. |
||
144 | * |
||
145 | * @return bool |
||
146 | */ |
||
147 | public function hasPreviousPage() |
||
151 | |||
152 | /** |
||
153 | * Get the previous page URL. |
||
154 | * |
||
155 | * @param bool $full Return the full version of the URL in for the first page |
||
156 | * Ex. /users/page/1 instead of /users |
||
157 | * |
||
158 | * @return string|null |
||
159 | */ |
||
160 | public function previousPageUrl($full = false) |
||
170 | |||
171 | /** |
||
172 | * Get all urls in an array. |
||
173 | * |
||
174 | * @param \Illuminate\Contracts\Pagination\LengthAwarePaginator $paginator |
||
175 | * @param bool $full Return the full version of the URL in for the first page |
||
176 | * Ex. /users/page/1 instead of /users |
||
177 | * |
||
178 | * @return array |
||
179 | */ |
||
180 | public function allUrls(LengthAwarePaginator $paginator, $full = false) |
||
181 | { |
||
182 | if (! $paginator->hasPages()) { |
||
183 | return []; |
||
184 | } |
||
185 | |||
186 | $urls = []; |
||
187 | $left = $this->getLeftPoint($paginator); |
||
188 | $right = $this->getRightPoint($paginator); |
||
189 | for ($page = $left; $page <= $right; $page++) { |
||
190 | $urls[$page] = $this->pageUrl($page, $full); |
||
191 | } |
||
192 | |||
193 | return $urls; |
||
194 | } |
||
195 | |||
196 | /** |
||
197 | * Get the left most point in the pagination element. |
||
198 | * |
||
199 | * @param LengthAwarePaginator $paginator |
||
200 | * @return int |
||
201 | */ |
||
202 | public function getLeftPoint(LengthAwarePaginator $paginator) |
||
216 | |||
217 | /** |
||
218 | * Get the right or last point of the pagination element. |
||
219 | * |
||
220 | * @param LengthAwarePaginator $paginator |
||
221 | * @return int |
||
222 | */ |
||
223 | public function getRightPoint(LengthAwarePaginator $paginator) |
||
236 | |||
237 | /** |
||
238 | * Render a plain html list with previous, next and all urls. The current page gets a current class on the list item. |
||
239 | * |
||
240 | * @param \Illuminate\Contracts\Pagination\LengthAwarePaginator $paginator |
||
241 | * @param bool $full Return the full version of the URL in for the first page |
||
242 | * Ex. /users/page/1 instead of /users |
||
243 | * @param string $class Include class on pagination list |
||
244 | * Ex. <ul class="pagination"> |
||
245 | * @param bool $additionalLinks Include prev and next links on pagination list |
||
246 | * |
||
247 | * @return string |
||
248 | */ |
||
249 | public function renderPageList(LengthAwarePaginator $paginator, $full = false, $class = null, $additionalLinks = false) |
||
284 | |||
285 | /** |
||
286 | * Render html link tags for SEO indication of previous and next page. |
||
287 | * |
||
288 | * @param \Illuminate\Contracts\Pagination\LengthAwarePaginator $paginator |
||
289 | * @param bool $full Return the full version of the URL in for the first page |
||
290 | * Ex. /users/page/1 instead of /users |
||
291 | * |
||
292 | * @return string |
||
293 | */ |
||
294 | public function renderRelLinks(LengthAwarePaginator $paginator, $full = false) |
||
315 | |||
316 | /** |
||
317 | * @deprecated in favor of renderPageList. |
||
318 | * |
||
319 | * @param \Illuminate\Contracts\Pagination\LengthAwarePaginator $paginator |
||
320 | * @param bool $full Return the full version of the URL in for the first page |
||
321 | * Ex. /users/page/1 instead of /users |
||
322 | * |
||
323 | * @return string |
||
324 | */ |
||
325 | public function renderHtml(LengthAwarePaginator $paginator, $full = false) |
||
329 | |||
330 | /** |
||
331 | * Generate a page URL, based on the request's current URL. |
||
332 | * |
||
333 | * @param int $page |
||
334 | * @param bool $full Return the full version of the URL in for the first page |
||
335 | * Ex. /users/page/1 instead of /users |
||
336 | * |
||
337 | * @return string |
||
338 | */ |
||
339 | public function pageUrl($page, $full = false) |
||
357 | |||
358 | /** |
||
359 | * Append the page query to a URL. |
||
360 | * |
||
361 | * @param string $url |
||
362 | * @param int $page |
||
363 | * @param bool $full Return the full version of the URL in for the first page |
||
364 | * Ex. /users/page/1 instead of /users |
||
365 | * |
||
366 | * @return string |
||
367 | */ |
||
368 | public function addPageQuery($url, $page, $full = false) |
||
377 | |||
378 | /** |
||
379 | * Register the Route::paginate macro. |
||
380 | */ |
||
381 | public function registerMacros() |
||
398 | } |
||
399 |
If you access a property on an interface, you most likely code against a concrete implementation of the interface.
Available Fixes
Adding an additional type check:
Changing the type hint: