├── .all-contributorsrc
├── .gitattributes
├── .phplint.yml
├── CHANGELOG.md
├── CODE_OF_CONDUCT.md
├── LICENSE.md
├── TODO.md
├── composer.json
├── composer.lock
├── phpcs.xml.dist
├── phpstan.neon.dist
└── src
├── Traits
├── Arrays.php
├── Collections.php
├── Functions.php
├── Objects.php
├── Sequence
│ ├── Chain.php
│ └── ChainWrapper.php
├── Strings.php
└── Utilities.php
└── __.php
/.all-contributorsrc:
--------------------------------------------------------------------------------
1 | {
2 | "projectName": "php-lodash",
3 | "projectOwner": "",
4 | "files": [
5 | "README.md"
6 | ],
7 | "imageSize": 100,
8 | "commit": false,
9 | "contributors": [
10 | {
11 | "login": "Meabed",
12 | "name": "Mohamed Meabed",
13 | "avatar_url": "https://avatars0.githubusercontent.com/u/45731?v=3",
14 | "profile": "https://github.com/Meabed",
15 | "contributions": [
16 | "code",
17 | "test",
18 | "talk"
19 | ]
20 | },
21 | {
22 | "login": "ziishaned",
23 | "name": "Zeeshan Ahmad",
24 | "avatar_url": "https://avatars2.githubusercontent.com/u/16267321?v=3",
25 | "profile": "https://github.com/ziishaned",
26 | "contributions": [
27 | "code",
28 | "bug",
29 | "test",
30 | "doc"
31 | ]
32 | }
33 | ]
34 | }
35 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Path-based git attributes
2 | # https://www.kernel.org/pub/software/scm/git/docs/gitattributes.html
3 | * text=auto
4 | *.txt text
5 |
6 | # Ignore all test and documentation with "export-ignore".
7 | /.editorconfig export-ignore
8 | /.gitattributesexport-ignore
9 | /.gitignore export-ignore
10 | /.scrutinizer.yml export-ignore
11 | /.styleci.yml export-ignore
12 | /.travis.yml export-ignore
13 | /.github export-ignore
14 | /docs export-ignore
15 | /phpunit.xml.dist export-ignore
16 | /tests export-ignore
17 | /Gruntfile.js export-ignore
18 | /package.json export-ignore
19 | /README.md export-ignore
20 | /CONTRIBUTING.md export-ignore
21 |
--------------------------------------------------------------------------------
/.phplint.yml:
--------------------------------------------------------------------------------
1 | path: ./
2 | jobs: 10
3 | cache: ./build/phplint-cache
4 | extensions:
5 | - php
6 | exclude:
7 | - vendor
8 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | All notable changes to `:package_name` will be documented in this file.
4 |
5 | Updates should follow the [Keep a CHANGELOG](http://keepachangelog.com/) principles.
6 |
7 | ## NEXT - YYYY-MM-DD
8 |
9 | ### Added
10 | - Nothing
11 |
12 | ### Deprecated
13 | - Nothing
14 |
15 | ### Fixed
16 | - Nothing
17 |
18 | ### Removed
19 | - Nothing
20 |
21 | ### Security
22 | - Nothing
23 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | In the interest of fostering an open and welcoming environment, we as
6 | contributors and maintainers pledge to make participation in our project and
7 | our community a harassment-free experience for everyone, regardless of age, body
8 | size, disability, ethnicity, gender identity and expression, level of experience,
9 | nationality, personal appearance, race, religion, or sexual identity and
10 | orientation.
11 |
12 | ## Our Standards
13 |
14 | Examples of behavior that contributes to creating a positive environment
15 | include:
16 |
17 | * Using welcoming and inclusive language
18 | * Being respectful of differing viewpoints and experiences
19 | * Gracefully accepting constructive criticism
20 | * Focusing on what is best for the community
21 | * Showing empathy towards other community members
22 |
23 | Examples of unacceptable behavior by participants include:
24 |
25 | * The use of sexualized language or imagery and unwelcome sexual attention or
26 | advances
27 | * Trolling, insulting/derogatory comments, and personal or political attacks
28 | * Public or private harassment
29 | * Publishing others' private information, such as a physical or electronic
30 | address, without explicit permission
31 | * Other conduct which could reasonably be considered inappropriate in a
32 | professional setting
33 |
34 | ## Our Responsibilities
35 |
36 | Project maintainers are responsible for clarifying the standards of acceptable
37 | behavior and are expected to take appropriate and fair corrective action in
38 | response to any instances of unacceptable behavior.
39 |
40 | Project maintainers have the right and responsibility to remove, edit, or
41 | reject comments, commits, code, wiki edits, issues, and other contributions
42 | that are not aligned to this Code of Conduct, or to ban temporarily or
43 | permanently any contributor for other behaviors that they deem inappropriate,
44 | threatening, offensive, or harmful.
45 |
46 | ## Scope
47 |
48 | This Code of Conduct applies both within project spaces and in public spaces
49 | when an individual is representing the project or its community. Examples of
50 | representing a project or community include using an official project e-mail
51 | address, posting via an official social media account, or acting as an appointed
52 | representative at an online or offline event. Representation of a project may be
53 | further defined and clarified by project maintainers.
54 |
55 | ## Enforcement
56 |
57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be
58 | reported by contacting the project team at `:author_email`. All
59 | complaints will be reviewed and investigated and will result in a response that
60 | is deemed necessary and appropriate to the circumstances. The project team is
61 | obligated to maintain confidentiality with regard to the reporter of an incident.
62 | Further details of specific enforcement policies may be posted separately.
63 |
64 | Project maintainers who do not follow or enforce the Code of Conduct in good
65 | faith may face temporary or permanent repercussions as determined by other
66 | members of the project's leadership.
67 |
68 | ## Attribution
69 |
70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71 | available at [http://contributor-covenant.org/version/1/4][version]
72 |
73 | [homepage]: http://contributor-covenant.org
74 | [version]: http://contributor-covenant.org/version/1/4/
75 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 me.io
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 |
--------------------------------------------------------------------------------
/TODO.md:
--------------------------------------------------------------------------------
1 | ## TODO
2 |
3 | - [ ] Documentation
4 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "me-io/php-lodash",
3 | "type": "library",
4 | "version": "2.0.0",
5 | "description": "A full-on PHP manipulation utility-belt that provides support for the usual functional.",
6 | "keywords": [
7 | "__",
8 | "lodash",
9 | "bottomline",
10 | "library",
11 | "utility",
12 | "functions"
13 | ],
14 | "license": "MIT",
15 | "minimum-stability": "dev",
16 | "prefer-stable": true,
17 | "require": {
18 | "php": ">=7.1"
19 | },
20 | "require-dev": {
21 | "phpunit/phpunit": "^7.5",
22 | "squizlabs/php_codesniffer": "^3.4",
23 | "overtrue/phplint": "^1.1",
24 | "phpstan/phpstan": "^0.11"
25 | },
26 | "autoload": {
27 | "files": [
28 | "src/__.php"
29 | ],
30 | "psr-4": {
31 | "__\\": "src/"
32 | }
33 | },
34 | "autoload-dev": {
35 | "psr-4": {
36 | "Tests\\": "tests/"
37 | }
38 | },
39 | "scripts": {
40 | "update-dev": "composer update",
41 | "install-dev": "composer install --no-interaction",
42 | "update-prod": "composer update --no-dev",
43 | "install-prod": "composer install --no-dev --no-interaction",
44 | "stan": "phpstan analyse src",
45 | "test": "phpunit",
46 | "test-cov": "phpunit --coverage-text --coverage-clover=coverage.xml",
47 | "test-html": "phpunit --coverage-text --coverage-clover=coverage.xml --coverage-html=./report/",
48 | "lint": "phplint",
49 | "check-style": "phpcs src tests",
50 | "fix-style": "phpcbf src tests"
51 | },
52 | "extra": {
53 | "branch-alias": {
54 | "dev-master": "2.0.x-dev"
55 | }
56 | },
57 | "config": {
58 | "optimize-autoloader": true,
59 | "preferred-install": "dist",
60 | "sort-packages": true,
61 | "process-timeout": 1000000
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/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": "69539d8aca6ee20a2a331c8834290c6b",
8 | "packages": [],
9 | "packages-dev": [
10 | {
11 | "name": "composer/xdebug-handler",
12 | "version": "1.3.1",
13 | "source": {
14 | "type": "git",
15 | "url": "https://github.com/composer/xdebug-handler.git",
16 | "reference": "dc523135366eb68f22268d069ea7749486458562"
17 | },
18 | "dist": {
19 | "type": "zip",
20 | "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/dc523135366eb68f22268d069ea7749486458562",
21 | "reference": "dc523135366eb68f22268d069ea7749486458562",
22 | "shasum": ""
23 | },
24 | "require": {
25 | "php": "^5.3.2 || ^7.0",
26 | "psr/log": "^1.0"
27 | },
28 | "require-dev": {
29 | "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5"
30 | },
31 | "type": "library",
32 | "autoload": {
33 | "psr-4": {
34 | "Composer\\XdebugHandler\\": "src"
35 | }
36 | },
37 | "notification-url": "https://packagist.org/downloads/",
38 | "license": [
39 | "MIT"
40 | ],
41 | "authors": [
42 | {
43 | "name": "John Stevenson",
44 | "email": "john-stevenson@blueyonder.co.uk"
45 | }
46 | ],
47 | "description": "Restarts a process without xdebug.",
48 | "keywords": [
49 | "Xdebug",
50 | "performance"
51 | ],
52 | "time": "2018-11-29T10:59:02+00:00"
53 | },
54 | {
55 | "name": "doctrine/instantiator",
56 | "version": "1.1.0",
57 | "source": {
58 | "type": "git",
59 | "url": "https://github.com/doctrine/instantiator.git",
60 | "reference": "185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda"
61 | },
62 | "dist": {
63 | "type": "zip",
64 | "url": "https://api.github.com/repos/doctrine/instantiator/zipball/185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda",
65 | "reference": "185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda",
66 | "shasum": ""
67 | },
68 | "require": {
69 | "php": "^7.1"
70 | },
71 | "require-dev": {
72 | "athletic/athletic": "~0.1.8",
73 | "ext-pdo": "*",
74 | "ext-phar": "*",
75 | "phpunit/phpunit": "^6.2.3",
76 | "squizlabs/php_codesniffer": "^3.0.2"
77 | },
78 | "type": "library",
79 | "extra": {
80 | "branch-alias": {
81 | "dev-master": "1.2.x-dev"
82 | }
83 | },
84 | "autoload": {
85 | "psr-4": {
86 | "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/"
87 | }
88 | },
89 | "notification-url": "https://packagist.org/downloads/",
90 | "license": [
91 | "MIT"
92 | ],
93 | "authors": [
94 | {
95 | "name": "Marco Pivetta",
96 | "email": "ocramius@gmail.com",
97 | "homepage": "http://ocramius.github.com/"
98 | }
99 | ],
100 | "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors",
101 | "homepage": "https://github.com/doctrine/instantiator",
102 | "keywords": [
103 | "constructor",
104 | "instantiate"
105 | ],
106 | "time": "2017-07-22T11:58:36+00:00"
107 | },
108 | {
109 | "name": "jean85/pretty-package-versions",
110 | "version": "1.2",
111 | "source": {
112 | "type": "git",
113 | "url": "https://github.com/Jean85/pretty-package-versions.git",
114 | "reference": "75c7effcf3f77501d0e0caa75111aff4daa0dd48"
115 | },
116 | "dist": {
117 | "type": "zip",
118 | "url": "https://api.github.com/repos/Jean85/pretty-package-versions/zipball/75c7effcf3f77501d0e0caa75111aff4daa0dd48",
119 | "reference": "75c7effcf3f77501d0e0caa75111aff4daa0dd48",
120 | "shasum": ""
121 | },
122 | "require": {
123 | "ocramius/package-versions": "^1.2.0",
124 | "php": "^7.0"
125 | },
126 | "require-dev": {
127 | "phpunit/phpunit": "^6.0"
128 | },
129 | "type": "library",
130 | "extra": {
131 | "branch-alias": {
132 | "dev-master": "1.x-dev"
133 | }
134 | },
135 | "autoload": {
136 | "psr-4": {
137 | "Jean85\\": "src/"
138 | }
139 | },
140 | "notification-url": "https://packagist.org/downloads/",
141 | "license": [
142 | "MIT"
143 | ],
144 | "authors": [
145 | {
146 | "name": "Alessandro Lai",
147 | "email": "alessandro.lai85@gmail.com"
148 | }
149 | ],
150 | "description": "A wrapper for ocramius/package-versions to get pretty versions strings",
151 | "keywords": [
152 | "composer",
153 | "package",
154 | "release",
155 | "versions"
156 | ],
157 | "time": "2018-06-13T13:22:40+00:00"
158 | },
159 | {
160 | "name": "myclabs/deep-copy",
161 | "version": "1.8.1",
162 | "source": {
163 | "type": "git",
164 | "url": "https://github.com/myclabs/DeepCopy.git",
165 | "reference": "3e01bdad3e18354c3dce54466b7fbe33a9f9f7f8"
166 | },
167 | "dist": {
168 | "type": "zip",
169 | "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3e01bdad3e18354c3dce54466b7fbe33a9f9f7f8",
170 | "reference": "3e01bdad3e18354c3dce54466b7fbe33a9f9f7f8",
171 | "shasum": ""
172 | },
173 | "require": {
174 | "php": "^7.1"
175 | },
176 | "replace": {
177 | "myclabs/deep-copy": "self.version"
178 | },
179 | "require-dev": {
180 | "doctrine/collections": "^1.0",
181 | "doctrine/common": "^2.6",
182 | "phpunit/phpunit": "^7.1"
183 | },
184 | "type": "library",
185 | "autoload": {
186 | "psr-4": {
187 | "DeepCopy\\": "src/DeepCopy/"
188 | },
189 | "files": [
190 | "src/DeepCopy/deep_copy.php"
191 | ]
192 | },
193 | "notification-url": "https://packagist.org/downloads/",
194 | "license": [
195 | "MIT"
196 | ],
197 | "description": "Create deep copies (clones) of your objects",
198 | "keywords": [
199 | "clone",
200 | "copy",
201 | "duplicate",
202 | "object",
203 | "object graph"
204 | ],
205 | "time": "2018-06-11T23:09:50+00:00"
206 | },
207 | {
208 | "name": "nette/bootstrap",
209 | "version": "v2.4.6",
210 | "source": {
211 | "type": "git",
212 | "url": "https://github.com/nette/bootstrap.git",
213 | "reference": "268816e3f1bb7426c3a4ceec2bd38a036b532543"
214 | },
215 | "dist": {
216 | "type": "zip",
217 | "url": "https://api.github.com/repos/nette/bootstrap/zipball/268816e3f1bb7426c3a4ceec2bd38a036b532543",
218 | "reference": "268816e3f1bb7426c3a4ceec2bd38a036b532543",
219 | "shasum": ""
220 | },
221 | "require": {
222 | "nette/di": "~2.4.7",
223 | "nette/utils": "~2.4",
224 | "php": ">=5.6.0"
225 | },
226 | "conflict": {
227 | "nette/nette": "<2.2"
228 | },
229 | "require-dev": {
230 | "latte/latte": "~2.2",
231 | "nette/application": "~2.3",
232 | "nette/caching": "~2.3",
233 | "nette/database": "~2.3",
234 | "nette/forms": "~2.3",
235 | "nette/http": "~2.4.0",
236 | "nette/mail": "~2.3",
237 | "nette/robot-loader": "^2.4.2 || ^3.0",
238 | "nette/safe-stream": "~2.2",
239 | "nette/security": "~2.3",
240 | "nette/tester": "~2.0",
241 | "tracy/tracy": "^2.4.1"
242 | },
243 | "suggest": {
244 | "nette/robot-loader": "to use Configurator::createRobotLoader()",
245 | "tracy/tracy": "to use Configurator::enableTracy()"
246 | },
247 | "type": "library",
248 | "extra": {
249 | "branch-alias": {
250 | "dev-master": "2.4-dev"
251 | }
252 | },
253 | "autoload": {
254 | "classmap": [
255 | "src/"
256 | ]
257 | },
258 | "notification-url": "https://packagist.org/downloads/",
259 | "license": [
260 | "BSD-3-Clause",
261 | "GPL-2.0",
262 | "GPL-3.0"
263 | ],
264 | "authors": [
265 | {
266 | "name": "David Grudl",
267 | "homepage": "https://davidgrudl.com"
268 | },
269 | {
270 | "name": "Nette Community",
271 | "homepage": "https://nette.org/contributors"
272 | }
273 | ],
274 | "description": "🅱 Nette Bootstrap: the simple way to configure and bootstrap your Nette application.",
275 | "homepage": "https://nette.org",
276 | "keywords": [
277 | "bootstrapping",
278 | "configurator",
279 | "nette"
280 | ],
281 | "time": "2018-05-17T12:52:20+00:00"
282 | },
283 | {
284 | "name": "nette/di",
285 | "version": "v2.4.14",
286 | "source": {
287 | "type": "git",
288 | "url": "https://github.com/nette/di.git",
289 | "reference": "923da3e2c0aa53162ef455472c0ac7787b096c5a"
290 | },
291 | "dist": {
292 | "type": "zip",
293 | "url": "https://api.github.com/repos/nette/di/zipball/923da3e2c0aa53162ef455472c0ac7787b096c5a",
294 | "reference": "923da3e2c0aa53162ef455472c0ac7787b096c5a",
295 | "shasum": ""
296 | },
297 | "require": {
298 | "ext-tokenizer": "*",
299 | "nette/neon": "^2.3.3 || ~3.0.0",
300 | "nette/php-generator": "^2.6.1 || ~3.0.0",
301 | "nette/utils": "^2.4.3 || ~3.0.0",
302 | "php": ">=5.6.0"
303 | },
304 | "conflict": {
305 | "nette/bootstrap": "<2.4",
306 | "nette/nette": "<2.2"
307 | },
308 | "require-dev": {
309 | "nette/tester": "^2.0",
310 | "tracy/tracy": "^2.3"
311 | },
312 | "type": "library",
313 | "extra": {
314 | "branch-alias": {
315 | "dev-master": "2.4-dev"
316 | }
317 | },
318 | "autoload": {
319 | "classmap": [
320 | "src/"
321 | ]
322 | },
323 | "notification-url": "https://packagist.org/downloads/",
324 | "license": [
325 | "BSD-3-Clause",
326 | "GPL-2.0",
327 | "GPL-3.0"
328 | ],
329 | "authors": [
330 | {
331 | "name": "David Grudl",
332 | "homepage": "https://davidgrudl.com"
333 | },
334 | {
335 | "name": "Nette Community",
336 | "homepage": "https://nette.org/contributors"
337 | }
338 | ],
339 | "description": "💎 Nette Dependency Injection Container: Flexible, compiled and full-featured DIC with perfectly usable autowiring and support for all new PHP 7.1 features.",
340 | "homepage": "https://nette.org",
341 | "keywords": [
342 | "compiled",
343 | "di",
344 | "dic",
345 | "factory",
346 | "ioc",
347 | "nette",
348 | "static"
349 | ],
350 | "time": "2018-09-17T15:47:40+00:00"
351 | },
352 | {
353 | "name": "nette/finder",
354 | "version": "v2.4.2",
355 | "source": {
356 | "type": "git",
357 | "url": "https://github.com/nette/finder.git",
358 | "reference": "ee951a656cb8ac622e5dd33474a01fd2470505a0"
359 | },
360 | "dist": {
361 | "type": "zip",
362 | "url": "https://api.github.com/repos/nette/finder/zipball/ee951a656cb8ac622e5dd33474a01fd2470505a0",
363 | "reference": "ee951a656cb8ac622e5dd33474a01fd2470505a0",
364 | "shasum": ""
365 | },
366 | "require": {
367 | "nette/utils": "~2.4",
368 | "php": ">=5.6.0"
369 | },
370 | "conflict": {
371 | "nette/nette": "<2.2"
372 | },
373 | "require-dev": {
374 | "nette/tester": "~2.0",
375 | "tracy/tracy": "^2.3"
376 | },
377 | "type": "library",
378 | "extra": {
379 | "branch-alias": {
380 | "dev-master": "2.4-dev"
381 | }
382 | },
383 | "autoload": {
384 | "classmap": [
385 | "src/"
386 | ]
387 | },
388 | "notification-url": "https://packagist.org/downloads/",
389 | "license": [
390 | "BSD-3-Clause",
391 | "GPL-2.0",
392 | "GPL-3.0"
393 | ],
394 | "authors": [
395 | {
396 | "name": "David Grudl",
397 | "homepage": "https://davidgrudl.com"
398 | },
399 | {
400 | "name": "Nette Community",
401 | "homepage": "https://nette.org/contributors"
402 | }
403 | ],
404 | "description": "🔍 Nette Finder: find files and directories with an intuitive API.",
405 | "homepage": "https://nette.org",
406 | "keywords": [
407 | "filesystem",
408 | "glob",
409 | "iterator",
410 | "nette"
411 | ],
412 | "time": "2018-06-28T11:49:23+00:00"
413 | },
414 | {
415 | "name": "nette/neon",
416 | "version": "v2.4.3",
417 | "source": {
418 | "type": "git",
419 | "url": "https://github.com/nette/neon.git",
420 | "reference": "5e72b1dd3e2d34f0863c5561139a19df6a1ef398"
421 | },
422 | "dist": {
423 | "type": "zip",
424 | "url": "https://api.github.com/repos/nette/neon/zipball/5e72b1dd3e2d34f0863c5561139a19df6a1ef398",
425 | "reference": "5e72b1dd3e2d34f0863c5561139a19df6a1ef398",
426 | "shasum": ""
427 | },
428 | "require": {
429 | "ext-iconv": "*",
430 | "ext-json": "*",
431 | "php": ">=5.6.0"
432 | },
433 | "require-dev": {
434 | "nette/tester": "~2.0",
435 | "tracy/tracy": "^2.3"
436 | },
437 | "type": "library",
438 | "extra": {
439 | "branch-alias": {
440 | "dev-master": "2.4-dev"
441 | }
442 | },
443 | "autoload": {
444 | "classmap": [
445 | "src/"
446 | ]
447 | },
448 | "notification-url": "https://packagist.org/downloads/",
449 | "license": [
450 | "BSD-3-Clause",
451 | "GPL-2.0",
452 | "GPL-3.0"
453 | ],
454 | "authors": [
455 | {
456 | "name": "David Grudl",
457 | "homepage": "https://davidgrudl.com"
458 | },
459 | {
460 | "name": "Nette Community",
461 | "homepage": "https://nette.org/contributors"
462 | }
463 | ],
464 | "description": "🍸 Nette NEON: encodes and decodes NEON file format.",
465 | "homepage": "http://ne-on.org",
466 | "keywords": [
467 | "export",
468 | "import",
469 | "neon",
470 | "nette",
471 | "yaml"
472 | ],
473 | "time": "2018-03-21T12:12:21+00:00"
474 | },
475 | {
476 | "name": "nette/php-generator",
477 | "version": "v3.0.5",
478 | "source": {
479 | "type": "git",
480 | "url": "https://github.com/nette/php-generator.git",
481 | "reference": "ea90209c2e8a7cd087b2742ca553c047a8df5eff"
482 | },
483 | "dist": {
484 | "type": "zip",
485 | "url": "https://api.github.com/repos/nette/php-generator/zipball/ea90209c2e8a7cd087b2742ca553c047a8df5eff",
486 | "reference": "ea90209c2e8a7cd087b2742ca553c047a8df5eff",
487 | "shasum": ""
488 | },
489 | "require": {
490 | "nette/utils": "^2.4.2 || ~3.0.0",
491 | "php": ">=7.0"
492 | },
493 | "conflict": {
494 | "nette/nette": "<2.2"
495 | },
496 | "require-dev": {
497 | "nette/tester": "^2.0",
498 | "tracy/tracy": "^2.3"
499 | },
500 | "type": "library",
501 | "extra": {
502 | "branch-alias": {
503 | "dev-master": "3.0-dev"
504 | }
505 | },
506 | "autoload": {
507 | "classmap": [
508 | "src/"
509 | ]
510 | },
511 | "notification-url": "https://packagist.org/downloads/",
512 | "license": [
513 | "BSD-3-Clause",
514 | "GPL-2.0",
515 | "GPL-3.0"
516 | ],
517 | "authors": [
518 | {
519 | "name": "David Grudl",
520 | "homepage": "https://davidgrudl.com"
521 | },
522 | {
523 | "name": "Nette Community",
524 | "homepage": "https://nette.org/contributors"
525 | }
526 | ],
527 | "description": "🐘 Nette PHP Generator: generates neat PHP code for you. Supports new PHP 7.2 features.",
528 | "homepage": "https://nette.org",
529 | "keywords": [
530 | "code",
531 | "nette",
532 | "php",
533 | "scaffolding"
534 | ],
535 | "time": "2018-08-09T14:32:27+00:00"
536 | },
537 | {
538 | "name": "nette/robot-loader",
539 | "version": "v3.1.0",
540 | "source": {
541 | "type": "git",
542 | "url": "https://github.com/nette/robot-loader.git",
543 | "reference": "fc76c70e740b10f091e502b2e393d0be912f38d4"
544 | },
545 | "dist": {
546 | "type": "zip",
547 | "url": "https://api.github.com/repos/nette/robot-loader/zipball/fc76c70e740b10f091e502b2e393d0be912f38d4",
548 | "reference": "fc76c70e740b10f091e502b2e393d0be912f38d4",
549 | "shasum": ""
550 | },
551 | "require": {
552 | "ext-tokenizer": "*",
553 | "nette/finder": "^2.3 || ^3.0",
554 | "nette/utils": "^2.4 || ^3.0",
555 | "php": ">=5.6.0"
556 | },
557 | "conflict": {
558 | "nette/nette": "<2.2"
559 | },
560 | "require-dev": {
561 | "nette/tester": "^2.0",
562 | "tracy/tracy": "^2.3"
563 | },
564 | "type": "library",
565 | "extra": {
566 | "branch-alias": {
567 | "dev-master": "3.1-dev"
568 | }
569 | },
570 | "autoload": {
571 | "classmap": [
572 | "src/"
573 | ]
574 | },
575 | "notification-url": "https://packagist.org/downloads/",
576 | "license": [
577 | "BSD-3-Clause",
578 | "GPL-2.0",
579 | "GPL-3.0"
580 | ],
581 | "authors": [
582 | {
583 | "name": "David Grudl",
584 | "homepage": "https://davidgrudl.com"
585 | },
586 | {
587 | "name": "Nette Community",
588 | "homepage": "https://nette.org/contributors"
589 | }
590 | ],
591 | "description": "🍀 Nette RobotLoader: high performance and comfortable autoloader that will search and autoload classes within your application.",
592 | "homepage": "https://nette.org",
593 | "keywords": [
594 | "autoload",
595 | "class",
596 | "interface",
597 | "nette",
598 | "trait"
599 | ],
600 | "time": "2018-08-13T14:19:06+00:00"
601 | },
602 | {
603 | "name": "nette/utils",
604 | "version": "v2.5.3",
605 | "source": {
606 | "type": "git",
607 | "url": "https://github.com/nette/utils.git",
608 | "reference": "17b9f76f2abd0c943adfb556e56f2165460b15ce"
609 | },
610 | "dist": {
611 | "type": "zip",
612 | "url": "https://api.github.com/repos/nette/utils/zipball/17b9f76f2abd0c943adfb556e56f2165460b15ce",
613 | "reference": "17b9f76f2abd0c943adfb556e56f2165460b15ce",
614 | "shasum": ""
615 | },
616 | "require": {
617 | "php": ">=5.6.0"
618 | },
619 | "conflict": {
620 | "nette/nette": "<2.2"
621 | },
622 | "require-dev": {
623 | "nette/tester": "~2.0",
624 | "tracy/tracy": "^2.3"
625 | },
626 | "suggest": {
627 | "ext-gd": "to use Image",
628 | "ext-iconv": "to use Strings::webalize() and toAscii()",
629 | "ext-intl": "for script transliteration in Strings::webalize() and toAscii()",
630 | "ext-json": "to use Nette\\Utils\\Json",
631 | "ext-mbstring": "to use Strings::lower() etc...",
632 | "ext-xml": "to use Strings::length() etc. when mbstring is not available"
633 | },
634 | "type": "library",
635 | "extra": {
636 | "branch-alias": {
637 | "dev-master": "2.5-dev"
638 | }
639 | },
640 | "autoload": {
641 | "classmap": [
642 | "src/"
643 | ],
644 | "files": [
645 | "src/loader.php"
646 | ]
647 | },
648 | "notification-url": "https://packagist.org/downloads/",
649 | "license": [
650 | "BSD-3-Clause",
651 | "GPL-2.0",
652 | "GPL-3.0"
653 | ],
654 | "authors": [
655 | {
656 | "name": "David Grudl",
657 | "homepage": "https://davidgrudl.com"
658 | },
659 | {
660 | "name": "Nette Community",
661 | "homepage": "https://nette.org/contributors"
662 | }
663 | ],
664 | "description": "🛠 Nette Utils: lightweight utilities for string & array manipulation, image handling, safe JSON encoding/decoding, validation, slug or strong password generating etc.",
665 | "homepage": "https://nette.org",
666 | "keywords": [
667 | "array",
668 | "core",
669 | "datetime",
670 | "images",
671 | "json",
672 | "nette",
673 | "paginator",
674 | "password",
675 | "slugify",
676 | "string",
677 | "unicode",
678 | "utf-8",
679 | "utility",
680 | "validation"
681 | ],
682 | "time": "2018-09-18T10:22:16+00:00"
683 | },
684 | {
685 | "name": "nikic/php-parser",
686 | "version": "v4.2.0",
687 | "source": {
688 | "type": "git",
689 | "url": "https://github.com/nikic/PHP-Parser.git",
690 | "reference": "594bcae1fc0bccd3993d2f0d61a018e26ac2865a"
691 | },
692 | "dist": {
693 | "type": "zip",
694 | "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/594bcae1fc0bccd3993d2f0d61a018e26ac2865a",
695 | "reference": "594bcae1fc0bccd3993d2f0d61a018e26ac2865a",
696 | "shasum": ""
697 | },
698 | "require": {
699 | "ext-tokenizer": "*",
700 | "php": ">=7.0"
701 | },
702 | "require-dev": {
703 | "phpunit/phpunit": "^6.5 || ^7.0"
704 | },
705 | "bin": [
706 | "bin/php-parse"
707 | ],
708 | "type": "library",
709 | "extra": {
710 | "branch-alias": {
711 | "dev-master": "4.2-dev"
712 | }
713 | },
714 | "autoload": {
715 | "psr-4": {
716 | "PhpParser\\": "lib/PhpParser"
717 | }
718 | },
719 | "notification-url": "https://packagist.org/downloads/",
720 | "license": [
721 | "BSD-3-Clause"
722 | ],
723 | "authors": [
724 | {
725 | "name": "Nikita Popov"
726 | }
727 | ],
728 | "description": "A PHP parser written in PHP",
729 | "keywords": [
730 | "parser",
731 | "php"
732 | ],
733 | "time": "2019-01-12T16:31:37+00:00"
734 | },
735 | {
736 | "name": "ocramius/package-versions",
737 | "version": "1.3.0",
738 | "source": {
739 | "type": "git",
740 | "url": "https://github.com/Ocramius/PackageVersions.git",
741 | "reference": "4489d5002c49d55576fa0ba786f42dbb009be46f"
742 | },
743 | "dist": {
744 | "type": "zip",
745 | "url": "https://api.github.com/repos/Ocramius/PackageVersions/zipball/4489d5002c49d55576fa0ba786f42dbb009be46f",
746 | "reference": "4489d5002c49d55576fa0ba786f42dbb009be46f",
747 | "shasum": ""
748 | },
749 | "require": {
750 | "composer-plugin-api": "^1.0.0",
751 | "php": "^7.1.0"
752 | },
753 | "require-dev": {
754 | "composer/composer": "^1.6.3",
755 | "ext-zip": "*",
756 | "infection/infection": "^0.7.1",
757 | "phpunit/phpunit": "^7.0.0"
758 | },
759 | "type": "composer-plugin",
760 | "extra": {
761 | "class": "PackageVersions\\Installer",
762 | "branch-alias": {
763 | "dev-master": "2.0.x-dev"
764 | }
765 | },
766 | "autoload": {
767 | "psr-4": {
768 | "PackageVersions\\": "src/PackageVersions"
769 | }
770 | },
771 | "notification-url": "https://packagist.org/downloads/",
772 | "license": [
773 | "MIT"
774 | ],
775 | "authors": [
776 | {
777 | "name": "Marco Pivetta",
778 | "email": "ocramius@gmail.com"
779 | }
780 | ],
781 | "description": "Composer plugin that provides efficient querying for installed package versions (no runtime IO)",
782 | "time": "2018-02-05T13:05:30+00:00"
783 | },
784 | {
785 | "name": "overtrue/phplint",
786 | "version": "1.1.9",
787 | "source": {
788 | "type": "git",
789 | "url": "https://github.com/overtrue/phplint.git",
790 | "reference": "dab041512195a6bf52401a66b65dc5b19e4d09ea"
791 | },
792 | "dist": {
793 | "type": "zip",
794 | "url": "https://api.github.com/repos/overtrue/phplint/zipball/dab041512195a6bf52401a66b65dc5b19e4d09ea",
795 | "reference": "dab041512195a6bf52401a66b65dc5b19e4d09ea",
796 | "shasum": ""
797 | },
798 | "require": {
799 | "ext-json": "*",
800 | "php": ">=5.5.9",
801 | "symfony/console": "^3.2|^4.0",
802 | "symfony/finder": "^3.0|^4.0",
803 | "symfony/process": "^3.0|^4.0",
804 | "symfony/yaml": "^3.0|^4.0"
805 | },
806 | "require-dev": {
807 | "jakub-onderka/php-console-highlighter": "^0.3.2"
808 | },
809 | "bin": [
810 | "bin/phplint"
811 | ],
812 | "type": "library",
813 | "autoload": {
814 | "psr-4": {
815 | "Overtrue\\PHPLint\\": "src/"
816 | }
817 | },
818 | "notification-url": "https://packagist.org/downloads/",
819 | "license": [
820 | "MIT"
821 | ],
822 | "authors": [
823 | {
824 | "name": "overtrue",
825 | "email": "anzhengchao@gmail.com"
826 | }
827 | ],
828 | "description": "a php syntax check tool.",
829 | "keywords": [
830 | "check",
831 | "lint",
832 | "phplint",
833 | "syntax"
834 | ],
835 | "time": "2019-01-04T12:59:53+00:00"
836 | },
837 | {
838 | "name": "phar-io/manifest",
839 | "version": "1.0.3",
840 | "source": {
841 | "type": "git",
842 | "url": "https://github.com/phar-io/manifest.git",
843 | "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4"
844 | },
845 | "dist": {
846 | "type": "zip",
847 | "url": "https://api.github.com/repos/phar-io/manifest/zipball/7761fcacf03b4d4f16e7ccb606d4879ca431fcf4",
848 | "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4",
849 | "shasum": ""
850 | },
851 | "require": {
852 | "ext-dom": "*",
853 | "ext-phar": "*",
854 | "phar-io/version": "^2.0",
855 | "php": "^5.6 || ^7.0"
856 | },
857 | "type": "library",
858 | "extra": {
859 | "branch-alias": {
860 | "dev-master": "1.0.x-dev"
861 | }
862 | },
863 | "autoload": {
864 | "classmap": [
865 | "src/"
866 | ]
867 | },
868 | "notification-url": "https://packagist.org/downloads/",
869 | "license": [
870 | "BSD-3-Clause"
871 | ],
872 | "authors": [
873 | {
874 | "name": "Arne Blankerts",
875 | "email": "arne@blankerts.de",
876 | "role": "Developer"
877 | },
878 | {
879 | "name": "Sebastian Heuer",
880 | "email": "sebastian@phpeople.de",
881 | "role": "Developer"
882 | },
883 | {
884 | "name": "Sebastian Bergmann",
885 | "email": "sebastian@phpunit.de",
886 | "role": "Developer"
887 | }
888 | ],
889 | "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)",
890 | "time": "2018-07-08T19:23:20+00:00"
891 | },
892 | {
893 | "name": "phar-io/version",
894 | "version": "2.0.1",
895 | "source": {
896 | "type": "git",
897 | "url": "https://github.com/phar-io/version.git",
898 | "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6"
899 | },
900 | "dist": {
901 | "type": "zip",
902 | "url": "https://api.github.com/repos/phar-io/version/zipball/45a2ec53a73c70ce41d55cedef9063630abaf1b6",
903 | "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6",
904 | "shasum": ""
905 | },
906 | "require": {
907 | "php": "^5.6 || ^7.0"
908 | },
909 | "type": "library",
910 | "autoload": {
911 | "classmap": [
912 | "src/"
913 | ]
914 | },
915 | "notification-url": "https://packagist.org/downloads/",
916 | "license": [
917 | "BSD-3-Clause"
918 | ],
919 | "authors": [
920 | {
921 | "name": "Arne Blankerts",
922 | "email": "arne@blankerts.de",
923 | "role": "Developer"
924 | },
925 | {
926 | "name": "Sebastian Heuer",
927 | "email": "sebastian@phpeople.de",
928 | "role": "Developer"
929 | },
930 | {
931 | "name": "Sebastian Bergmann",
932 | "email": "sebastian@phpunit.de",
933 | "role": "Developer"
934 | }
935 | ],
936 | "description": "Library for handling version information and constraints",
937 | "time": "2018-07-08T19:19:57+00:00"
938 | },
939 | {
940 | "name": "phpdocumentor/reflection-common",
941 | "version": "1.0.1",
942 | "source": {
943 | "type": "git",
944 | "url": "https://github.com/phpDocumentor/ReflectionCommon.git",
945 | "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6"
946 | },
947 | "dist": {
948 | "type": "zip",
949 | "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6",
950 | "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6",
951 | "shasum": ""
952 | },
953 | "require": {
954 | "php": ">=5.5"
955 | },
956 | "require-dev": {
957 | "phpunit/phpunit": "^4.6"
958 | },
959 | "type": "library",
960 | "extra": {
961 | "branch-alias": {
962 | "dev-master": "1.0.x-dev"
963 | }
964 | },
965 | "autoload": {
966 | "psr-4": {
967 | "phpDocumentor\\Reflection\\": [
968 | "src"
969 | ]
970 | }
971 | },
972 | "notification-url": "https://packagist.org/downloads/",
973 | "license": [
974 | "MIT"
975 | ],
976 | "authors": [
977 | {
978 | "name": "Jaap van Otterdijk",
979 | "email": "opensource@ijaap.nl"
980 | }
981 | ],
982 | "description": "Common reflection classes used by phpdocumentor to reflect the code structure",
983 | "homepage": "http://www.phpdoc.org",
984 | "keywords": [
985 | "FQSEN",
986 | "phpDocumentor",
987 | "phpdoc",
988 | "reflection",
989 | "static analysis"
990 | ],
991 | "time": "2017-09-11T18:02:19+00:00"
992 | },
993 | {
994 | "name": "phpdocumentor/reflection-docblock",
995 | "version": "4.3.0",
996 | "source": {
997 | "type": "git",
998 | "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
999 | "reference": "94fd0001232e47129dd3504189fa1c7225010d08"
1000 | },
1001 | "dist": {
1002 | "type": "zip",
1003 | "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/94fd0001232e47129dd3504189fa1c7225010d08",
1004 | "reference": "94fd0001232e47129dd3504189fa1c7225010d08",
1005 | "shasum": ""
1006 | },
1007 | "require": {
1008 | "php": "^7.0",
1009 | "phpdocumentor/reflection-common": "^1.0.0",
1010 | "phpdocumentor/type-resolver": "^0.4.0",
1011 | "webmozart/assert": "^1.0"
1012 | },
1013 | "require-dev": {
1014 | "doctrine/instantiator": "~1.0.5",
1015 | "mockery/mockery": "^1.0",
1016 | "phpunit/phpunit": "^6.4"
1017 | },
1018 | "type": "library",
1019 | "extra": {
1020 | "branch-alias": {
1021 | "dev-master": "4.x-dev"
1022 | }
1023 | },
1024 | "autoload": {
1025 | "psr-4": {
1026 | "phpDocumentor\\Reflection\\": [
1027 | "src/"
1028 | ]
1029 | }
1030 | },
1031 | "notification-url": "https://packagist.org/downloads/",
1032 | "license": [
1033 | "MIT"
1034 | ],
1035 | "authors": [
1036 | {
1037 | "name": "Mike van Riel",
1038 | "email": "me@mikevanriel.com"
1039 | }
1040 | ],
1041 | "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.",
1042 | "time": "2017-11-30T07:14:17+00:00"
1043 | },
1044 | {
1045 | "name": "phpdocumentor/type-resolver",
1046 | "version": "0.4.0",
1047 | "source": {
1048 | "type": "git",
1049 | "url": "https://github.com/phpDocumentor/TypeResolver.git",
1050 | "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7"
1051 | },
1052 | "dist": {
1053 | "type": "zip",
1054 | "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/9c977708995954784726e25d0cd1dddf4e65b0f7",
1055 | "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7",
1056 | "shasum": ""
1057 | },
1058 | "require": {
1059 | "php": "^5.5 || ^7.0",
1060 | "phpdocumentor/reflection-common": "^1.0"
1061 | },
1062 | "require-dev": {
1063 | "mockery/mockery": "^0.9.4",
1064 | "phpunit/phpunit": "^5.2||^4.8.24"
1065 | },
1066 | "type": "library",
1067 | "extra": {
1068 | "branch-alias": {
1069 | "dev-master": "1.0.x-dev"
1070 | }
1071 | },
1072 | "autoload": {
1073 | "psr-4": {
1074 | "phpDocumentor\\Reflection\\": [
1075 | "src/"
1076 | ]
1077 | }
1078 | },
1079 | "notification-url": "https://packagist.org/downloads/",
1080 | "license": [
1081 | "MIT"
1082 | ],
1083 | "authors": [
1084 | {
1085 | "name": "Mike van Riel",
1086 | "email": "me@mikevanriel.com"
1087 | }
1088 | ],
1089 | "time": "2017-07-14T14:27:02+00:00"
1090 | },
1091 | {
1092 | "name": "phpspec/prophecy",
1093 | "version": "1.8.0",
1094 | "source": {
1095 | "type": "git",
1096 | "url": "https://github.com/phpspec/prophecy.git",
1097 | "reference": "4ba436b55987b4bf311cb7c6ba82aa528aac0a06"
1098 | },
1099 | "dist": {
1100 | "type": "zip",
1101 | "url": "https://api.github.com/repos/phpspec/prophecy/zipball/4ba436b55987b4bf311cb7c6ba82aa528aac0a06",
1102 | "reference": "4ba436b55987b4bf311cb7c6ba82aa528aac0a06",
1103 | "shasum": ""
1104 | },
1105 | "require": {
1106 | "doctrine/instantiator": "^1.0.2",
1107 | "php": "^5.3|^7.0",
1108 | "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0",
1109 | "sebastian/comparator": "^1.1|^2.0|^3.0",
1110 | "sebastian/recursion-context": "^1.0|^2.0|^3.0"
1111 | },
1112 | "require-dev": {
1113 | "phpspec/phpspec": "^2.5|^3.2",
1114 | "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5 || ^7.1"
1115 | },
1116 | "type": "library",
1117 | "extra": {
1118 | "branch-alias": {
1119 | "dev-master": "1.8.x-dev"
1120 | }
1121 | },
1122 | "autoload": {
1123 | "psr-0": {
1124 | "Prophecy\\": "src/"
1125 | }
1126 | },
1127 | "notification-url": "https://packagist.org/downloads/",
1128 | "license": [
1129 | "MIT"
1130 | ],
1131 | "authors": [
1132 | {
1133 | "name": "Konstantin Kudryashov",
1134 | "email": "ever.zet@gmail.com",
1135 | "homepage": "http://everzet.com"
1136 | },
1137 | {
1138 | "name": "Marcello Duarte",
1139 | "email": "marcello.duarte@gmail.com"
1140 | }
1141 | ],
1142 | "description": "Highly opinionated mocking framework for PHP 5.3+",
1143 | "homepage": "https://github.com/phpspec/prophecy",
1144 | "keywords": [
1145 | "Double",
1146 | "Dummy",
1147 | "fake",
1148 | "mock",
1149 | "spy",
1150 | "stub"
1151 | ],
1152 | "time": "2018-08-05T17:53:17+00:00"
1153 | },
1154 | {
1155 | "name": "phpstan/phpdoc-parser",
1156 | "version": "0.3.1",
1157 | "source": {
1158 | "type": "git",
1159 | "url": "https://github.com/phpstan/phpdoc-parser.git",
1160 | "reference": "2cc49f47c69b023eaf05b48e6529389893b13d74"
1161 | },
1162 | "dist": {
1163 | "type": "zip",
1164 | "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/2cc49f47c69b023eaf05b48e6529389893b13d74",
1165 | "reference": "2cc49f47c69b023eaf05b48e6529389893b13d74",
1166 | "shasum": ""
1167 | },
1168 | "require": {
1169 | "php": "~7.1"
1170 | },
1171 | "require-dev": {
1172 | "consistence/coding-standard": "^2.0.0",
1173 | "jakub-onderka/php-parallel-lint": "^0.9.2",
1174 | "phing/phing": "^2.16.0",
1175 | "phpstan/phpstan": "^0.10",
1176 | "phpunit/phpunit": "^6.3",
1177 | "slevomat/coding-standard": "^3.3.0",
1178 | "symfony/process": "^3.4 || ^4.0"
1179 | },
1180 | "type": "library",
1181 | "extra": {
1182 | "branch-alias": {
1183 | "dev-master": "0.3-dev"
1184 | }
1185 | },
1186 | "autoload": {
1187 | "psr-4": {
1188 | "PHPStan\\PhpDocParser\\": [
1189 | "src/"
1190 | ]
1191 | }
1192 | },
1193 | "notification-url": "https://packagist.org/downloads/",
1194 | "license": [
1195 | "MIT"
1196 | ],
1197 | "description": "PHPDoc parser with support for nullable, intersection and generic types",
1198 | "time": "2019-01-14T12:26:23+00:00"
1199 | },
1200 | {
1201 | "name": "phpstan/phpstan",
1202 | "version": "0.11.1",
1203 | "source": {
1204 | "type": "git",
1205 | "url": "https://github.com/phpstan/phpstan.git",
1206 | "reference": "a138b8a2731b2c19f1dffa2f1411984a638fe977"
1207 | },
1208 | "dist": {
1209 | "type": "zip",
1210 | "url": "https://api.github.com/repos/phpstan/phpstan/zipball/a138b8a2731b2c19f1dffa2f1411984a638fe977",
1211 | "reference": "a138b8a2731b2c19f1dffa2f1411984a638fe977",
1212 | "shasum": ""
1213 | },
1214 | "require": {
1215 | "composer/xdebug-handler": "^1.3.0",
1216 | "jean85/pretty-package-versions": "^1.0.3",
1217 | "nette/bootstrap": "^2.4 || ^3.0",
1218 | "nette/di": "^2.4.7 || ^3.0",
1219 | "nette/robot-loader": "^3.0.1",
1220 | "nette/utils": "^2.4.5 || ^3.0",
1221 | "nikic/php-parser": "^4.0.2",
1222 | "php": "~7.1",
1223 | "phpstan/phpdoc-parser": "^0.3",
1224 | "symfony/console": "~3.2 || ~4.0",
1225 | "symfony/finder": "~3.2 || ~4.0"
1226 | },
1227 | "conflict": {
1228 | "symfony/console": "3.4.16 || 4.1.5"
1229 | },
1230 | "require-dev": {
1231 | "brianium/paratest": "^2.0",
1232 | "consistence/coding-standard": "^3.5",
1233 | "dealerdirect/phpcodesniffer-composer-installer": "^0.4.4",
1234 | "ext-intl": "*",
1235 | "ext-mysqli": "*",
1236 | "ext-soap": "*",
1237 | "ext-zip": "*",
1238 | "jakub-onderka/php-parallel-lint": "^1.0",
1239 | "localheinz/composer-normalize": "^1.1.0",
1240 | "phing/phing": "^2.16.0",
1241 | "phpstan/phpstan-deprecation-rules": "^0.11",
1242 | "phpstan/phpstan-php-parser": "^0.11",
1243 | "phpstan/phpstan-phpunit": "^0.11",
1244 | "phpstan/phpstan-strict-rules": "^0.11",
1245 | "phpunit/phpunit": "^7.0",
1246 | "slevomat/coding-standard": "^4.7.2",
1247 | "squizlabs/php_codesniffer": "^3.3.2"
1248 | },
1249 | "bin": [
1250 | "bin/phpstan"
1251 | ],
1252 | "type": "library",
1253 | "extra": {
1254 | "branch-alias": {
1255 | "dev-master": "0.11-dev"
1256 | }
1257 | },
1258 | "autoload": {
1259 | "psr-4": {
1260 | "PHPStan\\": [
1261 | "src/",
1262 | "build/PHPStan"
1263 | ]
1264 | }
1265 | },
1266 | "notification-url": "https://packagist.org/downloads/",
1267 | "license": [
1268 | "MIT"
1269 | ],
1270 | "description": "PHPStan - PHP Static Analysis Tool",
1271 | "time": "2019-01-19T20:23:08+00:00"
1272 | },
1273 | {
1274 | "name": "phpunit/php-code-coverage",
1275 | "version": "6.1.4",
1276 | "source": {
1277 | "type": "git",
1278 | "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
1279 | "reference": "807e6013b00af69b6c5d9ceb4282d0393dbb9d8d"
1280 | },
1281 | "dist": {
1282 | "type": "zip",
1283 | "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/807e6013b00af69b6c5d9ceb4282d0393dbb9d8d",
1284 | "reference": "807e6013b00af69b6c5d9ceb4282d0393dbb9d8d",
1285 | "shasum": ""
1286 | },
1287 | "require": {
1288 | "ext-dom": "*",
1289 | "ext-xmlwriter": "*",
1290 | "php": "^7.1",
1291 | "phpunit/php-file-iterator": "^2.0",
1292 | "phpunit/php-text-template": "^1.2.1",
1293 | "phpunit/php-token-stream": "^3.0",
1294 | "sebastian/code-unit-reverse-lookup": "^1.0.1",
1295 | "sebastian/environment": "^3.1 || ^4.0",
1296 | "sebastian/version": "^2.0.1",
1297 | "theseer/tokenizer": "^1.1"
1298 | },
1299 | "require-dev": {
1300 | "phpunit/phpunit": "^7.0"
1301 | },
1302 | "suggest": {
1303 | "ext-xdebug": "^2.6.0"
1304 | },
1305 | "type": "library",
1306 | "extra": {
1307 | "branch-alias": {
1308 | "dev-master": "6.1-dev"
1309 | }
1310 | },
1311 | "autoload": {
1312 | "classmap": [
1313 | "src/"
1314 | ]
1315 | },
1316 | "notification-url": "https://packagist.org/downloads/",
1317 | "license": [
1318 | "BSD-3-Clause"
1319 | ],
1320 | "authors": [
1321 | {
1322 | "name": "Sebastian Bergmann",
1323 | "email": "sebastian@phpunit.de",
1324 | "role": "lead"
1325 | }
1326 | ],
1327 | "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.",
1328 | "homepage": "https://github.com/sebastianbergmann/php-code-coverage",
1329 | "keywords": [
1330 | "coverage",
1331 | "testing",
1332 | "xunit"
1333 | ],
1334 | "time": "2018-10-31T16:06:48+00:00"
1335 | },
1336 | {
1337 | "name": "phpunit/php-file-iterator",
1338 | "version": "2.0.2",
1339 | "source": {
1340 | "type": "git",
1341 | "url": "https://github.com/sebastianbergmann/php-file-iterator.git",
1342 | "reference": "050bedf145a257b1ff02746c31894800e5122946"
1343 | },
1344 | "dist": {
1345 | "type": "zip",
1346 | "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/050bedf145a257b1ff02746c31894800e5122946",
1347 | "reference": "050bedf145a257b1ff02746c31894800e5122946",
1348 | "shasum": ""
1349 | },
1350 | "require": {
1351 | "php": "^7.1"
1352 | },
1353 | "require-dev": {
1354 | "phpunit/phpunit": "^7.1"
1355 | },
1356 | "type": "library",
1357 | "extra": {
1358 | "branch-alias": {
1359 | "dev-master": "2.0.x-dev"
1360 | }
1361 | },
1362 | "autoload": {
1363 | "classmap": [
1364 | "src/"
1365 | ]
1366 | },
1367 | "notification-url": "https://packagist.org/downloads/",
1368 | "license": [
1369 | "BSD-3-Clause"
1370 | ],
1371 | "authors": [
1372 | {
1373 | "name": "Sebastian Bergmann",
1374 | "email": "sebastian@phpunit.de",
1375 | "role": "lead"
1376 | }
1377 | ],
1378 | "description": "FilterIterator implementation that filters files based on a list of suffixes.",
1379 | "homepage": "https://github.com/sebastianbergmann/php-file-iterator/",
1380 | "keywords": [
1381 | "filesystem",
1382 | "iterator"
1383 | ],
1384 | "time": "2018-09-13T20:33:42+00:00"
1385 | },
1386 | {
1387 | "name": "phpunit/php-text-template",
1388 | "version": "1.2.1",
1389 | "source": {
1390 | "type": "git",
1391 | "url": "https://github.com/sebastianbergmann/php-text-template.git",
1392 | "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686"
1393 | },
1394 | "dist": {
1395 | "type": "zip",
1396 | "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
1397 | "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
1398 | "shasum": ""
1399 | },
1400 | "require": {
1401 | "php": ">=5.3.3"
1402 | },
1403 | "type": "library",
1404 | "autoload": {
1405 | "classmap": [
1406 | "src/"
1407 | ]
1408 | },
1409 | "notification-url": "https://packagist.org/downloads/",
1410 | "license": [
1411 | "BSD-3-Clause"
1412 | ],
1413 | "authors": [
1414 | {
1415 | "name": "Sebastian Bergmann",
1416 | "email": "sebastian@phpunit.de",
1417 | "role": "lead"
1418 | }
1419 | ],
1420 | "description": "Simple template engine.",
1421 | "homepage": "https://github.com/sebastianbergmann/php-text-template/",
1422 | "keywords": [
1423 | "template"
1424 | ],
1425 | "time": "2015-06-21T13:50:34+00:00"
1426 | },
1427 | {
1428 | "name": "phpunit/php-timer",
1429 | "version": "2.0.0",
1430 | "source": {
1431 | "type": "git",
1432 | "url": "https://github.com/sebastianbergmann/php-timer.git",
1433 | "reference": "8b8454ea6958c3dee38453d3bd571e023108c91f"
1434 | },
1435 | "dist": {
1436 | "type": "zip",
1437 | "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/8b8454ea6958c3dee38453d3bd571e023108c91f",
1438 | "reference": "8b8454ea6958c3dee38453d3bd571e023108c91f",
1439 | "shasum": ""
1440 | },
1441 | "require": {
1442 | "php": "^7.1"
1443 | },
1444 | "require-dev": {
1445 | "phpunit/phpunit": "^7.0"
1446 | },
1447 | "type": "library",
1448 | "extra": {
1449 | "branch-alias": {
1450 | "dev-master": "2.0-dev"
1451 | }
1452 | },
1453 | "autoload": {
1454 | "classmap": [
1455 | "src/"
1456 | ]
1457 | },
1458 | "notification-url": "https://packagist.org/downloads/",
1459 | "license": [
1460 | "BSD-3-Clause"
1461 | ],
1462 | "authors": [
1463 | {
1464 | "name": "Sebastian Bergmann",
1465 | "email": "sebastian@phpunit.de",
1466 | "role": "lead"
1467 | }
1468 | ],
1469 | "description": "Utility class for timing",
1470 | "homepage": "https://github.com/sebastianbergmann/php-timer/",
1471 | "keywords": [
1472 | "timer"
1473 | ],
1474 | "time": "2018-02-01T13:07:23+00:00"
1475 | },
1476 | {
1477 | "name": "phpunit/php-token-stream",
1478 | "version": "3.0.1",
1479 | "source": {
1480 | "type": "git",
1481 | "url": "https://github.com/sebastianbergmann/php-token-stream.git",
1482 | "reference": "c99e3be9d3e85f60646f152f9002d46ed7770d18"
1483 | },
1484 | "dist": {
1485 | "type": "zip",
1486 | "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/c99e3be9d3e85f60646f152f9002d46ed7770d18",
1487 | "reference": "c99e3be9d3e85f60646f152f9002d46ed7770d18",
1488 | "shasum": ""
1489 | },
1490 | "require": {
1491 | "ext-tokenizer": "*",
1492 | "php": "^7.1"
1493 | },
1494 | "require-dev": {
1495 | "phpunit/phpunit": "^7.0"
1496 | },
1497 | "type": "library",
1498 | "extra": {
1499 | "branch-alias": {
1500 | "dev-master": "3.0-dev"
1501 | }
1502 | },
1503 | "autoload": {
1504 | "classmap": [
1505 | "src/"
1506 | ]
1507 | },
1508 | "notification-url": "https://packagist.org/downloads/",
1509 | "license": [
1510 | "BSD-3-Clause"
1511 | ],
1512 | "authors": [
1513 | {
1514 | "name": "Sebastian Bergmann",
1515 | "email": "sebastian@phpunit.de"
1516 | }
1517 | ],
1518 | "description": "Wrapper around PHP's tokenizer extension.",
1519 | "homepage": "https://github.com/sebastianbergmann/php-token-stream/",
1520 | "keywords": [
1521 | "tokenizer"
1522 | ],
1523 | "time": "2018-10-30T05:52:18+00:00"
1524 | },
1525 | {
1526 | "name": "phpunit/phpunit",
1527 | "version": "7.5.2",
1528 | "source": {
1529 | "type": "git",
1530 | "url": "https://github.com/sebastianbergmann/phpunit.git",
1531 | "reference": "7c89093bd00f7d5ddf0ab81dee04f801416b4944"
1532 | },
1533 | "dist": {
1534 | "type": "zip",
1535 | "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/7c89093bd00f7d5ddf0ab81dee04f801416b4944",
1536 | "reference": "7c89093bd00f7d5ddf0ab81dee04f801416b4944",
1537 | "shasum": ""
1538 | },
1539 | "require": {
1540 | "doctrine/instantiator": "^1.1",
1541 | "ext-dom": "*",
1542 | "ext-json": "*",
1543 | "ext-libxml": "*",
1544 | "ext-mbstring": "*",
1545 | "ext-xml": "*",
1546 | "myclabs/deep-copy": "^1.7",
1547 | "phar-io/manifest": "^1.0.2",
1548 | "phar-io/version": "^2.0",
1549 | "php": "^7.1",
1550 | "phpspec/prophecy": "^1.7",
1551 | "phpunit/php-code-coverage": "^6.0.7",
1552 | "phpunit/php-file-iterator": "^2.0.1",
1553 | "phpunit/php-text-template": "^1.2.1",
1554 | "phpunit/php-timer": "^2.0",
1555 | "sebastian/comparator": "^3.0",
1556 | "sebastian/diff": "^3.0",
1557 | "sebastian/environment": "^4.0",
1558 | "sebastian/exporter": "^3.1",
1559 | "sebastian/global-state": "^2.0",
1560 | "sebastian/object-enumerator": "^3.0.3",
1561 | "sebastian/resource-operations": "^2.0",
1562 | "sebastian/version": "^2.0.1"
1563 | },
1564 | "conflict": {
1565 | "phpunit/phpunit-mock-objects": "*"
1566 | },
1567 | "require-dev": {
1568 | "ext-pdo": "*"
1569 | },
1570 | "suggest": {
1571 | "ext-soap": "*",
1572 | "ext-xdebug": "*",
1573 | "phpunit/php-invoker": "^2.0"
1574 | },
1575 | "bin": [
1576 | "phpunit"
1577 | ],
1578 | "type": "library",
1579 | "extra": {
1580 | "branch-alias": {
1581 | "dev-master": "7.5-dev"
1582 | }
1583 | },
1584 | "autoload": {
1585 | "classmap": [
1586 | "src/"
1587 | ]
1588 | },
1589 | "notification-url": "https://packagist.org/downloads/",
1590 | "license": [
1591 | "BSD-3-Clause"
1592 | ],
1593 | "authors": [
1594 | {
1595 | "name": "Sebastian Bergmann",
1596 | "email": "sebastian@phpunit.de",
1597 | "role": "lead"
1598 | }
1599 | ],
1600 | "description": "The PHP Unit Testing framework.",
1601 | "homepage": "https://phpunit.de/",
1602 | "keywords": [
1603 | "phpunit",
1604 | "testing",
1605 | "xunit"
1606 | ],
1607 | "time": "2019-01-15T08:19:08+00:00"
1608 | },
1609 | {
1610 | "name": "psr/log",
1611 | "version": "1.1.0",
1612 | "source": {
1613 | "type": "git",
1614 | "url": "https://github.com/php-fig/log.git",
1615 | "reference": "6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd"
1616 | },
1617 | "dist": {
1618 | "type": "zip",
1619 | "url": "https://api.github.com/repos/php-fig/log/zipball/6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd",
1620 | "reference": "6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd",
1621 | "shasum": ""
1622 | },
1623 | "require": {
1624 | "php": ">=5.3.0"
1625 | },
1626 | "type": "library",
1627 | "extra": {
1628 | "branch-alias": {
1629 | "dev-master": "1.0.x-dev"
1630 | }
1631 | },
1632 | "autoload": {
1633 | "psr-4": {
1634 | "Psr\\Log\\": "Psr/Log/"
1635 | }
1636 | },
1637 | "notification-url": "https://packagist.org/downloads/",
1638 | "license": [
1639 | "MIT"
1640 | ],
1641 | "authors": [
1642 | {
1643 | "name": "PHP-FIG",
1644 | "homepage": "http://www.php-fig.org/"
1645 | }
1646 | ],
1647 | "description": "Common interface for logging libraries",
1648 | "homepage": "https://github.com/php-fig/log",
1649 | "keywords": [
1650 | "log",
1651 | "psr",
1652 | "psr-3"
1653 | ],
1654 | "time": "2018-11-20T15:27:04+00:00"
1655 | },
1656 | {
1657 | "name": "sebastian/code-unit-reverse-lookup",
1658 | "version": "1.0.1",
1659 | "source": {
1660 | "type": "git",
1661 | "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git",
1662 | "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18"
1663 | },
1664 | "dist": {
1665 | "type": "zip",
1666 | "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/4419fcdb5eabb9caa61a27c7a1db532a6b55dd18",
1667 | "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18",
1668 | "shasum": ""
1669 | },
1670 | "require": {
1671 | "php": "^5.6 || ^7.0"
1672 | },
1673 | "require-dev": {
1674 | "phpunit/phpunit": "^5.7 || ^6.0"
1675 | },
1676 | "type": "library",
1677 | "extra": {
1678 | "branch-alias": {
1679 | "dev-master": "1.0.x-dev"
1680 | }
1681 | },
1682 | "autoload": {
1683 | "classmap": [
1684 | "src/"
1685 | ]
1686 | },
1687 | "notification-url": "https://packagist.org/downloads/",
1688 | "license": [
1689 | "BSD-3-Clause"
1690 | ],
1691 | "authors": [
1692 | {
1693 | "name": "Sebastian Bergmann",
1694 | "email": "sebastian@phpunit.de"
1695 | }
1696 | ],
1697 | "description": "Looks up which function or method a line of code belongs to",
1698 | "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/",
1699 | "time": "2017-03-04T06:30:41+00:00"
1700 | },
1701 | {
1702 | "name": "sebastian/comparator",
1703 | "version": "3.0.2",
1704 | "source": {
1705 | "type": "git",
1706 | "url": "https://github.com/sebastianbergmann/comparator.git",
1707 | "reference": "5de4fc177adf9bce8df98d8d141a7559d7ccf6da"
1708 | },
1709 | "dist": {
1710 | "type": "zip",
1711 | "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/5de4fc177adf9bce8df98d8d141a7559d7ccf6da",
1712 | "reference": "5de4fc177adf9bce8df98d8d141a7559d7ccf6da",
1713 | "shasum": ""
1714 | },
1715 | "require": {
1716 | "php": "^7.1",
1717 | "sebastian/diff": "^3.0",
1718 | "sebastian/exporter": "^3.1"
1719 | },
1720 | "require-dev": {
1721 | "phpunit/phpunit": "^7.1"
1722 | },
1723 | "type": "library",
1724 | "extra": {
1725 | "branch-alias": {
1726 | "dev-master": "3.0-dev"
1727 | }
1728 | },
1729 | "autoload": {
1730 | "classmap": [
1731 | "src/"
1732 | ]
1733 | },
1734 | "notification-url": "https://packagist.org/downloads/",
1735 | "license": [
1736 | "BSD-3-Clause"
1737 | ],
1738 | "authors": [
1739 | {
1740 | "name": "Jeff Welch",
1741 | "email": "whatthejeff@gmail.com"
1742 | },
1743 | {
1744 | "name": "Volker Dusch",
1745 | "email": "github@wallbash.com"
1746 | },
1747 | {
1748 | "name": "Bernhard Schussek",
1749 | "email": "bschussek@2bepublished.at"
1750 | },
1751 | {
1752 | "name": "Sebastian Bergmann",
1753 | "email": "sebastian@phpunit.de"
1754 | }
1755 | ],
1756 | "description": "Provides the functionality to compare PHP values for equality",
1757 | "homepage": "https://github.com/sebastianbergmann/comparator",
1758 | "keywords": [
1759 | "comparator",
1760 | "compare",
1761 | "equality"
1762 | ],
1763 | "time": "2018-07-12T15:12:46+00:00"
1764 | },
1765 | {
1766 | "name": "sebastian/diff",
1767 | "version": "3.0.1",
1768 | "source": {
1769 | "type": "git",
1770 | "url": "https://github.com/sebastianbergmann/diff.git",
1771 | "reference": "366541b989927187c4ca70490a35615d3fef2dce"
1772 | },
1773 | "dist": {
1774 | "type": "zip",
1775 | "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/366541b989927187c4ca70490a35615d3fef2dce",
1776 | "reference": "366541b989927187c4ca70490a35615d3fef2dce",
1777 | "shasum": ""
1778 | },
1779 | "require": {
1780 | "php": "^7.1"
1781 | },
1782 | "require-dev": {
1783 | "phpunit/phpunit": "^7.0",
1784 | "symfony/process": "^2 || ^3.3 || ^4"
1785 | },
1786 | "type": "library",
1787 | "extra": {
1788 | "branch-alias": {
1789 | "dev-master": "3.0-dev"
1790 | }
1791 | },
1792 | "autoload": {
1793 | "classmap": [
1794 | "src/"
1795 | ]
1796 | },
1797 | "notification-url": "https://packagist.org/downloads/",
1798 | "license": [
1799 | "BSD-3-Clause"
1800 | ],
1801 | "authors": [
1802 | {
1803 | "name": "Kore Nordmann",
1804 | "email": "mail@kore-nordmann.de"
1805 | },
1806 | {
1807 | "name": "Sebastian Bergmann",
1808 | "email": "sebastian@phpunit.de"
1809 | }
1810 | ],
1811 | "description": "Diff implementation",
1812 | "homepage": "https://github.com/sebastianbergmann/diff",
1813 | "keywords": [
1814 | "diff",
1815 | "udiff",
1816 | "unidiff",
1817 | "unified diff"
1818 | ],
1819 | "time": "2018-06-10T07:54:39+00:00"
1820 | },
1821 | {
1822 | "name": "sebastian/environment",
1823 | "version": "4.0.1",
1824 | "source": {
1825 | "type": "git",
1826 | "url": "https://github.com/sebastianbergmann/environment.git",
1827 | "reference": "febd209a219cea7b56ad799b30ebbea34b71eb8f"
1828 | },
1829 | "dist": {
1830 | "type": "zip",
1831 | "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/febd209a219cea7b56ad799b30ebbea34b71eb8f",
1832 | "reference": "febd209a219cea7b56ad799b30ebbea34b71eb8f",
1833 | "shasum": ""
1834 | },
1835 | "require": {
1836 | "php": "^7.1"
1837 | },
1838 | "require-dev": {
1839 | "phpunit/phpunit": "^7.4"
1840 | },
1841 | "type": "library",
1842 | "extra": {
1843 | "branch-alias": {
1844 | "dev-master": "4.0-dev"
1845 | }
1846 | },
1847 | "autoload": {
1848 | "classmap": [
1849 | "src/"
1850 | ]
1851 | },
1852 | "notification-url": "https://packagist.org/downloads/",
1853 | "license": [
1854 | "BSD-3-Clause"
1855 | ],
1856 | "authors": [
1857 | {
1858 | "name": "Sebastian Bergmann",
1859 | "email": "sebastian@phpunit.de"
1860 | }
1861 | ],
1862 | "description": "Provides functionality to handle HHVM/PHP environments",
1863 | "homepage": "http://www.github.com/sebastianbergmann/environment",
1864 | "keywords": [
1865 | "Xdebug",
1866 | "environment",
1867 | "hhvm"
1868 | ],
1869 | "time": "2018-11-25T09:31:21+00:00"
1870 | },
1871 | {
1872 | "name": "sebastian/exporter",
1873 | "version": "3.1.0",
1874 | "source": {
1875 | "type": "git",
1876 | "url": "https://github.com/sebastianbergmann/exporter.git",
1877 | "reference": "234199f4528de6d12aaa58b612e98f7d36adb937"
1878 | },
1879 | "dist": {
1880 | "type": "zip",
1881 | "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/234199f4528de6d12aaa58b612e98f7d36adb937",
1882 | "reference": "234199f4528de6d12aaa58b612e98f7d36adb937",
1883 | "shasum": ""
1884 | },
1885 | "require": {
1886 | "php": "^7.0",
1887 | "sebastian/recursion-context": "^3.0"
1888 | },
1889 | "require-dev": {
1890 | "ext-mbstring": "*",
1891 | "phpunit/phpunit": "^6.0"
1892 | },
1893 | "type": "library",
1894 | "extra": {
1895 | "branch-alias": {
1896 | "dev-master": "3.1.x-dev"
1897 | }
1898 | },
1899 | "autoload": {
1900 | "classmap": [
1901 | "src/"
1902 | ]
1903 | },
1904 | "notification-url": "https://packagist.org/downloads/",
1905 | "license": [
1906 | "BSD-3-Clause"
1907 | ],
1908 | "authors": [
1909 | {
1910 | "name": "Jeff Welch",
1911 | "email": "whatthejeff@gmail.com"
1912 | },
1913 | {
1914 | "name": "Volker Dusch",
1915 | "email": "github@wallbash.com"
1916 | },
1917 | {
1918 | "name": "Bernhard Schussek",
1919 | "email": "bschussek@2bepublished.at"
1920 | },
1921 | {
1922 | "name": "Sebastian Bergmann",
1923 | "email": "sebastian@phpunit.de"
1924 | },
1925 | {
1926 | "name": "Adam Harvey",
1927 | "email": "aharvey@php.net"
1928 | }
1929 | ],
1930 | "description": "Provides the functionality to export PHP variables for visualization",
1931 | "homepage": "http://www.github.com/sebastianbergmann/exporter",
1932 | "keywords": [
1933 | "export",
1934 | "exporter"
1935 | ],
1936 | "time": "2017-04-03T13:19:02+00:00"
1937 | },
1938 | {
1939 | "name": "sebastian/global-state",
1940 | "version": "2.0.0",
1941 | "source": {
1942 | "type": "git",
1943 | "url": "https://github.com/sebastianbergmann/global-state.git",
1944 | "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4"
1945 | },
1946 | "dist": {
1947 | "type": "zip",
1948 | "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4",
1949 | "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4",
1950 | "shasum": ""
1951 | },
1952 | "require": {
1953 | "php": "^7.0"
1954 | },
1955 | "require-dev": {
1956 | "phpunit/phpunit": "^6.0"
1957 | },
1958 | "suggest": {
1959 | "ext-uopz": "*"
1960 | },
1961 | "type": "library",
1962 | "extra": {
1963 | "branch-alias": {
1964 | "dev-master": "2.0-dev"
1965 | }
1966 | },
1967 | "autoload": {
1968 | "classmap": [
1969 | "src/"
1970 | ]
1971 | },
1972 | "notification-url": "https://packagist.org/downloads/",
1973 | "license": [
1974 | "BSD-3-Clause"
1975 | ],
1976 | "authors": [
1977 | {
1978 | "name": "Sebastian Bergmann",
1979 | "email": "sebastian@phpunit.de"
1980 | }
1981 | ],
1982 | "description": "Snapshotting of global state",
1983 | "homepage": "http://www.github.com/sebastianbergmann/global-state",
1984 | "keywords": [
1985 | "global state"
1986 | ],
1987 | "time": "2017-04-27T15:39:26+00:00"
1988 | },
1989 | {
1990 | "name": "sebastian/object-enumerator",
1991 | "version": "3.0.3",
1992 | "source": {
1993 | "type": "git",
1994 | "url": "https://github.com/sebastianbergmann/object-enumerator.git",
1995 | "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5"
1996 | },
1997 | "dist": {
1998 | "type": "zip",
1999 | "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/7cfd9e65d11ffb5af41198476395774d4c8a84c5",
2000 | "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5",
2001 | "shasum": ""
2002 | },
2003 | "require": {
2004 | "php": "^7.0",
2005 | "sebastian/object-reflector": "^1.1.1",
2006 | "sebastian/recursion-context": "^3.0"
2007 | },
2008 | "require-dev": {
2009 | "phpunit/phpunit": "^6.0"
2010 | },
2011 | "type": "library",
2012 | "extra": {
2013 | "branch-alias": {
2014 | "dev-master": "3.0.x-dev"
2015 | }
2016 | },
2017 | "autoload": {
2018 | "classmap": [
2019 | "src/"
2020 | ]
2021 | },
2022 | "notification-url": "https://packagist.org/downloads/",
2023 | "license": [
2024 | "BSD-3-Clause"
2025 | ],
2026 | "authors": [
2027 | {
2028 | "name": "Sebastian Bergmann",
2029 | "email": "sebastian@phpunit.de"
2030 | }
2031 | ],
2032 | "description": "Traverses array structures and object graphs to enumerate all referenced objects",
2033 | "homepage": "https://github.com/sebastianbergmann/object-enumerator/",
2034 | "time": "2017-08-03T12:35:26+00:00"
2035 | },
2036 | {
2037 | "name": "sebastian/object-reflector",
2038 | "version": "1.1.1",
2039 | "source": {
2040 | "type": "git",
2041 | "url": "https://github.com/sebastianbergmann/object-reflector.git",
2042 | "reference": "773f97c67f28de00d397be301821b06708fca0be"
2043 | },
2044 | "dist": {
2045 | "type": "zip",
2046 | "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/773f97c67f28de00d397be301821b06708fca0be",
2047 | "reference": "773f97c67f28de00d397be301821b06708fca0be",
2048 | "shasum": ""
2049 | },
2050 | "require": {
2051 | "php": "^7.0"
2052 | },
2053 | "require-dev": {
2054 | "phpunit/phpunit": "^6.0"
2055 | },
2056 | "type": "library",
2057 | "extra": {
2058 | "branch-alias": {
2059 | "dev-master": "1.1-dev"
2060 | }
2061 | },
2062 | "autoload": {
2063 | "classmap": [
2064 | "src/"
2065 | ]
2066 | },
2067 | "notification-url": "https://packagist.org/downloads/",
2068 | "license": [
2069 | "BSD-3-Clause"
2070 | ],
2071 | "authors": [
2072 | {
2073 | "name": "Sebastian Bergmann",
2074 | "email": "sebastian@phpunit.de"
2075 | }
2076 | ],
2077 | "description": "Allows reflection of object attributes, including inherited and non-public ones",
2078 | "homepage": "https://github.com/sebastianbergmann/object-reflector/",
2079 | "time": "2017-03-29T09:07:27+00:00"
2080 | },
2081 | {
2082 | "name": "sebastian/recursion-context",
2083 | "version": "3.0.0",
2084 | "source": {
2085 | "type": "git",
2086 | "url": "https://github.com/sebastianbergmann/recursion-context.git",
2087 | "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8"
2088 | },
2089 | "dist": {
2090 | "type": "zip",
2091 | "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8",
2092 | "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8",
2093 | "shasum": ""
2094 | },
2095 | "require": {
2096 | "php": "^7.0"
2097 | },
2098 | "require-dev": {
2099 | "phpunit/phpunit": "^6.0"
2100 | },
2101 | "type": "library",
2102 | "extra": {
2103 | "branch-alias": {
2104 | "dev-master": "3.0.x-dev"
2105 | }
2106 | },
2107 | "autoload": {
2108 | "classmap": [
2109 | "src/"
2110 | ]
2111 | },
2112 | "notification-url": "https://packagist.org/downloads/",
2113 | "license": [
2114 | "BSD-3-Clause"
2115 | ],
2116 | "authors": [
2117 | {
2118 | "name": "Jeff Welch",
2119 | "email": "whatthejeff@gmail.com"
2120 | },
2121 | {
2122 | "name": "Sebastian Bergmann",
2123 | "email": "sebastian@phpunit.de"
2124 | },
2125 | {
2126 | "name": "Adam Harvey",
2127 | "email": "aharvey@php.net"
2128 | }
2129 | ],
2130 | "description": "Provides functionality to recursively process PHP variables",
2131 | "homepage": "http://www.github.com/sebastianbergmann/recursion-context",
2132 | "time": "2017-03-03T06:23:57+00:00"
2133 | },
2134 | {
2135 | "name": "sebastian/resource-operations",
2136 | "version": "2.0.1",
2137 | "source": {
2138 | "type": "git",
2139 | "url": "https://github.com/sebastianbergmann/resource-operations.git",
2140 | "reference": "4d7a795d35b889bf80a0cc04e08d77cedfa917a9"
2141 | },
2142 | "dist": {
2143 | "type": "zip",
2144 | "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/4d7a795d35b889bf80a0cc04e08d77cedfa917a9",
2145 | "reference": "4d7a795d35b889bf80a0cc04e08d77cedfa917a9",
2146 | "shasum": ""
2147 | },
2148 | "require": {
2149 | "php": "^7.1"
2150 | },
2151 | "type": "library",
2152 | "extra": {
2153 | "branch-alias": {
2154 | "dev-master": "2.0-dev"
2155 | }
2156 | },
2157 | "autoload": {
2158 | "classmap": [
2159 | "src/"
2160 | ]
2161 | },
2162 | "notification-url": "https://packagist.org/downloads/",
2163 | "license": [
2164 | "BSD-3-Clause"
2165 | ],
2166 | "authors": [
2167 | {
2168 | "name": "Sebastian Bergmann",
2169 | "email": "sebastian@phpunit.de"
2170 | }
2171 | ],
2172 | "description": "Provides a list of PHP built-in functions that operate on resources",
2173 | "homepage": "https://www.github.com/sebastianbergmann/resource-operations",
2174 | "time": "2018-10-04T04:07:39+00:00"
2175 | },
2176 | {
2177 | "name": "sebastian/version",
2178 | "version": "2.0.1",
2179 | "source": {
2180 | "type": "git",
2181 | "url": "https://github.com/sebastianbergmann/version.git",
2182 | "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019"
2183 | },
2184 | "dist": {
2185 | "type": "zip",
2186 | "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019",
2187 | "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019",
2188 | "shasum": ""
2189 | },
2190 | "require": {
2191 | "php": ">=5.6"
2192 | },
2193 | "type": "library",
2194 | "extra": {
2195 | "branch-alias": {
2196 | "dev-master": "2.0.x-dev"
2197 | }
2198 | },
2199 | "autoload": {
2200 | "classmap": [
2201 | "src/"
2202 | ]
2203 | },
2204 | "notification-url": "https://packagist.org/downloads/",
2205 | "license": [
2206 | "BSD-3-Clause"
2207 | ],
2208 | "authors": [
2209 | {
2210 | "name": "Sebastian Bergmann",
2211 | "email": "sebastian@phpunit.de",
2212 | "role": "lead"
2213 | }
2214 | ],
2215 | "description": "Library that helps with managing the version number of Git-hosted PHP projects",
2216 | "homepage": "https://github.com/sebastianbergmann/version",
2217 | "time": "2016-10-03T07:35:21+00:00"
2218 | },
2219 | {
2220 | "name": "squizlabs/php_codesniffer",
2221 | "version": "3.4.0",
2222 | "source": {
2223 | "type": "git",
2224 | "url": "https://github.com/squizlabs/PHP_CodeSniffer.git",
2225 | "reference": "379deb987e26c7cd103a7b387aea178baec96e48"
2226 | },
2227 | "dist": {
2228 | "type": "zip",
2229 | "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/379deb987e26c7cd103a7b387aea178baec96e48",
2230 | "reference": "379deb987e26c7cd103a7b387aea178baec96e48",
2231 | "shasum": ""
2232 | },
2233 | "require": {
2234 | "ext-simplexml": "*",
2235 | "ext-tokenizer": "*",
2236 | "ext-xmlwriter": "*",
2237 | "php": ">=5.4.0"
2238 | },
2239 | "require-dev": {
2240 | "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0"
2241 | },
2242 | "bin": [
2243 | "bin/phpcs",
2244 | "bin/phpcbf"
2245 | ],
2246 | "type": "library",
2247 | "extra": {
2248 | "branch-alias": {
2249 | "dev-master": "3.x-dev"
2250 | }
2251 | },
2252 | "notification-url": "https://packagist.org/downloads/",
2253 | "license": [
2254 | "BSD-3-Clause"
2255 | ],
2256 | "authors": [
2257 | {
2258 | "name": "Greg Sherwood",
2259 | "role": "lead"
2260 | }
2261 | ],
2262 | "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.",
2263 | "homepage": "http://www.squizlabs.com/php-codesniffer",
2264 | "keywords": [
2265 | "phpcs",
2266 | "standards"
2267 | ],
2268 | "time": "2018-12-19T23:57:18+00:00"
2269 | },
2270 | {
2271 | "name": "symfony/console",
2272 | "version": "v4.2.2",
2273 | "source": {
2274 | "type": "git",
2275 | "url": "https://github.com/symfony/console.git",
2276 | "reference": "b0a03c1bb0fcbe288629956cf2f1dd3f1dc97522"
2277 | },
2278 | "dist": {
2279 | "type": "zip",
2280 | "url": "https://api.github.com/repos/symfony/console/zipball/b0a03c1bb0fcbe288629956cf2f1dd3f1dc97522",
2281 | "reference": "b0a03c1bb0fcbe288629956cf2f1dd3f1dc97522",
2282 | "shasum": ""
2283 | },
2284 | "require": {
2285 | "php": "^7.1.3",
2286 | "symfony/contracts": "^1.0",
2287 | "symfony/polyfill-mbstring": "~1.0"
2288 | },
2289 | "conflict": {
2290 | "symfony/dependency-injection": "<3.4",
2291 | "symfony/process": "<3.3"
2292 | },
2293 | "require-dev": {
2294 | "psr/log": "~1.0",
2295 | "symfony/config": "~3.4|~4.0",
2296 | "symfony/dependency-injection": "~3.4|~4.0",
2297 | "symfony/event-dispatcher": "~3.4|~4.0",
2298 | "symfony/lock": "~3.4|~4.0",
2299 | "symfony/process": "~3.4|~4.0"
2300 | },
2301 | "suggest": {
2302 | "psr/log-implementation": "For using the console logger",
2303 | "symfony/event-dispatcher": "",
2304 | "symfony/lock": "",
2305 | "symfony/process": ""
2306 | },
2307 | "type": "library",
2308 | "extra": {
2309 | "branch-alias": {
2310 | "dev-master": "4.2-dev"
2311 | }
2312 | },
2313 | "autoload": {
2314 | "psr-4": {
2315 | "Symfony\\Component\\Console\\": ""
2316 | },
2317 | "exclude-from-classmap": [
2318 | "/Tests/"
2319 | ]
2320 | },
2321 | "notification-url": "https://packagist.org/downloads/",
2322 | "license": [
2323 | "MIT"
2324 | ],
2325 | "authors": [
2326 | {
2327 | "name": "Fabien Potencier",
2328 | "email": "fabien@symfony.com"
2329 | },
2330 | {
2331 | "name": "Symfony Community",
2332 | "homepage": "https://symfony.com/contributors"
2333 | }
2334 | ],
2335 | "description": "Symfony Console Component",
2336 | "homepage": "https://symfony.com",
2337 | "time": "2019-01-04T15:13:53+00:00"
2338 | },
2339 | {
2340 | "name": "symfony/contracts",
2341 | "version": "v1.0.2",
2342 | "source": {
2343 | "type": "git",
2344 | "url": "https://github.com/symfony/contracts.git",
2345 | "reference": "1aa7ab2429c3d594dd70689604b5cf7421254cdf"
2346 | },
2347 | "dist": {
2348 | "type": "zip",
2349 | "url": "https://api.github.com/repos/symfony/contracts/zipball/1aa7ab2429c3d594dd70689604b5cf7421254cdf",
2350 | "reference": "1aa7ab2429c3d594dd70689604b5cf7421254cdf",
2351 | "shasum": ""
2352 | },
2353 | "require": {
2354 | "php": "^7.1.3"
2355 | },
2356 | "require-dev": {
2357 | "psr/cache": "^1.0",
2358 | "psr/container": "^1.0"
2359 | },
2360 | "suggest": {
2361 | "psr/cache": "When using the Cache contracts",
2362 | "psr/container": "When using the Service contracts",
2363 | "symfony/cache-contracts-implementation": "",
2364 | "symfony/service-contracts-implementation": "",
2365 | "symfony/translation-contracts-implementation": ""
2366 | },
2367 | "type": "library",
2368 | "extra": {
2369 | "branch-alias": {
2370 | "dev-master": "1.0-dev"
2371 | }
2372 | },
2373 | "autoload": {
2374 | "psr-4": {
2375 | "Symfony\\Contracts\\": ""
2376 | },
2377 | "exclude-from-classmap": [
2378 | "**/Tests/"
2379 | ]
2380 | },
2381 | "notification-url": "https://packagist.org/downloads/",
2382 | "license": [
2383 | "MIT"
2384 | ],
2385 | "authors": [
2386 | {
2387 | "name": "Nicolas Grekas",
2388 | "email": "p@tchwork.com"
2389 | },
2390 | {
2391 | "name": "Symfony Community",
2392 | "homepage": "https://symfony.com/contributors"
2393 | }
2394 | ],
2395 | "description": "A set of abstractions extracted out of the Symfony components",
2396 | "homepage": "https://symfony.com",
2397 | "keywords": [
2398 | "abstractions",
2399 | "contracts",
2400 | "decoupling",
2401 | "interfaces",
2402 | "interoperability",
2403 | "standards"
2404 | ],
2405 | "time": "2018-12-05T08:06:11+00:00"
2406 | },
2407 | {
2408 | "name": "symfony/finder",
2409 | "version": "v4.2.2",
2410 | "source": {
2411 | "type": "git",
2412 | "url": "https://github.com/symfony/finder.git",
2413 | "reference": "9094d69e8c6ee3fe186a0ec5a4f1401e506071ce"
2414 | },
2415 | "dist": {
2416 | "type": "zip",
2417 | "url": "https://api.github.com/repos/symfony/finder/zipball/9094d69e8c6ee3fe186a0ec5a4f1401e506071ce",
2418 | "reference": "9094d69e8c6ee3fe186a0ec5a4f1401e506071ce",
2419 | "shasum": ""
2420 | },
2421 | "require": {
2422 | "php": "^7.1.3"
2423 | },
2424 | "type": "library",
2425 | "extra": {
2426 | "branch-alias": {
2427 | "dev-master": "4.2-dev"
2428 | }
2429 | },
2430 | "autoload": {
2431 | "psr-4": {
2432 | "Symfony\\Component\\Finder\\": ""
2433 | },
2434 | "exclude-from-classmap": [
2435 | "/Tests/"
2436 | ]
2437 | },
2438 | "notification-url": "https://packagist.org/downloads/",
2439 | "license": [
2440 | "MIT"
2441 | ],
2442 | "authors": [
2443 | {
2444 | "name": "Fabien Potencier",
2445 | "email": "fabien@symfony.com"
2446 | },
2447 | {
2448 | "name": "Symfony Community",
2449 | "homepage": "https://symfony.com/contributors"
2450 | }
2451 | ],
2452 | "description": "Symfony Finder Component",
2453 | "homepage": "https://symfony.com",
2454 | "time": "2019-01-03T09:07:35+00:00"
2455 | },
2456 | {
2457 | "name": "symfony/polyfill-ctype",
2458 | "version": "v1.10.0",
2459 | "source": {
2460 | "type": "git",
2461 | "url": "https://github.com/symfony/polyfill-ctype.git",
2462 | "reference": "e3d826245268269cd66f8326bd8bc066687b4a19"
2463 | },
2464 | "dist": {
2465 | "type": "zip",
2466 | "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/e3d826245268269cd66f8326bd8bc066687b4a19",
2467 | "reference": "e3d826245268269cd66f8326bd8bc066687b4a19",
2468 | "shasum": ""
2469 | },
2470 | "require": {
2471 | "php": ">=5.3.3"
2472 | },
2473 | "suggest": {
2474 | "ext-ctype": "For best performance"
2475 | },
2476 | "type": "library",
2477 | "extra": {
2478 | "branch-alias": {
2479 | "dev-master": "1.9-dev"
2480 | }
2481 | },
2482 | "autoload": {
2483 | "psr-4": {
2484 | "Symfony\\Polyfill\\Ctype\\": ""
2485 | },
2486 | "files": [
2487 | "bootstrap.php"
2488 | ]
2489 | },
2490 | "notification-url": "https://packagist.org/downloads/",
2491 | "license": [
2492 | "MIT"
2493 | ],
2494 | "authors": [
2495 | {
2496 | "name": "Symfony Community",
2497 | "homepage": "https://symfony.com/contributors"
2498 | },
2499 | {
2500 | "name": "Gert de Pagter",
2501 | "email": "backendtea@gmail.com"
2502 | }
2503 | ],
2504 | "description": "Symfony polyfill for ctype functions",
2505 | "homepage": "https://symfony.com",
2506 | "keywords": [
2507 | "compatibility",
2508 | "ctype",
2509 | "polyfill",
2510 | "portable"
2511 | ],
2512 | "time": "2018-08-06T14:22:27+00:00"
2513 | },
2514 | {
2515 | "name": "symfony/polyfill-mbstring",
2516 | "version": "v1.10.0",
2517 | "source": {
2518 | "type": "git",
2519 | "url": "https://github.com/symfony/polyfill-mbstring.git",
2520 | "reference": "c79c051f5b3a46be09205c73b80b346e4153e494"
2521 | },
2522 | "dist": {
2523 | "type": "zip",
2524 | "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/c79c051f5b3a46be09205c73b80b346e4153e494",
2525 | "reference": "c79c051f5b3a46be09205c73b80b346e4153e494",
2526 | "shasum": ""
2527 | },
2528 | "require": {
2529 | "php": ">=5.3.3"
2530 | },
2531 | "suggest": {
2532 | "ext-mbstring": "For best performance"
2533 | },
2534 | "type": "library",
2535 | "extra": {
2536 | "branch-alias": {
2537 | "dev-master": "1.9-dev"
2538 | }
2539 | },
2540 | "autoload": {
2541 | "psr-4": {
2542 | "Symfony\\Polyfill\\Mbstring\\": ""
2543 | },
2544 | "files": [
2545 | "bootstrap.php"
2546 | ]
2547 | },
2548 | "notification-url": "https://packagist.org/downloads/",
2549 | "license": [
2550 | "MIT"
2551 | ],
2552 | "authors": [
2553 | {
2554 | "name": "Nicolas Grekas",
2555 | "email": "p@tchwork.com"
2556 | },
2557 | {
2558 | "name": "Symfony Community",
2559 | "homepage": "https://symfony.com/contributors"
2560 | }
2561 | ],
2562 | "description": "Symfony polyfill for the Mbstring extension",
2563 | "homepage": "https://symfony.com",
2564 | "keywords": [
2565 | "compatibility",
2566 | "mbstring",
2567 | "polyfill",
2568 | "portable",
2569 | "shim"
2570 | ],
2571 | "time": "2018-09-21T13:07:52+00:00"
2572 | },
2573 | {
2574 | "name": "symfony/process",
2575 | "version": "v4.2.2",
2576 | "source": {
2577 | "type": "git",
2578 | "url": "https://github.com/symfony/process.git",
2579 | "reference": "ea043ab5d8ed13b467a9087d81cb876aee7f689a"
2580 | },
2581 | "dist": {
2582 | "type": "zip",
2583 | "url": "https://api.github.com/repos/symfony/process/zipball/ea043ab5d8ed13b467a9087d81cb876aee7f689a",
2584 | "reference": "ea043ab5d8ed13b467a9087d81cb876aee7f689a",
2585 | "shasum": ""
2586 | },
2587 | "require": {
2588 | "php": "^7.1.3"
2589 | },
2590 | "type": "library",
2591 | "extra": {
2592 | "branch-alias": {
2593 | "dev-master": "4.2-dev"
2594 | }
2595 | },
2596 | "autoload": {
2597 | "psr-4": {
2598 | "Symfony\\Component\\Process\\": ""
2599 | },
2600 | "exclude-from-classmap": [
2601 | "/Tests/"
2602 | ]
2603 | },
2604 | "notification-url": "https://packagist.org/downloads/",
2605 | "license": [
2606 | "MIT"
2607 | ],
2608 | "authors": [
2609 | {
2610 | "name": "Fabien Potencier",
2611 | "email": "fabien@symfony.com"
2612 | },
2613 | {
2614 | "name": "Symfony Community",
2615 | "homepage": "https://symfony.com/contributors"
2616 | }
2617 | ],
2618 | "description": "Symfony Process Component",
2619 | "homepage": "https://symfony.com",
2620 | "time": "2019-01-03T14:48:52+00:00"
2621 | },
2622 | {
2623 | "name": "symfony/yaml",
2624 | "version": "v4.2.2",
2625 | "source": {
2626 | "type": "git",
2627 | "url": "https://github.com/symfony/yaml.git",
2628 | "reference": "d0aa6c0ea484087927b49fd513383a7d36190ca6"
2629 | },
2630 | "dist": {
2631 | "type": "zip",
2632 | "url": "https://api.github.com/repos/symfony/yaml/zipball/d0aa6c0ea484087927b49fd513383a7d36190ca6",
2633 | "reference": "d0aa6c0ea484087927b49fd513383a7d36190ca6",
2634 | "shasum": ""
2635 | },
2636 | "require": {
2637 | "php": "^7.1.3",
2638 | "symfony/polyfill-ctype": "~1.8"
2639 | },
2640 | "conflict": {
2641 | "symfony/console": "<3.4"
2642 | },
2643 | "require-dev": {
2644 | "symfony/console": "~3.4|~4.0"
2645 | },
2646 | "suggest": {
2647 | "symfony/console": "For validating YAML files using the lint command"
2648 | },
2649 | "type": "library",
2650 | "extra": {
2651 | "branch-alias": {
2652 | "dev-master": "4.2-dev"
2653 | }
2654 | },
2655 | "autoload": {
2656 | "psr-4": {
2657 | "Symfony\\Component\\Yaml\\": ""
2658 | },
2659 | "exclude-from-classmap": [
2660 | "/Tests/"
2661 | ]
2662 | },
2663 | "notification-url": "https://packagist.org/downloads/",
2664 | "license": [
2665 | "MIT"
2666 | ],
2667 | "authors": [
2668 | {
2669 | "name": "Fabien Potencier",
2670 | "email": "fabien@symfony.com"
2671 | },
2672 | {
2673 | "name": "Symfony Community",
2674 | "homepage": "https://symfony.com/contributors"
2675 | }
2676 | ],
2677 | "description": "Symfony Yaml Component",
2678 | "homepage": "https://symfony.com",
2679 | "time": "2019-01-03T09:07:35+00:00"
2680 | },
2681 | {
2682 | "name": "theseer/tokenizer",
2683 | "version": "1.1.0",
2684 | "source": {
2685 | "type": "git",
2686 | "url": "https://github.com/theseer/tokenizer.git",
2687 | "reference": "cb2f008f3f05af2893a87208fe6a6c4985483f8b"
2688 | },
2689 | "dist": {
2690 | "type": "zip",
2691 | "url": "https://api.github.com/repos/theseer/tokenizer/zipball/cb2f008f3f05af2893a87208fe6a6c4985483f8b",
2692 | "reference": "cb2f008f3f05af2893a87208fe6a6c4985483f8b",
2693 | "shasum": ""
2694 | },
2695 | "require": {
2696 | "ext-dom": "*",
2697 | "ext-tokenizer": "*",
2698 | "ext-xmlwriter": "*",
2699 | "php": "^7.0"
2700 | },
2701 | "type": "library",
2702 | "autoload": {
2703 | "classmap": [
2704 | "src/"
2705 | ]
2706 | },
2707 | "notification-url": "https://packagist.org/downloads/",
2708 | "license": [
2709 | "BSD-3-Clause"
2710 | ],
2711 | "authors": [
2712 | {
2713 | "name": "Arne Blankerts",
2714 | "email": "arne@blankerts.de",
2715 | "role": "Developer"
2716 | }
2717 | ],
2718 | "description": "A small library for converting tokenized PHP source code into XML and potentially other formats",
2719 | "time": "2017-04-07T12:08:54+00:00"
2720 | },
2721 | {
2722 | "name": "webmozart/assert",
2723 | "version": "1.4.0",
2724 | "source": {
2725 | "type": "git",
2726 | "url": "https://github.com/webmozart/assert.git",
2727 | "reference": "83e253c8e0be5b0257b881e1827274667c5c17a9"
2728 | },
2729 | "dist": {
2730 | "type": "zip",
2731 | "url": "https://api.github.com/repos/webmozart/assert/zipball/83e253c8e0be5b0257b881e1827274667c5c17a9",
2732 | "reference": "83e253c8e0be5b0257b881e1827274667c5c17a9",
2733 | "shasum": ""
2734 | },
2735 | "require": {
2736 | "php": "^5.3.3 || ^7.0",
2737 | "symfony/polyfill-ctype": "^1.8"
2738 | },
2739 | "require-dev": {
2740 | "phpunit/phpunit": "^4.6",
2741 | "sebastian/version": "^1.0.1"
2742 | },
2743 | "type": "library",
2744 | "extra": {
2745 | "branch-alias": {
2746 | "dev-master": "1.3-dev"
2747 | }
2748 | },
2749 | "autoload": {
2750 | "psr-4": {
2751 | "Webmozart\\Assert\\": "src/"
2752 | }
2753 | },
2754 | "notification-url": "https://packagist.org/downloads/",
2755 | "license": [
2756 | "MIT"
2757 | ],
2758 | "authors": [
2759 | {
2760 | "name": "Bernhard Schussek",
2761 | "email": "bschussek@gmail.com"
2762 | }
2763 | ],
2764 | "description": "Assertions to validate method input/output with nice error messages.",
2765 | "keywords": [
2766 | "assert",
2767 | "check",
2768 | "validate"
2769 | ],
2770 | "time": "2018-12-25T11:19:39+00:00"
2771 | }
2772 | ],
2773 | "aliases": [],
2774 | "minimum-stability": "dev",
2775 | "stability-flags": [],
2776 | "prefer-stable": true,
2777 | "prefer-lowest": false,
2778 | "platform": {
2779 | "php": ">=7.1"
2780 | },
2781 | "platform-dev": []
2782 | }
2783 |
--------------------------------------------------------------------------------
/phpcs.xml.dist:
--------------------------------------------------------------------------------
1 |
2 |
3 | The coding standard of php-lodash package
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/phpstan.neon.dist:
--------------------------------------------------------------------------------
1 | parameters:
2 | level: 5
3 | paths:
4 | - src
5 | - tests
6 | reportUnmatchedIgnoredErrors: false
7 | ignoreErrors:
8 | - '#Array has 2 duplicate keys with value#'
9 |
--------------------------------------------------------------------------------
/src/Traits/Arrays.php:
--------------------------------------------------------------------------------
1 | > [1, 2, 3, 4]
14 | *
15 | * @param array $array original array
16 | * @param mixed $value new item or value to append
17 | *
18 | * @return array
19 | */
20 | public static function append(array $array = [], $value = null): array
21 | {
22 | $array[] = $value;
23 |
24 | return $array;
25 | }
26 |
27 | /**
28 | * Creates an array with all falsey values removed. The values false, null, 0, "", undefined, and NaN are all
29 | * falsey.
30 | *
31 | * @usage __::compact([0, 1, false, 2, '', 3]);
32 | * >> [1, 2, 3]
33 | *
34 | * @param array $array array to compact
35 | *
36 | * @return array
37 | */
38 | public static function compact(array $array = []): array
39 | {
40 | $result = [];
41 |
42 | foreach ($array as $value) {
43 | if ($value) {
44 | $result[] = $value;
45 | }
46 | }
47 |
48 | return $result;
49 | }
50 |
51 |
52 | /**
53 | * base flatten
54 | *
55 | * @param array $array
56 | * @param bool $shallow
57 | * @param bool $strict
58 | * @param int $startIndex
59 | *
60 | * @return array
61 | */
62 | public static function baseFlatten(
63 | array $array,
64 | bool $shallow = false,
65 | bool $strict = true,
66 | int $startIndex = 0
67 | ): array {
68 | $idx = 0;
69 | $output = [];
70 |
71 | foreach ($array as $index => $value) {
72 | if (is_array($value)) {
73 | if (!$shallow) {
74 | $value = static::baseFlatten($value, $shallow, $strict);
75 | }
76 | $j = 0;
77 | $len = count($value);
78 | while ($j < $len) {
79 | $output[$idx++] = $value[$j++];
80 | }
81 | } else {
82 | if (!$strict) {
83 | $output[$idx++] = $value;
84 | }
85 | }
86 | }
87 |
88 | return $output;
89 | }
90 |
91 | /**
92 | * Flattens a multidimensional array. If you pass shallow, the array will only be flattened a single level.
93 | *
94 | * @usage __::flatten([1, 2, [3, [4]]], [flatten]);
95 | * >> [1, 2, 3, 4]
96 | *
97 | * @param array $array
98 | * @param bool $shallow
99 | *
100 | * @return array
101 | */
102 | public static function flatten(array $array, bool $shallow = false): array
103 | {
104 | return static::baseFlatten($array, $shallow, false);
105 | }
106 |
107 | /**
108 | * Patches array by xpath.
109 | *
110 | * @usage __::patch(
111 | * ['addr' => ['country' => 'US', 'zip' => 12345]],
112 | * ['/addr/country' => 'CA','/addr/zip' => 54321]
113 | * );
114 | ** >> ['addr' => ['country' => 'CA', 'zip' => 54321]]
115 | *
116 | * @param array $array The array to patch
117 | * @param array $patches List of new xpath-value pairs
118 | * @param string $parent
119 | *
120 | * @return array Returns patched array
121 | */
122 | public static function patch(array $array, array $patches, string $parent = ''): array
123 | {
124 | foreach ($array as $key => $value) {
125 | $z = $parent . '/' . $key;
126 |
127 | if (isset($patches[$z])) {
128 | $array[$key] = $patches[$z];
129 | unset($patches[$z]);
130 |
131 | if (!count($patches)) {
132 | break;
133 | }
134 | }
135 |
136 | if (is_array($value)) {
137 | $array[$key] = static::patch($value, $patches, $z);
138 | }
139 | }
140 |
141 | return $array;
142 | }
143 |
144 | /**
145 | * Prepend item or value to an array
146 | *
147 | * @usage __::prepend([1, 2, 3], 4);
148 | * >> [4, 1, 2, 3]
149 | *
150 | * @param array $array
151 | * @param mixed $value
152 | *
153 | * @return array
154 | */
155 | public static function prepend(array $array = [], $value = null): array
156 | {
157 | array_unshift($array, $value);
158 |
159 | return $array;
160 | }
161 |
162 | /**
163 | * Generate range of values based on start , end and step
164 | *
165 | * @usage __::range(1, 10, 2);
166 | ** >> [1, 3, 5, 7, 9]
167 | *
168 | * @param int|null $start range start
169 | * @param int|null $stop range end
170 | * @param int $step range step value
171 | *
172 | * @return array range of values
173 | */
174 | public static function range($start = null, $stop = null, int $step = 1): array
175 | {
176 | if ($stop == null && $start != null) {
177 | $stop = $start;
178 | $start = 1;
179 | }
180 |
181 | return range($start, $stop, $step);
182 | }
183 |
184 | /**
185 | * Generate array of repeated values
186 | *
187 | * @usage __::repeat('foo', 3);
188 | ** >> ['foo', 'foo', 'foo']
189 | *
190 | * @param string $object The object to repeat.
191 | * @param int $times ow many times has to be repeated.
192 | *
193 | * @return array Returns a new array of filled values.
194 | *
195 | */
196 | public static function repeat($object = '', int $times = null): array
197 | {
198 | $times = abs($times);
199 | if ($times == null) {
200 | return [];
201 | }
202 |
203 | return array_fill(0, $times, $object);
204 | }
205 |
206 | /**
207 | * Creates an array of elements split into groups the length of size. If array can't be split evenly, the final
208 | * chunk will be the remaining elements.
209 | *
210 | * @usage __::chunk([1, 2, 3, 4, 5], 3);
211 | * >> [[1, 2, 3], [4, 5]]
212 | *
213 | * @param array $array original array
214 | * @param int $size the chunk size
215 | * @param bool $preserveKeys When set to TRUE keys will be preserved. Default is FALSE which will reindex the
216 | * chunk numerically
217 | *
218 | * @return array
219 | */
220 | public static function chunk(array $array, int $size = 1, bool $preserveKeys = false): array
221 | {
222 | return array_chunk($array, $size, $preserveKeys);
223 | }
224 |
225 | /**
226 | * Creates a slice of array with n elements dropped from the beginning.
227 | *
228 | * @usage __::drop([0, 1, 3], 2);
229 | * >> [3]
230 | *
231 | * @param array $input The array to query.
232 | * @param int $number The number of elements to drop.
233 | *
234 | * @return array
235 | */
236 | public static function drop(array $input, int $number = 1): array
237 | {
238 | return array_slice($input, $number);
239 | }
240 |
241 | /**
242 | * Shuffle an array ensuring no item remains in the same position.
243 | *
244 | * @usage __::randomize([1, 2, 3]);
245 | * >> [2, 3, 1]
246 | *
247 | * @param array $array original array
248 | *
249 | * @return array
250 | */
251 | public static function randomize(array $array): array
252 | {
253 | for ($i = 0, $c = count($array); $i < $c - 1; $i++) {
254 | $j = rand($i + 1, $c - 1);
255 | list($array[$i], $array[$j]) = [$array[$j], $array[$i]];
256 | }
257 |
258 | return $array;
259 | }
260 |
261 | /**
262 | * Search for the index of a value in an array.
263 | *
264 | * @usage __::search(['a', 'b', 'c'], 'b')
265 | * >> 1
266 | *
267 | * @param array $array
268 | * @param string $value
269 | *
270 | * @return mixed
271 | */
272 | public static function search(array $array, string $value)
273 | {
274 | return array_search($value, $array, true);
275 | }
276 |
277 | /**
278 | * Check if an item is in an array.
279 | *
280 | * @usage __::contains(['a', 'b', 'c'], 'b')
281 | * >> true
282 | *
283 | * @param array $array
284 | * @param string $value
285 | *
286 | * @return bool
287 | */
288 | public static function contains(array $array, string $value): bool
289 | {
290 | return in_array($value, $array, true);
291 | }
292 |
293 | /**
294 | * Returns the average value of an array.
295 | *
296 | * @usage __::average([1, 2, 3])
297 | * >> 2
298 | *
299 | * @param array $array The source array
300 | * @param int $decimals The number of decimals to return
301 | *
302 | * @return float The average value
303 | */
304 | public static function average(array $array, int $decimals = 0): float
305 | {
306 | return round((array_sum($array) / count($array)), $decimals);
307 | }
308 |
309 | /**
310 | * Get the size of an array.
311 | *
312 | * @usage __::size([1, 2, 3])
313 | * >> 3
314 | *
315 | * @param array $array
316 | *
317 | * @return int
318 | */
319 | public static function size(array $array)
320 | {
321 | return count($array);
322 | }
323 |
324 | /**
325 | * Clean all falsy values from an array.
326 | *
327 | * @usage __::clean([true, false, 0, 1, 'string', ''])
328 | * >> [true, 1, 'string']
329 | *
330 | * @param array $array
331 | *
332 | * @return mixed
333 | */
334 | public static function clean(array $array)
335 | {
336 | return __::filter($array, function ($value) {
337 | return (bool)$value;
338 | });
339 | }
340 |
341 | /**
342 | * Get a random string from an array.
343 | *
344 | * @usage __::random([1, 2, 3])
345 | * >> Returns 1, 2 or 3
346 | *
347 | * @param array $array
348 | * @param integer $take
349 | *
350 | * @return mixed
351 | */
352 | public static function random(array $array, $take = null)
353 | {
354 | if (!$take) {
355 | return $array[array_rand($array)];
356 | }
357 | shuffle($array);
358 |
359 | return __::first($array, $take);
360 | }
361 |
362 |
363 | /**
364 | * Return an array with all elements found in both input arrays.
365 | *
366 | * @usage __::intersection(["green", "red", "blue"], ["green", "yellow", "red"])
367 | * >> ["green", "red"]
368 | *
369 | * @param array $a
370 | * @param array $b
371 | *
372 | * @return array
373 | */
374 | public static function intersection(array $a, array $b): array
375 | {
376 | $a = (array)$a;
377 | $b = (array)$b;
378 |
379 | return array_values(array_intersect($a, $b));
380 | }
381 |
382 | /**
383 | * Return a boolean flag which indicates whether the two input arrays have any common elements.
384 | *
385 | * @usage __::intersects(["green", "red", "blue"], ["green", "yellow", "red"])
386 | * >> true
387 | *
388 | * @param array $a
389 | * @param array $b
390 | *
391 | * @return bool
392 | */
393 | public static function intersects(array $a, array $b): bool
394 | {
395 | $a = (array)$a;
396 | $b = (array)$b;
397 |
398 | return count(self::intersection($a, $b)) > 0;
399 | }
400 |
401 | /**
402 | * Exclude the last X elements from an array
403 | *
404 | * @usage __::initial([1, 2, 3], 1);
405 | * >> [1, 2]
406 | *
407 | * @param array $array
408 | * @param int $to
409 | *
410 | * @return mixed
411 | */
412 | public static function initial(array $array, int $to = 1)
413 | {
414 | $slice = count($array) - $to;
415 |
416 | return __::first($array, $slice);
417 | }
418 |
419 | /**
420 | * Exclude the first X elements from an array
421 | *
422 | * @usage __::rest([1, 2, 3], 2);
423 | * >> [3]
424 | *
425 | * @param array $array
426 | * @param int $from
427 | *
428 | * @return array
429 | */
430 | public static function rest(array $array, int $from = 1): array
431 | {
432 | return array_splice($array, $from);
433 | }
434 |
435 | /**
436 | * Sort an array by key.
437 | *
438 | * @usage __::sortKeys(['z' => 0, 'b' => 1, 'r' => 2])
439 | * >> ['b' => 1, 'r' => 2, 'z' => 0]
440 | *
441 | * @param array $array
442 | * @param string $direction
443 | *
444 | * @return mixed
445 | */
446 | public static function sortKeys(array $array, string $direction = 'ASC')
447 | {
448 | $direction = (strtolower($direction) === 'desc') ? SORT_DESC : SORT_ASC;
449 | if ($direction === SORT_ASC) {
450 | ksort($array);
451 | } else {
452 | krsort($array);
453 | }
454 |
455 | return $array;
456 | }
457 |
458 | /**
459 | * Remove unwanted values from array
460 | *
461 | * @param array $array
462 | * @param array|string $remove
463 | * @param bool $preserveKeys , set true if you want to preserve the keys. by default false
464 | *
465 | * @usage _::without([1,5=>3,2 => 4,5],2)
466 | *
467 | * @return array
468 | */
469 | public static function without(array $array, $remove, $preserveKeys = false): array
470 | {
471 | $remove = !is_array($remove) ? [$remove] : $remove;
472 | $result = [];
473 | foreach ($array as $key => $value) {
474 | if (in_array($value, $remove)) {
475 | continue;
476 | }
477 |
478 | if ($preserveKeys) {
479 | $result[$key] = $value;
480 | } else {
481 | $result[] = $value;
482 | }
483 | }
484 |
485 | return $result;
486 | }
487 | }
488 |
--------------------------------------------------------------------------------
/src/Traits/Collections.php:
--------------------------------------------------------------------------------
1 | $value) {
26 | if (call_user_func($closure, $value)) {
27 | $result[] = $value;
28 | }
29 | }
30 |
31 | return $result;
32 | }
33 |
34 | return __::compact($array);
35 | }
36 |
37 | /**
38 | * Gets the first element of an array. Passing n returns the first n elements.
39 | *
40 | * @usage __::first([1, 2, 3]);
41 | * >> 1
42 | *
43 | * @param array $array of values
44 | * @param int|null $take number of values to return
45 | *
46 | * @return mixed
47 | */
48 | public static function first(array $array, $take = null)
49 | {
50 | if (!$take) {
51 | return array_shift($array);
52 | }
53 |
54 | return array_splice($array, 0, $take);
55 | }
56 |
57 | /**
58 | * Get item of an array by index, accepting nested index
59 | *
60 | * @usage __::get(['foo' => ['bar' => 'ter']], 'foo.bar');
61 | * >> 'ter'
62 | *
63 | * @param array|object $collection array of values
64 | * @param null|string $key key or index
65 | * @param mixed $default default value to return if index not exist
66 | *
67 | * @return mixed
68 | */
69 | public static function get($collection = [], $key = null, $default = null)
70 | {
71 | if (__::isNull($key)) {
72 | return $collection;
73 | }
74 |
75 | if (!__::isObject($collection) && isset($collection[$key])) {
76 | return $collection[$key];
77 | }
78 |
79 | foreach (explode('.', $key) as $segment) {
80 | if (__::isObject($collection)) {
81 | if (!isset($collection->{$segment})) {
82 | return $default instanceof Closure ? $default() : $default;
83 | } else {
84 | $collection = $collection->{$segment};
85 | }
86 | } else {
87 | if (!isset($collection[$segment])) {
88 | return $default instanceof Closure ? $default() : $default;
89 | } else {
90 | $collection = $collection[$segment];
91 | }
92 | }
93 | }
94 |
95 | return $collection;
96 | }
97 |
98 | /**
99 | * Get last item(s) of an array
100 | *
101 | * @usage __::last([1, 2, 3, 4, 5], 2);
102 | * >> [4, 5]
103 | *
104 | * @param array $array array of values
105 | * @param int|null $take number of returned values
106 | *
107 | * @return mixed
108 | */
109 | public static function last(array $array, $take = null)
110 | {
111 | if (!$take) {
112 | return array_pop($array);
113 | }
114 |
115 | return array_splice($array, -$take);
116 | }
117 |
118 | /**
119 | * Returns an array of values by mapping each in collection through the iterateFn. The iterateFn is invoked with
120 | * three arguments: (value, index|key, collection).
121 | *
122 | * @usage __::map([1, 2, 3], function($n) {
123 | * return $n * 3;
124 | * });
125 | * >> [3, 6, 9]
126 | *
127 | * @param array|object $collection The collection of values to map over.
128 | * @param \Closure $iterateFn The function to apply on each value.
129 | *
130 | * @return array
131 | */
132 | public static function map($collection, Closure $iterateFn): array
133 | {
134 | $result = [];
135 |
136 | __::doForEach($collection, function ($value, $key, $collection) use (&$result, $iterateFn) {
137 | $result[] = $iterateFn($value, $key, $collection);
138 | });
139 |
140 | return $result;
141 | }
142 |
143 | /**
144 | * Returns the maximum value from the collection. If passed an iterator, max will return max value returned by the
145 | * iterator.
146 | *
147 | * @usage __::max([1, 2, 3]);
148 | * >> 3
149 | *
150 | * @param array $array The array to iterate over
151 | *
152 | * @return mixed Returns the maximum value
153 | */
154 | public static function max(array $array = [])
155 | {
156 | return max($array);
157 | }
158 |
159 | /**
160 | * Returns the minimum value from the collection. If passed an iterator, min will return min value returned by the
161 | * iterator.
162 | *
163 | * @usage __::min([1, 2, 3]);
164 | * >> 1
165 | *
166 | * @param array $array array of values
167 | *
168 | * @return mixed
169 | */
170 | public static function min(array $array = [])
171 | {
172 | return min($array);
173 | }
174 |
175 | /**
176 | * Returns an array of values belonging to a given property of each item in a collection.
177 | *
178 | * @usage $a = [
179 | * ['foo' => 'bar', 'bis' => 'ter' ],
180 | * ['foo' => 'bar2', 'bis' => 'ter2'],
181 | * ];
182 | *
183 | * __::pluck($a, 'foo');
184 | * >> ['bar', 'bar2']
185 | *
186 | * @param array|object $collection array or object that can be converted to array
187 | * @param string $property property name
188 | *
189 | * @return array
190 | */
191 | public static function pluck($collection, string $property): array
192 | {
193 | $result = array_map(function ($value) use ($property) {
194 | if (is_array($value) && isset($value[$property])) {
195 | return $value[$property];
196 | } elseif (is_object($value) && isset($value->{$property})) {
197 | return $value->{$property};
198 | }
199 | foreach (__::split($property, '.') as $segment) {
200 | if (is_object($value)) {
201 | if (isset($value->{$segment})) {
202 | $value = $value->{$segment};
203 | } else {
204 | return null;
205 | }
206 | } else {
207 | if (isset($value[$segment])) {
208 | $value = $value[$segment];
209 | } else {
210 | return null;
211 | }
212 | }
213 | }
214 |
215 | return $value;
216 | }, (array)$collection);
217 |
218 | return array_values($result);
219 | }
220 |
221 |
222 | /**
223 | * Return data matching specific key value condition
224 | *
225 | * @usage __::where($a, ['age' => 16]);
226 | * >> [['name' => 'maciej', 'age' => 16]]
227 | *
228 | * @param array $array array of values
229 | * @param array $key condition in format of ['KEY'=>'VALUE']
230 | * @param bool $keepKeys keep original keys
231 | *
232 | * @return array
233 | */
234 | public static function where(array $array = [], array $key = [], bool $keepKeys = false): array
235 | {
236 | $result = [];
237 |
238 | foreach ($array as $k => $v) {
239 | $not = false;
240 |
241 | foreach ($key as $j => $w) {
242 | if (__::isArray($w)) {
243 | $inKV = $v[$j] ?? [];
244 | if (count(array_intersect_assoc($w, $inKV)) == 0) {
245 | $not = true;
246 | break;
247 | }
248 | } else {
249 | if (!isset($v[$j]) || $v[$j] != $w) {
250 | $not = true;
251 | break;
252 | }
253 | }
254 | }
255 |
256 | if ($not == false) {
257 | if ($keepKeys) {
258 | $result[$k] = $v;
259 | } else {
260 | $result[] = $v;
261 | }
262 | }
263 | }
264 |
265 | return $result;
266 | }
267 |
268 | /**
269 | * Combines and merge collections provided with each others.
270 | *
271 | * If the collections have common keys, then the last passed keys override the
272 | * previous. If numerical indexes are passed, then last passed indexes override
273 | * the previous.
274 | *
275 | * For a recursive merge, see __::merge.
276 | *
277 | * @usage __::assign(['color' => ['favorite' => 'red', 5], 3], [10, 'color' => ['favorite' => 'green', 'blue']]);
278 | * >> ['color' => ['favorite' => 'green', 'blue'], 10]
279 | *
280 | * @param array|object $collection1 Collection to assign to.
281 | * @param array|object $collection2 Other collections to assign
282 | *
283 | * @return array|object Assigned collection.
284 | */
285 | public static function assign($collection1, $collection2)
286 | {
287 | return __::reduceRight(func_get_args(), function ($source, $result) {
288 | __::doForEach($source, function ($sourceValue, $key) use (&$result) {
289 | $result = __::set($result, $key, $sourceValue);
290 | });
291 |
292 | return $result;
293 | }, []);
294 | }
295 |
296 | /**
297 | * Reduces $collection to a value which is the $accumulator result of running each
298 | * element in $collection - from right to left - thru $iterateFn, where each
299 | * successive invocation is supplied the return value of the previous.
300 | *
301 | * If $accumulator is not given, the first element of $collection is used as the
302 | * initial value.
303 | *
304 | * The $iterateFn is invoked with four arguments:
305 | * ($accumulator, $value, $index|$key, $collection).
306 | *
307 | * @usage __::reduceRight(['a', 'b', 'c'], function ($word, $char) {
308 | * return $word . $char;
309 | * }, '');
310 | * >> 'cba'
311 | *
312 | * @param array|object $collection The collection to iterate over.
313 | * @param \Closure $iterateFn The function invoked per iteration.
314 | * @param mixed $accumulator
315 | *
316 | * @return array|mixed|null (*): Returns the accumulated value.
317 | */
318 | public static function reduceRight($collection, Closure $iterateFn, $accumulator = null)
319 | {
320 | if ($accumulator === null) {
321 | $accumulator = array_pop($collection);
322 | }
323 |
324 | __::doForEachRight(
325 | $collection,
326 | function ($value, $key, $collection) use (&$accumulator, $iterateFn) {
327 | $accumulator = $iterateFn($accumulator, $value, $key, $collection);
328 | }
329 | );
330 |
331 | return $accumulator;
332 | }
333 |
334 | /**
335 | * Iterate over elements of the collection, from right to left, and invokes iterate
336 | * for each element.
337 | *
338 | * The iterate is invoked with three arguments: (value, index|key, collection).
339 | * Iterate functions may exit iteration early by explicitly returning false.
340 | *
341 | * @usage __::doForEachRight([1, 2, 3], function ($value) { print_r($value) });
342 | * >> (Side effect: print 3, 2, 1)
343 | *
344 | * @param array|object $collection The collection to iterate over.
345 | * @param \Closure $iterateFn The function to call for each value.
346 | *
347 | * @return boolean
348 | */
349 | public static function doForEachRight($collection, Closure $iterateFn)
350 | {
351 | __::doForEach(__::iteratorReverse($collection), $iterateFn);
352 | return true;
353 | }
354 |
355 | /**
356 | * Iterate over elements of the collection and invokes iterate for each element.
357 | *
358 | * The iterate is invoked with three arguments: (value, index|key, collection).
359 | * Iterate functions may exit iteration early by explicitly returning false.
360 | *
361 | * @usage __::doForEach([1, 2, 3], function ($value) { print_r($value) });
362 | * >> (Side effect: print 1, 2, 3)
363 | *
364 | * @param array|object $collection The collection to iterate over.
365 | * @param \Closure $iterateFn The function to call for each value
366 | *
367 | * @return boolean
368 | */
369 | public static function doForEach($collection, Closure $iterateFn)
370 | {
371 | foreach ($collection as $key => $value) {
372 | if ($iterateFn($value, $key, $collection) === false) {
373 | break;
374 | }
375 | }
376 | return true;
377 | }
378 |
379 | /**
380 | * @param array $iterable
381 | *
382 | * @return \Generator
383 | */
384 | public static function iteratorReverse($iterable)
385 | {
386 | for (end($iterable); ($key = key($iterable)) !== null; prev($iterable)) {
387 | yield $key => current($iterable);
388 | }
389 | }
390 |
391 | /**
392 | * Return a new collection with the item set at index to given value.
393 | * Index can be a path of nested indexes.
394 | *
395 | * If a portion of path doesn't exist, it's created. Arrays are created for missing
396 | * index in an array; objects are created for missing property in an object.
397 | *
398 | * @usage __::set(['foo' => ['bar' => 'ter']], 'foo.baz.ber', 'fer');
399 | * >> '['foo' => ['bar' => 'ter', 'baz' => ['ber' => 'fer']]]'
400 | *
401 | * @param array|object $collection collection of values
402 | * @param string|int|null $path key or index
403 | * @param mixed $value the value to set at position $key
404 | *
405 | * @throws \Exception if the path consists of a non collection and strict is set to false
406 | *
407 | * @return array|object the new collection with the item set
408 | */
409 | public static function set($collection, $path, $value = null)
410 | {
411 | if ($path === null) {
412 | return $collection;
413 | }
414 | $portions = __::split($path, '.', 2);
415 | $key = $portions[0];
416 | if (count($portions) === 1) {
417 | return __::universalSet($collection, $key, $value);
418 | }
419 | // Here we manage the case where the portion of the path points to nothing,
420 | // or to a value that does not match the type of the source collection
421 | // (e.g. the path portion 'foo.bar' points to an integer value, while we
422 | // want to set a string at 'foo.bar.fun'. We first set an object or array
423 | // - following the current collection type - to 'for.bar' before setting
424 | // 'foo.bar.fun' to the specified value).
425 | if (!__::has($collection, $key)
426 | || (__::isObject($collection) && !__::isObject(__::get($collection, $key)))
427 | || (__::isArray($collection) && !__::isArray(__::get($collection, $key)))
428 | ) {
429 | $collection = __::universalSet($collection, $key, __::isObject($collection) ? new stdClass : []);
430 | }
431 |
432 | return __::universalSet($collection, $key, __::set(__::get($collection, $key), $portions[1], $value));
433 | }
434 |
435 | /**
436 | * @param mixed $collection
437 | * @param mixed $key
438 | * @param mixed $value
439 | *
440 | * @return mixed
441 | */
442 | public static function universalSet($collection, $key, $value)
443 | {
444 | $set_object = function ($object, $key, $value) {
445 | $newObject = clone $object;
446 | $newObject->$key = $value;
447 |
448 | return $newObject;
449 | };
450 | $set_array = function ($array, $key, $value) {
451 | $array[$key] = $value;
452 |
453 | return $array;
454 | };
455 | $setter = __::isObject($collection) ? $set_object : $set_array;
456 |
457 | return call_user_func_array($setter, [$collection, $key, $value]);
458 | }
459 |
460 | /**
461 | * Returns if $input contains all requested $keys. If $strict is true it also checks if $input exclusively contains
462 | * the given $keys.
463 | *
464 | * @usage __::hasKeys(['foo' => 'bar', 'foz' => 'baz'], ['foo', 'foz']);
465 | * >> true
466 | *
467 | * @param array $collection of key values pairs
468 | * @param array $keys collection of keys to look for
469 | * @param boolean $strict to exclusively check
470 | *
471 | * @return boolean
472 | */
473 | public static function hasKeys($collection = [], array $keys = [], bool $strict = false): bool
474 | {
475 | $keyCount = count($keys);
476 | if ($strict && count($collection) !== $keyCount) {
477 | return false;
478 | }
479 |
480 | return __::every(
481 | __::map($keys, function ($key) use ($collection) {
482 | return __::has($collection, $key);
483 | }),
484 | function ($v) {
485 | return $v === true;
486 | }
487 | );
488 | }
489 |
490 | /**
491 | * Return true if $collection contains the requested $key.
492 | *
493 | * In constraint to isset(), __::has() returns true if the key exists but is null.
494 | *
495 | * @usage __::has(['foo' => ['bar' => 'num'], 'foz' => 'baz'], 'foo.bar');
496 | * >> true
497 | *
498 | * __::hasKeys((object) ['foo' => 'bar', 'foz' => 'baz'], 'bar');
499 | * >> false
500 | *
501 | * @param array|object $collection of key values pairs
502 | * @param string $path Path to look for.
503 | *
504 | * @return boolean
505 | */
506 | public static function has($collection, $path): bool
507 | {
508 | $portions = __::split($path, '.', 2);
509 | $key = $portions[0];
510 |
511 | if (count($portions) === 1) {
512 | return array_key_exists($key, (array)$collection);
513 | }
514 |
515 | return __::has(__::get($collection, $key), $portions[1]);
516 | }
517 |
518 | /**
519 | * Combines and concat collections provided with each others.
520 | *
521 | * If the collections have common keys, then the values are appended in an array.
522 | * If numerical indexes are passed, then values are appended.
523 | *
524 | * For a recursive merge, see __::merge.
525 | *
526 | * @usage __::concat(['color' => ['favorite' => 'red', 5], 3], [10, 'color' => ['favorite' => 'green', 'blue']]);
527 | * >> ['color' => ['favorite' => ['green'], 5, 'blue'], 3, 10]
528 | *
529 | * @param array|object $collection1 Collection to assign to.
530 | * @param array|object $collection2 Other collections to assign.
531 | *
532 | * @return array|object Assigned collection.
533 | */
534 | public static function concat($collection1, $collection2)
535 | {
536 | $isObject = __::isObject($collection1);
537 |
538 | $args = __::map(func_get_args(), function ($arg) {
539 | return (array)$arg;
540 | });
541 |
542 | $merged = call_user_func_array('array_merge', $args);
543 |
544 | return $isObject ? (object)$merged : $merged;
545 | }
546 |
547 | /**
548 | * Recursively combines and concat collections provided with each others.
549 | *
550 | * If the collections have common keys, then the values are appended in an array.
551 | * If numerical indexes are passed, then values are appended.
552 | *
553 | * For a non-recursive concat, see __::concat.
554 | *
555 | * @usage __::concatDeep(['color' => ['favorite' => 'red', 5], 3], [10, 'color' => ['favorite' => 'green',
556 | * 'blue']]);
557 | * >> ['color' => ['favorite' => ['red', 'green'], 5, 'blue'], 3, 10]
558 | *
559 | * @param array|object $collection1 First collection to concatDeep.
560 | * @param array|object $collection2 other collections to concatDeep.
561 | *
562 | * @return array|object Concatenated collection.
563 | */
564 | public static function concatDeep($collection1, $collection2)
565 | {
566 | return __::reduceRight(func_get_args(), function ($source, $result) {
567 | __::doForEach($source, function ($sourceValue, $key) use (&$result) {
568 | if (!__::has($result, $key)) {
569 | $result = __::set($result, $key, $sourceValue);
570 | } else {
571 | if (is_numeric($key)) {
572 | $result = __::concat($result, [$sourceValue]);
573 | } else {
574 | $resultValue = __::get($result, $key);
575 | $result = __::set($result, $key, __::concatDeep(
576 | __::isCollection($resultValue) ? $resultValue : (array)$resultValue,
577 | __::isCollection($sourceValue) ? $sourceValue : (array)$sourceValue
578 | ));
579 | }
580 | }
581 | });
582 |
583 | return $result;
584 | }, []);
585 | }
586 |
587 | /**
588 | * Flattens a complex collection by mapping each ending leafs value to a key consisting of all previous indexes.
589 | *
590 | * @usage __::ease(['foo' => ['bar' => 'ter'], 'baz' => ['b', 'z']]);
591 | * >> '['foo.bar' => 'ter', 'baz.0' => 'b', , 'baz.1' => 'z']'
592 | *
593 | * @param array $collection array of values
594 | * @param string $glue glue between key path
595 | *
596 | * @return array flatten collection
597 | */
598 | public static function ease(array $collection, string $glue = '.'): array
599 | {
600 | $map = [];
601 | __::internalEase($map, $collection, $glue);
602 |
603 | return $map;
604 | }
605 |
606 | /**
607 | * Inner function for collections::ease
608 | *
609 | * @param array $map
610 | * @param array $array
611 | * @param string $glue
612 | * @param string $prefix
613 | */
614 | private static function internalEase(array &$map, array $array, string $glue, string $prefix = '')
615 | {
616 | foreach ($array as $index => $value) {
617 | if (is_array($value)) {
618 | __::internalEase($map, $value, $glue, $prefix . $index . $glue);
619 | } else {
620 | $map[$prefix . $index] = $value;
621 | }
622 | }
623 | }
624 |
625 | /**
626 | * Checks if predicate returns truthy for all elements of collection.
627 | *
628 | * Iteration is stopped once predicate returns falsey.
629 | * The predicate is invoked with three arguments: (value, index|key, collection).
630 | *
631 | * @usage __::every([1, 3, 4], function ($v) { return is_int($v); });
632 | * >> true
633 | *
634 | * @param array|object $collection The collection to iterate over.
635 | * @param \Closure $iterateFn The function to call for each value.
636 | *
637 | * @return bool
638 | */
639 | public static function every($collection, Closure $iterateFn): bool
640 | {
641 | $truthy = true;
642 |
643 | __::doForEach(
644 | $collection,
645 | function ($value, $key, $collection) use (&$truthy, $iterateFn) {
646 | $truthy = $truthy && $iterateFn($value, $key, $collection);
647 | if (!$truthy) {
648 | return false;
649 | }
650 | }
651 | );
652 |
653 | return $truthy;
654 | }
655 |
656 | /**
657 | * Returns an associative array where the keys are values of $key.
658 | *
659 | * @author Chauncey McAskill
660 | * @link https://gist.github.com/mcaskill/baaee44487653e1afc0d array_group_by() function.
661 | *
662 | * @usage __::groupBy([
663 | * ['state' => 'IN', 'city' => 'Indianapolis', 'object' => 'School bus'],
664 | * ['state' => 'CA', 'city' => 'San Diego', 'object' => 'Light bulb'],
665 | * ['state' => 'CA', 'city' => 'Mountain View', 'object' => 'Space pen'],
666 | * ], 'state');
667 | * >> [
668 | * 'IN' => [
669 | * ['state' => 'IN', 'city' => 'Indianapolis', 'object' => 'School bus'],
670 | * ['state' => 'CA', 'city' => 'San Diego', 'object' => 'Light bulb'],
671 | * ],
672 | * 'CA' => [
673 | * ['state' => 'CA', 'city' => 'Mountain View', 'object' => 'Space pen']
674 | * ]
675 | * ]
676 | *
677 | *
678 | * __::groupBy([
679 | * ['state' => 'IN', 'city' => 'Indianapolis', 'object' => 'School bus'],
680 | * ['state' => 'IN', 'city' => 'Indianapolis', 'object' => 'Manhole'],
681 | * ['state' => 'CA', 'city' => 'San Diego', 'object' => 'Light bulb'],
682 | * ],
683 | * function ($value) {
684 | * return $value->city;
685 | * }
686 | * );
687 | * >> [
688 | * 'Indianapolis' => [
689 | * ['state' => 'IN', 'city' => 'Indianapolis', 'object' => 'School bus'],
690 | * ['state' => 'IN', 'city' => 'Indianapolis', 'object' => 'Manhole'],
691 | * ],
692 | * 'San Diego' => [
693 | * ['state' => 'CA', 'city' => 'San Diego', 'object' => 'Light bulb'],
694 | * ]
695 | * ]
696 | *
697 | * @param array $array
698 | * @param mixed $key
699 | *
700 | * @return array
701 | */
702 | public static function groupBy(array $array, $key): array
703 | {
704 | if (!is_bool($key) && !is_scalar($key) && !is_callable($key)) {
705 | return $array;
706 | }
707 | $grouped = [];
708 | foreach ($array as $value) {
709 | $groupKey = null;
710 | if (is_callable($key)) {
711 | $groupKey = call_user_func($key, $value);
712 | } elseif (is_object($value) && property_exists($value, (string)$key)) {
713 | $groupKey = $value->{$key};
714 | } elseif (is_array($value) && isset($value[$key])) {
715 | $groupKey = $value[$key];
716 | }
717 | if ($groupKey === null) {
718 | continue;
719 | }
720 | $grouped[$groupKey][] = $value;
721 | }
722 | if (($argCnt = func_num_args()) > 2) {
723 | $args = func_get_args();
724 | foreach ($grouped as $_key => $value) {
725 | $params = array_merge([$value], array_slice($args, 2, $argCnt));
726 | $grouped[$_key] = call_user_func_array('\__::groupBy', $params);
727 | }
728 | }
729 |
730 | return $grouped;
731 | }
732 |
733 | /**
734 | * Check if value is an empty array or object. We consider any non enumerable as empty.
735 | *
736 | * @usage __::isEmpty([]);
737 | * >> true
738 | *
739 | * @param mixed $value The value to check for emptiness.
740 | *
741 | * @return bool
742 | */
743 | public static function isEmpty($value): bool
744 | {
745 | return (!__::isArray($value) && !__::isObject($value)) || count((array)$value) === 0;
746 | }
747 |
748 | /**
749 | * Transforms the keys in a collection by running each key through the iterator
750 | *
751 | * @param array $array array of values
752 | * @param \Closure $closure closure to map the keys
753 | *
754 | * @throws \Exception if closure doesn't return a valid key that can be used in PHP array
755 | *
756 | * @return array
757 | */
758 | public static function mapKeys(array $array, Closure $closure = null): array
759 | {
760 | if (is_null($closure)) {
761 | $closure = '__::identity';
762 | }
763 | $resultArray = [];
764 | foreach ($array as $key => $value) {
765 | $newKey = call_user_func_array($closure, [$key, $value, $array]);
766 | // key must be a number or string
767 | if (!is_numeric($newKey) && !is_string($newKey)) {
768 | throw new Exception('closure must returns a number or string');
769 | }
770 | $resultArray[$newKey] = $value;
771 | }
772 |
773 | return $resultArray;
774 | }
775 |
776 | /**
777 | * Transforms the values in a collection by running each value through the iterator
778 | *
779 | * @param array $array array of values
780 | * @param \Closure $closure closure to map the values
781 | *
782 | * @return array
783 | */
784 | public static function mapValues(array $array, Closure $closure = null): array
785 | {
786 | if (is_null($closure)) {
787 | $closure = '__::identity';
788 | }
789 | $resultArray = [];
790 | foreach ($array as $key => $value) {
791 | $resultArray[$key] = call_user_func_array($closure, [$value, $key, $array]);
792 | }
793 |
794 | return $resultArray;
795 | }
796 |
797 | /**
798 | * Recursively combines and merge collections provided with each others.
799 | *
800 | * If the collections have common keys, then the last passed keys override the previous.
801 | * If numerical indexes are passed, then last passed indexes override the previous.
802 | *
803 | * For a non-recursive merge, see __::merge.
804 | *
805 | * @usage __::merge(['color' => ['favorite' => 'red', 'model' => 3, 5], 3], [10, 'color' => ['favorite' => 'green',
806 | * 'blue']]);
807 | * >> ['color' => ['favorite' => 'green', 'model' => 3, 'blue'], 10]
808 | *
809 | * @param array|object $collection1 First collection to merge.
810 | * @param array|object $collection2 Other collections to merge.
811 | *
812 | * @return array|object Concatenated collection.
813 | */
814 | public static function merge($collection1, $collection2)
815 | {
816 | return __::reduceRight(func_get_args(), function ($source, $result) {
817 | __::doForEach($source, function ($sourceValue, $key) use (&$result) {
818 | $value = $sourceValue;
819 | if (__::isCollection($value)) {
820 | $value = __::merge(__::get($result, $key), $sourceValue);
821 | }
822 | $result = __::set($result, $key, $value);
823 | });
824 |
825 | return $result;
826 | }, []);
827 | }
828 |
829 | /**
830 | * Returns an array having only keys present in the given path list. Values for missing keys values will be filled
831 | * with provided default value.
832 | *
833 | * @usage __::pick(['a' => 1, 'b' => ['c' => 3, 'd' => 4]], ['a', 'b.d']);
834 | * >> ['a' => 1, 'b' => ['d' => 4]]
835 | *
836 | * @param array|object $collection The collection to iterate over.
837 | * @param array $paths array paths to pick
838 | * @param null $default
839 | *
840 | * @return array|object
841 | */
842 | public static function pick($collection = [], array $paths = [], $default = null)
843 | {
844 | return __::reduce($paths, function ($results, $path) use ($collection, $default) {
845 | return __::set($results, $path, __::get($collection, $path, $default));
846 | }, __::isObject($collection) ? new stdClass() : []);
847 | }
848 |
849 | /**
850 | * Reduces $collection to a value which is the $accumulator result of running each
851 | * element in $collection thru $iterateFn, where each successive invocation is supplied
852 | * the return value of the previous.
853 | *
854 | * If $accumulator is not given, the first element of $collection is used as the
855 | * initial value.
856 | *
857 | * The $iterateFn is invoked with four arguments:
858 | * ($accumulator, $value, $index|$key, $collection).
859 | *
860 | * @usage __::reduce([1, 2], function ($sum, $number) {
861 | * return $sum + $number;
862 | * }, 0);
863 | * >> 3
864 | *
865 | * $a = [
866 | * ['state' => 'IN', 'city' => 'Indianapolis', 'object' => 'School bus'],
867 | * ['state' => 'IN', 'city' => 'Indianapolis', 'object' => 'Manhole'],
868 | * ['state' => 'IN', 'city' => 'Plainfield', 'object' => 'Basketball'],
869 | * ['state' => 'CA', 'city' => 'San Diego', 'object' => 'Light bulb'],
870 | * ['state' => 'CA', 'city' => 'Mountain View', 'object' => 'Space pen'],
871 | * ];
872 | * $iterateFn = function ($accumulator, $value) {
873 | * if (isset($accumulator[$value['city']]))
874 | * $accumulator[$value['city']]++;
875 | * else
876 | * $accumulator[$value['city']] = 1;
877 | * return $accumulator;
878 | * };
879 | * __::reduce($c, $iterateFn, []);
880 | * >> [
881 | * 'Indianapolis' => 2,
882 | * 'Plainfield' => 1,
883 | * 'San Diego' => 1,
884 | * 'Mountain View' => 1,
885 | * ]
886 | *
887 | * $object = new \stdClass();
888 | * $object->a = 1;
889 | * $object->b = 2;
890 | * $object->c = 1;
891 | * __::reduce($object, function ($result, $value, $key) {
892 | * if (!isset($result[$value]))
893 | * $result[$value] = [];
894 | * $result[$value][] = $key;
895 | * return $result;
896 | * }, [])
897 | * >> [
898 | * '1' => ['a', 'c'],
899 | * '2' => ['b']
900 | * ]
901 | *
902 | * @param array $collection The collection to iterate over.
903 | * @param \Closure $iterateFn The function invoked per iteration.
904 | * @param array|null $accumulator
905 | *
906 | * @return array|mixed|null (*): Returns the accumulated value.
907 | */
908 | public static function reduce($collection, Closure $iterateFn, $accumulator = null)
909 | {
910 | if ($accumulator === null) {
911 | $accumulator = array_shift($collection);
912 | }
913 | __::doForEach(
914 | $collection,
915 | function ($value, $key, $collection) use (&$accumulator, $iterateFn) {
916 | $accumulator = $iterateFn($accumulator, $value, $key, $collection);
917 | }
918 | );
919 |
920 | return $accumulator;
921 | }
922 |
923 | /**
924 | * Builds a multidimensional collection out of a hash map using the key as indicator where to put the value.
925 | *
926 | * @usage __::unease(['foo.bar' => 'ter', 'baz.0' => 'b', , 'baz.1' => 'z']);
927 | * >> '['foo' => ['bar' => 'ter'], 'baz' => ['b', 'z']]'
928 | *
929 | * @param array $collection hash map of values
930 | * @param string $separator the glue used in the keys
931 | *
932 | * @return array
933 | * @throws \Exception
934 | */
935 | public static function unease(array $collection, string $separator = '.'): array
936 | {
937 | $nonDefaultSeparator = $separator !== '.';
938 | $map = [];
939 |
940 | foreach ($collection as $key => $value) {
941 | $map = __::set(
942 | $map,
943 | $nonDefaultSeparator ? str_replace($separator, '.', $key) : $key,
944 | $value
945 | );
946 | }
947 |
948 | return $map;
949 | }
950 | }
951 |
--------------------------------------------------------------------------------
/src/Traits/Functions.php:
--------------------------------------------------------------------------------
1 | > 'jakies-zdanie-z-duza-iloscia-obcych-znakow'
17 | *
18 | * @param string $str string to generate slug from
19 | * @param array $options method options which includes: delimiter, limit, lowercase, replacements, transliterate
20 | *
21 | * @return string
22 | */
23 | public static function slug(string $str, array $options = []): string
24 | {
25 | // Make sure string is in UTF-8 and strip invalid UTF-8 characters
26 | $str = mb_convert_encoding((string)$str, 'UTF-8', mb_list_encodings());
27 |
28 | $defaults = [
29 | 'delimiter' => '-',
30 | 'limit' => null,
31 | 'lowercase' => true,
32 | 'replacements' => [],
33 | 'transliterate' => true,
34 | ];
35 |
36 | // Merge options
37 | $options = array_merge($defaults, $options);
38 |
39 | $char_map = [
40 | // Latin
41 | 'À' => 'A',
42 | 'Á' => 'A',
43 | 'Â' => 'A',
44 | 'Ã' => 'A',
45 | 'Ä' => 'A',
46 | 'Å' => 'A',
47 | 'Æ' => 'AE',
48 | 'Ç' => 'C',
49 | 'È' => 'E',
50 | 'É' => 'E',
51 | 'Ê' => 'E',
52 | 'Ë' => 'E',
53 | 'Ì' => 'I',
54 | 'Í' => 'I',
55 | 'Î' => 'I',
56 | 'Ï' => 'I',
57 | 'Ð' => 'D',
58 | 'Ñ' => 'N',
59 | 'Ò' => 'O',
60 | 'Ó' => 'O',
61 | 'Ô' => 'O',
62 | 'Õ' => 'O',
63 | 'Ö' => 'O',
64 | 'Ő' => 'O',
65 | 'Ø' => 'O',
66 | 'Ù' => 'U',
67 | 'Ú' => 'U',
68 | 'Û' => 'U',
69 | 'Ü' => 'U',
70 | 'Ű' => 'U',
71 | 'Ý' => 'Y',
72 | 'Þ' => 'TH',
73 | 'ß' => 'ss',
74 | 'à' => 'a',
75 | 'á' => 'a',
76 | 'â' => 'a',
77 | 'ã' => 'a',
78 | 'ä' => 'a',
79 | 'å' => 'a',
80 | 'æ' => 'ae',
81 | 'ç' => 'c',
82 | 'è' => 'e',
83 | 'é' => 'e',
84 | 'ê' => 'e',
85 | 'ë' => 'e',
86 | 'ì' => 'i',
87 | 'í' => 'i',
88 | 'î' => 'i',
89 | 'ï' => 'i',
90 | 'ð' => 'd',
91 | 'ñ' => 'n',
92 | 'ò' => 'o',
93 | 'ó' => 'o',
94 | 'ô' => 'o',
95 | 'õ' => 'o',
96 | 'ö' => 'o',
97 | 'ő' => 'o',
98 | 'ø' => 'o',
99 | 'ù' => 'u',
100 | 'ú' => 'u',
101 | 'û' => 'u',
102 | 'ü' => 'u',
103 | 'ű' => 'u',
104 | 'ý' => 'y',
105 | 'þ' => 'th',
106 | 'ÿ' => 'y',
107 |
108 | // Latin symbols
109 | '©' => '(c)',
110 |
111 | // Greek
112 | 'Α' => 'A',
113 | 'Β' => 'B',
114 | 'Γ' => 'G',
115 | 'Δ' => 'D',
116 | 'Ε' => 'E',
117 | 'Ζ' => 'Z',
118 | 'Η' => 'H',
119 | 'Θ' => '8',
120 | 'Ι' => 'I',
121 | 'Κ' => 'K',
122 | 'Λ' => 'L',
123 | 'Μ' => 'M',
124 | 'Ν' => 'N',
125 | 'Ξ' => '3',
126 | 'Ο' => 'O',
127 | 'Π' => 'P',
128 | 'Ρ' => 'R',
129 | 'Σ' => 'S',
130 | 'Τ' => 'T',
131 | 'Υ' => 'Y',
132 | 'Φ' => 'F',
133 | 'Χ' => 'X',
134 | 'Ψ' => 'PS',
135 | 'Ω' => 'W',
136 | 'Ά' => 'A',
137 | 'Έ' => 'E',
138 | 'Ί' => 'I',
139 | 'Ό' => 'O',
140 | 'Ύ' => 'Y',
141 | 'Ή' => 'H',
142 | 'Ώ' => 'W',
143 | 'Ϊ' => 'I',
144 | 'Ϋ' => 'Y',
145 | 'α' => 'a',
146 | 'β' => 'b',
147 | 'γ' => 'g',
148 | 'δ' => 'd',
149 | 'ε' => 'e',
150 | 'ζ' => 'z',
151 | 'η' => 'h',
152 | 'θ' => '8',
153 | 'ι' => 'i',
154 | 'κ' => 'k',
155 | 'λ' => 'l',
156 | 'μ' => 'm',
157 | 'ν' => 'n',
158 | 'ξ' => '3',
159 | 'ο' => 'o',
160 | 'π' => 'p',
161 | 'ρ' => 'r',
162 | 'σ' => 's',
163 | 'τ' => 't',
164 | 'υ' => 'y',
165 | 'φ' => 'f',
166 | 'χ' => 'x',
167 | 'ψ' => 'ps',
168 | 'ω' => 'w',
169 | 'ά' => 'a',
170 | 'έ' => 'e',
171 | 'ί' => 'i',
172 | 'ό' => 'o',
173 | 'ύ' => 'y',
174 | 'ή' => 'h',
175 | 'ώ' => 'w',
176 | 'ς' => 's',
177 | 'ϊ' => 'i',
178 | 'ΰ' => 'y',
179 | 'ϋ' => 'y',
180 | 'ΐ' => 'i',
181 |
182 | // Turkish
183 | 'Ş' => 'S',
184 | 'İ' => 'I',
185 | 'Ç' => 'C',
186 | 'Ü' => 'U',
187 | 'Ö' => 'O',
188 | 'Ğ' => 'G',
189 | 'ş' => 's',
190 | 'ı' => 'i',
191 | 'ç' => 'c',
192 | 'ü' => 'u',
193 | 'ö' => 'o',
194 | 'ğ' => 'g',
195 |
196 | // Russian
197 | 'А' => 'A',
198 | 'Б' => 'B',
199 | 'В' => 'V',
200 | 'Г' => 'G',
201 | 'Д' => 'D',
202 | 'Е' => 'E',
203 | 'Ё' => 'Yo',
204 | 'Ж' => 'Zh',
205 | 'З' => 'Z',
206 | 'И' => 'I',
207 | 'Й' => 'J',
208 | 'К' => 'K',
209 | 'Л' => 'L',
210 | 'М' => 'M',
211 | 'Н' => 'N',
212 | 'О' => 'O',
213 | 'П' => 'P',
214 | 'Р' => 'R',
215 | 'С' => 'S',
216 | 'Т' => 'T',
217 | 'У' => 'U',
218 | 'Ф' => 'F',
219 | 'Х' => 'H',
220 | 'Ц' => 'C',
221 | 'Ч' => 'Ch',
222 | 'Ш' => 'Sh',
223 | 'Щ' => 'Sh',
224 | 'Ъ' => '',
225 | 'Ы' => 'Y',
226 | 'Ь' => '',
227 | 'Э' => 'E',
228 | 'Ю' => 'Yu',
229 | 'Я' => 'Ya',
230 | 'а' => 'a',
231 | 'б' => 'b',
232 | 'в' => 'v',
233 | 'г' => 'g',
234 | 'д' => 'd',
235 | 'е' => 'e',
236 | 'ё' => 'yo',
237 | 'ж' => 'zh',
238 | 'з' => 'z',
239 | 'и' => 'i',
240 | 'й' => 'j',
241 | 'к' => 'k',
242 | 'л' => 'l',
243 | 'м' => 'm',
244 | 'н' => 'n',
245 | 'о' => 'o',
246 | 'п' => 'p',
247 | 'р' => 'r',
248 | 'с' => 's',
249 | 'т' => 't',
250 | 'у' => 'u',
251 | 'ф' => 'f',
252 | 'х' => 'h',
253 | 'ц' => 'c',
254 | 'ч' => 'ch',
255 | 'ш' => 'sh',
256 | 'щ' => 'sh',
257 | 'ъ' => '',
258 | 'ы' => 'y',
259 | 'ь' => '',
260 | 'э' => 'e',
261 | 'ю' => 'yu',
262 | 'я' => 'ya',
263 |
264 | // Ukrainian
265 | 'Є' => 'Ye',
266 | 'І' => 'I',
267 | 'Ї' => 'Yi',
268 | 'Ґ' => 'G',
269 | 'є' => 'ye',
270 | 'і' => 'i',
271 | 'ї' => 'yi',
272 | 'ґ' => 'g',
273 |
274 | // Czech
275 | 'Č' => 'C',
276 | 'Ď' => 'D',
277 | 'Ě' => 'E',
278 | 'Ň' => 'N',
279 | 'Ř' => 'R',
280 | 'Š' => 'S',
281 | 'Ť' => 'T',
282 | 'Ů' => 'U',
283 | 'Ž' => 'Z',
284 | 'č' => 'c',
285 | 'ď' => 'd',
286 | 'ě' => 'e',
287 | 'ň' => 'n',
288 | 'ř' => 'r',
289 | 'š' => 's',
290 | 'ť' => 't',
291 | 'ů' => 'u',
292 | 'ž' => 'z',
293 |
294 | // Polish
295 | 'Ą' => 'A',
296 | 'Ć' => 'C',
297 | 'Ę' => 'e',
298 | 'Ł' => 'L',
299 | 'Ń' => 'N',
300 | 'Ó' => 'o',
301 | 'Ś' => 'S',
302 | 'Ź' => 'Z',
303 | 'Ż' => 'Z',
304 | 'ą' => 'a',
305 | 'ć' => 'c',
306 | 'ę' => 'e',
307 | 'ł' => 'l',
308 | 'ń' => 'n',
309 | 'ó' => 'o',
310 | 'ś' => 's',
311 | 'ź' => 'z',
312 | 'ż' => 'z',
313 |
314 | // Latvian
315 | 'Ā' => 'A',
316 | 'Č' => 'C',
317 | 'Ē' => 'E',
318 | 'Ģ' => 'G',
319 | 'Ī' => 'i',
320 | 'Ķ' => 'k',
321 | 'Ļ' => 'L',
322 | 'Ņ' => 'N',
323 | 'Š' => 'S',
324 | 'Ū' => 'u',
325 | 'Ž' => 'Z',
326 | 'ā' => 'a',
327 | 'č' => 'c',
328 | 'ē' => 'e',
329 | 'ģ' => 'g',
330 | 'ī' => 'i',
331 | 'ķ' => 'k',
332 | 'ļ' => 'l',
333 | 'ņ' => 'n',
334 | 'š' => 's',
335 | 'ū' => 'u',
336 | 'ž' => 'z',
337 | ];
338 |
339 | // Make custom replacements
340 | $str = preg_replace(array_keys($options['replacements']), $options['replacements'], $str);
341 |
342 | // Transliterate characters to ASCII
343 | if ($options['transliterate']) {
344 | $str = str_replace(array_keys($char_map), $char_map, $str);
345 | }
346 |
347 | // Replace non-alphanumeric characters with our delimiter
348 | $str = preg_replace('/[^\p{L}\p{Nd}]+/u', $options['delimiter'], $str);
349 |
350 | // Remove duplicate delimiters
351 | $str = preg_replace('/(' . preg_quote($options['delimiter'], '/') . '){2,}/', '$1', $str);
352 |
353 | // Truncate slug to max. characters
354 | $str = mb_substr($str, 0, ($options['limit'] ? $options['limit'] : mb_strlen($str, 'UTF-8')), 'UTF-8');
355 |
356 | // Remove delimiter from ends
357 | $str = trim($str, $options['delimiter']);
358 |
359 | return $options['lowercase'] ? mb_strtolower($str, 'UTF-8') : $str;
360 | }
361 |
362 | /**
363 | * Find the urls inside a string a put them inside anchor tags.
364 | *
365 | * @usage __::urlify("I love https://google.com");
366 | * >> 'I love google.com'
367 | *
368 | * @param string $string
369 | *
370 | * @return string|mixed
371 | */
372 | public static function urlify(string $string)
373 | {
374 | /* Proposed by:
375 | * Søren Løvborg
376 | * http://stackoverflow.com/users/136796/soren-lovborg
377 | * http://stackoverflow.com/questions/17900004/turn-plain-text-urls-into-active-links-using-php/17900021#17900021
378 | */
379 |
380 | $rexProtocol = '(https?://)?';
381 | $rexDomain = '((?:[-a-zA-Z0-9]{1,63}\.)+[-a-zA-Z0-9]{2,63}|(?:[0-9]{1,3}\.){3}[0-9]{1,3})';
382 | $rexPort = '(:[0-9]{1,5})?';
383 | $rexPath = '(/[!$-/0-9:;=@_\':;!a-zA-Z\x7f-\xff]*?)?';
384 | $rexQuery = '(\?[!$-/0-9:;=@_\':;!a-zA-Z\x7f-\xff]+?)?';
385 | $rexFragment = '(#[!$-/0-9:;=@_\':;!a-zA-Z\x7f-\xff]+?)?';
386 |
387 | return preg_replace_callback(
388 | "&\\b$rexProtocol$rexDomain$rexPort$rexPath$rexQuery$rexFragment(?=[?.!,;:\"]?(\s|$))&",
389 | function ($match) {
390 | $completeUrl = $match[1] ? $match[0] : "http://{$match[0]}";
391 |
392 | return '' . $match[2] . $match[3] . $match[4] . '';
393 | },
394 | htmlspecialchars($string)
395 | );
396 | }
397 |
398 | /**
399 | * Truncate string based on count of words
400 | *
401 | * @usage $string = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque et mi orci.';
402 | * __::truncate($string);
403 | * >> 'Lorem ipsum dolor sit amet, consectetur...'
404 | *
405 | * @param string $text text to truncate
406 | * @param integer $limit limit of words
407 | *
408 | * @return string
409 | */
410 |
411 | public static function truncate(string $text, int $limit = 40): string
412 | {
413 | if (str_word_count($text, 0) > $limit) {
414 | $words = (array)str_word_count($text, 2);
415 | $pos = array_keys($words);
416 | $text = mb_substr($text, 0, $pos[$limit], 'UTF-8') . '...';
417 | }
418 |
419 | return $text;
420 | }
421 | }
422 |
--------------------------------------------------------------------------------
/src/Traits/Objects.php:
--------------------------------------------------------------------------------
1 | > true
14 | *
15 | * @param mixed $value
16 | *
17 | * @return bool
18 | */
19 | public static function isArray($value = null): bool
20 | {
21 | return is_array($value);
22 | }
23 |
24 | /**
25 | * Check if give value is function or not.
26 | *
27 | * @usage __::isFunction(function ($a) { return $a + 2; });
28 | * >> true
29 | *
30 | * @param mixed $value
31 | *
32 | * @return bool
33 | */
34 | public static function isFunction($value = null): bool
35 | {
36 | return is_callable($value);
37 | }
38 |
39 | /**
40 | * Check if give value is null or not.
41 | *
42 | * @usage __::isNull(null);
43 | * >> true
44 | *
45 | * @param mixed $value
46 | *
47 | * @return bool
48 | */
49 | public static function isNull($value = null): bool
50 | {
51 | return is_null($value);
52 | }
53 |
54 |
55 | /**
56 | * Check if give value is number or not.
57 | *
58 | * @usage __::isNumber(123);
59 | * >> true
60 | *
61 | * @param mixed $value
62 | *
63 | * @return bool
64 | */
65 | public static function isNumber($value = null): bool
66 | {
67 | return is_numeric($value);
68 | }
69 |
70 | /**
71 | * Check if give value is object or not.
72 | *
73 | * @usage __::isObject('fred');
74 | * >> false
75 | *
76 | * @param mixed $value
77 | *
78 | * @return bool
79 | */
80 | public static function isObject($value = null): bool
81 | {
82 | return is_object($value);
83 | }
84 |
85 | /**
86 | * Check if give value is string or not.
87 | *
88 | * @usage __::isString('fred');
89 | * >> true
90 | *
91 | * @param mixed $value
92 | *
93 | * @return bool
94 | */
95 | public static function isString($value = null): bool
96 | {
97 | return is_string($value);
98 | }
99 |
100 | /**
101 | * Check if the object is a collection. A collection is either an array or an object.
102 | *
103 | * @param mixed $value
104 | *
105 | * @return bool
106 | */
107 | public static function isCollection($value): bool
108 | {
109 | return __::isArray($value) || __::isObject($value);
110 | }
111 | }
112 |
--------------------------------------------------------------------------------
/src/Traits/Sequence/Chain.php:
--------------------------------------------------------------------------------
1 | compact()
12 | * ->prepend(4)
13 | * ->value();
14 | * >> [4, 1, 2, 3]
15 | *
16 | * @param mixed $initialValue
17 | *
18 | * @return mixed
19 | */
20 | public static function chain($initialValue)
21 | {
22 | return new ChainWrapper($initialValue);
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/Traits/Sequence/ChainWrapper.php:
--------------------------------------------------------------------------------
1 | value = $value;
23 | }
24 |
25 | /**
26 | * Dynamically calls php-lodash functions, prepend the list of parameters with the current collection list
27 | *
28 | * @param string $functionName must be a valid php-lodash function
29 | * @param array $params
30 | *
31 | * @return $this
32 | * @throws \Exception
33 | */
34 | public function __call(string $functionName, array $params): self
35 | {
36 | if (is_callable('\__::' . $functionName, true)) {
37 | $params = $params == null ? [] : $params;
38 | $params = __::prepend($params, $this->value);
39 | /** @var callable $fnCallable */
40 | $fnCallable = ['\__', $functionName];
41 | $this->value = call_user_func_array($fnCallable, $params);
42 |
43 | return $this;
44 | } else {
45 | throw new Exception("Invalid function {$functionName}");
46 | }
47 | }
48 |
49 | /**
50 | * @return mixed
51 | */
52 | public function value()
53 | {
54 | return $this->value;
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/Traits/Strings.php:
--------------------------------------------------------------------------------
1 | > ['a', 'b-c']
15 | *
16 | * @param string $input The string to split.
17 | * @param string $delimiter The boundary string.
18 | * @param int $limit (optional) If limit is set and positive, the returned array
19 | * will contain a maximum of limit elements with the last element containing the
20 | * rest of string.
21 | * If the limit parameter is negative, all components except the last -limit are returned.
22 | * If the limit parameter is zero, then this is treated as 1.
23 | *
24 | * @return array
25 | */
26 | public static function split(string $input, string $delimiter, int $limit = PHP_INT_MAX)
27 | {
28 | return explode($delimiter, $input, $limit);
29 | }
30 |
31 | /**
32 | * Converts string to [camel case](https://en.wikipedia.org/wiki/CamelCase).
33 | *
34 | * @usage __::camelCase('Foo Bar');
35 | * >> 'fooBar'
36 | *
37 | * @param string $input
38 | *
39 | * @return string|array
40 | */
41 | public static function camelCase(string $input)
42 | {
43 | $words = __::words(preg_replace("/['\x{2019}]/u", '', $input));
44 |
45 | return array_reduce(
46 | $words,
47 | function ($result, $word) use ($words) {
48 | $isFirst = __::first($words) === $word;
49 | $word = __::toLower($word);
50 |
51 | return $result . (!$isFirst ? __::capitalize($word) : $word);
52 | },
53 | ''
54 | );
55 | }
56 |
57 | /**
58 | * Converts the first character of string to upper case and the remaining to lower case.
59 | *
60 | * @usage __::capitalize('FRED');
61 | * >> 'Fred'
62 | *
63 | * @param string $input
64 | *
65 | * @return string
66 | */
67 | public static function capitalize(string $input): string
68 | {
69 | return __::upperFirst(__::toLower($input));
70 | }
71 |
72 | /**
73 | * Converts string to kebab case.
74 | *
75 | * @link https://en.wikipedia.org/wiki/Letter_case#Special_case_styles kebab case
76 | *
77 | * @usage __::kebabCase('Foo Bar');
78 | * >> 'foo-bar'
79 | *
80 | * @param string $input
81 | *
82 | * @return string
83 | */
84 | public static function kebabCase(string $input): string
85 | {
86 | $words = __::words(preg_replace("/['\x{2019}]/u", '', $input));
87 |
88 | return array_reduce(
89 | $words,
90 | function ($result, $word) use ($words) {
91 | $isFirst = __::first($words) === $word;
92 |
93 | return $result . (!$isFirst ? '-' : '') . __::toLower($word);
94 | },
95 | ''
96 | );
97 | }
98 |
99 | /**
100 | * Converts the first character of string to lower case, like lcfirst.
101 | *
102 | * @usage __::lowerFirst('Fred');
103 | * >> 'fred'
104 | *
105 | * @param string $input
106 | *
107 | * @return string
108 | */
109 | public static function lowerFirst(string $input): string
110 | {
111 | return lcfirst($input);
112 | }
113 |
114 | /**
115 | * Converts string to snake case.
116 | *
117 | * @link https://en.wikipedia.org/wiki/Snake_case snake case
118 | *
119 | * @usage __::snakeCase('Foo Bar');
120 | * >> 'foo_bar'
121 | *
122 | * @param string $input
123 | *
124 | * @return string
125 | */
126 | public static function snakeCase(string $input): string
127 | {
128 | $words = __::words(preg_replace("/['\x{2019}]/u", '', $input));
129 |
130 | return array_reduce(
131 | $words,
132 | function ($result, $word) use ($words) {
133 | $isFirst = __::first($words) === $word;
134 |
135 | return $result . (!$isFirst ? '_' : '') . __::toLower($word);
136 | },
137 | ''
138 | );
139 | }
140 |
141 | /**
142 | * Converts string to start case.
143 | *
144 | * @link https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage start case
145 | *
146 | * @usage __::startCase('--foo-bar--');
147 | * >> 'Foo Bar'
148 | *
149 | * @param string $input
150 | *
151 | * @return string
152 | */
153 | public static function startCase(string $input): string
154 | {
155 | $words = __::words(preg_replace("/['\x{2019}]/u", '', $input));
156 |
157 | return array_reduce(
158 | $words,
159 | function ($result, $word) use ($words) {
160 | $isFirst = __::first($words) === $word;
161 |
162 | return $result . (!$isFirst ? ' ' : '') . __::upperFirst($word);
163 | },
164 | ''
165 | );
166 | }
167 |
168 | /**
169 | * Converts string, as a whole, to lower case just like strtolower.
170 | *
171 | * @usage __::toLower('fooBar');
172 | * >> 'foobar'
173 | *
174 | * @param string $input
175 | *
176 | * @return string
177 | */
178 | public static function toLower(string $input): string
179 | {
180 | return strtolower($input);
181 | }
182 |
183 | /**
184 | * Converts string, as a whole, to lower case just like strtoupper.
185 | *
186 | * @usage __::toUpper('fooBar');
187 | * >> 'FOOBAR'
188 | *
189 | * @param string $input
190 | *
191 | * @return string
192 | */
193 | public static function toUpper(string $input): string
194 | {
195 | return strtoupper($input);
196 | }
197 |
198 | /**
199 | * Converts string, as space separated words, to upper case.
200 | *
201 | * @usage __::upperCase('--foo-bar');
202 | * >> 'FOO BAR'
203 | *
204 | * @param string $input
205 | *
206 | * @return string
207 | */
208 | public static function upperCase(string $input): string
209 | {
210 | $words = __::words(preg_replace("/['\x{2019}]/u", '', $input));
211 |
212 | return array_reduce(
213 | $words,
214 | function ($result, $word) use ($words) {
215 | $isFirst = __::first($words) === $word;
216 |
217 | return $result . (!$isFirst ? ' ' : '') . __::toUpper($word);
218 | },
219 | ''
220 | );
221 | }
222 |
223 | /**
224 | * Converts the first character of string to upper case, like ucfirst.
225 | *
226 | * @usage __::upperFirst('fred');
227 | * >> 'Fred'
228 | *
229 | * @param string $input
230 | *
231 | * @return string
232 | */
233 | public static function upperFirst(string $input): string
234 | {
235 | return ucfirst($input);
236 | }
237 |
238 | /**
239 | * Splits string into an array of its words.
240 | *
241 | * @usage __::words('fred, barney, & pebbles');
242 | * >> ['fred', 'barney', 'pebbles']
243 | *
244 | * __::words('fred, barney, & pebbles', '/[^, ]+/');
245 | * >> ['fred', 'barney', '&', 'pebbles']
246 | *
247 | * @param string|null $input
248 | * @param string $pattern : The pattern to match words.
249 | *
250 | * @return array
251 | */
252 | public static function words(?string $input, $pattern = null)
253 | {
254 | /** Used to compose unicode character classes. */
255 | $rsAstralRange = '\x{e800}-\x{efff}';
256 | $rsComboMarksRange = '\x{0300}-\x{036f}';
257 | $reComboHalfMarksRange = '\x{fe20}-\x{fe2f}';
258 | $rsComboSymbolsRange = '\x{20d0}-\x{20ff}';
259 | $rsComboRange = $rsComboMarksRange . $reComboHalfMarksRange . $rsComboSymbolsRange;
260 | $rsDingbatRange = '\x{2700}-\x{27bf}';
261 | $rsLowerRange = 'a-z\\xdf-\\xf6\\xf8-\\xff';
262 | $rsMathOpRange = '\\xac\\xb1\\xd7\\xf7';
263 | $rsNonCharRange = '\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf';
264 | $rsPunctuationRange = '\x{2000}-\x{206f}';
265 | $rsSpaceRange = ' \\t\\x0b\\f\\xa0\x{feff}\\n\\r\x{2028}\x{2029}\x{1680}\x{180e}\x{2000}\x{2001}\x{2002}\x{2003}\x{2004}\x{2005}\x{2006}\x{2007}\x{2008}\x{2009}\x{200a}\x{202f}\x{205f}\x{3000}';
266 | $rsUpperRange = 'A-Z\\xc0-\\xd6\\xd8-\\xde';
267 | $rsVarRange = '\x{fe0e}\x{fe0f}';
268 | $rsBreakRange = $rsMathOpRange . $rsNonCharRange . $rsPunctuationRange . $rsSpaceRange;
269 | /** Used to compose unicode capture groups. */
270 | $rsApos = "['\x{2019}]";
271 | $rsBreak = '[' . $rsBreakRange . ']';
272 | $rsCombo = '[' . $rsComboRange . ']';
273 | $rsDigits = '\\d+';
274 | $rsDingbat = '[' . $rsDingbatRange . ']';
275 | $rsLower = '[' . $rsLowerRange . ']';
276 | $rsMisc = '[^' . $rsAstralRange . $rsBreakRange . $rsDigits . $rsDingbatRange . $rsLowerRange . $rsUpperRange . ']';
277 | $rsFitz = '\\x{e83c}[\x{effb}-\x{efff}]';
278 | $rsModifier = '(?:' . $rsCombo . '|' . $rsFitz . ')';
279 | $rsNonAstral = '[^' . $rsAstralRange . ']';
280 | $rsRegional = '(?:\x{e83c}[\x{ede6}-\x{edff}]){2}';
281 | $rsSurrPair = '[\x{e800}-\x{ebff}][\x{ec00}-\x{efff}]';
282 | $rsUpper = '[' . $rsUpperRange . ']';
283 | $rsZWJ = '\x{200d}';
284 | /** Used to compose unicode regexes. */
285 | $rsMiscLower = '(?:' . $rsLower . '|' . $rsMisc . ')';
286 | $rsMiscUpper = '(?:' . $rsUpper . '|' . $rsMisc . ')';
287 | $rsOptContrLower = '(?:' . $rsApos . '(?:d|ll|m|re|s|t|ve))?';
288 | $rsOptContrUpper = '(?:' . $rsApos . '(?:D|LL|M|RE|S|T|VE))?';
289 | $reOptMod = $rsModifier . '?';
290 | $rsOptVar = '[' . $rsVarRange . ']?';
291 | $rsOrdLower = '\\d*(?:(?:1st|2nd|3rd|(?![123])\\dth)\\b)';
292 | $rsOrdUpper = '\\d*(?:(?:1ST|2ND|3RD|(?![123])\\dTH)\\b)';
293 | $asciiWords = '/[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/';
294 | $hasUnicodeWordRegex = '/[a-z][A-Z]|[A-Z]{2,}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/';
295 | $rsOptJoin = '(?:' . $rsZWJ . '(?:' . join(
296 | '|',
297 | [$rsNonAstral, $rsRegional, $rsSurrPair]
298 | ) . ')' . $rsOptVar . $reOptMod . ')*';
299 | $rsSeq = $rsOptVar . $reOptMod . $rsOptJoin;
300 | $rsEmoji = '(?:' . join('|', [$rsDingbat, $rsRegional, $rsSurrPair]) . ')' . $rsSeq;
301 |
302 | /** @var string $unicodeWords unicode words patterns to be used in preg_match */
303 | $unicodeWords = '/' . join('|', [
304 | $rsUpper . '?' . $rsLower . '+' . $rsOptContrLower . '(?=' . join(
305 | '|',
306 | [$rsBreak, $rsUpper, '$']
307 | ) . ')',
308 | $rsMiscUpper . '+' . $rsOptContrUpper . '(?=' . join(
309 | '|',
310 | [$rsBreak, $rsUpper . $rsMiscLower, '$']
311 | ) . ')',
312 | $rsUpper . '?' . $rsMiscLower . '+' . $rsOptContrLower,
313 | $rsUpper . '+' . $rsOptContrUpper,
314 | $rsOrdUpper,
315 | $rsOrdLower,
316 | $rsDigits,
317 | $rsEmoji,
318 | ]) . '/u';
319 | if ($pattern === null) {
320 | $hasUnicodeWord = preg_match($hasUnicodeWordRegex, $input);
321 | $pattern = $hasUnicodeWord ? $unicodeWords : $asciiWords;
322 | }
323 | $r = preg_match_all($pattern, $input, $matches, PREG_PATTERN_ORDER);
324 | if ($r === false) {
325 | throw new \RuntimeException('Regex exception');
326 | }
327 |
328 | return count($matches[0]) > 0 ? $matches[0] : [];
329 | }
330 |
331 | /**
332 | * Converts string, as space separated words, to lower case.
333 | *
334 | * @usage __::lowerCase('--Foo-Bar--');
335 | * >> 'foo bar'
336 | *
337 | * @param string $input
338 | *
339 | * @return string
340 | */
341 | public static function lowerCase(string $input): string
342 | {
343 | $words = __::words(preg_replace("/['\x{2019}]/u", '', $input));
344 |
345 | return array_reduce(
346 | $words,
347 | function ($result, $word) use ($words) {
348 | $isFirst = __::first($words) === $word;
349 |
350 | return $result . (!$isFirst ? ' ' : '') . __::toLower($word);
351 | },
352 | ''
353 | );
354 | }
355 | }
356 |
--------------------------------------------------------------------------------
/src/Traits/Utilities.php:
--------------------------------------------------------------------------------
1 | > true
12 | *
13 | * @param string $value
14 | *
15 | * @return bool
16 | */
17 | public static function isEmail(string $value = null): bool
18 | {
19 | return filter_var($value, FILTER_VALIDATE_EMAIL) != false;
20 | }
21 |
22 | /**
23 | * Alis to original time() function which return current time.
24 | *
25 | * @usage __::now();
26 | * >> 1417546029
27 | *
28 | * @return mixed
29 | */
30 | public static function now()
31 | {
32 | $now = time();
33 |
34 | return $now;
35 | }
36 |
37 | /**
38 | * Readable wrapper for strpos()
39 | *
40 | * @usage __::stringContains('waffle', 'wafflecone');
41 | * >> true
42 | *
43 | * @param string $needle Substring to search for
44 | * @param string $haystack String to search within
45 | * @param int $offset Index of the $haystack we wish to start at
46 | *
47 | * @return bool
48 | */
49 | public static function stringContains(string $needle, string $haystack, int $offset = 0): bool
50 | {
51 | return strpos($haystack, $needle, $offset) !== false ? true : false;
52 | }
53 |
54 | /**
55 | * Returns the first argument it receives
56 | *
57 | * @usage __::identity('arg1', 'arg2');
58 | * >> 'arg1'
59 | *
60 | * @return mixed
61 | */
62 | public static function identity()
63 | {
64 | $args = func_get_args();
65 |
66 | return isset($args[0]) ? $args[0] : null;
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/src/__.php:
--------------------------------------------------------------------------------
1 |