1 2/** 3 * This file is part of the Phalcon Framework. 4 * 5 * (c) Phalcon Team <team@phalcon.io> 6 * 7 * For the full copyright and license information, please view the LICENSE.txt 8 * file that was distributed with this source code. 9 */ 10 11namespace Phalcon\Paginator\Adapter; 12 13use Phalcon\Helper\Arr; 14use Phalcon\Mvc\ModelInterface; 15use Phalcon\Mvc\Model\ResultsetInterface; 16use Phalcon\Paginator\Exception; 17use Phalcon\Paginator\RepositoryInterface; 18 19/** 20 * Phalcon\Paginator\Adapter\Model 21 * 22 * This adapter allows to paginate data using a Phalcon\Mvc\Model resultset as a 23 * base. 24 * 25 * ```php 26 * use Phalcon\Paginator\Adapter\Model; 27 * 28 * $paginator = new Model( 29 * [ 30 * "model" => Robots::class, 31 * "limit" => 25, 32 * "page" => $currentPage, 33 * ] 34 * ); 35 * 36 * 37 * $paginator = new Model( 38 * [ 39 * "model" => Robots::class, 40 * "parameters" => [ 41 * "columns" => "id, name" 42 * ], 43 * "limit" => 12, 44 * "page" => $currentPage, 45 * ] 46 * ); 47 * 48 * 49 * $paginator = new Model( 50 * [ 51 * "model" => Robots::class, 52 * "parameters" => [ 53 * "type = :type:", 54 * "bind" => [ 55 * "type" => "mechanical" 56 * ], 57 * "order" => "name" 58 * ], 59 * "limit" => 16, 60 * "page" => $currentPage, 61 * ] 62 * ); 63 * 64 * $paginator = new Model( 65 * [ 66 * "model" => Robots::class, 67 * "parameters" => "(id % 2) = 0", 68 * "limit" => 8, 69 * "page" => $currentPage, 70 * ] 71 * ); 72 * 73 * 74 * $paginator = new Model( 75 * [ 76 * "model" => Robots::class, 77 * "parameters" => [ "(id % 2) = 0" ], 78 * "limit" => 8, 79 * "page" => $currentPage, 80 * ] 81 * ); 82 * 83 * $paginate = $paginator->paginate(); 84 *``` 85 */ 86class Model extends AbstractAdapter 87{ 88 /** 89 * Returns a slice of the resultset to show in the pagination 90 */ 91 public function paginate() -> <RepositoryInterface> 92 { 93 var config, items, pageItems, modelClass, parameters; 94 int pageNumber, limit, rowcount, next, totalPages, 95 previous; 96 97 let limit = (int) this->limitRows, 98 config = this->config, 99 pageNumber = (int) this->page, 100 modelClass = <ModelInterface> config["model"], 101 parameters = Arr::get(config, "parameters", [], "array"); 102 103 //Prevents 0 or negative page numbers 104 if pageNumber <= 0 { 105 let pageNumber = 1; 106 } 107 108 let rowcount = (int) call_user_func([modelClass, "count"], parameters), 109 pageItems = []; 110 111 if rowcount % limit != 0 { 112 let totalPages = (int) (rowcount / limit + 1); 113 } else { 114 let totalPages = (int) (rowcount / limit); 115 } 116 117 if rowcount > 0 { 118 let parameters["limit"] = limit, 119 parameters["offset"] = limit * (pageNumber - 1); 120 121 let items = <ResultsetInterface> call_user_func( 122 [modelClass, "find"], 123 parameters 124 ); 125 let pageItems = items->toArray(); 126 } 127 128 //Fix next 129 let next = pageNumber + 1; 130 131 if next > totalPages { 132 let next = totalPages; 133 } 134 135 if pageNumber > 1 { 136 let previous = pageNumber - 1; 137 } else { 138 let previous = 1; 139 } 140 141 return this->getRepository( 142 [ 143 RepositoryInterface::PROPERTY_ITEMS : pageItems, 144 RepositoryInterface::PROPERTY_TOTAL_ITEMS : rowcount, 145 RepositoryInterface::PROPERTY_LIMIT : this->limitRows, 146 RepositoryInterface::PROPERTY_FIRST_PAGE : 1, 147 RepositoryInterface::PROPERTY_PREVIOUS_PAGE : previous, 148 RepositoryInterface::PROPERTY_CURRENT_PAGE : pageNumber, 149 RepositoryInterface::PROPERTY_NEXT_PAGE : next, 150 RepositoryInterface::PROPERTY_LAST_PAGE : totalPages 151 ] 152 ); 153 } 154} 155