/vendor/sonata-project/admin-bundle/Datagrid/Pager.php

https://gitlab.com/cuza/Clinic_Recods · PHP · 666 lines · 308 code · 82 blank · 276 comment · 39 complexity · 1879218190166ebb1305f5c56bc6382a MD5 · raw file

  1. <?php
  2. /*
  3. * This file is part of the Sonata Project package.
  4. *
  5. * (c) Thomas Rabaix <thomas.rabaix@sonata-project.org>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Sonata\AdminBundle\Datagrid;
  11. /**
  12. * Class Pager.
  13. *
  14. * @author Fabien Potencier <fabien.potencier@symfony-project.com>
  15. * @author Thomas Rabaix <thomas.rabaix@sonata-project.org>
  16. */
  17. abstract class Pager implements \Iterator, \Countable, \Serializable, PagerInterface
  18. {
  19. const TYPE_DEFAULT = 'default';
  20. const TYPE_SIMPLE = 'simple';
  21. /**
  22. * @var int
  23. */
  24. protected $page = 1;
  25. /**
  26. * @var int
  27. */
  28. protected $maxPerPage = 0;
  29. /**
  30. * @var int
  31. */
  32. protected $lastPage = 1;
  33. /**
  34. * @var int
  35. */
  36. protected $nbResults = 0;
  37. /**
  38. * @var int
  39. */
  40. protected $cursor = 1;
  41. /**
  42. * @var array
  43. */
  44. protected $parameters = array();
  45. /**
  46. * @var int
  47. */
  48. protected $currentMaxLink = 1;
  49. /**
  50. * @var bool
  51. */
  52. protected $maxRecordLimit = false;
  53. /**
  54. * @var int
  55. */
  56. protected $maxPageLinks = 0;
  57. // used by iterator interface
  58. /**
  59. * @var array|null
  60. */
  61. protected $results = null;
  62. /**
  63. * @var int
  64. */
  65. protected $resultsCounter = 0;
  66. /**
  67. * @var ProxyQueryInterface|null
  68. */
  69. protected $query = null;
  70. /**
  71. * @var array
  72. */
  73. protected $countColumn = array('id');
  74. /**
  75. * Constructor.
  76. *
  77. * @param int $maxPerPage Number of records to display per page
  78. */
  79. public function __construct($maxPerPage = 10)
  80. {
  81. $this->setMaxPerPage($maxPerPage);
  82. }
  83. /**
  84. * Returns the current pager's max link.
  85. *
  86. * @return int
  87. */
  88. public function getCurrentMaxLink()
  89. {
  90. return $this->currentMaxLink;
  91. }
  92. /**
  93. * Returns the current pager's max record limit.
  94. *
  95. * @return int
  96. */
  97. public function getMaxRecordLimit()
  98. {
  99. return $this->maxRecordLimit;
  100. }
  101. /**
  102. * Sets the current pager's max record limit.
  103. *
  104. * @param int $limit
  105. */
  106. public function setMaxRecordLimit($limit)
  107. {
  108. $this->maxRecordLimit = $limit;
  109. }
  110. /**
  111. * Returns an array of page numbers to use in pagination links.
  112. *
  113. * @param int $nbLinks The maximum number of page numbers to return
  114. *
  115. * @return array
  116. */
  117. public function getLinks($nbLinks = null)
  118. {
  119. if ($nbLinks == null) {
  120. $nbLinks = $this->getMaxPageLinks();
  121. }
  122. $links = array();
  123. $tmp = $this->page - floor($nbLinks / 2);
  124. $check = $this->lastPage - $nbLinks + 1;
  125. $limit = $check > 0 ? $check : 1;
  126. $begin = $tmp > 0 ? ($tmp > $limit ? $limit : $tmp) : 1;
  127. $i = (int) $begin;
  128. while ($i < $begin + $nbLinks && $i <= $this->lastPage) {
  129. $links[] = $i++;
  130. }
  131. $this->currentMaxLink = count($links) ? $links[count($links) - 1] : 1;
  132. return $links;
  133. }
  134. /**
  135. * Returns true if the current query requires pagination.
  136. *
  137. * @return bool
  138. */
  139. public function haveToPaginate()
  140. {
  141. return $this->getMaxPerPage() && $this->getNbResults() > $this->getMaxPerPage();
  142. }
  143. /**
  144. * Returns the current cursor.
  145. *
  146. * @return int
  147. */
  148. public function getCursor()
  149. {
  150. return $this->cursor;
  151. }
  152. /**
  153. * Sets the current cursor.
  154. *
  155. * @param int $pos
  156. */
  157. public function setCursor($pos)
  158. {
  159. if ($pos < 1) {
  160. $this->cursor = 1;
  161. } else {
  162. if ($pos > $this->nbResults) {
  163. $this->cursor = $this->nbResults;
  164. } else {
  165. $this->cursor = $pos;
  166. }
  167. }
  168. }
  169. /**
  170. * Returns an object by cursor position.
  171. *
  172. * @param int $pos
  173. *
  174. * @return mixed
  175. */
  176. public function getObjectByCursor($pos)
  177. {
  178. $this->setCursor($pos);
  179. return $this->getCurrent();
  180. }
  181. /**
  182. * Returns the current object.
  183. *
  184. * @return mixed
  185. */
  186. public function getCurrent()
  187. {
  188. return $this->retrieveObject($this->cursor);
  189. }
  190. /**
  191. * Returns the next object.
  192. *
  193. * @return mixed|null
  194. */
  195. public function getNext()
  196. {
  197. if ($this->cursor + 1 > $this->nbResults) {
  198. return;
  199. } else {
  200. return $this->retrieveObject($this->cursor + 1);
  201. }
  202. }
  203. /**
  204. * Returns the previous object.
  205. *
  206. * @return mixed|null
  207. */
  208. public function getPrevious()
  209. {
  210. if ($this->cursor - 1 < 1) {
  211. return;
  212. } else {
  213. return $this->retrieveObject($this->cursor - 1);
  214. }
  215. }
  216. /**
  217. * Returns the first index on the current page.
  218. *
  219. * @return int
  220. */
  221. public function getFirstIndice()
  222. {
  223. if ($this->page == 0) {
  224. return 1;
  225. } else {
  226. return ($this->page - 1) * $this->maxPerPage + 1;
  227. }
  228. }
  229. /**
  230. * Returns the last index on the current page.
  231. *
  232. * @return int
  233. */
  234. public function getLastIndice()
  235. {
  236. if ($this->page == 0) {
  237. return $this->nbResults;
  238. } else {
  239. if ($this->page * $this->maxPerPage >= $this->nbResults) {
  240. return $this->nbResults;
  241. } else {
  242. return $this->page * $this->maxPerPage;
  243. }
  244. }
  245. }
  246. /**
  247. * Returns the number of results.
  248. *
  249. * @return int
  250. */
  251. public function getNbResults()
  252. {
  253. return $this->nbResults;
  254. }
  255. /**
  256. * Sets the number of results.
  257. *
  258. * @param int $nb
  259. */
  260. protected function setNbResults($nb)
  261. {
  262. $this->nbResults = $nb;
  263. }
  264. /**
  265. * Returns the first page number.
  266. *
  267. * @return int
  268. */
  269. public function getFirstPage()
  270. {
  271. return 1;
  272. }
  273. /**
  274. * Returns the last page number.
  275. *
  276. * @return int
  277. */
  278. public function getLastPage()
  279. {
  280. return $this->lastPage;
  281. }
  282. /**
  283. * Sets the last page number.
  284. *
  285. * @param int $page
  286. */
  287. protected function setLastPage($page)
  288. {
  289. $this->lastPage = $page;
  290. if ($this->getPage() > $page) {
  291. $this->setPage($page);
  292. }
  293. }
  294. /**
  295. * Returns the current page.
  296. *
  297. * @return int
  298. */
  299. public function getPage()
  300. {
  301. return $this->page;
  302. }
  303. /**
  304. * Returns the next page.
  305. *
  306. * @return int
  307. */
  308. public function getNextPage()
  309. {
  310. return min($this->getPage() + 1, $this->getLastPage());
  311. }
  312. /**
  313. * Returns the previous page.
  314. *
  315. * @return int
  316. */
  317. public function getPreviousPage()
  318. {
  319. return max($this->getPage() - 1, $this->getFirstPage());
  320. }
  321. /**
  322. * {@inheritdoc}
  323. */
  324. public function setPage($page)
  325. {
  326. $this->page = intval($page);
  327. if ($this->page <= 0) {
  328. // set first page, which depends on a maximum set
  329. $this->page = $this->getMaxPerPage() ? 1 : 0;
  330. }
  331. }
  332. /**
  333. * {@inheritdoc}
  334. */
  335. public function getMaxPerPage()
  336. {
  337. return $this->maxPerPage;
  338. }
  339. /**
  340. * {@inheritdoc}
  341. */
  342. public function setMaxPerPage($max)
  343. {
  344. if ($max > 0) {
  345. $this->maxPerPage = $max;
  346. if ($this->page == 0) {
  347. $this->page = 1;
  348. }
  349. } else {
  350. if ($max == 0) {
  351. $this->maxPerPage = 0;
  352. $this->page = 0;
  353. } else {
  354. $this->maxPerPage = 1;
  355. if ($this->page == 0) {
  356. $this->page = 1;
  357. }
  358. }
  359. }
  360. }
  361. /**
  362. * {@inheritdoc}
  363. */
  364. public function getMaxPageLinks()
  365. {
  366. return $this->maxPageLinks;
  367. }
  368. /**
  369. * {@inheritdoc}
  370. */
  371. public function setMaxPageLinks($maxPageLinks)
  372. {
  373. $this->maxPageLinks = $maxPageLinks;
  374. }
  375. /**
  376. * Returns true if on the first page.
  377. *
  378. * @return bool
  379. */
  380. public function isFirstPage()
  381. {
  382. return 1 == $this->page;
  383. }
  384. /**
  385. * Returns true if on the last page.
  386. *
  387. * @return bool
  388. */
  389. public function isLastPage()
  390. {
  391. return $this->page == $this->lastPage;
  392. }
  393. /**
  394. * Returns the current pager's parameter holder.
  395. *
  396. * @return array
  397. */
  398. public function getParameters()
  399. {
  400. return $this->parameters;
  401. }
  402. /**
  403. * Returns a parameter.
  404. *
  405. * @param string $name
  406. * @param mixed $default
  407. *
  408. * @return mixed
  409. */
  410. public function getParameter($name, $default = null)
  411. {
  412. return isset($this->parameters[$name]) ? $this->parameters[$name] : $default;
  413. }
  414. /**
  415. * Checks whether a parameter has been set.
  416. *
  417. * @param string $name
  418. *
  419. * @return bool
  420. */
  421. public function hasParameter($name)
  422. {
  423. return isset($this->parameters[$name]);
  424. }
  425. /**
  426. * Sets a parameter.
  427. *
  428. * @param string $name
  429. * @param mixed $value
  430. */
  431. public function setParameter($name, $value)
  432. {
  433. $this->parameters[$name] = $value;
  434. }
  435. /**
  436. * Returns true if the properties used for iteration have been initialized.
  437. *
  438. * @return bool
  439. */
  440. protected function isIteratorInitialized()
  441. {
  442. return null !== $this->results;
  443. }
  444. /**
  445. * Loads data into properties used for iteration.
  446. */
  447. protected function initializeIterator()
  448. {
  449. $this->results = $this->getResults();
  450. $this->resultsCounter = count($this->results);
  451. }
  452. /**
  453. * Empties properties used for iteration.
  454. */
  455. protected function resetIterator()
  456. {
  457. $this->results = null;
  458. $this->resultsCounter = 0;
  459. }
  460. /**
  461. * {@inheritdoc}
  462. */
  463. public function current()
  464. {
  465. if (!$this->isIteratorInitialized()) {
  466. $this->initializeIterator();
  467. }
  468. return current($this->results);
  469. }
  470. /**
  471. * {@inheritdoc}
  472. */
  473. public function key()
  474. {
  475. if (!$this->isIteratorInitialized()) {
  476. $this->initializeIterator();
  477. }
  478. return key($this->results);
  479. }
  480. /**
  481. * {@inheritdoc}
  482. */
  483. public function next()
  484. {
  485. if (!$this->isIteratorInitialized()) {
  486. $this->initializeIterator();
  487. }
  488. --$this->resultsCounter;
  489. return next($this->results);
  490. }
  491. /**
  492. * {@inheritdoc}
  493. */
  494. public function rewind()
  495. {
  496. if (!$this->isIteratorInitialized()) {
  497. $this->initializeIterator();
  498. }
  499. $this->resultsCounter = count($this->results);
  500. return reset($this->results);
  501. }
  502. /**
  503. * {@inheritdoc}
  504. */
  505. public function valid()
  506. {
  507. if (!$this->isIteratorInitialized()) {
  508. $this->initializeIterator();
  509. }
  510. return $this->resultsCounter > 0;
  511. }
  512. /**
  513. * {@inheritdoc}
  514. */
  515. public function count()
  516. {
  517. return $this->getNbResults();
  518. }
  519. /**
  520. * {@inheritdoc}
  521. */
  522. public function serialize()
  523. {
  524. $vars = get_object_vars($this);
  525. unset($vars['query']);
  526. return serialize($vars);
  527. }
  528. /**
  529. * {@inheritdoc}
  530. */
  531. public function unserialize($serialized)
  532. {
  533. $array = unserialize($serialized);
  534. foreach ($array as $name => $values) {
  535. $this->$name = $values;
  536. }
  537. }
  538. /**
  539. * @return array
  540. */
  541. public function getCountColumn()
  542. {
  543. return $this->countColumn;
  544. }
  545. /**
  546. * @param array $countColumn
  547. *
  548. * @return array
  549. */
  550. public function setCountColumn(array $countColumn)
  551. {
  552. return $this->countColumn = $countColumn;
  553. }
  554. /**
  555. * Retrieve the object for a certain offset.
  556. *
  557. * @param int $offset
  558. *
  559. * @return object
  560. */
  561. protected function retrieveObject($offset)
  562. {
  563. $queryForRetrieve = clone $this->getQuery();
  564. $queryForRetrieve
  565. ->setFirstResult($offset - 1)
  566. ->setMaxResults(1);
  567. $results = $queryForRetrieve->execute();
  568. return $results[0];
  569. }
  570. /**
  571. * {@inheritdoc}
  572. */
  573. public function setQuery($query)
  574. {
  575. $this->query = $query;
  576. }
  577. /**
  578. * @return ProxyQueryInterface
  579. */
  580. public function getQuery()
  581. {
  582. return $this->query;
  583. }
  584. }