├── .github ├── FUNDING.yml └── workflows │ └── laravel.yml ├── .gitignore ├── LICENSE.md ├── README.md ├── composer.json ├── composer.lock ├── config └── laravel-vue-datatables.php ├── phpunit.xml ├── src ├── Classes │ ├── Factories │ │ └── RelationshipModelFactory.php │ ├── Filters │ │ ├── FilterBelongsToManyRelationships.php │ │ ├── FilterBelongsToRelationships.php │ │ ├── FilterHasManyRelationships.php │ │ ├── FilterHasOneRelationships.php │ │ └── FilterLocalData.php │ ├── Joins │ │ ├── JoinBelongsToManyRelationships.php │ │ ├── JoinBelongsToRelationships.php │ │ ├── JoinHasManyRelationships.php │ │ └── JoinHasOneRelationships.php │ ├── QueryBuilder.php │ └── Relationships │ │ ├── GetBelongsToManyRelationships.php │ │ ├── GetBelongsToRelationships.php │ │ ├── GetHasManyRelationships.php │ │ └── GetHasOneRelationships.php ├── Contracts │ ├── ExceptionHandlerContract.php │ └── QueryBuilderContract.php ├── Exceptions │ ├── ColumnNotFoundException.php │ ├── ColumnNotOrderableException.php │ ├── Exception.php │ ├── ExceptionHandler.php │ ├── RelationshipColumnsNotFoundException.php │ ├── RelationshipForeignKeyNotSetException.php │ ├── RelationshipModelNotInstantiatableException.php │ ├── RelationshipModelNotSetException.php │ └── RelationshipPivotDataNotFoundException.php ├── Http │ └── Resources │ │ └── DataTableCollectionResource.php ├── Providers │ └── LaravelVueDatatableServiceProvider.php └── Traits │ └── LaravelVueDatatableTrait.php └── tests ├── Factories └── RelationshipFactoryTest.php └── TestCase.php /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: [jamesdordoy] -------------------------------------------------------------------------------- /.github/workflows/laravel.yml: -------------------------------------------------------------------------------- 1 | name: Laravel 2 | 3 | on: [push] 4 | 5 | jobs: 6 | laravel-tests: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - uses: actions/checkout@v1 10 | - name: Copy .env 11 | run: php -r "file_exists('.env') || copy('.env.example', '.env');" 12 | - name: Install Dependencies 13 | run: composer install -q --no-ansi --no-interaction --no-scripts --no-suggest --no-progress --prefer-dist 14 | - name: Create Database 15 | run: | 16 | mkdir -p database 17 | touch database/database.sqlite 18 | - name: Execute tests (Unit and Feature tests) via PHPUnit 19 | env: 20 | DB_CONNECTION: sqlite 21 | DB_DATABASE: database/database.sqlite 22 | run: vendor/bin/phpunit 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /vendor -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 James Dordoy 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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # Laravel Vue Datatable 3 | A Vue.js Datatable Component for Laravel that works with Bootstrap. 4 | 5 | ## Requirements 6 | 7 | * [Vue.js](https://vuejs.org/) 2.x 8 | * [Laravel](http://laravel.com/docs/) 5.x 9 | * [Bootstrap](http://getbootstrap.com/) 4 (Optional) 10 | 11 | This package makes use of an optional default component, the [Laravel Vue Pagination](https://github.com/gilbitron/laravel-vue-pagination) component created by [gilbitron](https://github.com/gilbitron). If you need a pagination component for other areas of your website and you are using a Laravel API & Bootstrap, i highly suggest using this flexible component. 12 | 13 | ## Demo 14 | 15 | See [https://jamesdordoy.github.io/laravel-vue-datatable/](https://jamesdordoy.github.io/laravel-vue-datatable/) 16 | 17 | ## Table of Contents 18 | - [Example](#example) 19 | - [Package Installation](#package-installation) 20 | - [Add Service Provider](#add-service-provider) 21 | - [Publish the Config](#publish-the-config) 22 | - [Package Options](#package-options) 23 | - [Use the Trait](#use-the-trait) 24 | - [Use the Controller Resource](#use-the-controller-resource) 25 | - [Component Installation](#component-installation) 26 | 27 | ## Example 28 | ![Image description](https://www.jamesdordoy.co.uk/images/projects/bootstrap-datatable.png?a=a) 29 | 30 | ## Package Installation 31 | ``` 32 | $ composer require jamesdordoy/laravelvuedatatable 33 | ``` 34 | 35 | ### Add Service Provider 36 | ``` 37 | JamesDordoy\LaravelVueDatatable\Providers\LaravelVueDatatableServiceProvider::class, 38 | ``` 39 | 40 | ### Publish the Config 41 | ``` 42 | $ php artisan vendor:publish --provider="JamesDordoy\LaravelVueDatatable\Providers\LaravelVueDatatableServiceProvider" 43 | ``` 44 | 45 | #### Package Options 46 | 47 | ```php 48 | [ 49 | 'models' => [ 50 | "alias" => "as", 51 | "search_term" => "searchable", 52 | "order_term" => "orderable", 53 | ], 54 | "default_order_by" => "id" 55 | ] 56 | ``` 57 | 58 | 59 | ### Use the Trait 60 | This trait is optional and simply provides a basic method for filtering your data based on the $dataTableColumns attribute set in the model. If you would like more control on how the data is filtered, feel free to omit this trait use your own filtering methods. Just remember to paginate the results! 61 | 62 | ```php 63 | [ 78 | 'searchable' => false, 79 | ], 80 | 'name' => [ 81 | 'searchable' => true, 82 | ], 83 | 'email' => [ 84 | 'searchable' => true, 85 | ] 86 | ]; 87 | } 88 | ``` 89 | 90 | ## Use the Controller Resource 91 | 92 | The Collection Resource is expecting a paginated collection, so feel free to use your own queries and omit the provided query if your require more complex filtering. 93 | 94 | ```php 95 | input('length'); 108 | $orderBy = $request->input('column'); //Index 109 | $orderByDir = $request->input('dir', 'asc'); 110 | $searchValue = $request->input('search'); 111 | 112 | $query = User::eloquentQuery($orderBy, $orderByDir, $searchValue); 113 | $data = $query->paginate($length); 114 | 115 | return new DataTableCollectionResource($data); 116 | } 117 | } 118 | ``` 119 | 120 | ## Component Installation 121 | 122 | See [https://github.com/jamesdordoy/vue-datatable](https://github.com/jamesdordoy/vue-datatable) 123 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jamesdordoy/laravelvuedatatable", 3 | "authors": [ 4 | { 5 | "name": "James Dordoy", 6 | "email": "jamesdordoy@gmail.com" 7 | } 8 | ], 9 | "require": {}, 10 | "require-dev": { 11 | "phpunit/phpunit": "^7.5" 12 | }, 13 | "autoload": { 14 | "psr-4": { 15 | "JamesDordoy\\LaravelVueDatatable\\": "src/" 16 | }, 17 | "classmap": [ 18 | "src/" 19 | ] 20 | }, 21 | "extra": { 22 | "laravel": { 23 | "providers": [ 24 | "JamesDordoy\\LaravelVueDatatable\\Providers\\LaravelVueDatatableServiceProvider" 25 | ] 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /composer.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_readme": [ 3 | "This file locks the dependencies of your project to a known state", 4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", 5 | "This file is @generated automatically" 6 | ], 7 | "content-hash": "2b10c165b8a357fd42d66c1f63d62d36", 8 | "packages": [], 9 | "packages-dev": [ 10 | { 11 | "name": "doctrine/instantiator", 12 | "version": "1.4.0", 13 | "source": { 14 | "type": "git", 15 | "url": "https://github.com/doctrine/instantiator.git", 16 | "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b" 17 | }, 18 | "dist": { 19 | "type": "zip", 20 | "url": "https://api.github.com/repos/doctrine/instantiator/zipball/d56bf6102915de5702778fe20f2de3b2fe570b5b", 21 | "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b", 22 | "shasum": "" 23 | }, 24 | "require": { 25 | "php": "^7.1 || ^8.0" 26 | }, 27 | "require-dev": { 28 | "doctrine/coding-standard": "^8.0", 29 | "ext-pdo": "*", 30 | "ext-phar": "*", 31 | "phpbench/phpbench": "^0.13 || 1.0.0-alpha2", 32 | "phpstan/phpstan": "^0.12", 33 | "phpstan/phpstan-phpunit": "^0.12", 34 | "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0" 35 | }, 36 | "type": "library", 37 | "autoload": { 38 | "psr-4": { 39 | "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" 40 | } 41 | }, 42 | "notification-url": "https://packagist.org/downloads/", 43 | "license": [ 44 | "MIT" 45 | ], 46 | "authors": [ 47 | { 48 | "name": "Marco Pivetta", 49 | "email": "ocramius@gmail.com", 50 | "homepage": "https://ocramius.github.io/" 51 | } 52 | ], 53 | "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", 54 | "homepage": "https://www.doctrine-project.org/projects/instantiator.html", 55 | "keywords": [ 56 | "constructor", 57 | "instantiate" 58 | ], 59 | "support": { 60 | "issues": "https://github.com/doctrine/instantiator/issues", 61 | "source": "https://github.com/doctrine/instantiator/tree/1.4.0" 62 | }, 63 | "funding": [ 64 | { 65 | "url": "https://www.doctrine-project.org/sponsorship.html", 66 | "type": "custom" 67 | }, 68 | { 69 | "url": "https://www.patreon.com/phpdoctrine", 70 | "type": "patreon" 71 | }, 72 | { 73 | "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator", 74 | "type": "tidelift" 75 | } 76 | ], 77 | "time": "2020-11-10T18:47:58+00:00" 78 | }, 79 | { 80 | "name": "myclabs/deep-copy", 81 | "version": "1.10.2", 82 | "source": { 83 | "type": "git", 84 | "url": "https://github.com/myclabs/DeepCopy.git", 85 | "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220" 86 | }, 87 | "dist": { 88 | "type": "zip", 89 | "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/776f831124e9c62e1a2c601ecc52e776d8bb7220", 90 | "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220", 91 | "shasum": "" 92 | }, 93 | "require": { 94 | "php": "^7.1 || ^8.0" 95 | }, 96 | "replace": { 97 | "myclabs/deep-copy": "self.version" 98 | }, 99 | "require-dev": { 100 | "doctrine/collections": "^1.0", 101 | "doctrine/common": "^2.6", 102 | "phpunit/phpunit": "^7.1" 103 | }, 104 | "type": "library", 105 | "autoload": { 106 | "psr-4": { 107 | "DeepCopy\\": "src/DeepCopy/" 108 | }, 109 | "files": [ 110 | "src/DeepCopy/deep_copy.php" 111 | ] 112 | }, 113 | "notification-url": "https://packagist.org/downloads/", 114 | "license": [ 115 | "MIT" 116 | ], 117 | "description": "Create deep copies (clones) of your objects", 118 | "keywords": [ 119 | "clone", 120 | "copy", 121 | "duplicate", 122 | "object", 123 | "object graph" 124 | ], 125 | "support": { 126 | "issues": "https://github.com/myclabs/DeepCopy/issues", 127 | "source": "https://github.com/myclabs/DeepCopy/tree/1.10.2" 128 | }, 129 | "funding": [ 130 | { 131 | "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", 132 | "type": "tidelift" 133 | } 134 | ], 135 | "time": "2020-11-13T09:40:50+00:00" 136 | }, 137 | { 138 | "name": "phar-io/manifest", 139 | "version": "1.0.3", 140 | "source": { 141 | "type": "git", 142 | "url": "https://github.com/phar-io/manifest.git", 143 | "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4" 144 | }, 145 | "dist": { 146 | "type": "zip", 147 | "url": "https://api.github.com/repos/phar-io/manifest/zipball/7761fcacf03b4d4f16e7ccb606d4879ca431fcf4", 148 | "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4", 149 | "shasum": "" 150 | }, 151 | "require": { 152 | "ext-dom": "*", 153 | "ext-phar": "*", 154 | "phar-io/version": "^2.0", 155 | "php": "^5.6 || ^7.0" 156 | }, 157 | "type": "library", 158 | "extra": { 159 | "branch-alias": { 160 | "dev-master": "1.0.x-dev" 161 | } 162 | }, 163 | "autoload": { 164 | "classmap": [ 165 | "src/" 166 | ] 167 | }, 168 | "notification-url": "https://packagist.org/downloads/", 169 | "license": [ 170 | "BSD-3-Clause" 171 | ], 172 | "authors": [ 173 | { 174 | "name": "Arne Blankerts", 175 | "email": "arne@blankerts.de", 176 | "role": "Developer" 177 | }, 178 | { 179 | "name": "Sebastian Heuer", 180 | "email": "sebastian@phpeople.de", 181 | "role": "Developer" 182 | }, 183 | { 184 | "name": "Sebastian Bergmann", 185 | "email": "sebastian@phpunit.de", 186 | "role": "Developer" 187 | } 188 | ], 189 | "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", 190 | "support": { 191 | "issues": "https://github.com/phar-io/manifest/issues", 192 | "source": "https://github.com/phar-io/manifest/tree/master" 193 | }, 194 | "time": "2018-07-08T19:23:20+00:00" 195 | }, 196 | { 197 | "name": "phar-io/version", 198 | "version": "2.0.1", 199 | "source": { 200 | "type": "git", 201 | "url": "https://github.com/phar-io/version.git", 202 | "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6" 203 | }, 204 | "dist": { 205 | "type": "zip", 206 | "url": "https://api.github.com/repos/phar-io/version/zipball/45a2ec53a73c70ce41d55cedef9063630abaf1b6", 207 | "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6", 208 | "shasum": "" 209 | }, 210 | "require": { 211 | "php": "^5.6 || ^7.0" 212 | }, 213 | "type": "library", 214 | "autoload": { 215 | "classmap": [ 216 | "src/" 217 | ] 218 | }, 219 | "notification-url": "https://packagist.org/downloads/", 220 | "license": [ 221 | "BSD-3-Clause" 222 | ], 223 | "authors": [ 224 | { 225 | "name": "Arne Blankerts", 226 | "email": "arne@blankerts.de", 227 | "role": "Developer" 228 | }, 229 | { 230 | "name": "Sebastian Heuer", 231 | "email": "sebastian@phpeople.de", 232 | "role": "Developer" 233 | }, 234 | { 235 | "name": "Sebastian Bergmann", 236 | "email": "sebastian@phpunit.de", 237 | "role": "Developer" 238 | } 239 | ], 240 | "description": "Library for handling version information and constraints", 241 | "support": { 242 | "issues": "https://github.com/phar-io/version/issues", 243 | "source": "https://github.com/phar-io/version/tree/master" 244 | }, 245 | "time": "2018-07-08T19:19:57+00:00" 246 | }, 247 | { 248 | "name": "phpdocumentor/reflection-common", 249 | "version": "2.2.0", 250 | "source": { 251 | "type": "git", 252 | "url": "https://github.com/phpDocumentor/ReflectionCommon.git", 253 | "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b" 254 | }, 255 | "dist": { 256 | "type": "zip", 257 | "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b", 258 | "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b", 259 | "shasum": "" 260 | }, 261 | "require": { 262 | "php": "^7.2 || ^8.0" 263 | }, 264 | "type": "library", 265 | "extra": { 266 | "branch-alias": { 267 | "dev-2.x": "2.x-dev" 268 | } 269 | }, 270 | "autoload": { 271 | "psr-4": { 272 | "phpDocumentor\\Reflection\\": "src/" 273 | } 274 | }, 275 | "notification-url": "https://packagist.org/downloads/", 276 | "license": [ 277 | "MIT" 278 | ], 279 | "authors": [ 280 | { 281 | "name": "Jaap van Otterdijk", 282 | "email": "opensource@ijaap.nl" 283 | } 284 | ], 285 | "description": "Common reflection classes used by phpdocumentor to reflect the code structure", 286 | "homepage": "http://www.phpdoc.org", 287 | "keywords": [ 288 | "FQSEN", 289 | "phpDocumentor", 290 | "phpdoc", 291 | "reflection", 292 | "static analysis" 293 | ], 294 | "support": { 295 | "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues", 296 | "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x" 297 | }, 298 | "time": "2020-06-27T09:03:43+00:00" 299 | }, 300 | { 301 | "name": "phpdocumentor/reflection-docblock", 302 | "version": "5.2.2", 303 | "source": { 304 | "type": "git", 305 | "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", 306 | "reference": "069a785b2141f5bcf49f3e353548dc1cce6df556" 307 | }, 308 | "dist": { 309 | "type": "zip", 310 | "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/069a785b2141f5bcf49f3e353548dc1cce6df556", 311 | "reference": "069a785b2141f5bcf49f3e353548dc1cce6df556", 312 | "shasum": "" 313 | }, 314 | "require": { 315 | "ext-filter": "*", 316 | "php": "^7.2 || ^8.0", 317 | "phpdocumentor/reflection-common": "^2.2", 318 | "phpdocumentor/type-resolver": "^1.3", 319 | "webmozart/assert": "^1.9.1" 320 | }, 321 | "require-dev": { 322 | "mockery/mockery": "~1.3.2" 323 | }, 324 | "type": "library", 325 | "extra": { 326 | "branch-alias": { 327 | "dev-master": "5.x-dev" 328 | } 329 | }, 330 | "autoload": { 331 | "psr-4": { 332 | "phpDocumentor\\Reflection\\": "src" 333 | } 334 | }, 335 | "notification-url": "https://packagist.org/downloads/", 336 | "license": [ 337 | "MIT" 338 | ], 339 | "authors": [ 340 | { 341 | "name": "Mike van Riel", 342 | "email": "me@mikevanriel.com" 343 | }, 344 | { 345 | "name": "Jaap van Otterdijk", 346 | "email": "account@ijaap.nl" 347 | } 348 | ], 349 | "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", 350 | "support": { 351 | "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", 352 | "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/master" 353 | }, 354 | "time": "2020-09-03T19:13:55+00:00" 355 | }, 356 | { 357 | "name": "phpdocumentor/type-resolver", 358 | "version": "1.4.0", 359 | "source": { 360 | "type": "git", 361 | "url": "https://github.com/phpDocumentor/TypeResolver.git", 362 | "reference": "6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0" 363 | }, 364 | "dist": { 365 | "type": "zip", 366 | "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0", 367 | "reference": "6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0", 368 | "shasum": "" 369 | }, 370 | "require": { 371 | "php": "^7.2 || ^8.0", 372 | "phpdocumentor/reflection-common": "^2.0" 373 | }, 374 | "require-dev": { 375 | "ext-tokenizer": "*" 376 | }, 377 | "type": "library", 378 | "extra": { 379 | "branch-alias": { 380 | "dev-1.x": "1.x-dev" 381 | } 382 | }, 383 | "autoload": { 384 | "psr-4": { 385 | "phpDocumentor\\Reflection\\": "src" 386 | } 387 | }, 388 | "notification-url": "https://packagist.org/downloads/", 389 | "license": [ 390 | "MIT" 391 | ], 392 | "authors": [ 393 | { 394 | "name": "Mike van Riel", 395 | "email": "me@mikevanriel.com" 396 | } 397 | ], 398 | "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", 399 | "support": { 400 | "issues": "https://github.com/phpDocumentor/TypeResolver/issues", 401 | "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.4.0" 402 | }, 403 | "time": "2020-09-17T18:55:26+00:00" 404 | }, 405 | { 406 | "name": "phpspec/prophecy", 407 | "version": "1.13.0", 408 | "source": { 409 | "type": "git", 410 | "url": "https://github.com/phpspec/prophecy.git", 411 | "reference": "be1996ed8adc35c3fd795488a653f4b518be70ea" 412 | }, 413 | "dist": { 414 | "type": "zip", 415 | "url": "https://api.github.com/repos/phpspec/prophecy/zipball/be1996ed8adc35c3fd795488a653f4b518be70ea", 416 | "reference": "be1996ed8adc35c3fd795488a653f4b518be70ea", 417 | "shasum": "" 418 | }, 419 | "require": { 420 | "doctrine/instantiator": "^1.2", 421 | "php": "^7.2 || ~8.0, <8.1", 422 | "phpdocumentor/reflection-docblock": "^5.2", 423 | "sebastian/comparator": "^3.0 || ^4.0", 424 | "sebastian/recursion-context": "^3.0 || ^4.0" 425 | }, 426 | "require-dev": { 427 | "phpspec/phpspec": "^6.0", 428 | "phpunit/phpunit": "^8.0 || ^9.0" 429 | }, 430 | "type": "library", 431 | "extra": { 432 | "branch-alias": { 433 | "dev-master": "1.11.x-dev" 434 | } 435 | }, 436 | "autoload": { 437 | "psr-4": { 438 | "Prophecy\\": "src/Prophecy" 439 | } 440 | }, 441 | "notification-url": "https://packagist.org/downloads/", 442 | "license": [ 443 | "MIT" 444 | ], 445 | "authors": [ 446 | { 447 | "name": "Konstantin Kudryashov", 448 | "email": "ever.zet@gmail.com", 449 | "homepage": "http://everzet.com" 450 | }, 451 | { 452 | "name": "Marcello Duarte", 453 | "email": "marcello.duarte@gmail.com" 454 | } 455 | ], 456 | "description": "Highly opinionated mocking framework for PHP 5.3+", 457 | "homepage": "https://github.com/phpspec/prophecy", 458 | "keywords": [ 459 | "Double", 460 | "Dummy", 461 | "fake", 462 | "mock", 463 | "spy", 464 | "stub" 465 | ], 466 | "support": { 467 | "issues": "https://github.com/phpspec/prophecy/issues", 468 | "source": "https://github.com/phpspec/prophecy/tree/1.13.0" 469 | }, 470 | "time": "2021-03-17T13:42:18+00:00" 471 | }, 472 | { 473 | "name": "phpunit/php-code-coverage", 474 | "version": "6.1.4", 475 | "source": { 476 | "type": "git", 477 | "url": "https://github.com/sebastianbergmann/php-code-coverage.git", 478 | "reference": "807e6013b00af69b6c5d9ceb4282d0393dbb9d8d" 479 | }, 480 | "dist": { 481 | "type": "zip", 482 | "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/807e6013b00af69b6c5d9ceb4282d0393dbb9d8d", 483 | "reference": "807e6013b00af69b6c5d9ceb4282d0393dbb9d8d", 484 | "shasum": "" 485 | }, 486 | "require": { 487 | "ext-dom": "*", 488 | "ext-xmlwriter": "*", 489 | "php": "^7.1", 490 | "phpunit/php-file-iterator": "^2.0", 491 | "phpunit/php-text-template": "^1.2.1", 492 | "phpunit/php-token-stream": "^3.0", 493 | "sebastian/code-unit-reverse-lookup": "^1.0.1", 494 | "sebastian/environment": "^3.1 || ^4.0", 495 | "sebastian/version": "^2.0.1", 496 | "theseer/tokenizer": "^1.1" 497 | }, 498 | "require-dev": { 499 | "phpunit/phpunit": "^7.0" 500 | }, 501 | "suggest": { 502 | "ext-xdebug": "^2.6.0" 503 | }, 504 | "type": "library", 505 | "extra": { 506 | "branch-alias": { 507 | "dev-master": "6.1-dev" 508 | } 509 | }, 510 | "autoload": { 511 | "classmap": [ 512 | "src/" 513 | ] 514 | }, 515 | "notification-url": "https://packagist.org/downloads/", 516 | "license": [ 517 | "BSD-3-Clause" 518 | ], 519 | "authors": [ 520 | { 521 | "name": "Sebastian Bergmann", 522 | "email": "sebastian@phpunit.de", 523 | "role": "lead" 524 | } 525 | ], 526 | "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", 527 | "homepage": "https://github.com/sebastianbergmann/php-code-coverage", 528 | "keywords": [ 529 | "coverage", 530 | "testing", 531 | "xunit" 532 | ], 533 | "support": { 534 | "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", 535 | "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/master" 536 | }, 537 | "time": "2018-10-31T16:06:48+00:00" 538 | }, 539 | { 540 | "name": "phpunit/php-file-iterator", 541 | "version": "2.0.3", 542 | "source": { 543 | "type": "git", 544 | "url": "https://github.com/sebastianbergmann/php-file-iterator.git", 545 | "reference": "4b49fb70f067272b659ef0174ff9ca40fdaa6357" 546 | }, 547 | "dist": { 548 | "type": "zip", 549 | "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/4b49fb70f067272b659ef0174ff9ca40fdaa6357", 550 | "reference": "4b49fb70f067272b659ef0174ff9ca40fdaa6357", 551 | "shasum": "" 552 | }, 553 | "require": { 554 | "php": ">=7.1" 555 | }, 556 | "require-dev": { 557 | "phpunit/phpunit": "^8.5" 558 | }, 559 | "type": "library", 560 | "extra": { 561 | "branch-alias": { 562 | "dev-master": "2.0.x-dev" 563 | } 564 | }, 565 | "autoload": { 566 | "classmap": [ 567 | "src/" 568 | ] 569 | }, 570 | "notification-url": "https://packagist.org/downloads/", 571 | "license": [ 572 | "BSD-3-Clause" 573 | ], 574 | "authors": [ 575 | { 576 | "name": "Sebastian Bergmann", 577 | "email": "sebastian@phpunit.de", 578 | "role": "lead" 579 | } 580 | ], 581 | "description": "FilterIterator implementation that filters files based on a list of suffixes.", 582 | "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", 583 | "keywords": [ 584 | "filesystem", 585 | "iterator" 586 | ], 587 | "support": { 588 | "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", 589 | "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/2.0.3" 590 | }, 591 | "funding": [ 592 | { 593 | "url": "https://github.com/sebastianbergmann", 594 | "type": "github" 595 | } 596 | ], 597 | "time": "2020-11-30T08:25:21+00:00" 598 | }, 599 | { 600 | "name": "phpunit/php-text-template", 601 | "version": "1.2.1", 602 | "source": { 603 | "type": "git", 604 | "url": "https://github.com/sebastianbergmann/php-text-template.git", 605 | "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" 606 | }, 607 | "dist": { 608 | "type": "zip", 609 | "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", 610 | "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", 611 | "shasum": "" 612 | }, 613 | "require": { 614 | "php": ">=5.3.3" 615 | }, 616 | "type": "library", 617 | "autoload": { 618 | "classmap": [ 619 | "src/" 620 | ] 621 | }, 622 | "notification-url": "https://packagist.org/downloads/", 623 | "license": [ 624 | "BSD-3-Clause" 625 | ], 626 | "authors": [ 627 | { 628 | "name": "Sebastian Bergmann", 629 | "email": "sebastian@phpunit.de", 630 | "role": "lead" 631 | } 632 | ], 633 | "description": "Simple template engine.", 634 | "homepage": "https://github.com/sebastianbergmann/php-text-template/", 635 | "keywords": [ 636 | "template" 637 | ], 638 | "support": { 639 | "issues": "https://github.com/sebastianbergmann/php-text-template/issues", 640 | "source": "https://github.com/sebastianbergmann/php-text-template/tree/1.2.1" 641 | }, 642 | "time": "2015-06-21T13:50:34+00:00" 643 | }, 644 | { 645 | "name": "phpunit/php-timer", 646 | "version": "2.1.3", 647 | "source": { 648 | "type": "git", 649 | "url": "https://github.com/sebastianbergmann/php-timer.git", 650 | "reference": "2454ae1765516d20c4ffe103d85a58a9a3bd5662" 651 | }, 652 | "dist": { 653 | "type": "zip", 654 | "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/2454ae1765516d20c4ffe103d85a58a9a3bd5662", 655 | "reference": "2454ae1765516d20c4ffe103d85a58a9a3bd5662", 656 | "shasum": "" 657 | }, 658 | "require": { 659 | "php": ">=7.1" 660 | }, 661 | "require-dev": { 662 | "phpunit/phpunit": "^8.5" 663 | }, 664 | "type": "library", 665 | "extra": { 666 | "branch-alias": { 667 | "dev-master": "2.1-dev" 668 | } 669 | }, 670 | "autoload": { 671 | "classmap": [ 672 | "src/" 673 | ] 674 | }, 675 | "notification-url": "https://packagist.org/downloads/", 676 | "license": [ 677 | "BSD-3-Clause" 678 | ], 679 | "authors": [ 680 | { 681 | "name": "Sebastian Bergmann", 682 | "email": "sebastian@phpunit.de", 683 | "role": "lead" 684 | } 685 | ], 686 | "description": "Utility class for timing", 687 | "homepage": "https://github.com/sebastianbergmann/php-timer/", 688 | "keywords": [ 689 | "timer" 690 | ], 691 | "support": { 692 | "issues": "https://github.com/sebastianbergmann/php-timer/issues", 693 | "source": "https://github.com/sebastianbergmann/php-timer/tree/2.1.3" 694 | }, 695 | "funding": [ 696 | { 697 | "url": "https://github.com/sebastianbergmann", 698 | "type": "github" 699 | } 700 | ], 701 | "time": "2020-11-30T08:20:02+00:00" 702 | }, 703 | { 704 | "name": "phpunit/php-token-stream", 705 | "version": "3.1.2", 706 | "source": { 707 | "type": "git", 708 | "url": "https://github.com/sebastianbergmann/php-token-stream.git", 709 | "reference": "472b687829041c24b25f475e14c2f38a09edf1c2" 710 | }, 711 | "dist": { 712 | "type": "zip", 713 | "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/472b687829041c24b25f475e14c2f38a09edf1c2", 714 | "reference": "472b687829041c24b25f475e14c2f38a09edf1c2", 715 | "shasum": "" 716 | }, 717 | "require": { 718 | "ext-tokenizer": "*", 719 | "php": ">=7.1" 720 | }, 721 | "require-dev": { 722 | "phpunit/phpunit": "^7.0" 723 | }, 724 | "type": "library", 725 | "extra": { 726 | "branch-alias": { 727 | "dev-master": "3.1-dev" 728 | } 729 | }, 730 | "autoload": { 731 | "classmap": [ 732 | "src/" 733 | ] 734 | }, 735 | "notification-url": "https://packagist.org/downloads/", 736 | "license": [ 737 | "BSD-3-Clause" 738 | ], 739 | "authors": [ 740 | { 741 | "name": "Sebastian Bergmann", 742 | "email": "sebastian@phpunit.de" 743 | } 744 | ], 745 | "description": "Wrapper around PHP's tokenizer extension.", 746 | "homepage": "https://github.com/sebastianbergmann/php-token-stream/", 747 | "keywords": [ 748 | "tokenizer" 749 | ], 750 | "support": { 751 | "issues": "https://github.com/sebastianbergmann/php-token-stream/issues", 752 | "source": "https://github.com/sebastianbergmann/php-token-stream/tree/3.1.2" 753 | }, 754 | "funding": [ 755 | { 756 | "url": "https://github.com/sebastianbergmann", 757 | "type": "github" 758 | } 759 | ], 760 | "abandoned": true, 761 | "time": "2020-11-30T08:38:46+00:00" 762 | }, 763 | { 764 | "name": "phpunit/phpunit", 765 | "version": "7.5.20", 766 | "source": { 767 | "type": "git", 768 | "url": "https://github.com/sebastianbergmann/phpunit.git", 769 | "reference": "9467db479d1b0487c99733bb1e7944d32deded2c" 770 | }, 771 | "dist": { 772 | "type": "zip", 773 | "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/9467db479d1b0487c99733bb1e7944d32deded2c", 774 | "reference": "9467db479d1b0487c99733bb1e7944d32deded2c", 775 | "shasum": "" 776 | }, 777 | "require": { 778 | "doctrine/instantiator": "^1.1", 779 | "ext-dom": "*", 780 | "ext-json": "*", 781 | "ext-libxml": "*", 782 | "ext-mbstring": "*", 783 | "ext-xml": "*", 784 | "myclabs/deep-copy": "^1.7", 785 | "phar-io/manifest": "^1.0.2", 786 | "phar-io/version": "^2.0", 787 | "php": "^7.1", 788 | "phpspec/prophecy": "^1.7", 789 | "phpunit/php-code-coverage": "^6.0.7", 790 | "phpunit/php-file-iterator": "^2.0.1", 791 | "phpunit/php-text-template": "^1.2.1", 792 | "phpunit/php-timer": "^2.1", 793 | "sebastian/comparator": "^3.0", 794 | "sebastian/diff": "^3.0", 795 | "sebastian/environment": "^4.0", 796 | "sebastian/exporter": "^3.1", 797 | "sebastian/global-state": "^2.0", 798 | "sebastian/object-enumerator": "^3.0.3", 799 | "sebastian/resource-operations": "^2.0", 800 | "sebastian/version": "^2.0.1" 801 | }, 802 | "conflict": { 803 | "phpunit/phpunit-mock-objects": "*" 804 | }, 805 | "require-dev": { 806 | "ext-pdo": "*" 807 | }, 808 | "suggest": { 809 | "ext-soap": "*", 810 | "ext-xdebug": "*", 811 | "phpunit/php-invoker": "^2.0" 812 | }, 813 | "bin": [ 814 | "phpunit" 815 | ], 816 | "type": "library", 817 | "extra": { 818 | "branch-alias": { 819 | "dev-master": "7.5-dev" 820 | } 821 | }, 822 | "autoload": { 823 | "classmap": [ 824 | "src/" 825 | ] 826 | }, 827 | "notification-url": "https://packagist.org/downloads/", 828 | "license": [ 829 | "BSD-3-Clause" 830 | ], 831 | "authors": [ 832 | { 833 | "name": "Sebastian Bergmann", 834 | "email": "sebastian@phpunit.de", 835 | "role": "lead" 836 | } 837 | ], 838 | "description": "The PHP Unit Testing framework.", 839 | "homepage": "https://phpunit.de/", 840 | "keywords": [ 841 | "phpunit", 842 | "testing", 843 | "xunit" 844 | ], 845 | "support": { 846 | "issues": "https://github.com/sebastianbergmann/phpunit/issues", 847 | "source": "https://github.com/sebastianbergmann/phpunit/tree/7.5.20" 848 | }, 849 | "time": "2020-01-08T08:45:45+00:00" 850 | }, 851 | { 852 | "name": "sebastian/code-unit-reverse-lookup", 853 | "version": "1.0.2", 854 | "source": { 855 | "type": "git", 856 | "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", 857 | "reference": "1de8cd5c010cb153fcd68b8d0f64606f523f7619" 858 | }, 859 | "dist": { 860 | "type": "zip", 861 | "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/1de8cd5c010cb153fcd68b8d0f64606f523f7619", 862 | "reference": "1de8cd5c010cb153fcd68b8d0f64606f523f7619", 863 | "shasum": "" 864 | }, 865 | "require": { 866 | "php": ">=5.6" 867 | }, 868 | "require-dev": { 869 | "phpunit/phpunit": "^8.5" 870 | }, 871 | "type": "library", 872 | "extra": { 873 | "branch-alias": { 874 | "dev-master": "1.0.x-dev" 875 | } 876 | }, 877 | "autoload": { 878 | "classmap": [ 879 | "src/" 880 | ] 881 | }, 882 | "notification-url": "https://packagist.org/downloads/", 883 | "license": [ 884 | "BSD-3-Clause" 885 | ], 886 | "authors": [ 887 | { 888 | "name": "Sebastian Bergmann", 889 | "email": "sebastian@phpunit.de" 890 | } 891 | ], 892 | "description": "Looks up which function or method a line of code belongs to", 893 | "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", 894 | "support": { 895 | "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", 896 | "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/1.0.2" 897 | }, 898 | "funding": [ 899 | { 900 | "url": "https://github.com/sebastianbergmann", 901 | "type": "github" 902 | } 903 | ], 904 | "time": "2020-11-30T08:15:22+00:00" 905 | }, 906 | { 907 | "name": "sebastian/comparator", 908 | "version": "3.0.3", 909 | "source": { 910 | "type": "git", 911 | "url": "https://github.com/sebastianbergmann/comparator.git", 912 | "reference": "1071dfcef776a57013124ff35e1fc41ccd294758" 913 | }, 914 | "dist": { 915 | "type": "zip", 916 | "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/1071dfcef776a57013124ff35e1fc41ccd294758", 917 | "reference": "1071dfcef776a57013124ff35e1fc41ccd294758", 918 | "shasum": "" 919 | }, 920 | "require": { 921 | "php": ">=7.1", 922 | "sebastian/diff": "^3.0", 923 | "sebastian/exporter": "^3.1" 924 | }, 925 | "require-dev": { 926 | "phpunit/phpunit": "^8.5" 927 | }, 928 | "type": "library", 929 | "extra": { 930 | "branch-alias": { 931 | "dev-master": "3.0-dev" 932 | } 933 | }, 934 | "autoload": { 935 | "classmap": [ 936 | "src/" 937 | ] 938 | }, 939 | "notification-url": "https://packagist.org/downloads/", 940 | "license": [ 941 | "BSD-3-Clause" 942 | ], 943 | "authors": [ 944 | { 945 | "name": "Sebastian Bergmann", 946 | "email": "sebastian@phpunit.de" 947 | }, 948 | { 949 | "name": "Jeff Welch", 950 | "email": "whatthejeff@gmail.com" 951 | }, 952 | { 953 | "name": "Volker Dusch", 954 | "email": "github@wallbash.com" 955 | }, 956 | { 957 | "name": "Bernhard Schussek", 958 | "email": "bschussek@2bepublished.at" 959 | } 960 | ], 961 | "description": "Provides the functionality to compare PHP values for equality", 962 | "homepage": "https://github.com/sebastianbergmann/comparator", 963 | "keywords": [ 964 | "comparator", 965 | "compare", 966 | "equality" 967 | ], 968 | "support": { 969 | "issues": "https://github.com/sebastianbergmann/comparator/issues", 970 | "source": "https://github.com/sebastianbergmann/comparator/tree/3.0.3" 971 | }, 972 | "funding": [ 973 | { 974 | "url": "https://github.com/sebastianbergmann", 975 | "type": "github" 976 | } 977 | ], 978 | "time": "2020-11-30T08:04:30+00:00" 979 | }, 980 | { 981 | "name": "sebastian/diff", 982 | "version": "3.0.3", 983 | "source": { 984 | "type": "git", 985 | "url": "https://github.com/sebastianbergmann/diff.git", 986 | "reference": "14f72dd46eaf2f2293cbe79c93cc0bc43161a211" 987 | }, 988 | "dist": { 989 | "type": "zip", 990 | "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/14f72dd46eaf2f2293cbe79c93cc0bc43161a211", 991 | "reference": "14f72dd46eaf2f2293cbe79c93cc0bc43161a211", 992 | "shasum": "" 993 | }, 994 | "require": { 995 | "php": ">=7.1" 996 | }, 997 | "require-dev": { 998 | "phpunit/phpunit": "^7.5 || ^8.0", 999 | "symfony/process": "^2 || ^3.3 || ^4" 1000 | }, 1001 | "type": "library", 1002 | "extra": { 1003 | "branch-alias": { 1004 | "dev-master": "3.0-dev" 1005 | } 1006 | }, 1007 | "autoload": { 1008 | "classmap": [ 1009 | "src/" 1010 | ] 1011 | }, 1012 | "notification-url": "https://packagist.org/downloads/", 1013 | "license": [ 1014 | "BSD-3-Clause" 1015 | ], 1016 | "authors": [ 1017 | { 1018 | "name": "Sebastian Bergmann", 1019 | "email": "sebastian@phpunit.de" 1020 | }, 1021 | { 1022 | "name": "Kore Nordmann", 1023 | "email": "mail@kore-nordmann.de" 1024 | } 1025 | ], 1026 | "description": "Diff implementation", 1027 | "homepage": "https://github.com/sebastianbergmann/diff", 1028 | "keywords": [ 1029 | "diff", 1030 | "udiff", 1031 | "unidiff", 1032 | "unified diff" 1033 | ], 1034 | "support": { 1035 | "issues": "https://github.com/sebastianbergmann/diff/issues", 1036 | "source": "https://github.com/sebastianbergmann/diff/tree/3.0.3" 1037 | }, 1038 | "funding": [ 1039 | { 1040 | "url": "https://github.com/sebastianbergmann", 1041 | "type": "github" 1042 | } 1043 | ], 1044 | "time": "2020-11-30T07:59:04+00:00" 1045 | }, 1046 | { 1047 | "name": "sebastian/environment", 1048 | "version": "4.2.4", 1049 | "source": { 1050 | "type": "git", 1051 | "url": "https://github.com/sebastianbergmann/environment.git", 1052 | "reference": "d47bbbad83711771f167c72d4e3f25f7fcc1f8b0" 1053 | }, 1054 | "dist": { 1055 | "type": "zip", 1056 | "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/d47bbbad83711771f167c72d4e3f25f7fcc1f8b0", 1057 | "reference": "d47bbbad83711771f167c72d4e3f25f7fcc1f8b0", 1058 | "shasum": "" 1059 | }, 1060 | "require": { 1061 | "php": ">=7.1" 1062 | }, 1063 | "require-dev": { 1064 | "phpunit/phpunit": "^7.5" 1065 | }, 1066 | "suggest": { 1067 | "ext-posix": "*" 1068 | }, 1069 | "type": "library", 1070 | "extra": { 1071 | "branch-alias": { 1072 | "dev-master": "4.2-dev" 1073 | } 1074 | }, 1075 | "autoload": { 1076 | "classmap": [ 1077 | "src/" 1078 | ] 1079 | }, 1080 | "notification-url": "https://packagist.org/downloads/", 1081 | "license": [ 1082 | "BSD-3-Clause" 1083 | ], 1084 | "authors": [ 1085 | { 1086 | "name": "Sebastian Bergmann", 1087 | "email": "sebastian@phpunit.de" 1088 | } 1089 | ], 1090 | "description": "Provides functionality to handle HHVM/PHP environments", 1091 | "homepage": "http://www.github.com/sebastianbergmann/environment", 1092 | "keywords": [ 1093 | "Xdebug", 1094 | "environment", 1095 | "hhvm" 1096 | ], 1097 | "support": { 1098 | "issues": "https://github.com/sebastianbergmann/environment/issues", 1099 | "source": "https://github.com/sebastianbergmann/environment/tree/4.2.4" 1100 | }, 1101 | "funding": [ 1102 | { 1103 | "url": "https://github.com/sebastianbergmann", 1104 | "type": "github" 1105 | } 1106 | ], 1107 | "time": "2020-11-30T07:53:42+00:00" 1108 | }, 1109 | { 1110 | "name": "sebastian/exporter", 1111 | "version": "3.1.3", 1112 | "source": { 1113 | "type": "git", 1114 | "url": "https://github.com/sebastianbergmann/exporter.git", 1115 | "reference": "6b853149eab67d4da22291d36f5b0631c0fd856e" 1116 | }, 1117 | "dist": { 1118 | "type": "zip", 1119 | "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/6b853149eab67d4da22291d36f5b0631c0fd856e", 1120 | "reference": "6b853149eab67d4da22291d36f5b0631c0fd856e", 1121 | "shasum": "" 1122 | }, 1123 | "require": { 1124 | "php": ">=7.0", 1125 | "sebastian/recursion-context": "^3.0" 1126 | }, 1127 | "require-dev": { 1128 | "ext-mbstring": "*", 1129 | "phpunit/phpunit": "^6.0" 1130 | }, 1131 | "type": "library", 1132 | "extra": { 1133 | "branch-alias": { 1134 | "dev-master": "3.1.x-dev" 1135 | } 1136 | }, 1137 | "autoload": { 1138 | "classmap": [ 1139 | "src/" 1140 | ] 1141 | }, 1142 | "notification-url": "https://packagist.org/downloads/", 1143 | "license": [ 1144 | "BSD-3-Clause" 1145 | ], 1146 | "authors": [ 1147 | { 1148 | "name": "Sebastian Bergmann", 1149 | "email": "sebastian@phpunit.de" 1150 | }, 1151 | { 1152 | "name": "Jeff Welch", 1153 | "email": "whatthejeff@gmail.com" 1154 | }, 1155 | { 1156 | "name": "Volker Dusch", 1157 | "email": "github@wallbash.com" 1158 | }, 1159 | { 1160 | "name": "Adam Harvey", 1161 | "email": "aharvey@php.net" 1162 | }, 1163 | { 1164 | "name": "Bernhard Schussek", 1165 | "email": "bschussek@gmail.com" 1166 | } 1167 | ], 1168 | "description": "Provides the functionality to export PHP variables for visualization", 1169 | "homepage": "http://www.github.com/sebastianbergmann/exporter", 1170 | "keywords": [ 1171 | "export", 1172 | "exporter" 1173 | ], 1174 | "support": { 1175 | "issues": "https://github.com/sebastianbergmann/exporter/issues", 1176 | "source": "https://github.com/sebastianbergmann/exporter/tree/3.1.3" 1177 | }, 1178 | "funding": [ 1179 | { 1180 | "url": "https://github.com/sebastianbergmann", 1181 | "type": "github" 1182 | } 1183 | ], 1184 | "time": "2020-11-30T07:47:53+00:00" 1185 | }, 1186 | { 1187 | "name": "sebastian/global-state", 1188 | "version": "2.0.0", 1189 | "source": { 1190 | "type": "git", 1191 | "url": "https://github.com/sebastianbergmann/global-state.git", 1192 | "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4" 1193 | }, 1194 | "dist": { 1195 | "type": "zip", 1196 | "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", 1197 | "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", 1198 | "shasum": "" 1199 | }, 1200 | "require": { 1201 | "php": "^7.0" 1202 | }, 1203 | "require-dev": { 1204 | "phpunit/phpunit": "^6.0" 1205 | }, 1206 | "suggest": { 1207 | "ext-uopz": "*" 1208 | }, 1209 | "type": "library", 1210 | "extra": { 1211 | "branch-alias": { 1212 | "dev-master": "2.0-dev" 1213 | } 1214 | }, 1215 | "autoload": { 1216 | "classmap": [ 1217 | "src/" 1218 | ] 1219 | }, 1220 | "notification-url": "https://packagist.org/downloads/", 1221 | "license": [ 1222 | "BSD-3-Clause" 1223 | ], 1224 | "authors": [ 1225 | { 1226 | "name": "Sebastian Bergmann", 1227 | "email": "sebastian@phpunit.de" 1228 | } 1229 | ], 1230 | "description": "Snapshotting of global state", 1231 | "homepage": "http://www.github.com/sebastianbergmann/global-state", 1232 | "keywords": [ 1233 | "global state" 1234 | ], 1235 | "support": { 1236 | "issues": "https://github.com/sebastianbergmann/global-state/issues", 1237 | "source": "https://github.com/sebastianbergmann/global-state/tree/2.0.0" 1238 | }, 1239 | "time": "2017-04-27T15:39:26+00:00" 1240 | }, 1241 | { 1242 | "name": "sebastian/object-enumerator", 1243 | "version": "3.0.4", 1244 | "source": { 1245 | "type": "git", 1246 | "url": "https://github.com/sebastianbergmann/object-enumerator.git", 1247 | "reference": "e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2" 1248 | }, 1249 | "dist": { 1250 | "type": "zip", 1251 | "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2", 1252 | "reference": "e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2", 1253 | "shasum": "" 1254 | }, 1255 | "require": { 1256 | "php": ">=7.0", 1257 | "sebastian/object-reflector": "^1.1.1", 1258 | "sebastian/recursion-context": "^3.0" 1259 | }, 1260 | "require-dev": { 1261 | "phpunit/phpunit": "^6.0" 1262 | }, 1263 | "type": "library", 1264 | "extra": { 1265 | "branch-alias": { 1266 | "dev-master": "3.0.x-dev" 1267 | } 1268 | }, 1269 | "autoload": { 1270 | "classmap": [ 1271 | "src/" 1272 | ] 1273 | }, 1274 | "notification-url": "https://packagist.org/downloads/", 1275 | "license": [ 1276 | "BSD-3-Clause" 1277 | ], 1278 | "authors": [ 1279 | { 1280 | "name": "Sebastian Bergmann", 1281 | "email": "sebastian@phpunit.de" 1282 | } 1283 | ], 1284 | "description": "Traverses array structures and object graphs to enumerate all referenced objects", 1285 | "homepage": "https://github.com/sebastianbergmann/object-enumerator/", 1286 | "support": { 1287 | "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", 1288 | "source": "https://github.com/sebastianbergmann/object-enumerator/tree/3.0.4" 1289 | }, 1290 | "funding": [ 1291 | { 1292 | "url": "https://github.com/sebastianbergmann", 1293 | "type": "github" 1294 | } 1295 | ], 1296 | "time": "2020-11-30T07:40:27+00:00" 1297 | }, 1298 | { 1299 | "name": "sebastian/object-reflector", 1300 | "version": "1.1.2", 1301 | "source": { 1302 | "type": "git", 1303 | "url": "https://github.com/sebastianbergmann/object-reflector.git", 1304 | "reference": "9b8772b9cbd456ab45d4a598d2dd1a1bced6363d" 1305 | }, 1306 | "dist": { 1307 | "type": "zip", 1308 | "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/9b8772b9cbd456ab45d4a598d2dd1a1bced6363d", 1309 | "reference": "9b8772b9cbd456ab45d4a598d2dd1a1bced6363d", 1310 | "shasum": "" 1311 | }, 1312 | "require": { 1313 | "php": ">=7.0" 1314 | }, 1315 | "require-dev": { 1316 | "phpunit/phpunit": "^6.0" 1317 | }, 1318 | "type": "library", 1319 | "extra": { 1320 | "branch-alias": { 1321 | "dev-master": "1.1-dev" 1322 | } 1323 | }, 1324 | "autoload": { 1325 | "classmap": [ 1326 | "src/" 1327 | ] 1328 | }, 1329 | "notification-url": "https://packagist.org/downloads/", 1330 | "license": [ 1331 | "BSD-3-Clause" 1332 | ], 1333 | "authors": [ 1334 | { 1335 | "name": "Sebastian Bergmann", 1336 | "email": "sebastian@phpunit.de" 1337 | } 1338 | ], 1339 | "description": "Allows reflection of object attributes, including inherited and non-public ones", 1340 | "homepage": "https://github.com/sebastianbergmann/object-reflector/", 1341 | "support": { 1342 | "issues": "https://github.com/sebastianbergmann/object-reflector/issues", 1343 | "source": "https://github.com/sebastianbergmann/object-reflector/tree/1.1.2" 1344 | }, 1345 | "funding": [ 1346 | { 1347 | "url": "https://github.com/sebastianbergmann", 1348 | "type": "github" 1349 | } 1350 | ], 1351 | "time": "2020-11-30T07:37:18+00:00" 1352 | }, 1353 | { 1354 | "name": "sebastian/recursion-context", 1355 | "version": "3.0.1", 1356 | "source": { 1357 | "type": "git", 1358 | "url": "https://github.com/sebastianbergmann/recursion-context.git", 1359 | "reference": "367dcba38d6e1977be014dc4b22f47a484dac7fb" 1360 | }, 1361 | "dist": { 1362 | "type": "zip", 1363 | "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/367dcba38d6e1977be014dc4b22f47a484dac7fb", 1364 | "reference": "367dcba38d6e1977be014dc4b22f47a484dac7fb", 1365 | "shasum": "" 1366 | }, 1367 | "require": { 1368 | "php": ">=7.0" 1369 | }, 1370 | "require-dev": { 1371 | "phpunit/phpunit": "^6.0" 1372 | }, 1373 | "type": "library", 1374 | "extra": { 1375 | "branch-alias": { 1376 | "dev-master": "3.0.x-dev" 1377 | } 1378 | }, 1379 | "autoload": { 1380 | "classmap": [ 1381 | "src/" 1382 | ] 1383 | }, 1384 | "notification-url": "https://packagist.org/downloads/", 1385 | "license": [ 1386 | "BSD-3-Clause" 1387 | ], 1388 | "authors": [ 1389 | { 1390 | "name": "Sebastian Bergmann", 1391 | "email": "sebastian@phpunit.de" 1392 | }, 1393 | { 1394 | "name": "Jeff Welch", 1395 | "email": "whatthejeff@gmail.com" 1396 | }, 1397 | { 1398 | "name": "Adam Harvey", 1399 | "email": "aharvey@php.net" 1400 | } 1401 | ], 1402 | "description": "Provides functionality to recursively process PHP variables", 1403 | "homepage": "http://www.github.com/sebastianbergmann/recursion-context", 1404 | "support": { 1405 | "issues": "https://github.com/sebastianbergmann/recursion-context/issues", 1406 | "source": "https://github.com/sebastianbergmann/recursion-context/tree/3.0.1" 1407 | }, 1408 | "funding": [ 1409 | { 1410 | "url": "https://github.com/sebastianbergmann", 1411 | "type": "github" 1412 | } 1413 | ], 1414 | "time": "2020-11-30T07:34:24+00:00" 1415 | }, 1416 | { 1417 | "name": "sebastian/resource-operations", 1418 | "version": "2.0.2", 1419 | "source": { 1420 | "type": "git", 1421 | "url": "https://github.com/sebastianbergmann/resource-operations.git", 1422 | "reference": "31d35ca87926450c44eae7e2611d45a7a65ea8b3" 1423 | }, 1424 | "dist": { 1425 | "type": "zip", 1426 | "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/31d35ca87926450c44eae7e2611d45a7a65ea8b3", 1427 | "reference": "31d35ca87926450c44eae7e2611d45a7a65ea8b3", 1428 | "shasum": "" 1429 | }, 1430 | "require": { 1431 | "php": ">=7.1" 1432 | }, 1433 | "type": "library", 1434 | "extra": { 1435 | "branch-alias": { 1436 | "dev-master": "2.0-dev" 1437 | } 1438 | }, 1439 | "autoload": { 1440 | "classmap": [ 1441 | "src/" 1442 | ] 1443 | }, 1444 | "notification-url": "https://packagist.org/downloads/", 1445 | "license": [ 1446 | "BSD-3-Clause" 1447 | ], 1448 | "authors": [ 1449 | { 1450 | "name": "Sebastian Bergmann", 1451 | "email": "sebastian@phpunit.de" 1452 | } 1453 | ], 1454 | "description": "Provides a list of PHP built-in functions that operate on resources", 1455 | "homepage": "https://www.github.com/sebastianbergmann/resource-operations", 1456 | "support": { 1457 | "issues": "https://github.com/sebastianbergmann/resource-operations/issues", 1458 | "source": "https://github.com/sebastianbergmann/resource-operations/tree/2.0.2" 1459 | }, 1460 | "funding": [ 1461 | { 1462 | "url": "https://github.com/sebastianbergmann", 1463 | "type": "github" 1464 | } 1465 | ], 1466 | "time": "2020-11-30T07:30:19+00:00" 1467 | }, 1468 | { 1469 | "name": "sebastian/version", 1470 | "version": "2.0.1", 1471 | "source": { 1472 | "type": "git", 1473 | "url": "https://github.com/sebastianbergmann/version.git", 1474 | "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019" 1475 | }, 1476 | "dist": { 1477 | "type": "zip", 1478 | "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019", 1479 | "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019", 1480 | "shasum": "" 1481 | }, 1482 | "require": { 1483 | "php": ">=5.6" 1484 | }, 1485 | "type": "library", 1486 | "extra": { 1487 | "branch-alias": { 1488 | "dev-master": "2.0.x-dev" 1489 | } 1490 | }, 1491 | "autoload": { 1492 | "classmap": [ 1493 | "src/" 1494 | ] 1495 | }, 1496 | "notification-url": "https://packagist.org/downloads/", 1497 | "license": [ 1498 | "BSD-3-Clause" 1499 | ], 1500 | "authors": [ 1501 | { 1502 | "name": "Sebastian Bergmann", 1503 | "email": "sebastian@phpunit.de", 1504 | "role": "lead" 1505 | } 1506 | ], 1507 | "description": "Library that helps with managing the version number of Git-hosted PHP projects", 1508 | "homepage": "https://github.com/sebastianbergmann/version", 1509 | "support": { 1510 | "issues": "https://github.com/sebastianbergmann/version/issues", 1511 | "source": "https://github.com/sebastianbergmann/version/tree/master" 1512 | }, 1513 | "time": "2016-10-03T07:35:21+00:00" 1514 | }, 1515 | { 1516 | "name": "symfony/polyfill-ctype", 1517 | "version": "v1.23.0", 1518 | "source": { 1519 | "type": "git", 1520 | "url": "https://github.com/symfony/polyfill-ctype.git", 1521 | "reference": "46cd95797e9df938fdd2b03693b5fca5e64b01ce" 1522 | }, 1523 | "dist": { 1524 | "type": "zip", 1525 | "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/46cd95797e9df938fdd2b03693b5fca5e64b01ce", 1526 | "reference": "46cd95797e9df938fdd2b03693b5fca5e64b01ce", 1527 | "shasum": "" 1528 | }, 1529 | "require": { 1530 | "php": ">=7.1" 1531 | }, 1532 | "suggest": { 1533 | "ext-ctype": "For best performance" 1534 | }, 1535 | "type": "library", 1536 | "extra": { 1537 | "branch-alias": { 1538 | "dev-main": "1.23-dev" 1539 | }, 1540 | "thanks": { 1541 | "name": "symfony/polyfill", 1542 | "url": "https://github.com/symfony/polyfill" 1543 | } 1544 | }, 1545 | "autoload": { 1546 | "psr-4": { 1547 | "Symfony\\Polyfill\\Ctype\\": "" 1548 | }, 1549 | "files": [ 1550 | "bootstrap.php" 1551 | ] 1552 | }, 1553 | "notification-url": "https://packagist.org/downloads/", 1554 | "license": [ 1555 | "MIT" 1556 | ], 1557 | "authors": [ 1558 | { 1559 | "name": "Gert de Pagter", 1560 | "email": "BackEndTea@gmail.com" 1561 | }, 1562 | { 1563 | "name": "Symfony Community", 1564 | "homepage": "https://symfony.com/contributors" 1565 | } 1566 | ], 1567 | "description": "Symfony polyfill for ctype functions", 1568 | "homepage": "https://symfony.com", 1569 | "keywords": [ 1570 | "compatibility", 1571 | "ctype", 1572 | "polyfill", 1573 | "portable" 1574 | ], 1575 | "support": { 1576 | "source": "https://github.com/symfony/polyfill-ctype/tree/v1.23.0" 1577 | }, 1578 | "funding": [ 1579 | { 1580 | "url": "https://symfony.com/sponsor", 1581 | "type": "custom" 1582 | }, 1583 | { 1584 | "url": "https://github.com/fabpot", 1585 | "type": "github" 1586 | }, 1587 | { 1588 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 1589 | "type": "tidelift" 1590 | } 1591 | ], 1592 | "time": "2021-02-19T12:13:01+00:00" 1593 | }, 1594 | { 1595 | "name": "theseer/tokenizer", 1596 | "version": "1.2.0", 1597 | "source": { 1598 | "type": "git", 1599 | "url": "https://github.com/theseer/tokenizer.git", 1600 | "reference": "75a63c33a8577608444246075ea0af0d052e452a" 1601 | }, 1602 | "dist": { 1603 | "type": "zip", 1604 | "url": "https://api.github.com/repos/theseer/tokenizer/zipball/75a63c33a8577608444246075ea0af0d052e452a", 1605 | "reference": "75a63c33a8577608444246075ea0af0d052e452a", 1606 | "shasum": "" 1607 | }, 1608 | "require": { 1609 | "ext-dom": "*", 1610 | "ext-tokenizer": "*", 1611 | "ext-xmlwriter": "*", 1612 | "php": "^7.2 || ^8.0" 1613 | }, 1614 | "type": "library", 1615 | "autoload": { 1616 | "classmap": [ 1617 | "src/" 1618 | ] 1619 | }, 1620 | "notification-url": "https://packagist.org/downloads/", 1621 | "license": [ 1622 | "BSD-3-Clause" 1623 | ], 1624 | "authors": [ 1625 | { 1626 | "name": "Arne Blankerts", 1627 | "email": "arne@blankerts.de", 1628 | "role": "Developer" 1629 | } 1630 | ], 1631 | "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", 1632 | "support": { 1633 | "issues": "https://github.com/theseer/tokenizer/issues", 1634 | "source": "https://github.com/theseer/tokenizer/tree/master" 1635 | }, 1636 | "funding": [ 1637 | { 1638 | "url": "https://github.com/theseer", 1639 | "type": "github" 1640 | } 1641 | ], 1642 | "time": "2020-07-12T23:59:07+00:00" 1643 | }, 1644 | { 1645 | "name": "webmozart/assert", 1646 | "version": "1.10.0", 1647 | "source": { 1648 | "type": "git", 1649 | "url": "https://github.com/webmozarts/assert.git", 1650 | "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25" 1651 | }, 1652 | "dist": { 1653 | "type": "zip", 1654 | "url": "https://api.github.com/repos/webmozarts/assert/zipball/6964c76c7804814a842473e0c8fd15bab0f18e25", 1655 | "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25", 1656 | "shasum": "" 1657 | }, 1658 | "require": { 1659 | "php": "^7.2 || ^8.0", 1660 | "symfony/polyfill-ctype": "^1.8" 1661 | }, 1662 | "conflict": { 1663 | "phpstan/phpstan": "<0.12.20", 1664 | "vimeo/psalm": "<4.6.1 || 4.6.2" 1665 | }, 1666 | "require-dev": { 1667 | "phpunit/phpunit": "^8.5.13" 1668 | }, 1669 | "type": "library", 1670 | "extra": { 1671 | "branch-alias": { 1672 | "dev-master": "1.10-dev" 1673 | } 1674 | }, 1675 | "autoload": { 1676 | "psr-4": { 1677 | "Webmozart\\Assert\\": "src/" 1678 | } 1679 | }, 1680 | "notification-url": "https://packagist.org/downloads/", 1681 | "license": [ 1682 | "MIT" 1683 | ], 1684 | "authors": [ 1685 | { 1686 | "name": "Bernhard Schussek", 1687 | "email": "bschussek@gmail.com" 1688 | } 1689 | ], 1690 | "description": "Assertions to validate method input/output with nice error messages.", 1691 | "keywords": [ 1692 | "assert", 1693 | "check", 1694 | "validate" 1695 | ], 1696 | "support": { 1697 | "issues": "https://github.com/webmozarts/assert/issues", 1698 | "source": "https://github.com/webmozarts/assert/tree/1.10.0" 1699 | }, 1700 | "time": "2021-03-09T10:59:23+00:00" 1701 | } 1702 | ], 1703 | "aliases": [], 1704 | "minimum-stability": "stable", 1705 | "stability-flags": [], 1706 | "prefer-stable": false, 1707 | "prefer-lowest": false, 1708 | "platform": [], 1709 | "platform-dev": [], 1710 | "plugin-api-version": "2.0.0" 1711 | } 1712 | -------------------------------------------------------------------------------- /config/laravel-vue-datatables.php: -------------------------------------------------------------------------------- 1 | [ 5 | "alias" => "as", 6 | "search_term" => "searchable", 7 | "order_term" => "orderable", 8 | ], 9 | "default_order_by" => "id", 10 | "like_term" => "like" // use ilike for PostgreSQL 11 | ]; -------------------------------------------------------------------------------- /phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 11 | 12 | 13 | 14 | ./tests/ 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/Classes/Factories/RelationshipModelFactory.php: -------------------------------------------------------------------------------- 1 | $options) { 17 | 18 | if (! isset($options['model'])) { 19 | throw new RelationshipModelNotSetException( 20 | "Model not set on relationship: $tableName" 21 | ); 22 | } 23 | 24 | if (! isset($options['columns'])) { 25 | throw new RelationshipColumnsNotFoundException( 26 | "Columns array not set on relationship: $tableName" 27 | ); 28 | } 29 | 30 | $model = $relationshipModelFactory($options['model'], $tableName); 31 | 32 | $query = $query->orWhereHas($tableName, function ($query) use ($searchValue, $model, $options, $searchTerm, $likeTerm) { 33 | //Get the real table name 34 | $tableName = $model->getTable(); 35 | 36 | foreach ($options['columns'] as $columnName => $column) { 37 | //Check if column is searchable 38 | if ($column[$searchTerm]) { 39 | //Check if first key 40 | if ($columnName === key($options['columns'])) { 41 | $query->where("$tableName.$columnName", $likeTerm, "%$searchValue%"); 42 | } else { 43 | $query->orWhere("$tableName.$columnName", $likeTerm, "%$searchValue%"); 44 | } 45 | } 46 | } 47 | }); 48 | } 49 | } 50 | } 51 | } -------------------------------------------------------------------------------- /src/Classes/Filters/FilterBelongsToRelationships.php: -------------------------------------------------------------------------------- 1 | $options) { 17 | 18 | if (! isset($options['model'])) { 19 | throw new RelationshipModelNotSetException( 20 | "Model not set on relationship: $tableName" 21 | ); 22 | } 23 | 24 | if (! isset($options['columns'])) { 25 | throw new RelationshipColumnsNotFoundException( 26 | "Columns array not set on relationship: $tableName" 27 | ); 28 | } 29 | 30 | $model = $relationshipModelFactory($options['model'], $tableName); 31 | 32 | $query->orWhereHas($tableName, function ($query) use ($searchValue, $model, $options, $searchTerm, $likeTerm) { 33 | 34 | if (isset($options['columns'])) { 35 | 36 | $tableName = $model->getTable(); 37 | 38 | foreach ($options['columns'] as $columnName => $col) { 39 | if ($col[$searchTerm]) { 40 | if ($columnName === key($options['columns'])) { 41 | $query->where("$tableName.$columnName", $likeTerm, "%$searchValue%"); 42 | } else { 43 | $query->orWhere("$tableName.$columnName", $likeTerm, "%$searchValue%"); 44 | } 45 | } 46 | } 47 | } 48 | }); 49 | } 50 | 51 | return $query; 52 | } 53 | 54 | return $query; 55 | } 56 | } -------------------------------------------------------------------------------- /src/Classes/Filters/FilterHasManyRelationships.php: -------------------------------------------------------------------------------- 1 | $options) { 17 | 18 | if (! isset($options['model'])) { 19 | throw new RelationshipModelNotSetException( 20 | "Model not set on relationship: $tableName" 21 | ); 22 | } 23 | 24 | if (! isset($options['columns'])) { 25 | throw new RelationshipColumnsNotFoundException( 26 | "Columns array not set on relationship: $tableName" 27 | ); 28 | } 29 | 30 | $model = $relationshipModelFactory($options['model'], $tableName); 31 | 32 | $query->orWhereHas($tableName, function ($query) use ($searchValue, $model, $options, $searchTerm, $likeTerm) { 33 | 34 | $tableName = $model->getTable(); 35 | 36 | foreach ($options['columns'] as $columnName => $col) { 37 | if ($col[$searchTerm]) { 38 | if ($columnName === key($options['columns'])) { 39 | $query->where("$tableName.$columnName", $likeTerm, "%$searchValue%"); 40 | } else { 41 | $query->orWhere("$tableName.$columnName", $likeTerm, "%$searchValue%"); 42 | } 43 | } 44 | } 45 | }); 46 | } 47 | } 48 | 49 | return $query; 50 | } 51 | } -------------------------------------------------------------------------------- /src/Classes/Filters/FilterHasOneRelationships.php: -------------------------------------------------------------------------------- 1 | $options) { 18 | 19 | if (! isset($options['model'])) { 20 | throw new RelationshipModelNotSetException( 21 | "Model not set on relationship: $tableName" 22 | ); 23 | } 24 | 25 | if (! isset($options['columns'])) { 26 | throw new RelationshipColumnsNotFoundException( 27 | "Columns array not set on relationship: $tableName" 28 | ); 29 | } 30 | 31 | $model = $relationshipModelFactory($options['model'], $tableName); 32 | 33 | $query->orWhereHas($tableName, function ($query) use ($searchValue, $model, $options, $searchTerm, $likeTerm) { 34 | 35 | if (isset($options['columns'])) { 36 | 37 | $tableName = $model->getTable(); 38 | 39 | foreach ($options['columns'] as $columnName => $col) { 40 | if ($col[$searchTerm]) { 41 | if ($columnName === key($options['columns'])) { 42 | $query->where("$tableName.$columnName", $likeTerm, "%$searchValue%"); 43 | } else { 44 | $query->orWhere("$tableName.$columnName", $likeTerm, "%$searchValue%"); 45 | } 46 | } 47 | } 48 | } 49 | }); 50 | } 51 | } 52 | 53 | return $query; 54 | } 55 | } -------------------------------------------------------------------------------- /src/Classes/Filters/FilterLocalData.php: -------------------------------------------------------------------------------- 1 | where(function($query) use ($searchValue, $searchTerm, $model, $localColumns, $likeTerm) { 14 | foreach ($localColumns as $key => $column) { 15 | if (isset($column[$searchTerm])) { 16 | if ($key === key($localColumns)) { 17 | $query->where($model->getTable() . ".$key", $likeTerm, "%$searchValue%"); 18 | } else { 19 | $query->orWhere($model->getTable() . ".$key", $likeTerm, "%$searchValue%"); 20 | } 21 | } 22 | } 23 | }); 24 | } 25 | 26 | return $query; 27 | } 28 | } -------------------------------------------------------------------------------- /src/Classes/Joins/JoinBelongsToManyRelationships.php: -------------------------------------------------------------------------------- 1 | $options) { 16 | 17 | if (! isset($options['model'])) { 18 | throw new RelationshipModelNotSetException( 19 | "Model not set on relationship: $tableName" 20 | ); 21 | } 22 | 23 | if (! isset($options['pivot'])) { 24 | throw new RelationshipPivotDataNotFoundException( 25 | "Pivot data not set on relationship: $tableName" 26 | ); 27 | } 28 | 29 | if (! isset($options['pivot']['table_name'])) { 30 | throw new RelationshipPivotDataNotFoundException( 31 | "Pivot table_name not set on relationship: $tableName" 32 | ); 33 | } 34 | 35 | if (! isset($options['pivot']['local_key'])) { 36 | throw new RelationshipPivotDataNotFoundException( 37 | "Pivot local_key not set on relationship: $tableName" 38 | ); 39 | } 40 | 41 | if (! isset($options['pivot']['foreign_key'])) { 42 | throw new RelationshipPivotDataNotFoundException( 43 | "Pivot foreign_key not set on relationship: $tableName" 44 | ); 45 | } 46 | 47 | 48 | $model = $relationshipModelFactory($options['model'], $tableName); 49 | 50 | $tableName = $model->getTable(); 51 | 52 | //Join the table so it can be orderBy 53 | $query = $query->leftJoin( 54 | $options['pivot']['table_name'], 55 | $localModel->getTable() . "." . $localModel->getKeyName(), 56 | '=', 57 | $options['pivot']['table_name'] . "." . $options['pivot']['local_key'] 58 | ); 59 | 60 | $query = $query->leftJoin( 61 | $tableName, 62 | $options['pivot']['table_name'] . "." . $options['pivot']['foreign_key'], 63 | '=', 64 | $tableName . "." . $localModel->getKeyName() 65 | ); 66 | } 67 | } 68 | 69 | return $query; 70 | } 71 | } -------------------------------------------------------------------------------- /src/Classes/Joins/JoinBelongsToRelationships.php: -------------------------------------------------------------------------------- 1 | $options) { 15 | 16 | if (! isset($options['model'])) { 17 | throw new RelationshipModelNotSetException( 18 | "Model not set on relationship: $tableName" 19 | ); 20 | } 21 | 22 | if (! isset($options['foreign_key'])) { 23 | throw new RelationshipForeignKeyNotSetException( 24 | "Foreign Key not set on relationship: $tableName" 25 | ); 26 | } 27 | 28 | if (! isset($options['columns'])) { 29 | throw new RelationshipColumnsNotFoundException( 30 | "Columns array not set on relationship: $tableName" 31 | ); 32 | } 33 | 34 | $model = $relationshipModelFactory($options['model'], $tableName); 35 | 36 | //Join the table so it can be orderBy 37 | $tableName = isset($options['alias']) ? $options['alias'] : $model->getTable(); 38 | 39 | $query = $query->leftJoin( 40 | $model->getTable() . " as " . $tableName, 41 | $localModel->getTable() . "." . $options['foreign_key'], 42 | '=', 43 | $tableName . "." . $model->getKeyName() 44 | ); 45 | } 46 | } 47 | 48 | return $query; 49 | } 50 | } -------------------------------------------------------------------------------- /src/Classes/Joins/JoinHasManyRelationships.php: -------------------------------------------------------------------------------- 1 | $options) { 15 | 16 | if (! isset($options['model'])) { 17 | throw new RelationshipModelNotSetException( 18 | "Model not set on relationship: $tableName" 19 | ); 20 | } 21 | 22 | if (! isset($options['columns'])) { 23 | throw new RelationshipColumnsNotFoundException( 24 | "Columns array not set on relationship: $tableName" 25 | ); 26 | } 27 | 28 | if (! isset($options['foreign_key'])) { 29 | throw new RelationshipForeignKeyNotSetException( 30 | "Foreign Key not set on relationship: $tableName" 31 | ); 32 | } 33 | 34 | $model = $relationshipModelFactory($options['model'], $tableName); 35 | 36 | $tableName = $model->getTable(); 37 | 38 | //Join the table so it can be orderBy 39 | $query = $query->leftJoin( 40 | "$tableName", 41 | "$tableName." . $options['foreign_key'], 42 | '=', 43 | $localModel->getTable() . "." . $localModel->getKeyName() 44 | ); 45 | } 46 | } 47 | 48 | return $query; 49 | } 50 | } -------------------------------------------------------------------------------- /src/Classes/Joins/JoinHasOneRelationships.php: -------------------------------------------------------------------------------- 1 | $options) { 15 | 16 | if (! isset($options['model'])) { 17 | throw new RelationshipModelNotSetException( 18 | "Model not set on relationship: $tableName" 19 | ); 20 | } 21 | 22 | if (! isset($options['foreign_key'])) { 23 | throw new RelationshipForeignKeyNotSetException( 24 | "Foreign Key not set on relationship: $tableName" 25 | ); 26 | } 27 | 28 | if (! isset($options['columns'])) { 29 | throw new RelationshipColumnsNotFoundException( 30 | "Columns array not set on relationship: $tableName" 31 | ); 32 | } 33 | 34 | $model = $relationshipModelFactory($options['model'], $tableName); 35 | 36 | //Join the table so it can be orderBy 37 | $query = $query->leftJoin( 38 | $model->getTable(), 39 | $localModel->getTable().".".$options['foreign_key'], 40 | '=', 41 | $model->getTable().".".$model->getKeyName() 42 | ); 43 | } 44 | } 45 | 46 | return $query; 47 | } 48 | } -------------------------------------------------------------------------------- /src/Classes/QueryBuilder.php: -------------------------------------------------------------------------------- 1 | model = $model; 39 | $this->query = $query; 40 | $this->localColumns = $localColumns; 41 | $this->relationships = $relationships; 42 | $this->relationshipModelFactory = new RelationshipModelFactory; 43 | 44 | return $this; 45 | } 46 | 47 | public function selectData($dataTableColumns = [], $dataTableRelationships = []) 48 | { 49 | //Select local data 50 | $columnKeys = $this->selectModelColumns(); 51 | $columnKeys = $this->selectLocalForeignKeysForJoining($columnKeys); 52 | 53 | $joinBelongsTo = new JoinBelongsToRelationships; 54 | $this->query = $joinBelongsTo($this->query, $this->model, $this->relationships, $this->relationshipModelFactory); 55 | 56 | $joinHasMany = new JoinHasManyRelationships; 57 | $this->query = $joinHasMany($this->query, $this->model, $this->relationships, $this->relationshipModelFactory); 58 | 59 | $joinBelongMany = new JoinBelongsToManyRelationships; 60 | $this->query = $joinBelongMany($this->query, $this->model, $this->relationships, $this->relationshipModelFactory); 61 | 62 | if (count($columnKeys)) { 63 | $this->query = $this->query->select($columnKeys); 64 | } 65 | 66 | $this->query->groupBy($this->model->getTable().".".$this->model->getKeyName()); 67 | 68 | return $this; 69 | } 70 | 71 | public function orderBy($orderBy, $orderByDir = "asc") 72 | { 73 | $orderByDir = isset($orderByDir) ? $orderByDir : 'asc'; 74 | 75 | if (isset($orderBy) && ! empty($orderBy)) { 76 | $defaultOrderBy = config('laravel-vue-datatables.models.order_term'); 77 | $tableAndColumn = count(explode(".", $orderBy)) > 1 ? $orderBy : $this->model->getTable().".$orderBy"; 78 | $this->query->orderBy($tableAndColumn, $orderByDir); 79 | } else { 80 | $defaultOrderBy = config('laravel-vue-datatables.default_order_by'); 81 | $defaultOrderBy = is_null($defaultOrderBy) ? 'id' : $defaultOrderBy; 82 | $this->query->orderBy($this->model->getTable().".$defaultOrderBy", $orderByDir); 83 | } 84 | 85 | return $this; 86 | } 87 | 88 | public function addRelationships($declaredRelationship, $orderByDir) 89 | { 90 | $getBelongsTo = new GetBelongsToRelationships; 91 | $with = $getBelongsTo($this->relationships, $declaredRelationship); 92 | 93 | $getHasMany = new GetHasManyRelationships; 94 | $with = $getHasMany($this->relationships, $declaredRelationship, $with); 95 | 96 | $getBelongsToMany = new GetBelongsToManyRelationships; 97 | $with = $getBelongsToMany($this->relationships, $declaredRelationship, $with, $orderByDir); 98 | 99 | if (count($with)) { 100 | $this->query->with($with); 101 | } 102 | 103 | return $this; 104 | } 105 | 106 | public function filter($searchValue) 107 | { 108 | if (isset($searchValue) && ! empty($searchValue)) { 109 | 110 | $filterLocalData = new FilterLocalData; 111 | $this->query = $filterLocalData($this->query, $searchValue, $this->model, $this->localColumns); 112 | 113 | $filterBelongsTo = new FilterBelongsToRelationships; 114 | $this->query = $filterBelongsTo($this->query, $searchValue, $this->relationshipModelFactory, $this->model, $this->relationships); 115 | 116 | $filterHasMany = new FilterHasManyRelationships; 117 | $this->query = $filterHasMany($this->query, $searchValue, $this->relationshipModelFactory, $this->model, $this->relationships); 118 | 119 | $filterBelongsToMany = new FilterBelongsToManyRelationships; 120 | $this->query = $filterBelongsToMany($this->query, $searchValue, $this->relationshipModelFactory, $this->model, $this->relationships); 121 | 122 | return $this; 123 | } 124 | 125 | return $this; 126 | } 127 | 128 | protected function selectModelColumns() 129 | { 130 | if (isset($this->localColumns) && ! empty($this->localColumns)) { 131 | 132 | $columnKeys = array_keys($this->localColumns); 133 | 134 | foreach ($columnKeys as $index => $key) { 135 | $defaultAs = config('laravel-vue-datatables.models.alias'); 136 | $as = isset($this->localColumns[$key][$defaultAs]) ? ' as ' . $this->localColumns[$key][$defaultAs] : ''; 137 | 138 | $columnKeys[$index] = $this->model->getTable().".$key" . $as; 139 | } 140 | 141 | return $columnKeys; 142 | } 143 | 144 | return []; 145 | } 146 | 147 | protected function selectLocalForeignKeysForJoining($columnKeys) 148 | { 149 | if (isset($this->relationships['belongsTo'])) { 150 | foreach ($this->relationships['belongsTo'] as $tableName => $options) { 151 | if (! isset($options['foreign_key'])) { 152 | throw new RelationshipForeignKeyNotSetException( 153 | "Foreign Key not set on relationship: $tableName" 154 | ); 155 | } 156 | 157 | $columnKeys[count($columnKeys) + 1] = $this->model->getTable().".".$options['foreign_key']; 158 | } 159 | } 160 | 161 | return $columnKeys; 162 | } 163 | 164 | public function getQuery() 165 | { 166 | return $this->query; 167 | } 168 | } 169 | -------------------------------------------------------------------------------- /src/Classes/Relationships/GetBelongsToManyRelationships.php: -------------------------------------------------------------------------------- 1 | $item) { 18 | if (! is_numeric($key) && in_array($key, $relationships)){ 19 | $with[$key] = $item; 20 | } 21 | } 22 | 23 | foreach ($declaredRelationship['belongsToMany'] as $tableName => $relationship) { 24 | 25 | foreach ($belongsToMany as $name) { 26 | if ($tableName === $name) { 27 | 28 | if (isset($relationship['order_by'])) { 29 | $orderBy = $relationship['order_by']; 30 | 31 | $with[$name] = function($q) use ($orderBy, $orderByDir) { 32 | $q->orderBy($orderBy, $orderByDir); 33 | }; 34 | } 35 | } 36 | } 37 | } 38 | 39 | return $with; 40 | } 41 | 42 | return $with; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/Classes/Relationships/GetBelongsToRelationships.php: -------------------------------------------------------------------------------- 1 | $item) { 18 | if (in_array($item, $relationships)) { 19 | $with[] = $item; 20 | } 21 | } 22 | 23 | return $with; 24 | } 25 | 26 | return $with; 27 | } 28 | } -------------------------------------------------------------------------------- /src/Classes/Relationships/GetHasManyRelationships.php: -------------------------------------------------------------------------------- 1 | $item) { 18 | if (in_array($item, $relationships)) { 19 | $with[] = $item; 20 | } 21 | } 22 | 23 | return $with; 24 | } 25 | 26 | return $with; 27 | } 28 | } -------------------------------------------------------------------------------- /src/Classes/Relationships/GetHasOneRelationships.php: -------------------------------------------------------------------------------- 1 | $item) { 18 | if (in_array($item, $relationships)) { 19 | $with[] = $item; 20 | } 21 | } 22 | 23 | return $with; 24 | } 25 | 26 | return $with; 27 | } 28 | } -------------------------------------------------------------------------------- /src/Contracts/ExceptionHandlerContract.php: -------------------------------------------------------------------------------- 1 | $this->collection, 19 | 'payload' => $request->all() 20 | ]; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Providers/LaravelVueDatatableServiceProvider.php: -------------------------------------------------------------------------------- 1 | publishes([ 27 | __DIR__.'/../../config/laravel-vue-datatables.php' => config_path('laravel-vue-datatables.php') 28 | ], 'config'); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Traits/LaravelVueDatatableTrait.php: -------------------------------------------------------------------------------- 1 | dataTableColumns, $this->dataTableRelationships); 12 | 13 | return $queryBuilder->selectData() 14 | ->addRelationships($relationships, $orderByDir) 15 | ->orderBy($orderBy, $orderByDir) 16 | ->filter($searchValue) 17 | ->getQuery(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /tests/Factories/RelationshipFactoryTest.php: -------------------------------------------------------------------------------- 1 |