Просмотр файла vendor/illuminate/pagination/AbstractPaginator.php

Размер файла: 15.41Kb
  1. <?php
  2.  
  3. namespace Illuminate\Pagination;
  4.  
  5. use Closure;
  6. use Illuminate\Contracts\Support\Htmlable;
  7. use Illuminate\Support\Arr;
  8. use Illuminate\Support\Collection;
  9. use Illuminate\Support\Str;
  10. use Illuminate\Support\Traits\ForwardsCalls;
  11.  
  12. /**
  13. * @mixin \Illuminate\Support\Collection
  14. */
  15. abstract class AbstractPaginator implements Htmlable
  16. {
  17. use ForwardsCalls;
  18.  
  19. /**
  20. * All of the items being paginated.
  21. *
  22. * @var \Illuminate\Support\Collection
  23. */
  24. protected $items;
  25.  
  26. /**
  27. * The number of items to be shown per page.
  28. *
  29. * @var int
  30. */
  31. protected $perPage;
  32.  
  33. /**
  34. * The current page being "viewed".
  35. *
  36. * @var int
  37. */
  38. protected $currentPage;
  39.  
  40. /**
  41. * The base path to assign to all URLs.
  42. *
  43. * @var string
  44. */
  45. protected $path = '/';
  46.  
  47. /**
  48. * The query parameters to add to all URLs.
  49. *
  50. * @var array
  51. */
  52. protected $query = [];
  53.  
  54. /**
  55. * The URL fragment to add to all URLs.
  56. *
  57. * @var string|null
  58. */
  59. protected $fragment;
  60.  
  61. /**
  62. * The query string variable used to store the page.
  63. *
  64. * @var string
  65. */
  66. protected $pageName = 'page';
  67.  
  68. /**
  69. * The number of links to display on each side of current page link.
  70. *
  71. * @var int
  72. */
  73. public $onEachSide = 3;
  74.  
  75. /**
  76. * The paginator options.
  77. *
  78. * @var array
  79. */
  80. protected $options;
  81.  
  82. /**
  83. * The current path resolver callback.
  84. *
  85. * @var \Closure
  86. */
  87. protected static $currentPathResolver;
  88.  
  89. /**
  90. * The current page resolver callback.
  91. *
  92. * @var \Closure
  93. */
  94. protected static $currentPageResolver;
  95.  
  96. /**
  97. * The query string resolver callback.
  98. *
  99. * @var \Closure
  100. */
  101. protected static $queryStringResolver;
  102.  
  103. /**
  104. * The view factory resolver callback.
  105. *
  106. * @var \Closure
  107. */
  108. protected static $viewFactoryResolver;
  109.  
  110. /**
  111. * The default pagination view.
  112. *
  113. * @var string
  114. */
  115. public static $defaultView = 'pagination::tailwind';
  116.  
  117. /**
  118. * The default "simple" pagination view.
  119. *
  120. * @var string
  121. */
  122. public static $defaultSimpleView = 'pagination::simple-tailwind';
  123.  
  124. /**
  125. * Determine if the given value is a valid page number.
  126. *
  127. * @param int $page
  128. * @return bool
  129. */
  130. protected function isValidPageNumber($page)
  131. {
  132. return $page >= 1 && filter_var($page, FILTER_VALIDATE_INT) !== false;
  133. }
  134.  
  135. /**
  136. * Get the URL for the previous page.
  137. *
  138. * @return string|null
  139. */
  140. public function previousPageUrl()
  141. {
  142. if ($this->currentPage() > 1) {
  143. return $this->url($this->currentPage() - 1);
  144. }
  145. }
  146.  
  147. /**
  148. * Create a range of pagination URLs.
  149. *
  150. * @param int $start
  151. * @param int $end
  152. * @return array
  153. */
  154. public function getUrlRange($start, $end)
  155. {
  156. return collect(range($start, $end))->mapWithKeys(function ($page) {
  157. return [$page => $this->url($page)];
  158. })->all();
  159. }
  160.  
  161. /**
  162. * Get the URL for a given page number.
  163. *
  164. * @param int $page
  165. * @return string
  166. */
  167. public function url($page)
  168. {
  169. if ($page <= 0) {
  170. $page = 1;
  171. }
  172.  
  173. // If we have any extra query string key / value pairs that need to be added
  174. // onto the URL, we will put them in query string form and then attach it
  175. // to the URL. This allows for extra information like sortings storage.
  176. $parameters = [$this->pageName => $page];
  177.  
  178. if (count($this->query) > 0) {
  179. $parameters = array_merge($this->query, $parameters);
  180. }
  181.  
  182. return $this->path()
  183. .(Str::contains($this->path(), '?') ? '&' : '?')
  184. .Arr::query($parameters)
  185. .$this->buildFragment();
  186. }
  187.  
  188. /**
  189. * Get / set the URL fragment to be appended to URLs.
  190. *
  191. * @param string|null $fragment
  192. * @return $this|string|null
  193. */
  194. public function fragment($fragment = null)
  195. {
  196. if (is_null($fragment)) {
  197. return $this->fragment;
  198. }
  199.  
  200. $this->fragment = $fragment;
  201.  
  202. return $this;
  203. }
  204.  
  205. /**
  206. * Add a set of query string values to the paginator.
  207. *
  208. * @param array|string|null $key
  209. * @param string|null $value
  210. * @return $this
  211. */
  212. public function appends($key, $value = null)
  213. {
  214. if (is_null($key)) {
  215. return $this;
  216. }
  217.  
  218. if (is_array($key)) {
  219. return $this->appendArray($key);
  220. }
  221.  
  222. return $this->addQuery($key, $value);
  223. }
  224.  
  225. /**
  226. * Add an array of query string values.
  227. *
  228. * @param array $keys
  229. * @return $this
  230. */
  231. protected function appendArray(array $keys)
  232. {
  233. foreach ($keys as $key => $value) {
  234. $this->addQuery($key, $value);
  235. }
  236.  
  237. return $this;
  238. }
  239.  
  240. /**
  241. * Add all current query string values to the paginator.
  242. *
  243. * @return $this
  244. */
  245. public function withQueryString()
  246. {
  247. if (isset(static::$queryStringResolver)) {
  248. return $this->appends(call_user_func(static::$queryStringResolver));
  249. }
  250.  
  251. return $this;
  252. }
  253.  
  254. /**
  255. * Add a query string value to the paginator.
  256. *
  257. * @param string $key
  258. * @param string $value
  259. * @return $this
  260. */
  261. protected function addQuery($key, $value)
  262. {
  263. if ($key !== $this->pageName) {
  264. $this->query[$key] = $value;
  265. }
  266.  
  267. return $this;
  268. }
  269.  
  270. /**
  271. * Build the full fragment portion of a URL.
  272. *
  273. * @return string
  274. */
  275. protected function buildFragment()
  276. {
  277. return $this->fragment ? '#'.$this->fragment : '';
  278. }
  279.  
  280. /**
  281. * Load a set of relationships onto the mixed relationship collection.
  282. *
  283. * @param string $relation
  284. * @param array $relations
  285. * @return $this
  286. */
  287. public function loadMorph($relation, $relations)
  288. {
  289. $this->getCollection()->loadMorph($relation, $relations);
  290.  
  291. return $this;
  292. }
  293.  
  294. /**
  295. * Load a set of relationship counts onto the mixed relationship collection.
  296. *
  297. * @param string $relation
  298. * @param array $relations
  299. * @return $this
  300. */
  301. public function loadMorphCount($relation, $relations)
  302. {
  303. $this->getCollection()->loadMorphCount($relation, $relations);
  304.  
  305. return $this;
  306. }
  307.  
  308. /**
  309. * Get the slice of items being paginated.
  310. *
  311. * @return array
  312. */
  313. public function items()
  314. {
  315. return $this->items->all();
  316. }
  317.  
  318. /**
  319. * Get the number of the first item in the slice.
  320. *
  321. * @return int
  322. */
  323. public function firstItem()
  324. {
  325. return count($this->items) > 0 ? ($this->currentPage - 1) * $this->perPage + 1 : null;
  326. }
  327.  
  328. /**
  329. * Get the number of the last item in the slice.
  330. *
  331. * @return int
  332. */
  333. public function lastItem()
  334. {
  335. return count($this->items) > 0 ? $this->firstItem() + $this->count() - 1 : null;
  336. }
  337.  
  338. /**
  339. * Transform each item in the slice of items using a callback.
  340. *
  341. * @param callable $callback
  342. * @return $this
  343. */
  344. public function through(callable $callback)
  345. {
  346. $this->items->transform($callback);
  347.  
  348. return $this;
  349. }
  350.  
  351. /**
  352. * Get the number of items shown per page.
  353. *
  354. * @return int
  355. */
  356. public function perPage()
  357. {
  358. return $this->perPage;
  359. }
  360.  
  361. /**
  362. * Determine if there are enough items to split into multiple pages.
  363. *
  364. * @return bool
  365. */
  366. public function hasPages()
  367. {
  368. return $this->currentPage() != 1 || $this->hasMorePages();
  369. }
  370.  
  371. /**
  372. * Determine if the paginator is on the first page.
  373. *
  374. * @return bool
  375. */
  376. public function onFirstPage()
  377. {
  378. return $this->currentPage() <= 1;
  379. }
  380.  
  381. /**
  382. * Get the current page.
  383. *
  384. * @return int
  385. */
  386. public function currentPage()
  387. {
  388. return $this->currentPage;
  389. }
  390.  
  391. /**
  392. * Get the query string variable used to store the page.
  393. *
  394. * @return string
  395. */
  396. public function getPageName()
  397. {
  398. return $this->pageName;
  399. }
  400.  
  401. /**
  402. * Set the query string variable used to store the page.
  403. *
  404. * @param string $name
  405. * @return $this
  406. */
  407. public function setPageName($name)
  408. {
  409. $this->pageName = $name;
  410.  
  411. return $this;
  412. }
  413.  
  414. /**
  415. * Set the base path to assign to all URLs.
  416. *
  417. * @param string $path
  418. * @return $this
  419. */
  420. public function withPath($path)
  421. {
  422. return $this->setPath($path);
  423. }
  424.  
  425. /**
  426. * Set the base path to assign to all URLs.
  427. *
  428. * @param string $path
  429. * @return $this
  430. */
  431. public function setPath($path)
  432. {
  433. $this->path = $path;
  434.  
  435. return $this;
  436. }
  437.  
  438. /**
  439. * Set the number of links to display on each side of current page link.
  440. *
  441. * @param int $count
  442. * @return $this
  443. */
  444. public function onEachSide($count)
  445. {
  446. $this->onEachSide = $count;
  447.  
  448. return $this;
  449. }
  450.  
  451. /**
  452. * Get the base path for paginator generated URLs.
  453. *
  454. * @return string|null
  455. */
  456. public function path()
  457. {
  458. return $this->path;
  459. }
  460.  
  461. /**
  462. * Resolve the current request path or return the default value.
  463. *
  464. * @param string $default
  465. * @return string
  466. */
  467. public static function resolveCurrentPath($default = '/')
  468. {
  469. if (isset(static::$currentPathResolver)) {
  470. return call_user_func(static::$currentPathResolver);
  471. }
  472.  
  473. return $default;
  474. }
  475.  
  476. /**
  477. * Set the current request path resolver callback.
  478. *
  479. * @param \Closure $resolver
  480. * @return void
  481. */
  482. public static function currentPathResolver(Closure $resolver)
  483. {
  484. static::$currentPathResolver = $resolver;
  485. }
  486.  
  487. /**
  488. * Resolve the current page or return the default value.
  489. *
  490. * @param string $pageName
  491. * @param int $default
  492. * @return int
  493. */
  494. public static function resolveCurrentPage($pageName = 'page', $default = 1)
  495. {
  496. if (isset(static::$currentPageResolver)) {
  497. return (int) call_user_func(static::$currentPageResolver, $pageName);
  498. }
  499.  
  500. return $default;
  501. }
  502.  
  503. /**
  504. * Set the current page resolver callback.
  505. *
  506. * @param \Closure $resolver
  507. * @return void
  508. */
  509. public static function currentPageResolver(Closure $resolver)
  510. {
  511. static::$currentPageResolver = $resolver;
  512. }
  513.  
  514. /**
  515. * Set with query string resolver callback.
  516. *
  517. * @param \Closure $resolver
  518. * @return void
  519. */
  520. public static function queryStringResolver(Closure $resolver)
  521. {
  522. static::$queryStringResolver = $resolver;
  523. }
  524.  
  525. /**
  526. * Get an instance of the view factory from the resolver.
  527. *
  528. * @return \Illuminate\Contracts\View\Factory
  529. */
  530. public static function viewFactory()
  531. {
  532. return call_user_func(static::$viewFactoryResolver);
  533. }
  534.  
  535. /**
  536. * Set the view factory resolver callback.
  537. *
  538. * @param \Closure $resolver
  539. * @return void
  540. */
  541. public static function viewFactoryResolver(Closure $resolver)
  542. {
  543. static::$viewFactoryResolver = $resolver;
  544. }
  545.  
  546. /**
  547. * Set the default pagination view.
  548. *
  549. * @param string $view
  550. * @return void
  551. */
  552. public static function defaultView($view)
  553. {
  554. static::$defaultView = $view;
  555. }
  556.  
  557. /**
  558. * Set the default "simple" pagination view.
  559. *
  560. * @param string $view
  561. * @return void
  562. */
  563. public static function defaultSimpleView($view)
  564. {
  565. static::$defaultSimpleView = $view;
  566. }
  567.  
  568. /**
  569. * Indicate that Tailwind styling should be used for generated links.
  570. *
  571. * @return void
  572. */
  573. public static function useTailwind()
  574. {
  575. static::defaultView('pagination::tailwind');
  576. static::defaultSimpleView('pagination::simple-tailwind');
  577. }
  578.  
  579. /**
  580. * Indicate that Bootstrap 4 styling should be used for generated links.
  581. *
  582. * @return void
  583. */
  584. public static function useBootstrap()
  585. {
  586. static::defaultView('pagination::bootstrap-4');
  587. static::defaultSimpleView('pagination::simple-bootstrap-4');
  588. }
  589.  
  590. /**
  591. * Indicate that Bootstrap 3 styling should be used for generated links.
  592. *
  593. * @return void
  594. */
  595. public static function useBootstrapThree()
  596. {
  597. static::defaultView('pagination::default');
  598. static::defaultSimpleView('pagination::simple-default');
  599. }
  600.  
  601. /**
  602. * Get an iterator for the items.
  603. *
  604. * @return \ArrayIterator
  605. */
  606. public function getIterator()
  607. {
  608. return $this->items->getIterator();
  609. }
  610.  
  611. /**
  612. * Determine if the list of items is empty.
  613. *
  614. * @return bool
  615. */
  616. public function isEmpty()
  617. {
  618. return $this->items->isEmpty();
  619. }
  620.  
  621. /**
  622. * Determine if the list of items is not empty.
  623. *
  624. * @return bool
  625. */
  626. public function isNotEmpty()
  627. {
  628. return $this->items->isNotEmpty();
  629. }
  630.  
  631. /**
  632. * Get the number of items for the current page.
  633. *
  634. * @return int
  635. */
  636. public function count()
  637. {
  638. return $this->items->count();
  639. }
  640.  
  641. /**
  642. * Get the paginator's underlying collection.
  643. *
  644. * @return \Illuminate\Support\Collection
  645. */
  646. public function getCollection()
  647. {
  648. return $this->items;
  649. }
  650.  
  651. /**
  652. * Set the paginator's underlying collection.
  653. *
  654. * @param \Illuminate\Support\Collection $collection
  655. * @return $this
  656. */
  657. public function setCollection(Collection $collection)
  658. {
  659. $this->items = $collection;
  660.  
  661. return $this;
  662. }
  663.  
  664. /**
  665. * Get the paginator options.
  666. *
  667. * @return array
  668. */
  669. public function getOptions()
  670. {
  671. return $this->options;
  672. }
  673.  
  674. /**
  675. * Determine if the given item exists.
  676. *
  677. * @param mixed $key
  678. * @return bool
  679. */
  680. public function offsetExists($key)
  681. {
  682. return $this->items->has($key);
  683. }
  684.  
  685. /**
  686. * Get the item at the given offset.
  687. *
  688. * @param mixed $key
  689. * @return mixed
  690. */
  691. public function offsetGet($key)
  692. {
  693. return $this->items->get($key);
  694. }
  695.  
  696. /**
  697. * Set the item at the given offset.
  698. *
  699. * @param mixed $key
  700. * @param mixed $value
  701. * @return void
  702. */
  703. public function offsetSet($key, $value)
  704. {
  705. $this->items->put($key, $value);
  706. }
  707.  
  708. /**
  709. * Unset the item at the given key.
  710. *
  711. * @param mixed $key
  712. * @return void
  713. */
  714. public function offsetUnset($key)
  715. {
  716. $this->items->forget($key);
  717. }
  718.  
  719. /**
  720. * Render the contents of the paginator to HTML.
  721. *
  722. * @return string
  723. */
  724. public function toHtml()
  725. {
  726. return (string) $this->render();
  727. }
  728.  
  729. /**
  730. * Make dynamic calls into the collection.
  731. *
  732. * @param string $method
  733. * @param array $parameters
  734. * @return mixed
  735. */
  736. public function __call($method, $parameters)
  737. {
  738. return $this->forwardCallTo($this->getCollection(), $method, $parameters);
  739. }
  740.  
  741. /**
  742. * Render the contents of the paginator when casting to a string.
  743. *
  744. * @return string
  745. */
  746. public function __toString()
  747. {
  748. return (string) $this->render();
  749. }
  750. }