├── src ├── .gitkeep ├── ModelClassRequiredException.php └── LoadMorePagination.php ├── tests ├── .gitkeep ├── TestCase.php └── LoadMorePaginationTest.php ├── .gitignore ├── phpunit.xml ├── .travis.yml ├── composer.json ├── LICENSE └── README.md /src/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /vendor 2 | composer.phar 3 | composer.lock 4 | .DS_Store -------------------------------------------------------------------------------- /phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 13 | 14 | 15 | ./tests/ 16 | 17 | 18 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # see http://about.travis-ci.org/docs/user/languages/php/ for more hints 2 | language: php 3 | 4 | # list any PHP version you want to test against 5 | php: 6 | - 5.6 7 | - 7.0 8 | - 7.1 9 | - hhvm 10 | 11 | # optionally set up exclutions and allowed failures in the matrix 12 | matrix: 13 | allow_failures: 14 | - php: 5.6 15 | - php: hhvm 16 | fast_finish: true 17 | 18 | # execute any number of scripts before the test run, custom env's are available as variables 19 | before_script: 20 | - composer self-update 21 | - composer install --prefer-source --no-interaction --dev 22 | 23 | # Run phpunit tests 24 | script: phpunit --coverage-text 25 | 26 | # configure notifications (email, IRC, campfire etc) 27 | notifications: 28 | on_success: never 29 | on_failure: always -------------------------------------------------------------------------------- /src/ModelClassRequiredException.php: -------------------------------------------------------------------------------- 1 | code}]: {$this->message}\n"; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vitorf7/lv-loadmorepagination", 3 | "description": "Load More Pagination for Laravel. Allows to load an initial number of items and subsequent pages can load a different number of items", 4 | "version": "0.1.0", 5 | "keywords": ["laravel", "pagination", "custom", "load more"], 6 | "license": "MIT", 7 | "authors": [ 8 | { 9 | "name": "Vitor Faiante", 10 | "email": "vf7development@gmail.com" 11 | } 12 | ], 13 | "require": { 14 | "php": ">=5.4.0", 15 | "illuminate/support": "~5.0", 16 | "illuminate/pagination": "~5.0", 17 | "illuminate/database": "~5.0" 18 | }, 19 | "require-dev": { 20 | "phpunit/phpunit": "^5.3" 21 | }, 22 | "autoload": { 23 | "psr-4": { 24 | "VitorF7\\LoadMorePagination\\": "src/" 25 | } 26 | }, 27 | "autoload-dev": { 28 | "classmap": ["tests/TestCase.php"] 29 | }, 30 | "minimum-stability": "stable" 31 | } 32 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Colin Viebrock 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /tests/TestCase.php: -------------------------------------------------------------------------------- 1 | setUpDatabase(); 10 | $this->migrateTables(); 11 | } 12 | 13 | protected function setUpDatabase() 14 | { 15 | $database = new DB; 16 | $database->addConnection(['driver' => 'sqlite', 'database' => ':memory:']); 17 | $database->bootEloquent(); 18 | $database->setAsGlobal(); 19 | } 20 | 21 | protected function migrateTables() 22 | { 23 | DB::schema()->create('posts', function ($table) { 24 | $table->increments('id'); 25 | $table->string('title'); 26 | $table->string('slug'); 27 | $table->timestamps(); 28 | }); 29 | } 30 | 31 | protected function makePost() 32 | { 33 | $post = new Post; 34 | 35 | $post->title = 'Hello World'; 36 | $post->slug = 'hello-world'; 37 | $post->save(); 38 | 39 | return $post; 40 | } 41 | } 42 | 43 | class Post extends Illuminate\Database\Eloquent\Model 44 | { 45 | use VitorF7\LoadMorePagination\LoadMorePagination; 46 | } 47 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Laravel Load More Pagination 2 | 3 | [![Build Status](https://travis-ci.org/vitorf7/lv-loadmorepagination.svg?branch=master)](https://travis-ci.org/vitorf7/lv-loadmorepagination) 4 | 5 | A package that will give you access to a LoadMorePagination trait where you can paginate your model's results with an initial number of items and then a different number of items on subsequent pages. 6 | 7 | This package does not implement any paginator interfaces or anything like that it simply returns a similar array to a paginator with the usual information such as last_page, current_page, data, etc. 8 | 9 | ## Usage 10 | 11 | To install this package do the following: 12 | 13 | ``` 14 | composer require vitorf7/lv-loadmorepagination 15 | ``` 16 | 17 | Once installed you can use this in two ways. Either by imporating this into your Eloquent Model or using it in your Controller or Repository, etc. 18 | 19 | This package has an initial load of 9 items and subsequent load of 3. 20 | 21 | In a Model: 22 | ```php 23 | paginateLoadMore(); 41 | ``` 42 | 43 | If you want to use it in a Controller, Repository, etc you need to pass 3 arguments. 44 | - 1st Argument is the inital load of items 45 | - 2nd Argument is the load of subsequent items 46 | - 3rd Argument is the Model you are trying to paginate 47 | 48 | Like so: 49 | ```php 50 | paginatedLoadMore(9, 3, new Post); 64 | 65 | return view('posts.index', compact('posts')); 66 | } 67 | } 68 | ``` 69 | 70 | If you do not pass a model you will get a ``` VitorF7\LoadMorePagination\ModelClassRequiredException``` -------------------------------------------------------------------------------- /src/LoadMorePagination.php: -------------------------------------------------------------------------------- 1 | count(); 49 | // Get the correct results 50 | $modelResults = $model->skip($skip)->take($perPage)->get(); 51 | 52 | $lastPage = ($total > $initialQuantity) ? (int) ceil((($total - $initialQuantity) / $loadMore) + 1) : 1; 53 | $from = $skip + 1; 54 | $to = ($total > $initialQuantity) ? $skip + $perPage : $total; 55 | $nextPageUrl = ($page !== $lastPage) ? (string) Paginator::resolveCurrentPath() . '?page=' . ($page + 1) : null; 56 | $previousPageUrl = ($page !== 1) ? (string) Paginator::resolveCurrentPath() . '?page=' . ($page - 1) : null; 57 | 58 | return [ 59 | 'current_page' => $page, 60 | 'per_page' => $perPage, 61 | 'total' => $total, 62 | 'last_page' => $lastPage, 63 | 'from' => $from, 64 | 'to' => $to, 65 | 'previous_page_url' => $previousPageUrl, 66 | 'next_page_url' => $nextPageUrl, 67 | 'data' => $modelResults->toArray() 68 | ]; 69 | } 70 | 71 | /** 72 | * Query Scope paginateLoadMore 73 | * 74 | * This method is will be used when chaining a model with other methods 75 | * such as with() relationship methods 76 | * 77 | * @param Illuminate\Database\Query\Builder $query [An Eloquent Query Builder] 78 | * @param integer $initialQuantity [Quantity of items on the first page] 79 | * @param integer $loadMore [Quantity of items on subsequent pages] 80 | * @param Illuminate\Database\Eloquent\Model $model [An Eloquent Model] 81 | * 82 | * @return paginateLoadMore 83 | */ 84 | public function scopePaginateLoadMore($query, $initialQuantity = 9, $loadMore = 3, $model = null) 85 | { 86 | return $this->paginatedLoadMore($initialQuantity, $loadMore, $query); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /tests/LoadMorePaginationTest.php: -------------------------------------------------------------------------------- 1 | paginatedLoadMore(); 13 | } 14 | 15 | /** @test */ 16 | public function it_should_return_an_array_for_the_results() 17 | { 18 | $post = $this->makePost(); 19 | 20 | $results = $post->paginateLoadMore(); 21 | 22 | $this->assertTrue(is_array($results)); 23 | } 24 | 25 | /** @test */ 26 | public function it_allows_other_classes_to_call_method_to_get_paginated_load_more() 27 | { 28 | $testClass = new TestClass; 29 | 30 | $results = $testClass->paginatedLoadMore(9, 3, new Post); 31 | 32 | $this->assertTrue(is_array($results)); 33 | } 34 | 35 | /** @test */ 36 | public function it_allows_a_model_to_call_the_paginate_load_more_statically_and_return_the_full_results() 37 | { 38 | $this->makePost(); 39 | 40 | $results = Post::paginateLoadMore(); 41 | 42 | $this->assertEquals(1, $results['total']); 43 | } 44 | 45 | /** @test */ 46 | public function it_should_have_current_page_array_key() 47 | { 48 | $post = $this->makePost(); 49 | 50 | $results = $post->paginateLoadMore(); 51 | 52 | $this->assertArrayHasKey('current_page', $results); 53 | } 54 | 55 | /** @test */ 56 | public function it_should_have_per_page_array_key() 57 | { 58 | $post = $this->makePost(); 59 | 60 | $results = $post->paginateLoadMore(); 61 | 62 | $this->assertArrayHasKey('per_page', $results); 63 | } 64 | 65 | /** @test */ 66 | public function it_should_have_total_array_key() 67 | { 68 | $post = $this->makePost(); 69 | 70 | $results = $post->paginateLoadMore(); 71 | 72 | $this->assertArrayHasKey('total', $results); 73 | } 74 | 75 | /** @test */ 76 | public function it_should_have_last_page_array_key() 77 | { 78 | $post = $this->makePost(); 79 | 80 | $results = $post->paginateLoadMore(); 81 | 82 | $this->assertArrayHasKey('last_page', $results); 83 | } 84 | 85 | /** @test */ 86 | public function it_should_have_from_array_key() 87 | { 88 | $post = $this->makePost(); 89 | 90 | $results = $post->paginateLoadMore(); 91 | 92 | $this->assertArrayHasKey('from', $results); 93 | } 94 | 95 | /** @test */ 96 | public function it_should_have_to_array_key() 97 | { 98 | $post = $this->makePost(); 99 | 100 | $results = $post->paginateLoadMore(); 101 | 102 | $this->assertArrayHasKey('to', $results); 103 | } 104 | 105 | /** @test */ 106 | public function it_should_have_previous_page_url_array_key() 107 | { 108 | $post = $this->makePost(); 109 | 110 | $results = $post->paginateLoadMore(); 111 | 112 | $this->assertArrayHasKey('previous_page_url', $results); 113 | } 114 | 115 | /** @test */ 116 | public function it_should_have_next_page_url_array_key() 117 | { 118 | $post = $this->makePost(); 119 | 120 | $results = $post->paginateLoadMore(); 121 | 122 | $this->assertArrayHasKey('next_page_url', $results); 123 | } 124 | 125 | /** @test */ 126 | public function it_should_have_data_array_key() 127 | { 128 | $post = $this->makePost(); 129 | 130 | $results = $post->paginateLoadMore(); 131 | 132 | $this->assertArrayHasKey('data', $results); 133 | } 134 | 135 | /** @test */ 136 | public function it_should_have_an_initial_per_page_of_9() 137 | { 138 | $post = $this->makePost(); 139 | 140 | $results = $post->paginateLoadMore(); 141 | 142 | $this->assertEquals(9, $results['per_page']); 143 | } 144 | 145 | /** @test */ 146 | public function it_should_start_on_page_1() 147 | { 148 | $post = $this->makePost(); 149 | 150 | $results = $post->paginateLoadMore(); 151 | 152 | $this->assertEquals(1, $results['current_page']); 153 | } 154 | 155 | /** @test */ 156 | public function it_should_have_a_have_a_last_page_of_1_when_it_does_not_have_enough_for_more_than_one_page() 157 | { 158 | $post = $this->makePost(); 159 | 160 | $results = $post->paginateLoadMore(); 161 | 162 | $this->assertEquals(1, $results['last_page']); 163 | } 164 | 165 | /** @test */ 166 | public function it_should_not_have_to_key_with_more_than_the_total_number_of_items() 167 | { 168 | $post = $this->makePost(); 169 | 170 | $results = $post->paginateLoadMore(); 171 | 172 | $this->assertEquals(1, $results['to']); 173 | } 174 | 175 | /** @test */ 176 | public function it_should_have_2_pages_if_it_has_10_items_and_uses_default_options() 177 | { 178 | foreach (range(1, 10) as $number) { 179 | $this->makePost(); 180 | } 181 | 182 | $results = Post::paginateLoadMore(); 183 | 184 | $this->assertEquals(10, $results['total']); 185 | $this->assertEquals(2, $results['last_page']); 186 | } 187 | 188 | /** @test */ 189 | public function it_should_have_3_pages_if_it_has_15_items_and_uses_default_options() 190 | { 191 | foreach (range(1, 15) as $number) { 192 | $this->makePost(); 193 | } 194 | 195 | $results = Post::paginateLoadMore(); 196 | 197 | $this->assertEquals(15, $results['total']); 198 | $this->assertEquals(3, $results['last_page']); 199 | } 200 | 201 | /** @test */ 202 | public function it_should_have_3_pages_if_given_initial_value_3_and_load_more_3_in_a_result_set_of_9() 203 | { 204 | foreach (range(1, 9) as $number) { 205 | $this->makePost(); 206 | } 207 | 208 | $results = Post::paginateLoadMore(3, 3); 209 | 210 | $this->assertEquals(9, $results['total']); 211 | $this->assertEquals(3, $results['last_page']); 212 | } 213 | } 214 | 215 | class TestClass 216 | { 217 | use \VitorF7\LoadMorePagination\LoadMorePagination; 218 | } 219 | --------------------------------------------------------------------------------