├── .gitignore ├── .travis.yml ├── CHANGELOG.md ├── LICENSE.md ├── README.md ├── composer.json ├── composer.lock ├── src ├── Console │ ├── Commands │ │ └── MakeFilter.php │ └── Stubs │ │ ├── bound.stub │ │ └── filter.stub ├── Library │ ├── DateFilter.php │ ├── Decorators │ │ └── OsmoseDriver.php │ ├── Drivers │ │ ├── CallbackFilter.php │ │ ├── DirectFilter.php │ │ └── RelationshipFilter.php │ ├── OsmoseFilter.php │ └── Services │ │ ├── Contracts │ │ ├── OsmoseDriverInterface.php │ │ └── OsmoseFilterInterface.php │ │ ├── Facades │ │ └── Osmose.php │ │ ├── OsmoseFilterService.php │ │ └── Traits │ │ ├── OsmoseDatesTrait.php │ │ └── OsmoseDriverTrait.php ├── Providers │ └── OsmoseServiceProvider.php ├── config │ └── osmose.php └── functions.php └── tests └── DirectFilterTest.php /.gitignore: -------------------------------------------------------------------------------- 1 | /.idea 2 | /vendor 3 | 4 | /.DS_Store 5 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: php 2 | 3 | php: 4 | - 7.3 5 | 6 | before_script: 7 | - composer self-update 8 | - composer install --no-interaction 9 | 10 | script: 11 | - vendor/bin/phpunit tests/. 12 | 13 | cache: 14 | directories: 15 | - vendor 16 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Release Notes 2 | 3 | ## [v2.0.0 (29-10-2019)](https://github.com/franciskisiara/osmose/releases/tag/v2.0.0) 4 | 5 | ### Added 6 | - A column method on the filter class 7 | - A range method on the filter class 8 | - A limits method on the filter class 9 | 10 | ### Changed 11 | - `DEPRECATED` and removed the range property in favour of a range method defined in the filter class with a similar API 12 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) [2018] [Kisiara Francis](https://github.com/franciskisiara) 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. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Osmose Eloquent Filter 2 | 3 | [![Build Status](https://travis-ci.org/franciskisiara/osmose.svg?branch=master)](https://travis-ci.org/franciskisiara/osmose) 4 | [![Latest Stable Version](https://poser.pugx.org/agog/osmose/v/stable)](https://packagist.org/packages/agog/osmose) 5 | [![Total Downloads](https://poser.pugx.org/agog/osmose/downloads)](https://packagist.org/packages/agog/osmose) 6 | [![License](https://poser.pugx.org/agog/osmose/license)](https://packagist.org/packages/agog/osmose) 7 | 8 | An elegant way to filter your eloquent collections 9 | 10 | ## Getting Started 11 | To pull osmose in your project, use the command 12 | 13 | ``` 14 | composer require agog/osmose 15 | ``` 16 | 17 | ## Defining Osmose Filters 18 | Osmose provides an artisan command `make-filter` that accepts the name of the filter to be generated, which quickly scaffolds a filter class 19 | 20 | ``` 21 | php artisan osmose:make-filter CharacterFilter 22 | ``` 23 | A CharacterFilter.php file will be created in the `App\Http\Filters` namespace. 24 | 25 | ***NB: The Filters folder will be automatically created if it does not exist.*** 26 | 27 | A filter class extends the `Agog\Osmose\Library\OsmoseFilter` template and implements the `Agog\Osmose\Library\Services\Contracts\OsmoseFilterInterface` interface. 28 | 29 | It must define a residue method that returns an array defining the filtration rules 30 | 31 | ```php 32 | value pairs with the key representing the parameter passed as the request and the value represents the rule construct. 58 | 59 | Rules are defined based on the type of filter driver intended. Osmose presents three internal filter drivers 60 | 61 | 1. Agog\Osmose\Library\Drivers\DirectFilter 62 | 2. Agog\Osmose\Library\Drivers\CallbackFilter 63 | 3. Agog\Osmose\Library\Drivers\RelationshipFilter 64 | 65 | In our business logic, we call Osmose's sieve method on the filter object and pass the eloquent class that we intend to filter 66 | The sieve method will return Eloquent's builder. 67 | 68 | `CharacterController.php`
69 | ```php 70 | public function index (CharacterFilter $filter) 71 | { 72 | $characters = $filter->sieve(Character::class)->get(); 73 | } 74 | ``` 75 | 76 | ---------- 77 | 78 | Consider the following tables and their related eloquent models 79 | 80 | `Character.php`
81 | 82 | | id | name | gender | 83 | |------|-------------|---------| 84 | | 1 | Baraka | male | 85 | | 2 | Cassie Cage | female | 86 | | 3 | D'Vorah | female | 87 | | 4 | Geras | male | 88 | | 5 | Cetrion | female | 89 | 90 | ---------- 91 | 92 | `Role.php`
93 | 94 | | id | name | 95 | |------|-------------| 96 | | 1 | hero | 97 | | 2 | villain | 98 | | 3 | god | 99 | 100 | ---------- 101 | 102 | `CharacterRole.php`
103 | 104 | | id | character_id | role_id | 105 | |------|----------------|---------| 106 | | 1 | 1 | 2 | 107 | | 2 | 2 | 1 | 108 | | 3 | 3 | 2 | 109 | | 4 | 4 | 2 | 110 | | 5 | 4 | 3 | 111 | | 6 | 5 | 3 | 112 | 113 | ---------- 114 | 115 | ### DirectFilter 116 | 117 | To use the DirectFilter driver, we define the rule, prefixed with the word 'column' 118 | 119 | ```php 120 | public function residue () : array 121 | { 122 | return [ 123 | 'character_id' => 'column:id' 124 | ] 125 | } 126 | ``` 127 | 128 | Osmose will then look for the key 'character_id' within the request object and only return the result whose id matches the value passed 129 | 130 | /characters?character_id=1 131 | Will return the character record with an id of '1' 132 | 133 |
134 | 135 | ### RelationshipFilter 136 | 137 | To use the RelationshipFilter driver, we define the rule, prefixed with the word 'relationship', giving the name of the relationship and the column that should be checked in the related table 138 | 139 | ```php 140 | public function residue () : array 141 | { 142 | return [ 143 | 'role' => 'relationship:roles,name' 144 | ] 145 | } 146 | ``` 147 | ***NB: It is assumed a roles (belongsToMany) relationship exists in the Character model.*** 148 | 149 | Osmose will then look for the key 'role' within the request object and only return the result based on the rule definition 150 | 151 | /characters?role=god 152 | Will return all characters with the role of 'god' 153 | 154 |
155 | 156 | ### CallbackFilter 157 | 158 | To use the CallbackFilter driver, we pass a callback that takes in the query builder and the value of the request as arguments. The callback must return the result of the builder 159 | 160 | ```php 161 | public function residue () : array 162 | { 163 | return [ 164 | 'gender' => function ($query, $value) { 165 | 166 | return $query->where('gender', $value); 167 | 168 | } 169 | ] 170 | } 171 | ``` 172 | 173 | Osmose will then look for the key 'gender' within the request object and only return results based on the callback 174 | 175 | /characters?gender=male 176 | Will return all male characters 177 | 178 |
179 | 180 | ## Filtering Dates 181 | 182 | As of version 2.0.0, osmose has introduced three new methods to assist in date filtering. These methods are; 183 | 184 | ```php 185 | public function column () : string 186 | { 187 | return 'created_at'; 188 | } 189 | 190 | public function range () 191 | { 192 | return 'range'; 193 | } 194 | 195 | public function limits () : array 196 | { 197 | return [ 198 | 'from' => 'from', 199 | 'to' => 'to' 200 | ]; 201 | } 202 | ``` 203 | 204 | ## The column() method 205 | 206 | The `column()` method returns a string indicating the column to be filtered once the sieve method on the filter class is executed. It defaults to the `created_at` column. Simply override the method in your filter class, returning your desired column. 207 | 208 | ## The range() method 209 | 210 | *To use this feature, you must publish osmose's configuration file by running;* 211 | 212 | This method replaces the `range` property that was available in previous versions. It has a similar API, in which it returns the query parameter to be examined against, given predefined ranges within osmose's configuration file. Override the method to return an appropriate range string. 213 | 214 | If the defined range does not exist within the GET parameters, then osmose will not execute the range functionality. 215 | 216 | ## The limits() method 217 | 218 | The limits method refines date filtering within osmose by allowing one to configure request options. This methods returns an array with two keys `from` and `to` which indicate the request parameters. 219 | 220 | ## The bound() method 221 | 222 | Version 2.0.0 of osmose introduces the `bound()` method. This method, like the residue method returns an array of rule definitions. Rules defined in this method are *ALWAYS* executed and do not rely on a query parameter being passed in the url. As such, these rules are not defined as key => value pairs but simply as values in the array. 223 | 224 | ***NB: Only the direct and callback filters are currently supported.*** 225 | 226 | Values in the `bound()` method must be explicitly passed when defining the rules. Therefore, the CallbackFilter driver takes only one argument i.e the query builder. 227 | 228 | ```php 229 | public function bound () : array 230 | { 231 | return [ 232 | 'column:id,1,2,3,4', // will always return records with the IDs defined whenever the route is visited, 233 | function ($query) { 234 | return $query->orWhere('id', 5); // adds record where id=5 235 | } 236 | ]; 237 | } 238 | ``` 239 | 240 | You can automatically create the bound method by passing the bound option when creating an osmose filter. 241 | 242 | `php artisan osmose:make-filter ExampleFilter --bound` or `php artisan osmose:make-filter ExampleFilter -b` 243 | 244 | ## The Global Osmose Function 245 | 246 | Version 1.2.0 introduces a global function, `osmose()`, that can automatically detect a model class from the filter. 247 | 248 | *To use this feature, you must publish osmose's configuration file by running;* 249 | 250 | ``` 251 | php artisan vendor:publish --provider="Agog\Osmose\Providers\OsmoseServiceProvider" 252 | ``` 253 | 254 | To automatically detect models, the convention `${ModelName}Filter` should be followed when creating filters 255 | For example, a filter named **CharacterFilter** will look for and automatically load a model called **Character**. 256 | 257 | By default, osmose looks for models within the App namespace but this can be configured by changing the namespace's keyfrom within osmose's configuration file. 258 | 259 | The `osmose()` function receives the filter's fully qualified class name and an optional model name. 260 | 261 | It returns Eloquent's builder just like the sieve() method. 262 | 263 | ```php 264 | public function index () 265 | { 266 | $characters = osmose(CharacterFilter::class)->get(); 267 | } 268 | ``` 269 | 270 | if the model name completely differs from the filter or if there isn't a single namespace under which models reside. e.g in a micro service architecture, then you can pass the model's fully qualified name as a second argument to the osmose function. 271 | 272 | ```php 273 | public function index () 274 | { 275 | $characters = osmose(UserSieve::class, Character::class)->get(); 276 | } 277 | ``` 278 | 279 | ## Feature Requests 280 | 281 | If you have any feature requests, security vulnerabilities or just a good ol' thumbs up, dont hesitate to drop an email at [franciskisiara@gmail.com](mailto:franciskisiara@gmail.com) 282 | 283 | ## Inspiration 284 | 285 | This project was inspired by laravel's request validation. The name *osmose* comes from the biological word osmosis and how particles are able to *filter* through semi-permeable membranes. :) 286 | 287 | ## Osmose Authors 288 | ### Kisiara Francis 289 | - [Github](https://github.com/franciskisiara/) 290 | - [Medium](https://medium.com/@franciskisiara) 291 | - [LinkedIn](https://www.linkedin.com/in/francis-kisiara-289360ab/) 292 | 293 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "agog/osmose", 3 | "description": "Elegant filtering for laravel's eloquent models", 4 | "keywords": [ 5 | "eloquent", 6 | "laravel", 7 | "filter", 8 | "query" 9 | ], 10 | "license": "MIT", 11 | "authors": [ 12 | { 13 | "name": "Francis Kisiara", 14 | "email": "franciskisiara@gmail.com", 15 | "homepage": "https://profiles.agog.co.ke/kisiara", 16 | "role": "Software Engineer" 17 | } 18 | ], 19 | "minimum-stability": "dev", 20 | "require": {}, 21 | "require-dev": { 22 | "phpunit/phpunit": "^9.0@dev" 23 | }, 24 | "version": "3.0.0", 25 | "autoload": { 26 | "psr-4": { 27 | "Agog\\Osmose\\": "src/" 28 | }, 29 | "files": [ 30 | "src/functions.php" 31 | ] 32 | }, 33 | "autoload-dev": { 34 | "psr-4": { 35 | "Agog\\Osmose\\Tests\\": "tests/" 36 | } 37 | }, 38 | "extra": { 39 | "laravel": { 40 | "providers": [ 41 | "Agog\\Osmose\\Providers\\OsmoseServiceProvider" 42 | ], 43 | "aliases": { 44 | "Residue": "Agog\\Osmose\\Library\\Services\\Facades\\Residue" 45 | } 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /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": "134585f276d0b211649b5143a5afce4c", 8 | "packages": [], 9 | "packages-dev": [ 10 | { 11 | "name": "doctrine/instantiator", 12 | "version": "2.0.x-dev", 13 | "source": { 14 | "type": "git", 15 | "url": "https://github.com/doctrine/instantiator.git", 16 | "reference": "be6a7e86c74841eac964ae16853e4036a6a319d0" 17 | }, 18 | "dist": { 19 | "type": "zip", 20 | "url": "https://api.github.com/repos/doctrine/instantiator/zipball/be6a7e86c74841eac964ae16853e4036a6a319d0", 21 | "reference": "be6a7e86c74841eac964ae16853e4036a6a319d0", 22 | "shasum": "" 23 | }, 24 | "require": { 25 | "php": "^8.1" 26 | }, 27 | "require-dev": { 28 | "doctrine/coding-standard": "^12", 29 | "ext-pdo": "*", 30 | "ext-phar": "*", 31 | "phpbench/phpbench": "^1.2", 32 | "phpstan/phpstan": "^1.9.4", 33 | "phpstan/phpstan-phpunit": "^1.3", 34 | "phpunit/phpunit": "^10.5", 35 | "vimeo/psalm": "^5.4" 36 | }, 37 | "default-branch": true, 38 | "type": "library", 39 | "autoload": { 40 | "psr-4": { 41 | "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" 42 | } 43 | }, 44 | "notification-url": "https://packagist.org/downloads/", 45 | "license": [ 46 | "MIT" 47 | ], 48 | "authors": [ 49 | { 50 | "name": "Marco Pivetta", 51 | "email": "ocramius@gmail.com", 52 | "homepage": "https://ocramius.github.io/" 53 | } 54 | ], 55 | "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", 56 | "homepage": "https://www.doctrine-project.org/projects/instantiator.html", 57 | "keywords": [ 58 | "constructor", 59 | "instantiate" 60 | ], 61 | "support": { 62 | "issues": "https://github.com/doctrine/instantiator/issues", 63 | "source": "https://github.com/doctrine/instantiator/tree/2.0.x" 64 | }, 65 | "funding": [ 66 | { 67 | "url": "https://www.doctrine-project.org/sponsorship.html", 68 | "type": "custom" 69 | }, 70 | { 71 | "url": "https://www.patreon.com/phpdoctrine", 72 | "type": "patreon" 73 | }, 74 | { 75 | "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator", 76 | "type": "tidelift" 77 | } 78 | ], 79 | "time": "2024-10-16T22:06:28+00:00" 80 | }, 81 | { 82 | "name": "myclabs/deep-copy", 83 | "version": "1.x-dev", 84 | "source": { 85 | "type": "git", 86 | "url": "https://github.com/myclabs/DeepCopy.git", 87 | "reference": "3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c" 88 | }, 89 | "dist": { 90 | "type": "zip", 91 | "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c", 92 | "reference": "3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c", 93 | "shasum": "" 94 | }, 95 | "require": { 96 | "php": "^7.1 || ^8.0" 97 | }, 98 | "conflict": { 99 | "doctrine/collections": "<1.6.8", 100 | "doctrine/common": "<2.13.3 || >=3 <3.2.2" 101 | }, 102 | "require-dev": { 103 | "doctrine/collections": "^1.6.8", 104 | "doctrine/common": "^2.13.3 || ^3.2.2", 105 | "phpspec/prophecy": "^1.10", 106 | "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" 107 | }, 108 | "default-branch": true, 109 | "type": "library", 110 | "autoload": { 111 | "files": [ 112 | "src/DeepCopy/deep_copy.php" 113 | ], 114 | "psr-4": { 115 | "DeepCopy\\": "src/DeepCopy/" 116 | } 117 | }, 118 | "notification-url": "https://packagist.org/downloads/", 119 | "license": [ 120 | "MIT" 121 | ], 122 | "description": "Create deep copies (clones) of your objects", 123 | "keywords": [ 124 | "clone", 125 | "copy", 126 | "duplicate", 127 | "object", 128 | "object graph" 129 | ], 130 | "support": { 131 | "issues": "https://github.com/myclabs/DeepCopy/issues", 132 | "source": "https://github.com/myclabs/DeepCopy/tree/1.12.0" 133 | }, 134 | "funding": [ 135 | { 136 | "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", 137 | "type": "tidelift" 138 | } 139 | ], 140 | "time": "2024-06-12T14:39:25+00:00" 141 | }, 142 | { 143 | "name": "nikic/php-parser", 144 | "version": "v5.3.1", 145 | "source": { 146 | "type": "git", 147 | "url": "https://github.com/nikic/PHP-Parser.git", 148 | "reference": "8eea230464783aa9671db8eea6f8c6ac5285794b" 149 | }, 150 | "dist": { 151 | "type": "zip", 152 | "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/8eea230464783aa9671db8eea6f8c6ac5285794b", 153 | "reference": "8eea230464783aa9671db8eea6f8c6ac5285794b", 154 | "shasum": "" 155 | }, 156 | "require": { 157 | "ext-ctype": "*", 158 | "ext-json": "*", 159 | "ext-tokenizer": "*", 160 | "php": ">=7.4" 161 | }, 162 | "require-dev": { 163 | "ircmaxell/php-yacc": "^0.0.7", 164 | "phpunit/phpunit": "^9.0" 165 | }, 166 | "bin": [ 167 | "bin/php-parse" 168 | ], 169 | "type": "library", 170 | "extra": { 171 | "branch-alias": { 172 | "dev-master": "5.0-dev" 173 | } 174 | }, 175 | "autoload": { 176 | "psr-4": { 177 | "PhpParser\\": "lib/PhpParser" 178 | } 179 | }, 180 | "notification-url": "https://packagist.org/downloads/", 181 | "license": [ 182 | "BSD-3-Clause" 183 | ], 184 | "authors": [ 185 | { 186 | "name": "Nikita Popov" 187 | } 188 | ], 189 | "description": "A PHP parser written in PHP", 190 | "keywords": [ 191 | "parser", 192 | "php" 193 | ], 194 | "support": { 195 | "issues": "https://github.com/nikic/PHP-Parser/issues", 196 | "source": "https://github.com/nikic/PHP-Parser/tree/v5.3.1" 197 | }, 198 | "time": "2024-10-08T18:51:32+00:00" 199 | }, 200 | { 201 | "name": "phar-io/manifest", 202 | "version": "dev-master", 203 | "source": { 204 | "type": "git", 205 | "url": "https://github.com/phar-io/manifest.git", 206 | "reference": "54750ef60c58e43759730615a392c31c80e23176" 207 | }, 208 | "dist": { 209 | "type": "zip", 210 | "url": "https://api.github.com/repos/phar-io/manifest/zipball/54750ef60c58e43759730615a392c31c80e23176", 211 | "reference": "54750ef60c58e43759730615a392c31c80e23176", 212 | "shasum": "" 213 | }, 214 | "require": { 215 | "ext-dom": "*", 216 | "ext-libxml": "*", 217 | "ext-phar": "*", 218 | "ext-xmlwriter": "*", 219 | "phar-io/version": "^3.0.1", 220 | "php": "^7.2 || ^8.0" 221 | }, 222 | "default-branch": true, 223 | "type": "library", 224 | "extra": { 225 | "branch-alias": { 226 | "dev-master": "2.0.x-dev" 227 | } 228 | }, 229 | "autoload": { 230 | "classmap": [ 231 | "src/" 232 | ] 233 | }, 234 | "notification-url": "https://packagist.org/downloads/", 235 | "license": [ 236 | "BSD-3-Clause" 237 | ], 238 | "authors": [ 239 | { 240 | "name": "Arne Blankerts", 241 | "email": "arne@blankerts.de", 242 | "role": "Developer" 243 | }, 244 | { 245 | "name": "Sebastian Heuer", 246 | "email": "sebastian@phpeople.de", 247 | "role": "Developer" 248 | }, 249 | { 250 | "name": "Sebastian Bergmann", 251 | "email": "sebastian@phpunit.de", 252 | "role": "Developer" 253 | } 254 | ], 255 | "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", 256 | "support": { 257 | "issues": "https://github.com/phar-io/manifest/issues", 258 | "source": "https://github.com/phar-io/manifest/tree/2.0.4" 259 | }, 260 | "funding": [ 261 | { 262 | "url": "https://github.com/theseer", 263 | "type": "github" 264 | } 265 | ], 266 | "time": "2024-03-03T12:33:53+00:00" 267 | }, 268 | { 269 | "name": "phar-io/version", 270 | "version": "3.2.1", 271 | "source": { 272 | "type": "git", 273 | "url": "https://github.com/phar-io/version.git", 274 | "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74" 275 | }, 276 | "dist": { 277 | "type": "zip", 278 | "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74", 279 | "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74", 280 | "shasum": "" 281 | }, 282 | "require": { 283 | "php": "^7.2 || ^8.0" 284 | }, 285 | "type": "library", 286 | "autoload": { 287 | "classmap": [ 288 | "src/" 289 | ] 290 | }, 291 | "notification-url": "https://packagist.org/downloads/", 292 | "license": [ 293 | "BSD-3-Clause" 294 | ], 295 | "authors": [ 296 | { 297 | "name": "Arne Blankerts", 298 | "email": "arne@blankerts.de", 299 | "role": "Developer" 300 | }, 301 | { 302 | "name": "Sebastian Heuer", 303 | "email": "sebastian@phpeople.de", 304 | "role": "Developer" 305 | }, 306 | { 307 | "name": "Sebastian Bergmann", 308 | "email": "sebastian@phpunit.de", 309 | "role": "Developer" 310 | } 311 | ], 312 | "description": "Library for handling version information and constraints", 313 | "support": { 314 | "issues": "https://github.com/phar-io/version/issues", 315 | "source": "https://github.com/phar-io/version/tree/3.2.1" 316 | }, 317 | "time": "2022-02-21T01:04:05+00:00" 318 | }, 319 | { 320 | "name": "phpunit/php-code-coverage", 321 | "version": "9.2.x-dev", 322 | "source": { 323 | "type": "git", 324 | "url": "https://github.com/sebastianbergmann/php-code-coverage.git", 325 | "reference": "85402a822d1ecf1db1096959413d35e1c37cf1a5" 326 | }, 327 | "dist": { 328 | "type": "zip", 329 | "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/85402a822d1ecf1db1096959413d35e1c37cf1a5", 330 | "reference": "85402a822d1ecf1db1096959413d35e1c37cf1a5", 331 | "shasum": "" 332 | }, 333 | "require": { 334 | "ext-dom": "*", 335 | "ext-libxml": "*", 336 | "ext-xmlwriter": "*", 337 | "nikic/php-parser": "^4.19.1 || ^5.1.0", 338 | "php": ">=7.3", 339 | "phpunit/php-file-iterator": "^3.0.6", 340 | "phpunit/php-text-template": "^2.0.4", 341 | "sebastian/code-unit-reverse-lookup": "^2.0.3", 342 | "sebastian/complexity": "^2.0.3", 343 | "sebastian/environment": "^5.1.5", 344 | "sebastian/lines-of-code": "^1.0.4", 345 | "sebastian/version": "^3.0.2", 346 | "theseer/tokenizer": "^1.2.3" 347 | }, 348 | "require-dev": { 349 | "phpunit/phpunit": "^9.6" 350 | }, 351 | "suggest": { 352 | "ext-pcov": "PHP extension that provides line coverage", 353 | "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" 354 | }, 355 | "type": "library", 356 | "extra": { 357 | "branch-alias": { 358 | "dev-main": "9.2.x-dev" 359 | } 360 | }, 361 | "autoload": { 362 | "classmap": [ 363 | "src/" 364 | ] 365 | }, 366 | "notification-url": "https://packagist.org/downloads/", 367 | "license": [ 368 | "BSD-3-Clause" 369 | ], 370 | "authors": [ 371 | { 372 | "name": "Sebastian Bergmann", 373 | "email": "sebastian@phpunit.de", 374 | "role": "lead" 375 | } 376 | ], 377 | "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", 378 | "homepage": "https://github.com/sebastianbergmann/php-code-coverage", 379 | "keywords": [ 380 | "coverage", 381 | "testing", 382 | "xunit" 383 | ], 384 | "support": { 385 | "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", 386 | "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", 387 | "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.32" 388 | }, 389 | "funding": [ 390 | { 391 | "url": "https://github.com/sebastianbergmann", 392 | "type": "github" 393 | } 394 | ], 395 | "time": "2024-08-22T04:23:01+00:00" 396 | }, 397 | { 398 | "name": "phpunit/php-file-iterator", 399 | "version": "3.0.x-dev", 400 | "source": { 401 | "type": "git", 402 | "url": "https://github.com/sebastianbergmann/php-file-iterator.git", 403 | "reference": "38b24367e1b340aa78b96d7cab042942d917bb84" 404 | }, 405 | "dist": { 406 | "type": "zip", 407 | "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/38b24367e1b340aa78b96d7cab042942d917bb84", 408 | "reference": "38b24367e1b340aa78b96d7cab042942d917bb84", 409 | "shasum": "" 410 | }, 411 | "require": { 412 | "php": ">=7.3" 413 | }, 414 | "require-dev": { 415 | "phpunit/phpunit": "^9.3" 416 | }, 417 | "type": "library", 418 | "extra": { 419 | "branch-alias": { 420 | "dev-master": "3.0-dev" 421 | } 422 | }, 423 | "autoload": { 424 | "classmap": [ 425 | "src/" 426 | ] 427 | }, 428 | "notification-url": "https://packagist.org/downloads/", 429 | "license": [ 430 | "BSD-3-Clause" 431 | ], 432 | "authors": [ 433 | { 434 | "name": "Sebastian Bergmann", 435 | "email": "sebastian@phpunit.de", 436 | "role": "lead" 437 | } 438 | ], 439 | "description": "FilterIterator implementation that filters files based on a list of suffixes.", 440 | "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", 441 | "keywords": [ 442 | "filesystem", 443 | "iterator" 444 | ], 445 | "support": { 446 | "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", 447 | "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0" 448 | }, 449 | "funding": [ 450 | { 451 | "url": "https://github.com/sebastianbergmann", 452 | "type": "github" 453 | } 454 | ], 455 | "time": "2022-02-11T16:23:04+00:00" 456 | }, 457 | { 458 | "name": "phpunit/php-invoker", 459 | "version": "3.1.1", 460 | "source": { 461 | "type": "git", 462 | "url": "https://github.com/sebastianbergmann/php-invoker.git", 463 | "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67" 464 | }, 465 | "dist": { 466 | "type": "zip", 467 | "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/5a10147d0aaf65b58940a0b72f71c9ac0423cc67", 468 | "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67", 469 | "shasum": "" 470 | }, 471 | "require": { 472 | "php": ">=7.3" 473 | }, 474 | "require-dev": { 475 | "ext-pcntl": "*", 476 | "phpunit/phpunit": "^9.3" 477 | }, 478 | "suggest": { 479 | "ext-pcntl": "*" 480 | }, 481 | "type": "library", 482 | "extra": { 483 | "branch-alias": { 484 | "dev-master": "3.1-dev" 485 | } 486 | }, 487 | "autoload": { 488 | "classmap": [ 489 | "src/" 490 | ] 491 | }, 492 | "notification-url": "https://packagist.org/downloads/", 493 | "license": [ 494 | "BSD-3-Clause" 495 | ], 496 | "authors": [ 497 | { 498 | "name": "Sebastian Bergmann", 499 | "email": "sebastian@phpunit.de", 500 | "role": "lead" 501 | } 502 | ], 503 | "description": "Invoke callables with a timeout", 504 | "homepage": "https://github.com/sebastianbergmann/php-invoker/", 505 | "keywords": [ 506 | "process" 507 | ], 508 | "support": { 509 | "issues": "https://github.com/sebastianbergmann/php-invoker/issues", 510 | "source": "https://github.com/sebastianbergmann/php-invoker/tree/3.1.1" 511 | }, 512 | "funding": [ 513 | { 514 | "url": "https://github.com/sebastianbergmann", 515 | "type": "github" 516 | } 517 | ], 518 | "time": "2020-09-28T05:58:55+00:00" 519 | }, 520 | { 521 | "name": "phpunit/php-text-template", 522 | "version": "2.0.4", 523 | "source": { 524 | "type": "git", 525 | "url": "https://github.com/sebastianbergmann/php-text-template.git", 526 | "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28" 527 | }, 528 | "dist": { 529 | "type": "zip", 530 | "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", 531 | "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", 532 | "shasum": "" 533 | }, 534 | "require": { 535 | "php": ">=7.3" 536 | }, 537 | "require-dev": { 538 | "phpunit/phpunit": "^9.3" 539 | }, 540 | "type": "library", 541 | "extra": { 542 | "branch-alias": { 543 | "dev-master": "2.0-dev" 544 | } 545 | }, 546 | "autoload": { 547 | "classmap": [ 548 | "src/" 549 | ] 550 | }, 551 | "notification-url": "https://packagist.org/downloads/", 552 | "license": [ 553 | "BSD-3-Clause" 554 | ], 555 | "authors": [ 556 | { 557 | "name": "Sebastian Bergmann", 558 | "email": "sebastian@phpunit.de", 559 | "role": "lead" 560 | } 561 | ], 562 | "description": "Simple template engine.", 563 | "homepage": "https://github.com/sebastianbergmann/php-text-template/", 564 | "keywords": [ 565 | "template" 566 | ], 567 | "support": { 568 | "issues": "https://github.com/sebastianbergmann/php-text-template/issues", 569 | "source": "https://github.com/sebastianbergmann/php-text-template/tree/2.0.4" 570 | }, 571 | "funding": [ 572 | { 573 | "url": "https://github.com/sebastianbergmann", 574 | "type": "github" 575 | } 576 | ], 577 | "time": "2020-10-26T05:33:50+00:00" 578 | }, 579 | { 580 | "name": "phpunit/php-timer", 581 | "version": "5.0.3", 582 | "source": { 583 | "type": "git", 584 | "url": "https://github.com/sebastianbergmann/php-timer.git", 585 | "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2" 586 | }, 587 | "dist": { 588 | "type": "zip", 589 | "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", 590 | "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", 591 | "shasum": "" 592 | }, 593 | "require": { 594 | "php": ">=7.3" 595 | }, 596 | "require-dev": { 597 | "phpunit/phpunit": "^9.3" 598 | }, 599 | "type": "library", 600 | "extra": { 601 | "branch-alias": { 602 | "dev-master": "5.0-dev" 603 | } 604 | }, 605 | "autoload": { 606 | "classmap": [ 607 | "src/" 608 | ] 609 | }, 610 | "notification-url": "https://packagist.org/downloads/", 611 | "license": [ 612 | "BSD-3-Clause" 613 | ], 614 | "authors": [ 615 | { 616 | "name": "Sebastian Bergmann", 617 | "email": "sebastian@phpunit.de", 618 | "role": "lead" 619 | } 620 | ], 621 | "description": "Utility class for timing", 622 | "homepage": "https://github.com/sebastianbergmann/php-timer/", 623 | "keywords": [ 624 | "timer" 625 | ], 626 | "support": { 627 | "issues": "https://github.com/sebastianbergmann/php-timer/issues", 628 | "source": "https://github.com/sebastianbergmann/php-timer/tree/5.0.3" 629 | }, 630 | "funding": [ 631 | { 632 | "url": "https://github.com/sebastianbergmann", 633 | "type": "github" 634 | } 635 | ], 636 | "time": "2020-10-26T13:16:10+00:00" 637 | }, 638 | { 639 | "name": "phpunit/phpunit", 640 | "version": "9.6.x-dev", 641 | "source": { 642 | "type": "git", 643 | "url": "https://github.com/sebastianbergmann/phpunit.git", 644 | "reference": "fcd1efebc9510d2e1cff8fcf1b13ad2a7827d675" 645 | }, 646 | "dist": { 647 | "type": "zip", 648 | "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/fcd1efebc9510d2e1cff8fcf1b13ad2a7827d675", 649 | "reference": "fcd1efebc9510d2e1cff8fcf1b13ad2a7827d675", 650 | "shasum": "" 651 | }, 652 | "require": { 653 | "doctrine/instantiator": "^1.5.0 || ^2", 654 | "ext-dom": "*", 655 | "ext-json": "*", 656 | "ext-libxml": "*", 657 | "ext-mbstring": "*", 658 | "ext-xml": "*", 659 | "ext-xmlwriter": "*", 660 | "myclabs/deep-copy": "^1.12.0", 661 | "phar-io/manifest": "^2.0.4", 662 | "phar-io/version": "^3.2.1", 663 | "php": ">=7.3", 664 | "phpunit/php-code-coverage": "^9.2.32", 665 | "phpunit/php-file-iterator": "^3.0.6", 666 | "phpunit/php-invoker": "^3.1.1", 667 | "phpunit/php-text-template": "^2.0.4", 668 | "phpunit/php-timer": "^5.0.3", 669 | "sebastian/cli-parser": "^1.0.2", 670 | "sebastian/code-unit": "^1.0.8", 671 | "sebastian/comparator": "^4.0.8", 672 | "sebastian/diff": "^4.0.6", 673 | "sebastian/environment": "^5.1.5", 674 | "sebastian/exporter": "^4.0.6", 675 | "sebastian/global-state": "^5.0.7", 676 | "sebastian/object-enumerator": "^4.0.4", 677 | "sebastian/resource-operations": "^3.0.4", 678 | "sebastian/type": "^3.2.1", 679 | "sebastian/version": "^3.0.2" 680 | }, 681 | "suggest": { 682 | "ext-soap": "To be able to generate mocks based on WSDL files", 683 | "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" 684 | }, 685 | "bin": [ 686 | "phpunit" 687 | ], 688 | "type": "library", 689 | "extra": { 690 | "branch-alias": { 691 | "dev-master": "9.6-dev" 692 | } 693 | }, 694 | "autoload": { 695 | "files": [ 696 | "src/Framework/Assert/Functions.php" 697 | ], 698 | "classmap": [ 699 | "src/" 700 | ] 701 | }, 702 | "notification-url": "https://packagist.org/downloads/", 703 | "license": [ 704 | "BSD-3-Clause" 705 | ], 706 | "authors": [ 707 | { 708 | "name": "Sebastian Bergmann", 709 | "email": "sebastian@phpunit.de", 710 | "role": "lead" 711 | } 712 | ], 713 | "description": "The PHP Unit Testing framework.", 714 | "homepage": "https://phpunit.de/", 715 | "keywords": [ 716 | "phpunit", 717 | "testing", 718 | "xunit" 719 | ], 720 | "support": { 721 | "issues": "https://github.com/sebastianbergmann/phpunit/issues", 722 | "security": "https://github.com/sebastianbergmann/phpunit/security/policy", 723 | "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6" 724 | }, 725 | "funding": [ 726 | { 727 | "url": "https://phpunit.de/sponsors.html", 728 | "type": "custom" 729 | }, 730 | { 731 | "url": "https://github.com/sebastianbergmann", 732 | "type": "github" 733 | }, 734 | { 735 | "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit", 736 | "type": "tidelift" 737 | } 738 | ], 739 | "time": "2024-10-19T09:36:22+00:00" 740 | }, 741 | { 742 | "name": "sebastian/cli-parser", 743 | "version": "1.0.x-dev", 744 | "source": { 745 | "type": "git", 746 | "url": "https://github.com/sebastianbergmann/cli-parser.git", 747 | "reference": "2b56bea83a09de3ac06bb18b92f068e60cc6f50b" 748 | }, 749 | "dist": { 750 | "type": "zip", 751 | "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/2b56bea83a09de3ac06bb18b92f068e60cc6f50b", 752 | "reference": "2b56bea83a09de3ac06bb18b92f068e60cc6f50b", 753 | "shasum": "" 754 | }, 755 | "require": { 756 | "php": ">=7.3" 757 | }, 758 | "require-dev": { 759 | "phpunit/phpunit": "^9.3" 760 | }, 761 | "type": "library", 762 | "extra": { 763 | "branch-alias": { 764 | "dev-master": "1.0-dev" 765 | } 766 | }, 767 | "autoload": { 768 | "classmap": [ 769 | "src/" 770 | ] 771 | }, 772 | "notification-url": "https://packagist.org/downloads/", 773 | "license": [ 774 | "BSD-3-Clause" 775 | ], 776 | "authors": [ 777 | { 778 | "name": "Sebastian Bergmann", 779 | "email": "sebastian@phpunit.de", 780 | "role": "lead" 781 | } 782 | ], 783 | "description": "Library for parsing CLI options", 784 | "homepage": "https://github.com/sebastianbergmann/cli-parser", 785 | "support": { 786 | "issues": "https://github.com/sebastianbergmann/cli-parser/issues", 787 | "source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.2" 788 | }, 789 | "funding": [ 790 | { 791 | "url": "https://github.com/sebastianbergmann", 792 | "type": "github" 793 | } 794 | ], 795 | "time": "2024-03-02T06:27:43+00:00" 796 | }, 797 | { 798 | "name": "sebastian/code-unit", 799 | "version": "1.0.8", 800 | "source": { 801 | "type": "git", 802 | "url": "https://github.com/sebastianbergmann/code-unit.git", 803 | "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120" 804 | }, 805 | "dist": { 806 | "type": "zip", 807 | "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/1fc9f64c0927627ef78ba436c9b17d967e68e120", 808 | "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120", 809 | "shasum": "" 810 | }, 811 | "require": { 812 | "php": ">=7.3" 813 | }, 814 | "require-dev": { 815 | "phpunit/phpunit": "^9.3" 816 | }, 817 | "type": "library", 818 | "extra": { 819 | "branch-alias": { 820 | "dev-master": "1.0-dev" 821 | } 822 | }, 823 | "autoload": { 824 | "classmap": [ 825 | "src/" 826 | ] 827 | }, 828 | "notification-url": "https://packagist.org/downloads/", 829 | "license": [ 830 | "BSD-3-Clause" 831 | ], 832 | "authors": [ 833 | { 834 | "name": "Sebastian Bergmann", 835 | "email": "sebastian@phpunit.de", 836 | "role": "lead" 837 | } 838 | ], 839 | "description": "Collection of value objects that represent the PHP code units", 840 | "homepage": "https://github.com/sebastianbergmann/code-unit", 841 | "support": { 842 | "issues": "https://github.com/sebastianbergmann/code-unit/issues", 843 | "source": "https://github.com/sebastianbergmann/code-unit/tree/1.0.8" 844 | }, 845 | "funding": [ 846 | { 847 | "url": "https://github.com/sebastianbergmann", 848 | "type": "github" 849 | } 850 | ], 851 | "time": "2020-10-26T13:08:54+00:00" 852 | }, 853 | { 854 | "name": "sebastian/code-unit-reverse-lookup", 855 | "version": "2.0.3", 856 | "source": { 857 | "type": "git", 858 | "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", 859 | "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5" 860 | }, 861 | "dist": { 862 | "type": "zip", 863 | "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", 864 | "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", 865 | "shasum": "" 866 | }, 867 | "require": { 868 | "php": ">=7.3" 869 | }, 870 | "require-dev": { 871 | "phpunit/phpunit": "^9.3" 872 | }, 873 | "type": "library", 874 | "extra": { 875 | "branch-alias": { 876 | "dev-master": "2.0-dev" 877 | } 878 | }, 879 | "autoload": { 880 | "classmap": [ 881 | "src/" 882 | ] 883 | }, 884 | "notification-url": "https://packagist.org/downloads/", 885 | "license": [ 886 | "BSD-3-Clause" 887 | ], 888 | "authors": [ 889 | { 890 | "name": "Sebastian Bergmann", 891 | "email": "sebastian@phpunit.de" 892 | } 893 | ], 894 | "description": "Looks up which function or method a line of code belongs to", 895 | "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", 896 | "support": { 897 | "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", 898 | "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/2.0.3" 899 | }, 900 | "funding": [ 901 | { 902 | "url": "https://github.com/sebastianbergmann", 903 | "type": "github" 904 | } 905 | ], 906 | "time": "2020-09-28T05:30:19+00:00" 907 | }, 908 | { 909 | "name": "sebastian/comparator", 910 | "version": "4.0.x-dev", 911 | "source": { 912 | "type": "git", 913 | "url": "https://github.com/sebastianbergmann/comparator.git", 914 | "reference": "b247957a1c8dc81a671770f74b479c0a78a818f1" 915 | }, 916 | "dist": { 917 | "type": "zip", 918 | "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/b247957a1c8dc81a671770f74b479c0a78a818f1", 919 | "reference": "b247957a1c8dc81a671770f74b479c0a78a818f1", 920 | "shasum": "" 921 | }, 922 | "require": { 923 | "php": ">=7.3", 924 | "sebastian/diff": "^4.0", 925 | "sebastian/exporter": "^4.0" 926 | }, 927 | "require-dev": { 928 | "phpunit/phpunit": "^9.3" 929 | }, 930 | "type": "library", 931 | "extra": { 932 | "branch-alias": { 933 | "dev-master": "4.0-dev" 934 | } 935 | }, 936 | "autoload": { 937 | "classmap": [ 938 | "src/" 939 | ] 940 | }, 941 | "notification-url": "https://packagist.org/downloads/", 942 | "license": [ 943 | "BSD-3-Clause" 944 | ], 945 | "authors": [ 946 | { 947 | "name": "Sebastian Bergmann", 948 | "email": "sebastian@phpunit.de" 949 | }, 950 | { 951 | "name": "Jeff Welch", 952 | "email": "whatthejeff@gmail.com" 953 | }, 954 | { 955 | "name": "Volker Dusch", 956 | "email": "github@wallbash.com" 957 | }, 958 | { 959 | "name": "Bernhard Schussek", 960 | "email": "bschussek@2bepublished.at" 961 | } 962 | ], 963 | "description": "Provides the functionality to compare PHP values for equality", 964 | "homepage": "https://github.com/sebastianbergmann/comparator", 965 | "keywords": [ 966 | "comparator", 967 | "compare", 968 | "equality" 969 | ], 970 | "support": { 971 | "issues": "https://github.com/sebastianbergmann/comparator/issues", 972 | "source": "https://github.com/sebastianbergmann/comparator/tree/4.0" 973 | }, 974 | "funding": [ 975 | { 976 | "url": "https://github.com/sebastianbergmann", 977 | "type": "github" 978 | } 979 | ], 980 | "time": "2022-09-14T12:46:14+00:00" 981 | }, 982 | { 983 | "name": "sebastian/complexity", 984 | "version": "2.0.x-dev", 985 | "source": { 986 | "type": "git", 987 | "url": "https://github.com/sebastianbergmann/complexity.git", 988 | "reference": "25f207c40d62b8b7aa32f5ab026c53561964053a" 989 | }, 990 | "dist": { 991 | "type": "zip", 992 | "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/25f207c40d62b8b7aa32f5ab026c53561964053a", 993 | "reference": "25f207c40d62b8b7aa32f5ab026c53561964053a", 994 | "shasum": "" 995 | }, 996 | "require": { 997 | "nikic/php-parser": "^4.18 || ^5.0", 998 | "php": ">=7.3" 999 | }, 1000 | "require-dev": { 1001 | "phpunit/phpunit": "^9.3" 1002 | }, 1003 | "type": "library", 1004 | "extra": { 1005 | "branch-alias": { 1006 | "dev-master": "2.0-dev" 1007 | } 1008 | }, 1009 | "autoload": { 1010 | "classmap": [ 1011 | "src/" 1012 | ] 1013 | }, 1014 | "notification-url": "https://packagist.org/downloads/", 1015 | "license": [ 1016 | "BSD-3-Clause" 1017 | ], 1018 | "authors": [ 1019 | { 1020 | "name": "Sebastian Bergmann", 1021 | "email": "sebastian@phpunit.de", 1022 | "role": "lead" 1023 | } 1024 | ], 1025 | "description": "Library for calculating the complexity of PHP code units", 1026 | "homepage": "https://github.com/sebastianbergmann/complexity", 1027 | "support": { 1028 | "issues": "https://github.com/sebastianbergmann/complexity/issues", 1029 | "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.3" 1030 | }, 1031 | "funding": [ 1032 | { 1033 | "url": "https://github.com/sebastianbergmann", 1034 | "type": "github" 1035 | } 1036 | ], 1037 | "time": "2023-12-22T06:19:30+00:00" 1038 | }, 1039 | { 1040 | "name": "sebastian/diff", 1041 | "version": "4.0.x-dev", 1042 | "source": { 1043 | "type": "git", 1044 | "url": "https://github.com/sebastianbergmann/diff.git", 1045 | "reference": "ba01945089c3a293b01ba9badc29ad55b106b0bc" 1046 | }, 1047 | "dist": { 1048 | "type": "zip", 1049 | "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/ba01945089c3a293b01ba9badc29ad55b106b0bc", 1050 | "reference": "ba01945089c3a293b01ba9badc29ad55b106b0bc", 1051 | "shasum": "" 1052 | }, 1053 | "require": { 1054 | "php": ">=7.3" 1055 | }, 1056 | "require-dev": { 1057 | "phpunit/phpunit": "^9.3", 1058 | "symfony/process": "^4.2 || ^5" 1059 | }, 1060 | "type": "library", 1061 | "extra": { 1062 | "branch-alias": { 1063 | "dev-master": "4.0-dev" 1064 | } 1065 | }, 1066 | "autoload": { 1067 | "classmap": [ 1068 | "src/" 1069 | ] 1070 | }, 1071 | "notification-url": "https://packagist.org/downloads/", 1072 | "license": [ 1073 | "BSD-3-Clause" 1074 | ], 1075 | "authors": [ 1076 | { 1077 | "name": "Sebastian Bergmann", 1078 | "email": "sebastian@phpunit.de" 1079 | }, 1080 | { 1081 | "name": "Kore Nordmann", 1082 | "email": "mail@kore-nordmann.de" 1083 | } 1084 | ], 1085 | "description": "Diff implementation", 1086 | "homepage": "https://github.com/sebastianbergmann/diff", 1087 | "keywords": [ 1088 | "diff", 1089 | "udiff", 1090 | "unidiff", 1091 | "unified diff" 1092 | ], 1093 | "support": { 1094 | "issues": "https://github.com/sebastianbergmann/diff/issues", 1095 | "source": "https://github.com/sebastianbergmann/diff/tree/4.0.6" 1096 | }, 1097 | "funding": [ 1098 | { 1099 | "url": "https://github.com/sebastianbergmann", 1100 | "type": "github" 1101 | } 1102 | ], 1103 | "time": "2024-03-02T06:30:58+00:00" 1104 | }, 1105 | { 1106 | "name": "sebastian/environment", 1107 | "version": "5.1.x-dev", 1108 | "source": { 1109 | "type": "git", 1110 | "url": "https://github.com/sebastianbergmann/environment.git", 1111 | "reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed" 1112 | }, 1113 | "dist": { 1114 | "type": "zip", 1115 | "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/830c43a844f1f8d5b7a1f6d6076b784454d8b7ed", 1116 | "reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed", 1117 | "shasum": "" 1118 | }, 1119 | "require": { 1120 | "php": ">=7.3" 1121 | }, 1122 | "require-dev": { 1123 | "phpunit/phpunit": "^9.3" 1124 | }, 1125 | "suggest": { 1126 | "ext-posix": "*" 1127 | }, 1128 | "type": "library", 1129 | "extra": { 1130 | "branch-alias": { 1131 | "dev-master": "5.1-dev" 1132 | } 1133 | }, 1134 | "autoload": { 1135 | "classmap": [ 1136 | "src/" 1137 | ] 1138 | }, 1139 | "notification-url": "https://packagist.org/downloads/", 1140 | "license": [ 1141 | "BSD-3-Clause" 1142 | ], 1143 | "authors": [ 1144 | { 1145 | "name": "Sebastian Bergmann", 1146 | "email": "sebastian@phpunit.de" 1147 | } 1148 | ], 1149 | "description": "Provides functionality to handle HHVM/PHP environments", 1150 | "homepage": "http://www.github.com/sebastianbergmann/environment", 1151 | "keywords": [ 1152 | "Xdebug", 1153 | "environment", 1154 | "hhvm" 1155 | ], 1156 | "support": { 1157 | "issues": "https://github.com/sebastianbergmann/environment/issues", 1158 | "source": "https://github.com/sebastianbergmann/environment/tree/5.1" 1159 | }, 1160 | "funding": [ 1161 | { 1162 | "url": "https://github.com/sebastianbergmann", 1163 | "type": "github" 1164 | } 1165 | ], 1166 | "time": "2023-02-03T06:03:51+00:00" 1167 | }, 1168 | { 1169 | "name": "sebastian/exporter", 1170 | "version": "4.0.x-dev", 1171 | "source": { 1172 | "type": "git", 1173 | "url": "https://github.com/sebastianbergmann/exporter.git", 1174 | "reference": "78c00df8f170e02473b682df15bfcdacc3d32d72" 1175 | }, 1176 | "dist": { 1177 | "type": "zip", 1178 | "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/78c00df8f170e02473b682df15bfcdacc3d32d72", 1179 | "reference": "78c00df8f170e02473b682df15bfcdacc3d32d72", 1180 | "shasum": "" 1181 | }, 1182 | "require": { 1183 | "php": ">=7.3", 1184 | "sebastian/recursion-context": "^4.0" 1185 | }, 1186 | "require-dev": { 1187 | "ext-mbstring": "*", 1188 | "phpunit/phpunit": "^9.3" 1189 | }, 1190 | "type": "library", 1191 | "extra": { 1192 | "branch-alias": { 1193 | "dev-master": "4.0-dev" 1194 | } 1195 | }, 1196 | "autoload": { 1197 | "classmap": [ 1198 | "src/" 1199 | ] 1200 | }, 1201 | "notification-url": "https://packagist.org/downloads/", 1202 | "license": [ 1203 | "BSD-3-Clause" 1204 | ], 1205 | "authors": [ 1206 | { 1207 | "name": "Sebastian Bergmann", 1208 | "email": "sebastian@phpunit.de" 1209 | }, 1210 | { 1211 | "name": "Jeff Welch", 1212 | "email": "whatthejeff@gmail.com" 1213 | }, 1214 | { 1215 | "name": "Volker Dusch", 1216 | "email": "github@wallbash.com" 1217 | }, 1218 | { 1219 | "name": "Adam Harvey", 1220 | "email": "aharvey@php.net" 1221 | }, 1222 | { 1223 | "name": "Bernhard Schussek", 1224 | "email": "bschussek@gmail.com" 1225 | } 1226 | ], 1227 | "description": "Provides the functionality to export PHP variables for visualization", 1228 | "homepage": "https://www.github.com/sebastianbergmann/exporter", 1229 | "keywords": [ 1230 | "export", 1231 | "exporter" 1232 | ], 1233 | "support": { 1234 | "issues": "https://github.com/sebastianbergmann/exporter/issues", 1235 | "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.6" 1236 | }, 1237 | "funding": [ 1238 | { 1239 | "url": "https://github.com/sebastianbergmann", 1240 | "type": "github" 1241 | } 1242 | ], 1243 | "time": "2024-03-02T06:33:00+00:00" 1244 | }, 1245 | { 1246 | "name": "sebastian/global-state", 1247 | "version": "5.0.x-dev", 1248 | "source": { 1249 | "type": "git", 1250 | "url": "https://github.com/sebastianbergmann/global-state.git", 1251 | "reference": "bca7df1f32ee6fe93b4d4a9abbf69e13a4ada2c9" 1252 | }, 1253 | "dist": { 1254 | "type": "zip", 1255 | "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bca7df1f32ee6fe93b4d4a9abbf69e13a4ada2c9", 1256 | "reference": "bca7df1f32ee6fe93b4d4a9abbf69e13a4ada2c9", 1257 | "shasum": "" 1258 | }, 1259 | "require": { 1260 | "php": ">=7.3", 1261 | "sebastian/object-reflector": "^2.0", 1262 | "sebastian/recursion-context": "^4.0" 1263 | }, 1264 | "require-dev": { 1265 | "ext-dom": "*", 1266 | "phpunit/phpunit": "^9.3" 1267 | }, 1268 | "suggest": { 1269 | "ext-uopz": "*" 1270 | }, 1271 | "type": "library", 1272 | "extra": { 1273 | "branch-alias": { 1274 | "dev-master": "5.0-dev" 1275 | } 1276 | }, 1277 | "autoload": { 1278 | "classmap": [ 1279 | "src/" 1280 | ] 1281 | }, 1282 | "notification-url": "https://packagist.org/downloads/", 1283 | "license": [ 1284 | "BSD-3-Clause" 1285 | ], 1286 | "authors": [ 1287 | { 1288 | "name": "Sebastian Bergmann", 1289 | "email": "sebastian@phpunit.de" 1290 | } 1291 | ], 1292 | "description": "Snapshotting of global state", 1293 | "homepage": "http://www.github.com/sebastianbergmann/global-state", 1294 | "keywords": [ 1295 | "global state" 1296 | ], 1297 | "support": { 1298 | "issues": "https://github.com/sebastianbergmann/global-state/issues", 1299 | "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.7" 1300 | }, 1301 | "funding": [ 1302 | { 1303 | "url": "https://github.com/sebastianbergmann", 1304 | "type": "github" 1305 | } 1306 | ], 1307 | "time": "2024-03-02T06:35:11+00:00" 1308 | }, 1309 | { 1310 | "name": "sebastian/lines-of-code", 1311 | "version": "1.0.x-dev", 1312 | "source": { 1313 | "type": "git", 1314 | "url": "https://github.com/sebastianbergmann/lines-of-code.git", 1315 | "reference": "e1e4a170560925c26d424b6a03aed157e7dcc5c5" 1316 | }, 1317 | "dist": { 1318 | "type": "zip", 1319 | "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/e1e4a170560925c26d424b6a03aed157e7dcc5c5", 1320 | "reference": "e1e4a170560925c26d424b6a03aed157e7dcc5c5", 1321 | "shasum": "" 1322 | }, 1323 | "require": { 1324 | "nikic/php-parser": "^4.18 || ^5.0", 1325 | "php": ">=7.3" 1326 | }, 1327 | "require-dev": { 1328 | "phpunit/phpunit": "^9.3" 1329 | }, 1330 | "type": "library", 1331 | "extra": { 1332 | "branch-alias": { 1333 | "dev-master": "1.0-dev" 1334 | } 1335 | }, 1336 | "autoload": { 1337 | "classmap": [ 1338 | "src/" 1339 | ] 1340 | }, 1341 | "notification-url": "https://packagist.org/downloads/", 1342 | "license": [ 1343 | "BSD-3-Clause" 1344 | ], 1345 | "authors": [ 1346 | { 1347 | "name": "Sebastian Bergmann", 1348 | "email": "sebastian@phpunit.de", 1349 | "role": "lead" 1350 | } 1351 | ], 1352 | "description": "Library for counting the lines of code in PHP source code", 1353 | "homepage": "https://github.com/sebastianbergmann/lines-of-code", 1354 | "support": { 1355 | "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", 1356 | "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.4" 1357 | }, 1358 | "funding": [ 1359 | { 1360 | "url": "https://github.com/sebastianbergmann", 1361 | "type": "github" 1362 | } 1363 | ], 1364 | "time": "2023-12-22T06:20:34+00:00" 1365 | }, 1366 | { 1367 | "name": "sebastian/object-enumerator", 1368 | "version": "4.0.4", 1369 | "source": { 1370 | "type": "git", 1371 | "url": "https://github.com/sebastianbergmann/object-enumerator.git", 1372 | "reference": "5c9eeac41b290a3712d88851518825ad78f45c71" 1373 | }, 1374 | "dist": { 1375 | "type": "zip", 1376 | "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/5c9eeac41b290a3712d88851518825ad78f45c71", 1377 | "reference": "5c9eeac41b290a3712d88851518825ad78f45c71", 1378 | "shasum": "" 1379 | }, 1380 | "require": { 1381 | "php": ">=7.3", 1382 | "sebastian/object-reflector": "^2.0", 1383 | "sebastian/recursion-context": "^4.0" 1384 | }, 1385 | "require-dev": { 1386 | "phpunit/phpunit": "^9.3" 1387 | }, 1388 | "type": "library", 1389 | "extra": { 1390 | "branch-alias": { 1391 | "dev-master": "4.0-dev" 1392 | } 1393 | }, 1394 | "autoload": { 1395 | "classmap": [ 1396 | "src/" 1397 | ] 1398 | }, 1399 | "notification-url": "https://packagist.org/downloads/", 1400 | "license": [ 1401 | "BSD-3-Clause" 1402 | ], 1403 | "authors": [ 1404 | { 1405 | "name": "Sebastian Bergmann", 1406 | "email": "sebastian@phpunit.de" 1407 | } 1408 | ], 1409 | "description": "Traverses array structures and object graphs to enumerate all referenced objects", 1410 | "homepage": "https://github.com/sebastianbergmann/object-enumerator/", 1411 | "support": { 1412 | "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", 1413 | "source": "https://github.com/sebastianbergmann/object-enumerator/tree/4.0.4" 1414 | }, 1415 | "funding": [ 1416 | { 1417 | "url": "https://github.com/sebastianbergmann", 1418 | "type": "github" 1419 | } 1420 | ], 1421 | "time": "2020-10-26T13:12:34+00:00" 1422 | }, 1423 | { 1424 | "name": "sebastian/object-reflector", 1425 | "version": "2.0.4", 1426 | "source": { 1427 | "type": "git", 1428 | "url": "https://github.com/sebastianbergmann/object-reflector.git", 1429 | "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7" 1430 | }, 1431 | "dist": { 1432 | "type": "zip", 1433 | "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", 1434 | "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", 1435 | "shasum": "" 1436 | }, 1437 | "require": { 1438 | "php": ">=7.3" 1439 | }, 1440 | "require-dev": { 1441 | "phpunit/phpunit": "^9.3" 1442 | }, 1443 | "type": "library", 1444 | "extra": { 1445 | "branch-alias": { 1446 | "dev-master": "2.0-dev" 1447 | } 1448 | }, 1449 | "autoload": { 1450 | "classmap": [ 1451 | "src/" 1452 | ] 1453 | }, 1454 | "notification-url": "https://packagist.org/downloads/", 1455 | "license": [ 1456 | "BSD-3-Clause" 1457 | ], 1458 | "authors": [ 1459 | { 1460 | "name": "Sebastian Bergmann", 1461 | "email": "sebastian@phpunit.de" 1462 | } 1463 | ], 1464 | "description": "Allows reflection of object attributes, including inherited and non-public ones", 1465 | "homepage": "https://github.com/sebastianbergmann/object-reflector/", 1466 | "support": { 1467 | "issues": "https://github.com/sebastianbergmann/object-reflector/issues", 1468 | "source": "https://github.com/sebastianbergmann/object-reflector/tree/2.0.4" 1469 | }, 1470 | "funding": [ 1471 | { 1472 | "url": "https://github.com/sebastianbergmann", 1473 | "type": "github" 1474 | } 1475 | ], 1476 | "time": "2020-10-26T13:14:26+00:00" 1477 | }, 1478 | { 1479 | "name": "sebastian/recursion-context", 1480 | "version": "4.0.x-dev", 1481 | "source": { 1482 | "type": "git", 1483 | "url": "https://github.com/sebastianbergmann/recursion-context.git", 1484 | "reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1" 1485 | }, 1486 | "dist": { 1487 | "type": "zip", 1488 | "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1", 1489 | "reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1", 1490 | "shasum": "" 1491 | }, 1492 | "require": { 1493 | "php": ">=7.3" 1494 | }, 1495 | "require-dev": { 1496 | "phpunit/phpunit": "^9.3" 1497 | }, 1498 | "type": "library", 1499 | "extra": { 1500 | "branch-alias": { 1501 | "dev-master": "4.0-dev" 1502 | } 1503 | }, 1504 | "autoload": { 1505 | "classmap": [ 1506 | "src/" 1507 | ] 1508 | }, 1509 | "notification-url": "https://packagist.org/downloads/", 1510 | "license": [ 1511 | "BSD-3-Clause" 1512 | ], 1513 | "authors": [ 1514 | { 1515 | "name": "Sebastian Bergmann", 1516 | "email": "sebastian@phpunit.de" 1517 | }, 1518 | { 1519 | "name": "Jeff Welch", 1520 | "email": "whatthejeff@gmail.com" 1521 | }, 1522 | { 1523 | "name": "Adam Harvey", 1524 | "email": "aharvey@php.net" 1525 | } 1526 | ], 1527 | "description": "Provides functionality to recursively process PHP variables", 1528 | "homepage": "https://github.com/sebastianbergmann/recursion-context", 1529 | "support": { 1530 | "issues": "https://github.com/sebastianbergmann/recursion-context/issues", 1531 | "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.5" 1532 | }, 1533 | "funding": [ 1534 | { 1535 | "url": "https://github.com/sebastianbergmann", 1536 | "type": "github" 1537 | } 1538 | ], 1539 | "time": "2023-02-03T06:07:39+00:00" 1540 | }, 1541 | { 1542 | "name": "sebastian/resource-operations", 1543 | "version": "dev-main", 1544 | "source": { 1545 | "type": "git", 1546 | "url": "https://github.com/sebastianbergmann/resource-operations.git", 1547 | "reference": "ff553e7482dcee39fa4acc2b175d6ddeb0f7bc25" 1548 | }, 1549 | "dist": { 1550 | "type": "zip", 1551 | "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/ff553e7482dcee39fa4acc2b175d6ddeb0f7bc25", 1552 | "reference": "ff553e7482dcee39fa4acc2b175d6ddeb0f7bc25", 1553 | "shasum": "" 1554 | }, 1555 | "require": { 1556 | "php": ">=7.3" 1557 | }, 1558 | "require-dev": { 1559 | "phpunit/phpunit": "^9.0" 1560 | }, 1561 | "default-branch": true, 1562 | "type": "library", 1563 | "extra": { 1564 | "branch-alias": { 1565 | "dev-main": "3.0-dev" 1566 | } 1567 | }, 1568 | "autoload": { 1569 | "classmap": [ 1570 | "src/" 1571 | ] 1572 | }, 1573 | "notification-url": "https://packagist.org/downloads/", 1574 | "license": [ 1575 | "BSD-3-Clause" 1576 | ], 1577 | "authors": [ 1578 | { 1579 | "name": "Sebastian Bergmann", 1580 | "email": "sebastian@phpunit.de" 1581 | } 1582 | ], 1583 | "description": "Provides a list of PHP built-in functions that operate on resources", 1584 | "homepage": "https://www.github.com/sebastianbergmann/resource-operations", 1585 | "support": { 1586 | "source": "https://github.com/sebastianbergmann/resource-operations/tree/main" 1587 | }, 1588 | "funding": [ 1589 | { 1590 | "url": "https://github.com/sebastianbergmann", 1591 | "type": "github" 1592 | } 1593 | ], 1594 | "time": "2024-03-14T18:47:08+00:00" 1595 | }, 1596 | { 1597 | "name": "sebastian/type", 1598 | "version": "3.2.x-dev", 1599 | "source": { 1600 | "type": "git", 1601 | "url": "https://github.com/sebastianbergmann/type.git", 1602 | "reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7" 1603 | }, 1604 | "dist": { 1605 | "type": "zip", 1606 | "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7", 1607 | "reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7", 1608 | "shasum": "" 1609 | }, 1610 | "require": { 1611 | "php": ">=7.3" 1612 | }, 1613 | "require-dev": { 1614 | "phpunit/phpunit": "^9.5" 1615 | }, 1616 | "type": "library", 1617 | "extra": { 1618 | "branch-alias": { 1619 | "dev-master": "3.2-dev" 1620 | } 1621 | }, 1622 | "autoload": { 1623 | "classmap": [ 1624 | "src/" 1625 | ] 1626 | }, 1627 | "notification-url": "https://packagist.org/downloads/", 1628 | "license": [ 1629 | "BSD-3-Clause" 1630 | ], 1631 | "authors": [ 1632 | { 1633 | "name": "Sebastian Bergmann", 1634 | "email": "sebastian@phpunit.de", 1635 | "role": "lead" 1636 | } 1637 | ], 1638 | "description": "Collection of value objects that represent the types of the PHP type system", 1639 | "homepage": "https://github.com/sebastianbergmann/type", 1640 | "support": { 1641 | "issues": "https://github.com/sebastianbergmann/type/issues", 1642 | "source": "https://github.com/sebastianbergmann/type/tree/3.2" 1643 | }, 1644 | "funding": [ 1645 | { 1646 | "url": "https://github.com/sebastianbergmann", 1647 | "type": "github" 1648 | } 1649 | ], 1650 | "time": "2023-02-03T06:13:03+00:00" 1651 | }, 1652 | { 1653 | "name": "sebastian/version", 1654 | "version": "3.0.x-dev", 1655 | "source": { 1656 | "type": "git", 1657 | "url": "https://github.com/sebastianbergmann/version.git", 1658 | "reference": "c6c1022351a901512170118436c764e473f6de8c" 1659 | }, 1660 | "dist": { 1661 | "type": "zip", 1662 | "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c6c1022351a901512170118436c764e473f6de8c", 1663 | "reference": "c6c1022351a901512170118436c764e473f6de8c", 1664 | "shasum": "" 1665 | }, 1666 | "require": { 1667 | "php": ">=7.3" 1668 | }, 1669 | "type": "library", 1670 | "extra": { 1671 | "branch-alias": { 1672 | "dev-master": "3.0-dev" 1673 | } 1674 | }, 1675 | "autoload": { 1676 | "classmap": [ 1677 | "src/" 1678 | ] 1679 | }, 1680 | "notification-url": "https://packagist.org/downloads/", 1681 | "license": [ 1682 | "BSD-3-Clause" 1683 | ], 1684 | "authors": [ 1685 | { 1686 | "name": "Sebastian Bergmann", 1687 | "email": "sebastian@phpunit.de", 1688 | "role": "lead" 1689 | } 1690 | ], 1691 | "description": "Library that helps with managing the version number of Git-hosted PHP projects", 1692 | "homepage": "https://github.com/sebastianbergmann/version", 1693 | "support": { 1694 | "issues": "https://github.com/sebastianbergmann/version/issues", 1695 | "source": "https://github.com/sebastianbergmann/version/tree/3.0.2" 1696 | }, 1697 | "funding": [ 1698 | { 1699 | "url": "https://github.com/sebastianbergmann", 1700 | "type": "github" 1701 | } 1702 | ], 1703 | "time": "2020-09-28T06:39:44+00:00" 1704 | }, 1705 | { 1706 | "name": "theseer/tokenizer", 1707 | "version": "1.2.3", 1708 | "source": { 1709 | "type": "git", 1710 | "url": "https://github.com/theseer/tokenizer.git", 1711 | "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2" 1712 | }, 1713 | "dist": { 1714 | "type": "zip", 1715 | "url": "https://api.github.com/repos/theseer/tokenizer/zipball/737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2", 1716 | "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2", 1717 | "shasum": "" 1718 | }, 1719 | "require": { 1720 | "ext-dom": "*", 1721 | "ext-tokenizer": "*", 1722 | "ext-xmlwriter": "*", 1723 | "php": "^7.2 || ^8.0" 1724 | }, 1725 | "type": "library", 1726 | "autoload": { 1727 | "classmap": [ 1728 | "src/" 1729 | ] 1730 | }, 1731 | "notification-url": "https://packagist.org/downloads/", 1732 | "license": [ 1733 | "BSD-3-Clause" 1734 | ], 1735 | "authors": [ 1736 | { 1737 | "name": "Arne Blankerts", 1738 | "email": "arne@blankerts.de", 1739 | "role": "Developer" 1740 | } 1741 | ], 1742 | "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", 1743 | "support": { 1744 | "issues": "https://github.com/theseer/tokenizer/issues", 1745 | "source": "https://github.com/theseer/tokenizer/tree/1.2.3" 1746 | }, 1747 | "funding": [ 1748 | { 1749 | "url": "https://github.com/theseer", 1750 | "type": "github" 1751 | } 1752 | ], 1753 | "time": "2024-03-03T12:36:25+00:00" 1754 | } 1755 | ], 1756 | "aliases": [], 1757 | "minimum-stability": "dev", 1758 | "stability-flags": { 1759 | "phpunit/phpunit": 20 1760 | }, 1761 | "prefer-stable": false, 1762 | "prefer-lowest": false, 1763 | "platform": [], 1764 | "platform-dev": [], 1765 | "plugin-api-version": "2.6.0" 1766 | } 1767 | -------------------------------------------------------------------------------- /src/Console/Commands/MakeFilter.php: -------------------------------------------------------------------------------- 1 | option('bound') 31 | ? __DIR__.'/../Stubs/bound.stub' 32 | : __DIR__.'/../Stubs/filter.stub'; 33 | } 34 | /** 35 | * Get the console command arguments. 36 | * 37 | * @return array 38 | */ 39 | protected function getArguments() 40 | { 41 | return [ 42 | ['name', InputArgument::REQUIRED, 'The name of the filter.'], 43 | ]; 44 | } 45 | 46 | /** 47 | * Get the default namespace for the class. 48 | * 49 | * @param string $rootNamespace 50 | * @return string 51 | */ 52 | protected function getDefaultNamespace($rootNamespace) 53 | { 54 | return $rootNamespace.'\Http\Filters'; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/Console/Stubs/bound.stub: -------------------------------------------------------------------------------- 1 | filter = $requestFilter; 11 | $this->rule = $ruleDefinition; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/Library/Drivers/CallbackFilter.php: -------------------------------------------------------------------------------- 1 | rule) 12 | { 13 | $argsCount = (new \ReflectionFunction($this->rule))->getNumberOfParameters(); 14 | 15 | $filter = $this->filter ? request()->get($this->filter) : null; 16 | 17 | if ($argsCount == 1 || ($argsCount == 2 && !is_null($filter))) 18 | { 19 | return call_user_func_array($this->rule, [$builder, $filter]); 20 | } 21 | } 22 | 23 | return $builder; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Library/Drivers/DirectFilter.php: -------------------------------------------------------------------------------- 1 | rule) 15 | { 16 | $filter = $this->filter ? request()->get($this->filter) : null; 17 | 18 | if ($filter) 19 | { 20 | $column = explode(":", $this->rule)[1]; 21 | 22 | return $builder->where($column, $filter); 23 | } 24 | else 25 | { 26 | if (strpos($this->rule, ",")) 27 | { 28 | $details = explode(',', substr($this->rule, strpos($this->rule, ":") + 1)); 29 | 30 | $column = $details[0]; 31 | 32 | array_splice($details, 0, 1); 33 | 34 | return $builder->whereIn($column, $details); 35 | } 36 | } 37 | } 38 | 39 | return $builder; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/Library/Drivers/RelationshipFilter.php: -------------------------------------------------------------------------------- 1 | get($this->filter)) { 12 | 13 | $rules = explode(":", $this->rule)[1]; 14 | 15 | $load = explode(",", $rules); 16 | 17 | return $builder->whereHas($load[0], function ($query) use($load, $filter){ 18 | 19 | $query->where($load[1], $filter); 20 | 21 | }); 22 | } 23 | 24 | return $builder; 25 | } 26 | } -------------------------------------------------------------------------------- /src/Library/OsmoseFilter.php: -------------------------------------------------------------------------------- 1 | 'from', 37 | 'to' => 'to' 38 | ]; 39 | } 40 | 41 | /** 42 | * Filters collection based on the rules specified by the Osmose Filter 43 | * 44 | * @param string $model model class that ought to be sieved 45 | * @return \Illuminate\Database\Eloquent\Builder 46 | * @throws \Exception 47 | */ 48 | public function sieve (string $model): \Illuminate\Database\Eloquent\Builder 49 | { 50 | $filters = $this->residue(); 51 | $binds = method_exists($this, 'bound') ? $this->bound() : []; 52 | 53 | return Osmose::model($model) 54 | ->timeline( 55 | $this->column(), 56 | $this->range(), 57 | $this->limits() 58 | ) 59 | ->bound($binds) 60 | ->filter($filters); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/Library/Services/Contracts/OsmoseDriverInterface.php: -------------------------------------------------------------------------------- 1 | model = $model; 23 | 24 | $this->builder = $model::query(); 25 | 26 | return $this; 27 | } 28 | 29 | /** 30 | * Set the range of values that are to be filtered against 31 | * Supports the created_at column on the table to be filtered 32 | * 33 | * @param $column 34 | * @param $range 35 | * @param $limits 36 | */ 37 | public function timeline ($column, $range, $limits) 38 | { 39 | $timespan = request()->has($range) 40 | ? $this->rangeTimespan($range) 41 | : $this->limitTimespan($limits); 42 | 43 | if (is_array($timespan)) 44 | { 45 | $this->builder = $this->builder->whereBetween($column, $timespan); 46 | } 47 | 48 | return $this; 49 | } 50 | 51 | /** 52 | * Set the range of values that are to be filtered against 53 | * Supports the created_at column on the table to be filtered 54 | * 55 | * @param $column 56 | * @param $range 57 | * @param $limits 58 | * 59 | * @return self 60 | */ 61 | public function bound ($binds) : self 62 | { 63 | if(!is_array($binds)) { throw new Exception("Osmose's bound method should return an array"); } 64 | 65 | foreach ($binds as $rule) 66 | { 67 | $driver = $this->getOsmoseDriver(null, $rule); 68 | 69 | $this->builder = $driver->filtrate($this->builder); 70 | } 71 | 72 | return $this; 73 | } 74 | 75 | /** 76 | * Performs the base filtration process to determine 77 | * the filterable driver that ought to be executed 78 | * 79 | * @param array $filters 80 | * @return \Illuminate\Database\Eloquent\Builder; 81 | */ 82 | public function filter (array $filters) : \Illuminate\Database\Eloquent\Builder 83 | { 84 | foreach ($filters as $filter => $rule) 85 | { 86 | $driver = $this->getOsmoseDriver($filter, $rule); 87 | 88 | $this->builder = $driver->filtrate($this->builder); 89 | } 90 | 91 | return $this->builder; 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /src/Library/Services/Traits/OsmoseDatesTrait.php: -------------------------------------------------------------------------------- 1 | toDateTimeString() 21 | : null; 22 | 23 | $toDate = request($limits['to']) 24 | ? Carbon::parse(request($limits['to']))->endOfDay()->toDateTimeString() 25 | : today()->endOfDay()->toDateTimeString(); 26 | 27 | if (!$fromDate) return null; 28 | 29 | return [ 30 | $fromDate, $toDate 31 | ]; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/Library/Services/Traits/OsmoseDriverTrait.php: -------------------------------------------------------------------------------- 1 | publishes([ 19 | __DIR__ . '/../config/osmose.php' => config_path('osmose.php'), 20 | ]); 21 | 22 | $this->registerCommands(); 23 | } 24 | 25 | /** 26 | * Register services. 27 | * 28 | * @return void 29 | */ 30 | public function register(): void 31 | { 32 | $this->app->bind('Agog\Osmose\Library\Services\OsmoseFilterService', function() { 33 | return new OsmoseFilterService(); 34 | }); 35 | } 36 | 37 | /** 38 | * Register console commands 39 | * 40 | * @return void 41 | */ 42 | public function registerCommands(): void 43 | { 44 | if ($this->app->runningInConsole()) { 45 | $this->commands([ 46 | MakeFilter::class, 47 | ]); 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/config/osmose.php: -------------------------------------------------------------------------------- 1 | [ 11 | "d" => [ 12 | Carbon::now()->startOfDay(), Carbon::now()->endOfDay() 13 | ], 14 | 15 | "w" => [ 16 | Carbon::now()->startOfWeek(), Carbon::now()->endOfWeek() 17 | ], 18 | 19 | "m" => [ 20 | Carbon::now()->startOfMonth(), Carbon::now()->endOfMonth() 21 | ], 22 | 23 | "y" => [ 24 | Carbon::now()->startOfYear(), Carbon::now()->endOfYear() 25 | ] 26 | ], 27 | 28 | /** 29 | * For automatically loading of eloquent models using the 30 | * osmose function, please specify the namespace under 31 | * which your application models have been defined 32 | */ 33 | "namespace" => "App\\Models" 34 | 35 | ]; 36 | -------------------------------------------------------------------------------- /src/functions.php: -------------------------------------------------------------------------------- 1 | sieve($model); 26 | } 27 | } 28 | 29 | -------------------------------------------------------------------------------- /tests/DirectFilterTest.php: -------------------------------------------------------------------------------- 1 | assertSame(0, count([])); 9 | } 10 | } 11 | --------------------------------------------------------------------------------