├── .gitignore
├── .travis.yml
├── README.md
├── bin
├── setup-wp-redis.sh
└── test-wp-redis.sh
├── class-wp-predis-decorator.php
├── composer.json
├── composer.lock
├── functions.php
├── object-cache.php
├── phpcs.ruleset.xml
├── phpunit.xml
└── tests
├── bootstrap-wp-predis.php
├── bootstrap.php
├── fixtures
├── phpredis-info.php
└── predis-info.php
├── test-functions.php
└── test-wp-predis-decorator.php
/.gitignore:
--------------------------------------------------------------------------------
1 | vendor
2 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | sudo: false
2 | dist: trusty
3 |
4 | language: php
5 |
6 | notifications:
7 | email:
8 | on_success: never
9 | on_failure: change
10 |
11 | branches:
12 | only:
13 | - master
14 |
15 | cache:
16 | - composer
17 | - $HOME/.composer/cache
18 |
19 | matrix:
20 | fast_finish: true
21 | include:
22 | - php: nightly
23 | - php: 7.4
24 | - php: 7.3
25 | - php: 7.2
26 | - php: 7.1
27 | allow_failures:
28 | - php: nightly
29 |
30 | services:
31 | - redis-server
32 | addons:
33 | apt:
34 | packages:
35 | - realpath
36 |
37 | install:
38 | - composer config platform.php $(phpenv version-name)
39 | - composer install
40 |
41 | before_script:
42 | - export PATH="./vendor/bin:$PATH"
43 | - echo 'extension = "redis.so"' >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini
44 | - |
45 | if [[ "$WP_TRAVISCI" == "phpcs" ]] ; then
46 | export PATH="$HOME/.composer/vendor/bin:$PATH"
47 | composer global require wp-coding-standards/wpcs
48 | phpcs --config-set installed_paths $HOME/.composer/vendor/wp-coding-standards/wpcs
49 | fi
50 | - bin/setup-wp-redis.sh
51 |
52 | script:
53 | - phpunit
54 | - |
55 | if [[ "$WP_TRAVISCI" == "phpcs" ]] ; then
56 | phpcs --standard=phpcs.ruleset.xml $(find . -name '*.php')
57 | fi
58 | - bin/test-wp-redis.sh
59 | - vendor/bin/phpunit --coverage-clover=coverage.xml
60 |
61 | after_success:
62 | - bash <(curl -s https://codecov.io/bash)
63 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | WP Redis - Predis Client
5 | An alternative Redis client for use with WP Redis. Enables TLS connections.
6 | |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 | |
15 |
16 |
17 |
18 | A Human Made project. Maintained by @nathanielks.
19 | |
20 |
21 |
22 | |
23 |
24 |
25 |
26 | # WP Redis - Predis Client
27 |
28 | This is a package that enables the use of [Predis](https://github.com/nrk/predis/) as a Redis Client as opposed to PHPRedis for [WP Redis](https://github.com/pantheon-systems/wp-redis/). Predis has the distinct advantage of connecting to Redis via TLS, encrypting traffic in-transit. Requires WP Redis >= 0.7.0.
29 |
30 | ## Getting Started
31 |
32 | ### Requiring Files
33 | #### Composer
34 |
35 | When using Composer, `functions.php` file will automatically be loaded whenever you include Composer's autoloader in your project.
36 |
37 | #### Manually Requiring
38 |
39 | The only file needing `require_once`ing for WP Predis to work correctly is `functions.php` (which is automatically included via `vendor/autoload.php`, which is generated by Composer). Download this repo somewhere in your project, run `composer install`, and include `vendor/autoload.php` somewhere early (such as `wp-config.php`):
40 |
41 | ```
42 | require_once '/path/to/wp-redis-predis-client/vendor/autoload.php';
43 | ```
44 |
45 | ### Object Cache stub
46 |
47 |
48 | Now that files have been included, it's recommended you use the included [`object-cache.php`](object-cache.php) file instead of the one included with WP Redis. It will add the required filters for WP Predis to work and then include WP Redis' `object-cache.php` file. Once `object-cache.php` is in `wp-content` (or whatever content directory you are using), you're good to go!
49 |
50 | ### Configuring Predis
51 |
52 | WP Redis - Predis Client adheres to WP Redis' [configuration details](https://github.com/pantheon-systems/wp-redis#installation). Predis also takes an additional argument, `ssl`, for configuring TLS connections. See PHP's [SSL Context options](http://php.net/manual/en/context.ssl.php) for more details.
53 |
54 |
55 | ```php
56 | global $redis_server;
57 | $redis_server = array(
58 | 'host' => '127.0.0.1',
59 | 'port' => 6379,
60 | 'ssl' => array(
61 | 'local_cert' => '/path/to/certificate_and_key.pem',
62 | 'verify_peer' => true,
63 | ),
64 | );
65 | ```
66 |
67 |
68 |
--------------------------------------------------------------------------------
/bin/setup-wp-redis.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | WP_REDIS=/tmp/wp-redis
4 | MYSQL_DB="${MYSQL_DB:-wordpress_test}"
5 | MYSQL_USER="${MYSQL_USER:-root}"
6 | MYSQL_PASS="${MYSQL_PASS:-}"
7 | MYSQL_HOST="${MYSQL_HOST:-localhost}"
8 |
9 | git clone --single-branch --depth 1 https://github.com/pantheon-systems/wp-redis.git ${WP_REDIS}
10 |
11 | cd "${WP_REDIS}" || exit
12 | composer install
13 | bash bin/install-wp-tests.sh "${MYSQL_DB}" "${MYSQL_USER}" "${MYSQL_PASS}" "${MYSQL_HOST}" latest
14 |
--------------------------------------------------------------------------------
/bin/test-wp-redis.sh:
--------------------------------------------------------------------------------
1 | #! /usr/bin/env bash
2 | SCRIPT="$(realpath "$0")"
3 | SCRIPTPATH="$(dirname "$SCRIPT")"
4 | WP_PREDIS="${SCRIPTPATH}/.."
5 | WP_REDIS=/tmp/wp-redis
6 | WP_TESTS=/tmp/wordpress-tests-lib
7 | PHPUNIT="${WP_PREDIS}/vendor/bin/phpunit"
8 | BOOTSTRAP_FILENAME="bootstrap-wp-predis.php"
9 | BOOTSTRAP_FILE="${WP_PREDIS}/tests/${BOOTSTRAP_FILENAME}"
10 | REQUIRE_STATEMENT="require_once dirname( __FILE__ ) . '/${BOOTSTRAP_FILENAME}';"
11 | TESTS_BOOTSTRAP="${WP_TESTS}/${BOOTSTRAP_FILENAME}"
12 | TESTS_CONFIG="${WP_TESTS}/wp-tests-config.php"
13 |
14 | # If wp-predis-bootstrap.php doesn't exist in the tests lib folder, copy it
15 | # there
16 | if [[ ! -f "${TESTS_BOOTSTRAP}" || -n "${FORCE_COPY}" ]]; then
17 | echo "Copying ${BOOTSTRAP_FILE} to ${TESTS_BOOTSTRAP}"
18 | cp "${BOOTSTRAP_FILE}" "${TESTS_BOOTSTRAP}"
19 | else
20 | echo "${TESTS_BOOTSTRAP} exists, not copying in place."
21 | fi
22 |
23 | # if the wp-predis-bootstrap.php isn't required in wp-tests-config.php, append
24 | # it to the file
25 | if ! grep -Fxq "${REQUIRE_STATEMENT}" "${TESTS_CONFIG}"; then
26 | echo "Appending REQUIRE_STATEMENT to ${TESTS_CONFIG}"
27 | echo "${REQUIRE_STATEMENT}" | tee --append "${TESTS_CONFIG}"
28 | else
29 | echo "REQUIRE_STATEMENT exists in ${TESTS_CONFIG}"
30 | fi
31 |
32 | # Let's test WP Redis with Predis as the adapter!
33 | export WP_PREDIS_DIR="${WP_PREDIS}"
34 | (cd "${WP_REDIS}" && eval "$PHPUNIT")
35 |
--------------------------------------------------------------------------------
/class-wp-predis-decorator.php:
--------------------------------------------------------------------------------
1 | client = $client;
30 | }
31 |
32 | public function info( $section = null ) {
33 | $info = $this->client->info();
34 | return $this->transform_info( $info );
35 | }
36 |
37 | public function close() {
38 | return $this->client->disconnect();
39 | }
40 |
41 | public function transform_info( $info ) {
42 | // let's pop this off because special formatting is required`
43 | $keyspace = $info['Keyspace'];
44 | unset( $info['Keyspace'] );
45 |
46 | $newInfo = array_reduce( $info, function( $carry, $item ) {
47 | return array_merge( $carry, $item );
48 | }, array());
49 |
50 | foreach ( $keyspace as $db => $values ) {
51 | $newInfo[ $db ] = str_replace( '&', ',', http_build_query( $values ) );
52 | }
53 |
54 | return $newInfo;
55 | }
56 |
57 | public function __call( $method_name, $args ) {
58 | // Optionally prevent flushing on non-cli.
59 | if ( in_array( strtolower( $method_name ), [ 'flushdb', 'flushall' ], true ) ) {
60 | $trace = wp_debug_backtrace_summary();
61 | error_log( sprintf( 'wp_cache_flush() requested from ' . $trace ) );
62 |
63 | /**
64 | * Filter whether to allow flushing. By default, only allowed on the CLI.
65 | *
66 | * @param bool True to permit flushing, false to disallow it and return immediately.
67 | */
68 | $allowed = apply_filters( 'wp_cache_flush_allowed', 'cli' === php_sapi_name() );
69 | if ( ! $allowed ) {
70 | trigger_error( sprintf( 'wp_cache_flush() is only allowed via WP CLI. Called from %s', $trace ), E_USER_WARNING );
71 | return false;
72 | }
73 | }
74 |
75 | // TODO perhaps we wrap this in a try/catch and return false when
76 | // there's an exception?
77 | $start = microtime( true );
78 | $value = call_user_func_array( array( $this->client, $method_name ), $args );
79 | $this->time_spent += microtime( true ) - $start;
80 | $returns = $value;
81 |
82 | $lowered = strtolower( $method_name );
83 | if ( in_array( $lowered, $this->toBool, true ) ) {
84 | $returns = (bool) $value;
85 | }
86 |
87 | if ( in_array( $lowered, $this->nullToBool, true ) ) {
88 | $returns = null === $value ? false : $value;
89 | }
90 |
91 | return $returns;
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "humanmade/wp-redis-predis-client",
3 | "autoload": {
4 | "files": ["functions.php"]
5 | },
6 | "require": {
7 | "predis/predis": "~1.1"
8 | },
9 | "require-dev": {
10 | "phpunit/phpunit": "^7.1.4"
11 | },
12 | "config": {
13 | "platform": {
14 | "php": "7.1.0"
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/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": "96013fe675bb12d230f726457f79d82e",
8 | "packages": [
9 | {
10 | "name": "predis/predis",
11 | "version": "v1.1.7",
12 | "source": {
13 | "type": "git",
14 | "url": "https://github.com/predis/predis.git",
15 | "reference": "b240daa106d4e02f0c5b7079b41e31ddf66fddf8"
16 | },
17 | "dist": {
18 | "type": "zip",
19 | "url": "https://api.github.com/repos/predis/predis/zipball/b240daa106d4e02f0c5b7079b41e31ddf66fddf8",
20 | "reference": "b240daa106d4e02f0c5b7079b41e31ddf66fddf8",
21 | "shasum": ""
22 | },
23 | "require": {
24 | "php": ">=5.3.9"
25 | },
26 | "require-dev": {
27 | "phpunit/phpunit": "~4.8"
28 | },
29 | "suggest": {
30 | "ext-curl": "Allows access to Webdis when paired with phpiredis",
31 | "ext-phpiredis": "Allows faster serialization and deserialization of the Redis protocol"
32 | },
33 | "type": "library",
34 | "autoload": {
35 | "psr-4": {
36 | "Predis\\": "src/"
37 | }
38 | },
39 | "notification-url": "https://packagist.org/downloads/",
40 | "license": [
41 | "MIT"
42 | ],
43 | "authors": [
44 | {
45 | "name": "Daniele Alessandri",
46 | "email": "suppakilla@gmail.com",
47 | "homepage": "http://clorophilla.net",
48 | "role": "Creator & Maintainer"
49 | },
50 | {
51 | "name": "Till Krüss",
52 | "homepage": "https://till.im",
53 | "role": "Maintainer"
54 | }
55 | ],
56 | "description": "Flexible and feature-complete Redis client for PHP and HHVM",
57 | "homepage": "http://github.com/predis/predis",
58 | "keywords": [
59 | "nosql",
60 | "predis",
61 | "redis"
62 | ],
63 | "support": {
64 | "issues": "https://github.com/predis/predis/issues",
65 | "source": "https://github.com/predis/predis/tree/v1.1.7"
66 | },
67 | "funding": [
68 | {
69 | "url": "https://github.com/sponsors/tillkruss",
70 | "type": "github"
71 | }
72 | ],
73 | "time": "2021-04-04T19:34:46+00:00"
74 | }
75 | ],
76 | "packages-dev": [
77 | {
78 | "name": "doctrine/instantiator",
79 | "version": "1.4.0",
80 | "source": {
81 | "type": "git",
82 | "url": "https://github.com/doctrine/instantiator.git",
83 | "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b"
84 | },
85 | "dist": {
86 | "type": "zip",
87 | "url": "https://api.github.com/repos/doctrine/instantiator/zipball/d56bf6102915de5702778fe20f2de3b2fe570b5b",
88 | "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b",
89 | "shasum": ""
90 | },
91 | "require": {
92 | "php": "^7.1 || ^8.0"
93 | },
94 | "require-dev": {
95 | "doctrine/coding-standard": "^8.0",
96 | "ext-pdo": "*",
97 | "ext-phar": "*",
98 | "phpbench/phpbench": "^0.13 || 1.0.0-alpha2",
99 | "phpstan/phpstan": "^0.12",
100 | "phpstan/phpstan-phpunit": "^0.12",
101 | "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0"
102 | },
103 | "type": "library",
104 | "autoload": {
105 | "psr-4": {
106 | "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/"
107 | }
108 | },
109 | "notification-url": "https://packagist.org/downloads/",
110 | "license": [
111 | "MIT"
112 | ],
113 | "authors": [
114 | {
115 | "name": "Marco Pivetta",
116 | "email": "ocramius@gmail.com",
117 | "homepage": "https://ocramius.github.io/"
118 | }
119 | ],
120 | "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors",
121 | "homepage": "https://www.doctrine-project.org/projects/instantiator.html",
122 | "keywords": [
123 | "constructor",
124 | "instantiate"
125 | ],
126 | "support": {
127 | "issues": "https://github.com/doctrine/instantiator/issues",
128 | "source": "https://github.com/doctrine/instantiator/tree/1.4.0"
129 | },
130 | "funding": [
131 | {
132 | "url": "https://www.doctrine-project.org/sponsorship.html",
133 | "type": "custom"
134 | },
135 | {
136 | "url": "https://www.patreon.com/phpdoctrine",
137 | "type": "patreon"
138 | },
139 | {
140 | "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator",
141 | "type": "tidelift"
142 | }
143 | ],
144 | "time": "2020-11-10T18:47:58+00:00"
145 | },
146 | {
147 | "name": "myclabs/deep-copy",
148 | "version": "1.10.2",
149 | "source": {
150 | "type": "git",
151 | "url": "https://github.com/myclabs/DeepCopy.git",
152 | "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220"
153 | },
154 | "dist": {
155 | "type": "zip",
156 | "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/776f831124e9c62e1a2c601ecc52e776d8bb7220",
157 | "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220",
158 | "shasum": ""
159 | },
160 | "require": {
161 | "php": "^7.1 || ^8.0"
162 | },
163 | "replace": {
164 | "myclabs/deep-copy": "self.version"
165 | },
166 | "require-dev": {
167 | "doctrine/collections": "^1.0",
168 | "doctrine/common": "^2.6",
169 | "phpunit/phpunit": "^7.1"
170 | },
171 | "type": "library",
172 | "autoload": {
173 | "psr-4": {
174 | "DeepCopy\\": "src/DeepCopy/"
175 | },
176 | "files": [
177 | "src/DeepCopy/deep_copy.php"
178 | ]
179 | },
180 | "notification-url": "https://packagist.org/downloads/",
181 | "license": [
182 | "MIT"
183 | ],
184 | "description": "Create deep copies (clones) of your objects",
185 | "keywords": [
186 | "clone",
187 | "copy",
188 | "duplicate",
189 | "object",
190 | "object graph"
191 | ],
192 | "support": {
193 | "issues": "https://github.com/myclabs/DeepCopy/issues",
194 | "source": "https://github.com/myclabs/DeepCopy/tree/1.10.2"
195 | },
196 | "funding": [
197 | {
198 | "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy",
199 | "type": "tidelift"
200 | }
201 | ],
202 | "time": "2020-11-13T09:40:50+00:00"
203 | },
204 | {
205 | "name": "phar-io/manifest",
206 | "version": "1.0.3",
207 | "source": {
208 | "type": "git",
209 | "url": "https://github.com/phar-io/manifest.git",
210 | "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4"
211 | },
212 | "dist": {
213 | "type": "zip",
214 | "url": "https://api.github.com/repos/phar-io/manifest/zipball/7761fcacf03b4d4f16e7ccb606d4879ca431fcf4",
215 | "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4",
216 | "shasum": ""
217 | },
218 | "require": {
219 | "ext-dom": "*",
220 | "ext-phar": "*",
221 | "phar-io/version": "^2.0",
222 | "php": "^5.6 || ^7.0"
223 | },
224 | "type": "library",
225 | "extra": {
226 | "branch-alias": {
227 | "dev-master": "1.0.x-dev"
228 | }
229 | },
230 | "autoload": {
231 | "classmap": [
232 | "src/"
233 | ]
234 | },
235 | "notification-url": "https://packagist.org/downloads/",
236 | "license": [
237 | "BSD-3-Clause"
238 | ],
239 | "authors": [
240 | {
241 | "name": "Arne Blankerts",
242 | "email": "arne@blankerts.de",
243 | "role": "Developer"
244 | },
245 | {
246 | "name": "Sebastian Heuer",
247 | "email": "sebastian@phpeople.de",
248 | "role": "Developer"
249 | },
250 | {
251 | "name": "Sebastian Bergmann",
252 | "email": "sebastian@phpunit.de",
253 | "role": "Developer"
254 | }
255 | ],
256 | "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)",
257 | "support": {
258 | "issues": "https://github.com/phar-io/manifest/issues",
259 | "source": "https://github.com/phar-io/manifest/tree/master"
260 | },
261 | "time": "2018-07-08T19:23:20+00:00"
262 | },
263 | {
264 | "name": "phar-io/version",
265 | "version": "2.0.1",
266 | "source": {
267 | "type": "git",
268 | "url": "https://github.com/phar-io/version.git",
269 | "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6"
270 | },
271 | "dist": {
272 | "type": "zip",
273 | "url": "https://api.github.com/repos/phar-io/version/zipball/45a2ec53a73c70ce41d55cedef9063630abaf1b6",
274 | "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6",
275 | "shasum": ""
276 | },
277 | "require": {
278 | "php": "^5.6 || ^7.0"
279 | },
280 | "type": "library",
281 | "autoload": {
282 | "classmap": [
283 | "src/"
284 | ]
285 | },
286 | "notification-url": "https://packagist.org/downloads/",
287 | "license": [
288 | "BSD-3-Clause"
289 | ],
290 | "authors": [
291 | {
292 | "name": "Arne Blankerts",
293 | "email": "arne@blankerts.de",
294 | "role": "Developer"
295 | },
296 | {
297 | "name": "Sebastian Heuer",
298 | "email": "sebastian@phpeople.de",
299 | "role": "Developer"
300 | },
301 | {
302 | "name": "Sebastian Bergmann",
303 | "email": "sebastian@phpunit.de",
304 | "role": "Developer"
305 | }
306 | ],
307 | "description": "Library for handling version information and constraints",
308 | "support": {
309 | "issues": "https://github.com/phar-io/version/issues",
310 | "source": "https://github.com/phar-io/version/tree/master"
311 | },
312 | "time": "2018-07-08T19:19:57+00:00"
313 | },
314 | {
315 | "name": "phpdocumentor/reflection-common",
316 | "version": "2.1.0",
317 | "source": {
318 | "type": "git",
319 | "url": "https://github.com/phpDocumentor/ReflectionCommon.git",
320 | "reference": "6568f4687e5b41b054365f9ae03fcb1ed5f2069b"
321 | },
322 | "dist": {
323 | "type": "zip",
324 | "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/6568f4687e5b41b054365f9ae03fcb1ed5f2069b",
325 | "reference": "6568f4687e5b41b054365f9ae03fcb1ed5f2069b",
326 | "shasum": ""
327 | },
328 | "require": {
329 | "php": ">=7.1"
330 | },
331 | "type": "library",
332 | "extra": {
333 | "branch-alias": {
334 | "dev-master": "2.x-dev"
335 | }
336 | },
337 | "autoload": {
338 | "psr-4": {
339 | "phpDocumentor\\Reflection\\": "src/"
340 | }
341 | },
342 | "notification-url": "https://packagist.org/downloads/",
343 | "license": [
344 | "MIT"
345 | ],
346 | "authors": [
347 | {
348 | "name": "Jaap van Otterdijk",
349 | "email": "opensource@ijaap.nl"
350 | }
351 | ],
352 | "description": "Common reflection classes used by phpdocumentor to reflect the code structure",
353 | "homepage": "http://www.phpdoc.org",
354 | "keywords": [
355 | "FQSEN",
356 | "phpDocumentor",
357 | "phpdoc",
358 | "reflection",
359 | "static analysis"
360 | ],
361 | "support": {
362 | "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues",
363 | "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/master"
364 | },
365 | "time": "2020-04-27T09:25:28+00:00"
366 | },
367 | {
368 | "name": "phpdocumentor/reflection-docblock",
369 | "version": "4.3.4",
370 | "source": {
371 | "type": "git",
372 | "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
373 | "reference": "da3fd972d6bafd628114f7e7e036f45944b62e9c"
374 | },
375 | "dist": {
376 | "type": "zip",
377 | "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/da3fd972d6bafd628114f7e7e036f45944b62e9c",
378 | "reference": "da3fd972d6bafd628114f7e7e036f45944b62e9c",
379 | "shasum": ""
380 | },
381 | "require": {
382 | "php": "^7.0",
383 | "phpdocumentor/reflection-common": "^1.0.0 || ^2.0.0",
384 | "phpdocumentor/type-resolver": "~0.4 || ^1.0.0",
385 | "webmozart/assert": "^1.0"
386 | },
387 | "require-dev": {
388 | "doctrine/instantiator": "^1.0.5",
389 | "mockery/mockery": "^1.0",
390 | "phpdocumentor/type-resolver": "0.4.*",
391 | "phpunit/phpunit": "^6.4"
392 | },
393 | "type": "library",
394 | "extra": {
395 | "branch-alias": {
396 | "dev-master": "4.x-dev"
397 | }
398 | },
399 | "autoload": {
400 | "psr-4": {
401 | "phpDocumentor\\Reflection\\": [
402 | "src/"
403 | ]
404 | }
405 | },
406 | "notification-url": "https://packagist.org/downloads/",
407 | "license": [
408 | "MIT"
409 | ],
410 | "authors": [
411 | {
412 | "name": "Mike van Riel",
413 | "email": "me@mikevanriel.com"
414 | }
415 | ],
416 | "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.",
417 | "support": {
418 | "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues",
419 | "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/release/4.x"
420 | },
421 | "time": "2019-12-28T18:55:12+00:00"
422 | },
423 | {
424 | "name": "phpdocumentor/type-resolver",
425 | "version": "1.0.1",
426 | "source": {
427 | "type": "git",
428 | "url": "https://github.com/phpDocumentor/TypeResolver.git",
429 | "reference": "2e32a6d48972b2c1976ed5d8967145b6cec4a4a9"
430 | },
431 | "dist": {
432 | "type": "zip",
433 | "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/2e32a6d48972b2c1976ed5d8967145b6cec4a4a9",
434 | "reference": "2e32a6d48972b2c1976ed5d8967145b6cec4a4a9",
435 | "shasum": ""
436 | },
437 | "require": {
438 | "php": "^7.1",
439 | "phpdocumentor/reflection-common": "^2.0"
440 | },
441 | "require-dev": {
442 | "ext-tokenizer": "^7.1",
443 | "mockery/mockery": "~1",
444 | "phpunit/phpunit": "^7.0"
445 | },
446 | "type": "library",
447 | "extra": {
448 | "branch-alias": {
449 | "dev-master": "1.x-dev"
450 | }
451 | },
452 | "autoload": {
453 | "psr-4": {
454 | "phpDocumentor\\Reflection\\": "src"
455 | }
456 | },
457 | "notification-url": "https://packagist.org/downloads/",
458 | "license": [
459 | "MIT"
460 | ],
461 | "authors": [
462 | {
463 | "name": "Mike van Riel",
464 | "email": "me@mikevanriel.com"
465 | }
466 | ],
467 | "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names",
468 | "support": {
469 | "issues": "https://github.com/phpDocumentor/TypeResolver/issues",
470 | "source": "https://github.com/phpDocumentor/TypeResolver/tree/0.7.2"
471 | },
472 | "time": "2019-08-22T18:11:29+00:00"
473 | },
474 | {
475 | "name": "phpspec/prophecy",
476 | "version": "v1.10.3",
477 | "source": {
478 | "type": "git",
479 | "url": "https://github.com/phpspec/prophecy.git",
480 | "reference": "451c3cd1418cf640de218914901e51b064abb093"
481 | },
482 | "dist": {
483 | "type": "zip",
484 | "url": "https://api.github.com/repos/phpspec/prophecy/zipball/451c3cd1418cf640de218914901e51b064abb093",
485 | "reference": "451c3cd1418cf640de218914901e51b064abb093",
486 | "shasum": ""
487 | },
488 | "require": {
489 | "doctrine/instantiator": "^1.0.2",
490 | "php": "^5.3|^7.0",
491 | "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0|^5.0",
492 | "sebastian/comparator": "^1.2.3|^2.0|^3.0|^4.0",
493 | "sebastian/recursion-context": "^1.0|^2.0|^3.0|^4.0"
494 | },
495 | "require-dev": {
496 | "phpspec/phpspec": "^2.5 || ^3.2",
497 | "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5 || ^7.1"
498 | },
499 | "type": "library",
500 | "extra": {
501 | "branch-alias": {
502 | "dev-master": "1.10.x-dev"
503 | }
504 | },
505 | "autoload": {
506 | "psr-4": {
507 | "Prophecy\\": "src/Prophecy"
508 | }
509 | },
510 | "notification-url": "https://packagist.org/downloads/",
511 | "license": [
512 | "MIT"
513 | ],
514 | "authors": [
515 | {
516 | "name": "Konstantin Kudryashov",
517 | "email": "ever.zet@gmail.com",
518 | "homepage": "http://everzet.com"
519 | },
520 | {
521 | "name": "Marcello Duarte",
522 | "email": "marcello.duarte@gmail.com"
523 | }
524 | ],
525 | "description": "Highly opinionated mocking framework for PHP 5.3+",
526 | "homepage": "https://github.com/phpspec/prophecy",
527 | "keywords": [
528 | "Double",
529 | "Dummy",
530 | "fake",
531 | "mock",
532 | "spy",
533 | "stub"
534 | ],
535 | "support": {
536 | "issues": "https://github.com/phpspec/prophecy/issues",
537 | "source": "https://github.com/phpspec/prophecy/tree/v1.10.3"
538 | },
539 | "time": "2020-03-05T15:02:03+00:00"
540 | },
541 | {
542 | "name": "phpunit/php-code-coverage",
543 | "version": "6.1.4",
544 | "source": {
545 | "type": "git",
546 | "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
547 | "reference": "807e6013b00af69b6c5d9ceb4282d0393dbb9d8d"
548 | },
549 | "dist": {
550 | "type": "zip",
551 | "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/807e6013b00af69b6c5d9ceb4282d0393dbb9d8d",
552 | "reference": "807e6013b00af69b6c5d9ceb4282d0393dbb9d8d",
553 | "shasum": ""
554 | },
555 | "require": {
556 | "ext-dom": "*",
557 | "ext-xmlwriter": "*",
558 | "php": "^7.1",
559 | "phpunit/php-file-iterator": "^2.0",
560 | "phpunit/php-text-template": "^1.2.1",
561 | "phpunit/php-token-stream": "^3.0",
562 | "sebastian/code-unit-reverse-lookup": "^1.0.1",
563 | "sebastian/environment": "^3.1 || ^4.0",
564 | "sebastian/version": "^2.0.1",
565 | "theseer/tokenizer": "^1.1"
566 | },
567 | "require-dev": {
568 | "phpunit/phpunit": "^7.0"
569 | },
570 | "suggest": {
571 | "ext-xdebug": "^2.6.0"
572 | },
573 | "type": "library",
574 | "extra": {
575 | "branch-alias": {
576 | "dev-master": "6.1-dev"
577 | }
578 | },
579 | "autoload": {
580 | "classmap": [
581 | "src/"
582 | ]
583 | },
584 | "notification-url": "https://packagist.org/downloads/",
585 | "license": [
586 | "BSD-3-Clause"
587 | ],
588 | "authors": [
589 | {
590 | "name": "Sebastian Bergmann",
591 | "email": "sebastian@phpunit.de",
592 | "role": "lead"
593 | }
594 | ],
595 | "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.",
596 | "homepage": "https://github.com/sebastianbergmann/php-code-coverage",
597 | "keywords": [
598 | "coverage",
599 | "testing",
600 | "xunit"
601 | ],
602 | "support": {
603 | "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues",
604 | "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/master"
605 | },
606 | "time": "2018-10-31T16:06:48+00:00"
607 | },
608 | {
609 | "name": "phpunit/php-file-iterator",
610 | "version": "2.0.3",
611 | "source": {
612 | "type": "git",
613 | "url": "https://github.com/sebastianbergmann/php-file-iterator.git",
614 | "reference": "4b49fb70f067272b659ef0174ff9ca40fdaa6357"
615 | },
616 | "dist": {
617 | "type": "zip",
618 | "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/4b49fb70f067272b659ef0174ff9ca40fdaa6357",
619 | "reference": "4b49fb70f067272b659ef0174ff9ca40fdaa6357",
620 | "shasum": ""
621 | },
622 | "require": {
623 | "php": ">=7.1"
624 | },
625 | "require-dev": {
626 | "phpunit/phpunit": "^8.5"
627 | },
628 | "type": "library",
629 | "extra": {
630 | "branch-alias": {
631 | "dev-master": "2.0.x-dev"
632 | }
633 | },
634 | "autoload": {
635 | "classmap": [
636 | "src/"
637 | ]
638 | },
639 | "notification-url": "https://packagist.org/downloads/",
640 | "license": [
641 | "BSD-3-Clause"
642 | ],
643 | "authors": [
644 | {
645 | "name": "Sebastian Bergmann",
646 | "email": "sebastian@phpunit.de",
647 | "role": "lead"
648 | }
649 | ],
650 | "description": "FilterIterator implementation that filters files based on a list of suffixes.",
651 | "homepage": "https://github.com/sebastianbergmann/php-file-iterator/",
652 | "keywords": [
653 | "filesystem",
654 | "iterator"
655 | ],
656 | "support": {
657 | "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues",
658 | "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/2.0.3"
659 | },
660 | "funding": [
661 | {
662 | "url": "https://github.com/sebastianbergmann",
663 | "type": "github"
664 | }
665 | ],
666 | "time": "2020-11-30T08:25:21+00:00"
667 | },
668 | {
669 | "name": "phpunit/php-text-template",
670 | "version": "1.2.1",
671 | "source": {
672 | "type": "git",
673 | "url": "https://github.com/sebastianbergmann/php-text-template.git",
674 | "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686"
675 | },
676 | "dist": {
677 | "type": "zip",
678 | "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
679 | "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
680 | "shasum": ""
681 | },
682 | "require": {
683 | "php": ">=5.3.3"
684 | },
685 | "type": "library",
686 | "autoload": {
687 | "classmap": [
688 | "src/"
689 | ]
690 | },
691 | "notification-url": "https://packagist.org/downloads/",
692 | "license": [
693 | "BSD-3-Clause"
694 | ],
695 | "authors": [
696 | {
697 | "name": "Sebastian Bergmann",
698 | "email": "sebastian@phpunit.de",
699 | "role": "lead"
700 | }
701 | ],
702 | "description": "Simple template engine.",
703 | "homepage": "https://github.com/sebastianbergmann/php-text-template/",
704 | "keywords": [
705 | "template"
706 | ],
707 | "support": {
708 | "issues": "https://github.com/sebastianbergmann/php-text-template/issues",
709 | "source": "https://github.com/sebastianbergmann/php-text-template/tree/1.2.1"
710 | },
711 | "time": "2015-06-21T13:50:34+00:00"
712 | },
713 | {
714 | "name": "phpunit/php-timer",
715 | "version": "2.1.3",
716 | "source": {
717 | "type": "git",
718 | "url": "https://github.com/sebastianbergmann/php-timer.git",
719 | "reference": "2454ae1765516d20c4ffe103d85a58a9a3bd5662"
720 | },
721 | "dist": {
722 | "type": "zip",
723 | "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/2454ae1765516d20c4ffe103d85a58a9a3bd5662",
724 | "reference": "2454ae1765516d20c4ffe103d85a58a9a3bd5662",
725 | "shasum": ""
726 | },
727 | "require": {
728 | "php": ">=7.1"
729 | },
730 | "require-dev": {
731 | "phpunit/phpunit": "^8.5"
732 | },
733 | "type": "library",
734 | "extra": {
735 | "branch-alias": {
736 | "dev-master": "2.1-dev"
737 | }
738 | },
739 | "autoload": {
740 | "classmap": [
741 | "src/"
742 | ]
743 | },
744 | "notification-url": "https://packagist.org/downloads/",
745 | "license": [
746 | "BSD-3-Clause"
747 | ],
748 | "authors": [
749 | {
750 | "name": "Sebastian Bergmann",
751 | "email": "sebastian@phpunit.de",
752 | "role": "lead"
753 | }
754 | ],
755 | "description": "Utility class for timing",
756 | "homepage": "https://github.com/sebastianbergmann/php-timer/",
757 | "keywords": [
758 | "timer"
759 | ],
760 | "support": {
761 | "issues": "https://github.com/sebastianbergmann/php-timer/issues",
762 | "source": "https://github.com/sebastianbergmann/php-timer/tree/2.1.3"
763 | },
764 | "funding": [
765 | {
766 | "url": "https://github.com/sebastianbergmann",
767 | "type": "github"
768 | }
769 | ],
770 | "time": "2020-11-30T08:20:02+00:00"
771 | },
772 | {
773 | "name": "phpunit/php-token-stream",
774 | "version": "3.1.2",
775 | "source": {
776 | "type": "git",
777 | "url": "https://github.com/sebastianbergmann/php-token-stream.git",
778 | "reference": "472b687829041c24b25f475e14c2f38a09edf1c2"
779 | },
780 | "dist": {
781 | "type": "zip",
782 | "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/472b687829041c24b25f475e14c2f38a09edf1c2",
783 | "reference": "472b687829041c24b25f475e14c2f38a09edf1c2",
784 | "shasum": ""
785 | },
786 | "require": {
787 | "ext-tokenizer": "*",
788 | "php": ">=7.1"
789 | },
790 | "require-dev": {
791 | "phpunit/phpunit": "^7.0"
792 | },
793 | "type": "library",
794 | "extra": {
795 | "branch-alias": {
796 | "dev-master": "3.1-dev"
797 | }
798 | },
799 | "autoload": {
800 | "classmap": [
801 | "src/"
802 | ]
803 | },
804 | "notification-url": "https://packagist.org/downloads/",
805 | "license": [
806 | "BSD-3-Clause"
807 | ],
808 | "authors": [
809 | {
810 | "name": "Sebastian Bergmann",
811 | "email": "sebastian@phpunit.de"
812 | }
813 | ],
814 | "description": "Wrapper around PHP's tokenizer extension.",
815 | "homepage": "https://github.com/sebastianbergmann/php-token-stream/",
816 | "keywords": [
817 | "tokenizer"
818 | ],
819 | "support": {
820 | "issues": "https://github.com/sebastianbergmann/php-token-stream/issues",
821 | "source": "https://github.com/sebastianbergmann/php-token-stream/tree/3.1.2"
822 | },
823 | "funding": [
824 | {
825 | "url": "https://github.com/sebastianbergmann",
826 | "type": "github"
827 | }
828 | ],
829 | "abandoned": true,
830 | "time": "2020-11-30T08:38:46+00:00"
831 | },
832 | {
833 | "name": "phpunit/phpunit",
834 | "version": "7.5.20",
835 | "source": {
836 | "type": "git",
837 | "url": "https://github.com/sebastianbergmann/phpunit.git",
838 | "reference": "9467db479d1b0487c99733bb1e7944d32deded2c"
839 | },
840 | "dist": {
841 | "type": "zip",
842 | "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/9467db479d1b0487c99733bb1e7944d32deded2c",
843 | "reference": "9467db479d1b0487c99733bb1e7944d32deded2c",
844 | "shasum": ""
845 | },
846 | "require": {
847 | "doctrine/instantiator": "^1.1",
848 | "ext-dom": "*",
849 | "ext-json": "*",
850 | "ext-libxml": "*",
851 | "ext-mbstring": "*",
852 | "ext-xml": "*",
853 | "myclabs/deep-copy": "^1.7",
854 | "phar-io/manifest": "^1.0.2",
855 | "phar-io/version": "^2.0",
856 | "php": "^7.1",
857 | "phpspec/prophecy": "^1.7",
858 | "phpunit/php-code-coverage": "^6.0.7",
859 | "phpunit/php-file-iterator": "^2.0.1",
860 | "phpunit/php-text-template": "^1.2.1",
861 | "phpunit/php-timer": "^2.1",
862 | "sebastian/comparator": "^3.0",
863 | "sebastian/diff": "^3.0",
864 | "sebastian/environment": "^4.0",
865 | "sebastian/exporter": "^3.1",
866 | "sebastian/global-state": "^2.0",
867 | "sebastian/object-enumerator": "^3.0.3",
868 | "sebastian/resource-operations": "^2.0",
869 | "sebastian/version": "^2.0.1"
870 | },
871 | "conflict": {
872 | "phpunit/phpunit-mock-objects": "*"
873 | },
874 | "require-dev": {
875 | "ext-pdo": "*"
876 | },
877 | "suggest": {
878 | "ext-soap": "*",
879 | "ext-xdebug": "*",
880 | "phpunit/php-invoker": "^2.0"
881 | },
882 | "bin": [
883 | "phpunit"
884 | ],
885 | "type": "library",
886 | "extra": {
887 | "branch-alias": {
888 | "dev-master": "7.5-dev"
889 | }
890 | },
891 | "autoload": {
892 | "classmap": [
893 | "src/"
894 | ]
895 | },
896 | "notification-url": "https://packagist.org/downloads/",
897 | "license": [
898 | "BSD-3-Clause"
899 | ],
900 | "authors": [
901 | {
902 | "name": "Sebastian Bergmann",
903 | "email": "sebastian@phpunit.de",
904 | "role": "lead"
905 | }
906 | ],
907 | "description": "The PHP Unit Testing framework.",
908 | "homepage": "https://phpunit.de/",
909 | "keywords": [
910 | "phpunit",
911 | "testing",
912 | "xunit"
913 | ],
914 | "support": {
915 | "issues": "https://github.com/sebastianbergmann/phpunit/issues",
916 | "source": "https://github.com/sebastianbergmann/phpunit/tree/7.5.20"
917 | },
918 | "time": "2020-01-08T08:45:45+00:00"
919 | },
920 | {
921 | "name": "sebastian/code-unit-reverse-lookup",
922 | "version": "1.0.2",
923 | "source": {
924 | "type": "git",
925 | "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git",
926 | "reference": "1de8cd5c010cb153fcd68b8d0f64606f523f7619"
927 | },
928 | "dist": {
929 | "type": "zip",
930 | "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/1de8cd5c010cb153fcd68b8d0f64606f523f7619",
931 | "reference": "1de8cd5c010cb153fcd68b8d0f64606f523f7619",
932 | "shasum": ""
933 | },
934 | "require": {
935 | "php": ">=5.6"
936 | },
937 | "require-dev": {
938 | "phpunit/phpunit": "^8.5"
939 | },
940 | "type": "library",
941 | "extra": {
942 | "branch-alias": {
943 | "dev-master": "1.0.x-dev"
944 | }
945 | },
946 | "autoload": {
947 | "classmap": [
948 | "src/"
949 | ]
950 | },
951 | "notification-url": "https://packagist.org/downloads/",
952 | "license": [
953 | "BSD-3-Clause"
954 | ],
955 | "authors": [
956 | {
957 | "name": "Sebastian Bergmann",
958 | "email": "sebastian@phpunit.de"
959 | }
960 | ],
961 | "description": "Looks up which function or method a line of code belongs to",
962 | "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/",
963 | "support": {
964 | "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues",
965 | "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/1.0.2"
966 | },
967 | "funding": [
968 | {
969 | "url": "https://github.com/sebastianbergmann",
970 | "type": "github"
971 | }
972 | ],
973 | "time": "2020-11-30T08:15:22+00:00"
974 | },
975 | {
976 | "name": "sebastian/comparator",
977 | "version": "3.0.3",
978 | "source": {
979 | "type": "git",
980 | "url": "https://github.com/sebastianbergmann/comparator.git",
981 | "reference": "1071dfcef776a57013124ff35e1fc41ccd294758"
982 | },
983 | "dist": {
984 | "type": "zip",
985 | "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/1071dfcef776a57013124ff35e1fc41ccd294758",
986 | "reference": "1071dfcef776a57013124ff35e1fc41ccd294758",
987 | "shasum": ""
988 | },
989 | "require": {
990 | "php": ">=7.1",
991 | "sebastian/diff": "^3.0",
992 | "sebastian/exporter": "^3.1"
993 | },
994 | "require-dev": {
995 | "phpunit/phpunit": "^8.5"
996 | },
997 | "type": "library",
998 | "extra": {
999 | "branch-alias": {
1000 | "dev-master": "3.0-dev"
1001 | }
1002 | },
1003 | "autoload": {
1004 | "classmap": [
1005 | "src/"
1006 | ]
1007 | },
1008 | "notification-url": "https://packagist.org/downloads/",
1009 | "license": [
1010 | "BSD-3-Clause"
1011 | ],
1012 | "authors": [
1013 | {
1014 | "name": "Sebastian Bergmann",
1015 | "email": "sebastian@phpunit.de"
1016 | },
1017 | {
1018 | "name": "Jeff Welch",
1019 | "email": "whatthejeff@gmail.com"
1020 | },
1021 | {
1022 | "name": "Volker Dusch",
1023 | "email": "github@wallbash.com"
1024 | },
1025 | {
1026 | "name": "Bernhard Schussek",
1027 | "email": "bschussek@2bepublished.at"
1028 | }
1029 | ],
1030 | "description": "Provides the functionality to compare PHP values for equality",
1031 | "homepage": "https://github.com/sebastianbergmann/comparator",
1032 | "keywords": [
1033 | "comparator",
1034 | "compare",
1035 | "equality"
1036 | ],
1037 | "support": {
1038 | "issues": "https://github.com/sebastianbergmann/comparator/issues",
1039 | "source": "https://github.com/sebastianbergmann/comparator/tree/3.0.3"
1040 | },
1041 | "funding": [
1042 | {
1043 | "url": "https://github.com/sebastianbergmann",
1044 | "type": "github"
1045 | }
1046 | ],
1047 | "time": "2020-11-30T08:04:30+00:00"
1048 | },
1049 | {
1050 | "name": "sebastian/diff",
1051 | "version": "3.0.3",
1052 | "source": {
1053 | "type": "git",
1054 | "url": "https://github.com/sebastianbergmann/diff.git",
1055 | "reference": "14f72dd46eaf2f2293cbe79c93cc0bc43161a211"
1056 | },
1057 | "dist": {
1058 | "type": "zip",
1059 | "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/14f72dd46eaf2f2293cbe79c93cc0bc43161a211",
1060 | "reference": "14f72dd46eaf2f2293cbe79c93cc0bc43161a211",
1061 | "shasum": ""
1062 | },
1063 | "require": {
1064 | "php": ">=7.1"
1065 | },
1066 | "require-dev": {
1067 | "phpunit/phpunit": "^7.5 || ^8.0",
1068 | "symfony/process": "^2 || ^3.3 || ^4"
1069 | },
1070 | "type": "library",
1071 | "extra": {
1072 | "branch-alias": {
1073 | "dev-master": "3.0-dev"
1074 | }
1075 | },
1076 | "autoload": {
1077 | "classmap": [
1078 | "src/"
1079 | ]
1080 | },
1081 | "notification-url": "https://packagist.org/downloads/",
1082 | "license": [
1083 | "BSD-3-Clause"
1084 | ],
1085 | "authors": [
1086 | {
1087 | "name": "Sebastian Bergmann",
1088 | "email": "sebastian@phpunit.de"
1089 | },
1090 | {
1091 | "name": "Kore Nordmann",
1092 | "email": "mail@kore-nordmann.de"
1093 | }
1094 | ],
1095 | "description": "Diff implementation",
1096 | "homepage": "https://github.com/sebastianbergmann/diff",
1097 | "keywords": [
1098 | "diff",
1099 | "udiff",
1100 | "unidiff",
1101 | "unified diff"
1102 | ],
1103 | "support": {
1104 | "issues": "https://github.com/sebastianbergmann/diff/issues",
1105 | "source": "https://github.com/sebastianbergmann/diff/tree/3.0.3"
1106 | },
1107 | "funding": [
1108 | {
1109 | "url": "https://github.com/sebastianbergmann",
1110 | "type": "github"
1111 | }
1112 | ],
1113 | "time": "2020-11-30T07:59:04+00:00"
1114 | },
1115 | {
1116 | "name": "sebastian/environment",
1117 | "version": "4.2.4",
1118 | "source": {
1119 | "type": "git",
1120 | "url": "https://github.com/sebastianbergmann/environment.git",
1121 | "reference": "d47bbbad83711771f167c72d4e3f25f7fcc1f8b0"
1122 | },
1123 | "dist": {
1124 | "type": "zip",
1125 | "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/d47bbbad83711771f167c72d4e3f25f7fcc1f8b0",
1126 | "reference": "d47bbbad83711771f167c72d4e3f25f7fcc1f8b0",
1127 | "shasum": ""
1128 | },
1129 | "require": {
1130 | "php": ">=7.1"
1131 | },
1132 | "require-dev": {
1133 | "phpunit/phpunit": "^7.5"
1134 | },
1135 | "suggest": {
1136 | "ext-posix": "*"
1137 | },
1138 | "type": "library",
1139 | "extra": {
1140 | "branch-alias": {
1141 | "dev-master": "4.2-dev"
1142 | }
1143 | },
1144 | "autoload": {
1145 | "classmap": [
1146 | "src/"
1147 | ]
1148 | },
1149 | "notification-url": "https://packagist.org/downloads/",
1150 | "license": [
1151 | "BSD-3-Clause"
1152 | ],
1153 | "authors": [
1154 | {
1155 | "name": "Sebastian Bergmann",
1156 | "email": "sebastian@phpunit.de"
1157 | }
1158 | ],
1159 | "description": "Provides functionality to handle HHVM/PHP environments",
1160 | "homepage": "http://www.github.com/sebastianbergmann/environment",
1161 | "keywords": [
1162 | "Xdebug",
1163 | "environment",
1164 | "hhvm"
1165 | ],
1166 | "support": {
1167 | "issues": "https://github.com/sebastianbergmann/environment/issues",
1168 | "source": "https://github.com/sebastianbergmann/environment/tree/4.2.4"
1169 | },
1170 | "funding": [
1171 | {
1172 | "url": "https://github.com/sebastianbergmann",
1173 | "type": "github"
1174 | }
1175 | ],
1176 | "time": "2020-11-30T07:53:42+00:00"
1177 | },
1178 | {
1179 | "name": "sebastian/exporter",
1180 | "version": "3.1.3",
1181 | "source": {
1182 | "type": "git",
1183 | "url": "https://github.com/sebastianbergmann/exporter.git",
1184 | "reference": "6b853149eab67d4da22291d36f5b0631c0fd856e"
1185 | },
1186 | "dist": {
1187 | "type": "zip",
1188 | "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/6b853149eab67d4da22291d36f5b0631c0fd856e",
1189 | "reference": "6b853149eab67d4da22291d36f5b0631c0fd856e",
1190 | "shasum": ""
1191 | },
1192 | "require": {
1193 | "php": ">=7.0",
1194 | "sebastian/recursion-context": "^3.0"
1195 | },
1196 | "require-dev": {
1197 | "ext-mbstring": "*",
1198 | "phpunit/phpunit": "^6.0"
1199 | },
1200 | "type": "library",
1201 | "extra": {
1202 | "branch-alias": {
1203 | "dev-master": "3.1.x-dev"
1204 | }
1205 | },
1206 | "autoload": {
1207 | "classmap": [
1208 | "src/"
1209 | ]
1210 | },
1211 | "notification-url": "https://packagist.org/downloads/",
1212 | "license": [
1213 | "BSD-3-Clause"
1214 | ],
1215 | "authors": [
1216 | {
1217 | "name": "Sebastian Bergmann",
1218 | "email": "sebastian@phpunit.de"
1219 | },
1220 | {
1221 | "name": "Jeff Welch",
1222 | "email": "whatthejeff@gmail.com"
1223 | },
1224 | {
1225 | "name": "Volker Dusch",
1226 | "email": "github@wallbash.com"
1227 | },
1228 | {
1229 | "name": "Adam Harvey",
1230 | "email": "aharvey@php.net"
1231 | },
1232 | {
1233 | "name": "Bernhard Schussek",
1234 | "email": "bschussek@gmail.com"
1235 | }
1236 | ],
1237 | "description": "Provides the functionality to export PHP variables for visualization",
1238 | "homepage": "http://www.github.com/sebastianbergmann/exporter",
1239 | "keywords": [
1240 | "export",
1241 | "exporter"
1242 | ],
1243 | "support": {
1244 | "issues": "https://github.com/sebastianbergmann/exporter/issues",
1245 | "source": "https://github.com/sebastianbergmann/exporter/tree/3.1.3"
1246 | },
1247 | "funding": [
1248 | {
1249 | "url": "https://github.com/sebastianbergmann",
1250 | "type": "github"
1251 | }
1252 | ],
1253 | "time": "2020-11-30T07:47:53+00:00"
1254 | },
1255 | {
1256 | "name": "sebastian/global-state",
1257 | "version": "2.0.0",
1258 | "source": {
1259 | "type": "git",
1260 | "url": "https://github.com/sebastianbergmann/global-state.git",
1261 | "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4"
1262 | },
1263 | "dist": {
1264 | "type": "zip",
1265 | "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4",
1266 | "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4",
1267 | "shasum": ""
1268 | },
1269 | "require": {
1270 | "php": "^7.0"
1271 | },
1272 | "require-dev": {
1273 | "phpunit/phpunit": "^6.0"
1274 | },
1275 | "suggest": {
1276 | "ext-uopz": "*"
1277 | },
1278 | "type": "library",
1279 | "extra": {
1280 | "branch-alias": {
1281 | "dev-master": "2.0-dev"
1282 | }
1283 | },
1284 | "autoload": {
1285 | "classmap": [
1286 | "src/"
1287 | ]
1288 | },
1289 | "notification-url": "https://packagist.org/downloads/",
1290 | "license": [
1291 | "BSD-3-Clause"
1292 | ],
1293 | "authors": [
1294 | {
1295 | "name": "Sebastian Bergmann",
1296 | "email": "sebastian@phpunit.de"
1297 | }
1298 | ],
1299 | "description": "Snapshotting of global state",
1300 | "homepage": "http://www.github.com/sebastianbergmann/global-state",
1301 | "keywords": [
1302 | "global state"
1303 | ],
1304 | "support": {
1305 | "issues": "https://github.com/sebastianbergmann/global-state/issues",
1306 | "source": "https://github.com/sebastianbergmann/global-state/tree/2.0.0"
1307 | },
1308 | "time": "2017-04-27T15:39:26+00:00"
1309 | },
1310 | {
1311 | "name": "sebastian/object-enumerator",
1312 | "version": "3.0.4",
1313 | "source": {
1314 | "type": "git",
1315 | "url": "https://github.com/sebastianbergmann/object-enumerator.git",
1316 | "reference": "e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2"
1317 | },
1318 | "dist": {
1319 | "type": "zip",
1320 | "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2",
1321 | "reference": "e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2",
1322 | "shasum": ""
1323 | },
1324 | "require": {
1325 | "php": ">=7.0",
1326 | "sebastian/object-reflector": "^1.1.1",
1327 | "sebastian/recursion-context": "^3.0"
1328 | },
1329 | "require-dev": {
1330 | "phpunit/phpunit": "^6.0"
1331 | },
1332 | "type": "library",
1333 | "extra": {
1334 | "branch-alias": {
1335 | "dev-master": "3.0.x-dev"
1336 | }
1337 | },
1338 | "autoload": {
1339 | "classmap": [
1340 | "src/"
1341 | ]
1342 | },
1343 | "notification-url": "https://packagist.org/downloads/",
1344 | "license": [
1345 | "BSD-3-Clause"
1346 | ],
1347 | "authors": [
1348 | {
1349 | "name": "Sebastian Bergmann",
1350 | "email": "sebastian@phpunit.de"
1351 | }
1352 | ],
1353 | "description": "Traverses array structures and object graphs to enumerate all referenced objects",
1354 | "homepage": "https://github.com/sebastianbergmann/object-enumerator/",
1355 | "support": {
1356 | "issues": "https://github.com/sebastianbergmann/object-enumerator/issues",
1357 | "source": "https://github.com/sebastianbergmann/object-enumerator/tree/3.0.4"
1358 | },
1359 | "funding": [
1360 | {
1361 | "url": "https://github.com/sebastianbergmann",
1362 | "type": "github"
1363 | }
1364 | ],
1365 | "time": "2020-11-30T07:40:27+00:00"
1366 | },
1367 | {
1368 | "name": "sebastian/object-reflector",
1369 | "version": "1.1.2",
1370 | "source": {
1371 | "type": "git",
1372 | "url": "https://github.com/sebastianbergmann/object-reflector.git",
1373 | "reference": "9b8772b9cbd456ab45d4a598d2dd1a1bced6363d"
1374 | },
1375 | "dist": {
1376 | "type": "zip",
1377 | "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/9b8772b9cbd456ab45d4a598d2dd1a1bced6363d",
1378 | "reference": "9b8772b9cbd456ab45d4a598d2dd1a1bced6363d",
1379 | "shasum": ""
1380 | },
1381 | "require": {
1382 | "php": ">=7.0"
1383 | },
1384 | "require-dev": {
1385 | "phpunit/phpunit": "^6.0"
1386 | },
1387 | "type": "library",
1388 | "extra": {
1389 | "branch-alias": {
1390 | "dev-master": "1.1-dev"
1391 | }
1392 | },
1393 | "autoload": {
1394 | "classmap": [
1395 | "src/"
1396 | ]
1397 | },
1398 | "notification-url": "https://packagist.org/downloads/",
1399 | "license": [
1400 | "BSD-3-Clause"
1401 | ],
1402 | "authors": [
1403 | {
1404 | "name": "Sebastian Bergmann",
1405 | "email": "sebastian@phpunit.de"
1406 | }
1407 | ],
1408 | "description": "Allows reflection of object attributes, including inherited and non-public ones",
1409 | "homepage": "https://github.com/sebastianbergmann/object-reflector/",
1410 | "support": {
1411 | "issues": "https://github.com/sebastianbergmann/object-reflector/issues",
1412 | "source": "https://github.com/sebastianbergmann/object-reflector/tree/1.1.2"
1413 | },
1414 | "funding": [
1415 | {
1416 | "url": "https://github.com/sebastianbergmann",
1417 | "type": "github"
1418 | }
1419 | ],
1420 | "time": "2020-11-30T07:37:18+00:00"
1421 | },
1422 | {
1423 | "name": "sebastian/recursion-context",
1424 | "version": "3.0.1",
1425 | "source": {
1426 | "type": "git",
1427 | "url": "https://github.com/sebastianbergmann/recursion-context.git",
1428 | "reference": "367dcba38d6e1977be014dc4b22f47a484dac7fb"
1429 | },
1430 | "dist": {
1431 | "type": "zip",
1432 | "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/367dcba38d6e1977be014dc4b22f47a484dac7fb",
1433 | "reference": "367dcba38d6e1977be014dc4b22f47a484dac7fb",
1434 | "shasum": ""
1435 | },
1436 | "require": {
1437 | "php": ">=7.0"
1438 | },
1439 | "require-dev": {
1440 | "phpunit/phpunit": "^6.0"
1441 | },
1442 | "type": "library",
1443 | "extra": {
1444 | "branch-alias": {
1445 | "dev-master": "3.0.x-dev"
1446 | }
1447 | },
1448 | "autoload": {
1449 | "classmap": [
1450 | "src/"
1451 | ]
1452 | },
1453 | "notification-url": "https://packagist.org/downloads/",
1454 | "license": [
1455 | "BSD-3-Clause"
1456 | ],
1457 | "authors": [
1458 | {
1459 | "name": "Sebastian Bergmann",
1460 | "email": "sebastian@phpunit.de"
1461 | },
1462 | {
1463 | "name": "Jeff Welch",
1464 | "email": "whatthejeff@gmail.com"
1465 | },
1466 | {
1467 | "name": "Adam Harvey",
1468 | "email": "aharvey@php.net"
1469 | }
1470 | ],
1471 | "description": "Provides functionality to recursively process PHP variables",
1472 | "homepage": "http://www.github.com/sebastianbergmann/recursion-context",
1473 | "support": {
1474 | "issues": "https://github.com/sebastianbergmann/recursion-context/issues",
1475 | "source": "https://github.com/sebastianbergmann/recursion-context/tree/3.0.1"
1476 | },
1477 | "funding": [
1478 | {
1479 | "url": "https://github.com/sebastianbergmann",
1480 | "type": "github"
1481 | }
1482 | ],
1483 | "time": "2020-11-30T07:34:24+00:00"
1484 | },
1485 | {
1486 | "name": "sebastian/resource-operations",
1487 | "version": "2.0.2",
1488 | "source": {
1489 | "type": "git",
1490 | "url": "https://github.com/sebastianbergmann/resource-operations.git",
1491 | "reference": "31d35ca87926450c44eae7e2611d45a7a65ea8b3"
1492 | },
1493 | "dist": {
1494 | "type": "zip",
1495 | "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/31d35ca87926450c44eae7e2611d45a7a65ea8b3",
1496 | "reference": "31d35ca87926450c44eae7e2611d45a7a65ea8b3",
1497 | "shasum": ""
1498 | },
1499 | "require": {
1500 | "php": ">=7.1"
1501 | },
1502 | "type": "library",
1503 | "extra": {
1504 | "branch-alias": {
1505 | "dev-master": "2.0-dev"
1506 | }
1507 | },
1508 | "autoload": {
1509 | "classmap": [
1510 | "src/"
1511 | ]
1512 | },
1513 | "notification-url": "https://packagist.org/downloads/",
1514 | "license": [
1515 | "BSD-3-Clause"
1516 | ],
1517 | "authors": [
1518 | {
1519 | "name": "Sebastian Bergmann",
1520 | "email": "sebastian@phpunit.de"
1521 | }
1522 | ],
1523 | "description": "Provides a list of PHP built-in functions that operate on resources",
1524 | "homepage": "https://www.github.com/sebastianbergmann/resource-operations",
1525 | "support": {
1526 | "issues": "https://github.com/sebastianbergmann/resource-operations/issues",
1527 | "source": "https://github.com/sebastianbergmann/resource-operations/tree/2.0.2"
1528 | },
1529 | "funding": [
1530 | {
1531 | "url": "https://github.com/sebastianbergmann",
1532 | "type": "github"
1533 | }
1534 | ],
1535 | "time": "2020-11-30T07:30:19+00:00"
1536 | },
1537 | {
1538 | "name": "sebastian/version",
1539 | "version": "2.0.1",
1540 | "source": {
1541 | "type": "git",
1542 | "url": "https://github.com/sebastianbergmann/version.git",
1543 | "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019"
1544 | },
1545 | "dist": {
1546 | "type": "zip",
1547 | "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019",
1548 | "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019",
1549 | "shasum": ""
1550 | },
1551 | "require": {
1552 | "php": ">=5.6"
1553 | },
1554 | "type": "library",
1555 | "extra": {
1556 | "branch-alias": {
1557 | "dev-master": "2.0.x-dev"
1558 | }
1559 | },
1560 | "autoload": {
1561 | "classmap": [
1562 | "src/"
1563 | ]
1564 | },
1565 | "notification-url": "https://packagist.org/downloads/",
1566 | "license": [
1567 | "BSD-3-Clause"
1568 | ],
1569 | "authors": [
1570 | {
1571 | "name": "Sebastian Bergmann",
1572 | "email": "sebastian@phpunit.de",
1573 | "role": "lead"
1574 | }
1575 | ],
1576 | "description": "Library that helps with managing the version number of Git-hosted PHP projects",
1577 | "homepage": "https://github.com/sebastianbergmann/version",
1578 | "support": {
1579 | "issues": "https://github.com/sebastianbergmann/version/issues",
1580 | "source": "https://github.com/sebastianbergmann/version/tree/master"
1581 | },
1582 | "time": "2016-10-03T07:35:21+00:00"
1583 | },
1584 | {
1585 | "name": "symfony/polyfill-ctype",
1586 | "version": "v1.22.1",
1587 | "source": {
1588 | "type": "git",
1589 | "url": "https://github.com/symfony/polyfill-ctype.git",
1590 | "reference": "c6c942b1ac76c82448322025e084cadc56048b4e"
1591 | },
1592 | "dist": {
1593 | "type": "zip",
1594 | "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/c6c942b1ac76c82448322025e084cadc56048b4e",
1595 | "reference": "c6c942b1ac76c82448322025e084cadc56048b4e",
1596 | "shasum": ""
1597 | },
1598 | "require": {
1599 | "php": ">=7.1"
1600 | },
1601 | "suggest": {
1602 | "ext-ctype": "For best performance"
1603 | },
1604 | "type": "library",
1605 | "extra": {
1606 | "branch-alias": {
1607 | "dev-main": "1.22-dev"
1608 | },
1609 | "thanks": {
1610 | "name": "symfony/polyfill",
1611 | "url": "https://github.com/symfony/polyfill"
1612 | }
1613 | },
1614 | "autoload": {
1615 | "psr-4": {
1616 | "Symfony\\Polyfill\\Ctype\\": ""
1617 | },
1618 | "files": [
1619 | "bootstrap.php"
1620 | ]
1621 | },
1622 | "notification-url": "https://packagist.org/downloads/",
1623 | "license": [
1624 | "MIT"
1625 | ],
1626 | "authors": [
1627 | {
1628 | "name": "Gert de Pagter",
1629 | "email": "BackEndTea@gmail.com"
1630 | },
1631 | {
1632 | "name": "Symfony Community",
1633 | "homepage": "https://symfony.com/contributors"
1634 | }
1635 | ],
1636 | "description": "Symfony polyfill for ctype functions",
1637 | "homepage": "https://symfony.com",
1638 | "keywords": [
1639 | "compatibility",
1640 | "ctype",
1641 | "polyfill",
1642 | "portable"
1643 | ],
1644 | "support": {
1645 | "source": "https://github.com/symfony/polyfill-ctype/tree/v1.22.1"
1646 | },
1647 | "funding": [
1648 | {
1649 | "url": "https://symfony.com/sponsor",
1650 | "type": "custom"
1651 | },
1652 | {
1653 | "url": "https://github.com/fabpot",
1654 | "type": "github"
1655 | },
1656 | {
1657 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
1658 | "type": "tidelift"
1659 | }
1660 | ],
1661 | "time": "2021-01-07T16:49:33+00:00"
1662 | },
1663 | {
1664 | "name": "theseer/tokenizer",
1665 | "version": "1.1.3",
1666 | "source": {
1667 | "type": "git",
1668 | "url": "https://github.com/theseer/tokenizer.git",
1669 | "reference": "11336f6f84e16a720dae9d8e6ed5019efa85a0f9"
1670 | },
1671 | "dist": {
1672 | "type": "zip",
1673 | "url": "https://api.github.com/repos/theseer/tokenizer/zipball/11336f6f84e16a720dae9d8e6ed5019efa85a0f9",
1674 | "reference": "11336f6f84e16a720dae9d8e6ed5019efa85a0f9",
1675 | "shasum": ""
1676 | },
1677 | "require": {
1678 | "ext-dom": "*",
1679 | "ext-tokenizer": "*",
1680 | "ext-xmlwriter": "*",
1681 | "php": "^7.0"
1682 | },
1683 | "type": "library",
1684 | "autoload": {
1685 | "classmap": [
1686 | "src/"
1687 | ]
1688 | },
1689 | "notification-url": "https://packagist.org/downloads/",
1690 | "license": [
1691 | "BSD-3-Clause"
1692 | ],
1693 | "authors": [
1694 | {
1695 | "name": "Arne Blankerts",
1696 | "email": "arne@blankerts.de",
1697 | "role": "Developer"
1698 | }
1699 | ],
1700 | "description": "A small library for converting tokenized PHP source code into XML and potentially other formats",
1701 | "support": {
1702 | "issues": "https://github.com/theseer/tokenizer/issues",
1703 | "source": "https://github.com/theseer/tokenizer/tree/master"
1704 | },
1705 | "time": "2019-06-13T22:48:21+00:00"
1706 | },
1707 | {
1708 | "name": "webmozart/assert",
1709 | "version": "1.9.1",
1710 | "source": {
1711 | "type": "git",
1712 | "url": "https://github.com/webmozarts/assert.git",
1713 | "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389"
1714 | },
1715 | "dist": {
1716 | "type": "zip",
1717 | "url": "https://api.github.com/repos/webmozarts/assert/zipball/bafc69caeb4d49c39fd0779086c03a3738cbb389",
1718 | "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389",
1719 | "shasum": ""
1720 | },
1721 | "require": {
1722 | "php": "^5.3.3 || ^7.0 || ^8.0",
1723 | "symfony/polyfill-ctype": "^1.8"
1724 | },
1725 | "conflict": {
1726 | "phpstan/phpstan": "<0.12.20",
1727 | "vimeo/psalm": "<3.9.1"
1728 | },
1729 | "require-dev": {
1730 | "phpunit/phpunit": "^4.8.36 || ^7.5.13"
1731 | },
1732 | "type": "library",
1733 | "autoload": {
1734 | "psr-4": {
1735 | "Webmozart\\Assert\\": "src/"
1736 | }
1737 | },
1738 | "notification-url": "https://packagist.org/downloads/",
1739 | "license": [
1740 | "MIT"
1741 | ],
1742 | "authors": [
1743 | {
1744 | "name": "Bernhard Schussek",
1745 | "email": "bschussek@gmail.com"
1746 | }
1747 | ],
1748 | "description": "Assertions to validate method input/output with nice error messages.",
1749 | "keywords": [
1750 | "assert",
1751 | "check",
1752 | "validate"
1753 | ],
1754 | "support": {
1755 | "issues": "https://github.com/webmozarts/assert/issues",
1756 | "source": "https://github.com/webmozarts/assert/tree/1.9.1"
1757 | },
1758 | "time": "2020-07-08T17:02:28+00:00"
1759 | }
1760 | ],
1761 | "aliases": [],
1762 | "minimum-stability": "stable",
1763 | "stability-flags": [],
1764 | "prefer-stable": false,
1765 | "prefer-lowest": false,
1766 | "platform": [],
1767 | "platform-dev": [],
1768 | "platform-overrides": {
1769 | "php": "7.1.0"
1770 | },
1771 | "plugin-api-version": "2.0.0"
1772 | }
1773 |
--------------------------------------------------------------------------------
/functions.php:
--------------------------------------------------------------------------------
1 | connect();
41 | } catch ( Exception $e ) {
42 |
43 | // Predis throws an Exception when it fails a server call.
44 | // To prevent WordPress from fataling, we catch the Exception.
45 | // TODO Perhaps we catch and rethrow? or return instance of
46 | // WP_Error?
47 | throw new Exception( $e->getMessage(), $e->getCode(), $e );
48 | }
49 | return true;
50 | }
51 |
52 | function build_params( $args ) {
53 | $scheme = 'tcp';
54 | $hostKey = 'host';
55 | $isTLS = isset( $args['ssl'] ) && is_array( $args['ssl'] );
56 |
57 | if ( $isTLS ) {
58 | $scheme = 'tls';
59 | } elseif ( null === $args['port'] ) {
60 | // If port is null, it's a socket connection
61 | $scheme = 'unix';
62 | $hostKey = 'path';
63 | }
64 |
65 | $params = array(
66 | 'scheme' => $scheme,
67 | $hostKey => $args['host'],
68 | );
69 |
70 | if ( 'unix' !== $scheme ) {
71 | $params['port'] = $args['port'];
72 | }
73 |
74 | if ( $isTLS ) {
75 | $params['ssl'] = $args['ssl'];
76 | }
77 | return $params;
78 | }
79 |
80 | function build_options( $args ) {
81 |
82 | $options = array(
83 | 'exceptions' => true,
84 | 'parameters' => array(
85 | 'password' => isset( $args['auth'] ) ? $args['auth'] : null,
86 | 'database' => isset( $args['database'] ) ? $args['database'] : null,
87 | 'persistent' => isset( $args['persistent'] ) ? $args['persistent'] : null,
88 | ),
89 | );
90 |
91 | return $options;
92 | }
93 |
94 | function append_error_messages( $errors ) {
95 | return array(
96 | '/^Connection refused/',
97 | );
98 | }
99 |
100 | function check_client_dependencies_callback() {
101 | return 'WP_Predis\check_client_dependencies';
102 | }
103 |
104 | function prepare_client_connection_callback() {
105 | return 'WP_Predis\prepare_client_connection';
106 | }
107 |
108 | function perform_client_connection_callback() {
109 | return 'WP_Predis\perform_client_connection';
110 | }
111 |
112 | /**
113 | * Shutdown hook.
114 | *
115 | * Runs during shutdown, even if the shutdown happened due
116 | * to a fatal error/exception.
117 | */
118 | function shutdown() {
119 | global $wp_object_cache;
120 |
121 | // Disconnect a Redis socket if the shutdown happened with a fatal.
122 | // Prevents a persistent socket from being corrupted if the error
123 | // happens while reading from Redis.
124 |
125 | $error = error_get_last();
126 | if ( $error && $error['type'] === E_ERROR && isset( $wp_object_cache->redis ) ) {
127 | $wp_object_cache->redis->disconnect();
128 | }
129 | }
130 |
--------------------------------------------------------------------------------
/object-cache.php:
--------------------------------------------------------------------------------
1 |
2 |
3 | Sniffs for the coding standards of the WP Redis plugin
4 |
5 | vendor
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/phpunit.xml:
--------------------------------------------------------------------------------
1 |
9 |
10 |
11 | ./tests/
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/tests/bootstrap-wp-predis.php:
--------------------------------------------------------------------------------
1 | $v ) {
22 | if ( $v !== $b[ $k ] ) {
23 | return false;
24 | }
25 | }
26 | // we have identical indexes, and no unequal values
27 | return true;
28 | }
29 |
--------------------------------------------------------------------------------
/tests/fixtures/phpredis-info.php:
--------------------------------------------------------------------------------
1 | '4.0.1',
5 | 'redis_git_sha1' => 0,
6 | 'redis_git_dirty' => 0,
7 | 'redis_build_id' => 'f37081b32886670b',
8 | 'redis_mode' => 'standalone',
9 | 'os' => 'Darwin 16.7.0 x86_64',
10 | 'arch_bits' => 64,
11 | 'multiplexing_api' => 'kqueue',
12 | 'atomicvar_api' => 'atomic-builtin',
13 | 'gcc_version' => '4.2.1',
14 | 'process_id' => 7830,
15 | 'run_id' => 'ff052fa3c9e7f581ff3b9e0e0f8aafe03fdff8d0',
16 | 'tcp_port' => 6379,
17 | 'uptime_in_seconds' => 163154,
18 | 'uptime_in_days' => 1,
19 | 'hz' => 10,
20 | 'lru_clock' => 9838681,
21 | 'executable' => '/usr/local/opt/redis/bin/redis-server',
22 | 'config_file' => '/usr/local/etc/redis.conf',
23 | 'connected_clients' => 1,
24 | 'client_longest_output_list' => 0,
25 | 'client_biggest_input_buf' => 0,
26 | 'blocked_clients' => 0,
27 | 'used_memory' => 1031072,
28 | 'used_memory_human' => '1006.91K',
29 | 'used_memory_rss' => 1400832,
30 | 'used_memory_rss_human' => '1.34M',
31 | 'used_memory_peak' => 2426048,
32 | 'used_memory_peak_human' => '2.31M',
33 | 'used_memory_peak_perc' => '42.50%',
34 | 'used_memory_overhead' => 1013014,
35 | 'used_memory_startup' => 963312,
36 | 'used_memory_dataset' => 18058,
37 | 'used_memory_dataset_perc' => '26.65%',
38 | 'total_system_memory' => 17179869184,
39 | 'total_system_memory_human' => '16.00G',
40 | 'used_memory_lua' => 37888,
41 | 'used_memory_lua_human' => '37.00K',
42 | 'maxmemory' => 0,
43 | 'maxmemory_human' => '0B',
44 | 'maxmemory_policy' => 'noeviction',
45 | 'mem_fragmentation_ratio' => '1.36',
46 | 'mem_allocator' => 'libc',
47 | 'active_defrag_running' => 0,
48 | 'lazyfree_pending_objects' => 0,
49 | 'loading' => 0,
50 | 'rdb_changes_since_last_save' => 0,
51 | 'rdb_bgsave_in_progress' => 0,
52 | 'rdb_last_save_time' => 1503010591,
53 | 'rdb_last_bgsave_status' => 'ok',
54 | 'rdb_last_bgsave_time_sec' => 0,
55 | 'rdb_current_bgsave_time_sec' => '-1',
56 | 'rdb_last_cow_size' => 0,
57 | 'aof_enabled' => 0,
58 | 'aof_rewrite_in_progress' => 0,
59 | 'aof_rewrite_scheduled' => 0,
60 | 'aof_last_rewrite_time_sec' => '-1',
61 | 'aof_current_rewrite_time_sec' => '-1',
62 | 'aof_last_bgrewrite_status' => 'ok',
63 | 'aof_last_write_status' => 'ok',
64 | 'aof_last_cow_size' => 0,
65 | 'total_connections_received' => 553,
66 | 'total_commands_processed' => 1978,
67 | 'instantaneous_ops_per_sec' => 0,
68 | 'total_net_input_bytes' => 418353,
69 | 'total_net_output_bytes' => 184734,
70 | 'instantaneous_input_kbps' => '0.00',
71 | 'instantaneous_output_kbps' => '0.00',
72 | 'rejected_connections' => 0,
73 | 'sync_full' => 0,
74 | 'sync_partial_ok' => 0,
75 | 'sync_partial_err' => 0,
76 | 'expired_keys' => 4,
77 | 'evicted_keys' => 0,
78 | 'keyspace_hits' => 283,
79 | 'keyspace_misses' => 459,
80 | 'pubsub_channels' => 0,
81 | 'pubsub_patterns' => 0,
82 | 'latest_fork_usec' => 422,
83 | 'migrate_cached_sockets' => 0,
84 | 'slave_expires_tracked_keys' => 0,
85 | 'active_defrag_hits' => 0,
86 | 'active_defrag_misses' => 0,
87 | 'active_defrag_key_hits' => 0,
88 | 'active_defrag_key_misses' => 0,
89 | 'role' => 'master',
90 | 'connected_slaves' => 0,
91 | 'master_replid' => 'f652af702c58e3d2cc4a593149b22931613e2b09',
92 | 'master_replid2' => 0,
93 | 'master_repl_offset' => 0,
94 | 'second_repl_offset' => '-1',
95 | 'repl_backlog_active' => 0,
96 | 'repl_backlog_size' => 1048576,
97 | 'repl_backlog_first_byte_offset' => 0,
98 | 'repl_backlog_histlen' => 0,
99 | 'used_cpu_sys' => '10.92',
100 | 'used_cpu_user' => '6.97',
101 | 'used_cpu_sys_children' => '0.06',
102 | 'used_cpu_user_children' => '0.01',
103 | 'cluster_enabled' => 0,
104 | 'db0' => 'keys=1,expires=0,avg_ttl=0',
105 | );
106 |
--------------------------------------------------------------------------------
/tests/fixtures/predis-info.php:
--------------------------------------------------------------------------------
1 | array(
5 | 'redis_version' => '4.0.1',
6 | 'redis_git_sha1' => '00000000',
7 | 'redis_git_dirty' => '0',
8 | 'redis_build_id' => 'f37081b32886670b',
9 | 'redis_mode' => 'standalone',
10 | 'os' => 'Darwin 16.7.0 x86_64',
11 | 'arch_bits' => '64',
12 | 'multiplexing_api' => 'kqueue',
13 | 'atomicvar_api' => 'atomic-builtin',
14 | 'gcc_version' => '4.2.1',
15 | 'process_id' => '7830',
16 | 'run_id' => 'ff052fa3c9e7f581ff3b9e0e0f8aafe03fdff8d0',
17 | 'tcp_port' => '6379',
18 | 'uptime_in_seconds' => '163207',
19 | 'uptime_in_days' => '1',
20 | 'hz' => '10',
21 | 'lru_clock' => '9838734',
22 | 'executable' => '/usr/local/opt/redis/bin/redis-server',
23 | 'config_file' => '/usr/local/etc/redis.conf',
24 | ),
25 | 'Clients' => array(
26 | 'connected_clients' => '1',
27 | 'client_longest_output_list' => '0',
28 | 'client_biggest_input_buf' => '0',
29 | 'blocked_clients' => '0',
30 | ),
31 | 'Memory' => array(
32 | 'used_memory' => '1031488',
33 | 'used_memory_human' => '1007.31K',
34 | 'used_memory_rss' => '1482752',
35 | 'used_memory_rss_human' => '1.41M',
36 | 'used_memory_peak' => '2426048',
37 | 'used_memory_peak_human' => '2.31M',
38 | 'used_memory_peak_perc' => '42.52%',
39 | 'used_memory_overhead' => '1013014',
40 | 'used_memory_startup' => '963312',
41 | 'used_memory_dataset' => '18474',
42 | 'used_memory_dataset_perc' => '27.10%',
43 | 'total_system_memory' => '17179869184',
44 | 'total_system_memory_human' => '16.00G',
45 | 'used_memory_lua' => '37888',
46 | 'used_memory_lua_human' => '37.00K',
47 | 'maxmemory' => '0',
48 | 'maxmemory_human' => '0B',
49 | 'maxmemory_policy' => 'noeviction',
50 | 'mem_fragmentation_ratio' => '1.44',
51 | 'mem_allocator' => 'libc',
52 | 'active_defrag_running' => '0',
53 | 'lazyfree_pending_objects' => '0',
54 | ),
55 | 'Persistence' => array(
56 | 'loading' => '0',
57 | 'rdb_changes_since_last_save' => '0',
58 | 'rdb_bgsave_in_progress' => '0',
59 | 'rdb_last_save_time' => '1503010591',
60 | 'rdb_last_bgsave_status' => 'ok',
61 | 'rdb_last_bgsave_time_sec' => '0',
62 | 'rdb_current_bgsave_time_sec' => '-1',
63 | 'rdb_last_cow_size' => '0',
64 | 'aof_enabled' => '0',
65 | 'aof_rewrite_in_progress' => '0',
66 | 'aof_rewrite_scheduled' => '0',
67 | 'aof_last_rewrite_time_sec' => '-1',
68 | 'aof_current_rewrite_time_sec' => '-1',
69 | 'aof_last_bgrewrite_status' => 'ok',
70 | 'aof_last_write_status' => 'ok',
71 | 'aof_last_cow_size' => '0',
72 | ),
73 | 'Stats' => array(
74 | 'total_connections_received' => '554',
75 | 'total_commands_processed' => '1980',
76 | 'instantaneous_ops_per_sec' => '0',
77 | 'total_net_input_bytes' => '418381',
78 | 'total_net_output_bytes' => '190194',
79 | 'instantaneous_input_kbps' => '0.00',
80 | 'instantaneous_output_kbps' => '0.00',
81 | 'rejected_connections' => '0',
82 | 'sync_full' => '0',
83 | 'sync_partial_ok' => '0',
84 | 'sync_partial_err' => '0',
85 | 'expired_keys' => '4',
86 | 'evicted_keys' => '0',
87 | 'keyspace_hits' => '283',
88 | 'keyspace_misses' => '459',
89 | 'pubsub_channels' => '0',
90 | 'pubsub_patterns' => '0',
91 | 'latest_fork_usec' => '422',
92 | 'migrate_cached_sockets' => '0',
93 | 'slave_expires_tracked_keys' => '0',
94 | 'active_defrag_hits' => '0',
95 | 'active_defrag_misses' => '0',
96 | 'active_defrag_key_hits' => '0',
97 | 'active_defrag_key_misses' => '0',
98 | ),
99 | 'Replication' => array(
100 | 'role' => 'master',
101 | 'connected_slaves' => '0',
102 | 'master_replid' => 'f652af702c58e3d2cc4a593149b22931613e2b09',
103 | 'master_replid2' => '0000000000000000000000000000000000000000',
104 | 'master_repl_offset' => '0',
105 | 'second_repl_offset' => '-1',
106 | 'repl_backlog_active' => '0',
107 | 'repl_backlog_size' => '1048576',
108 | 'repl_backlog_first_byte_offset' => '0',
109 | 'repl_backlog_histlen' => '0',
110 | ),
111 | 'CPU' => array(
112 | 'used_cpu_sys' => '10.93',
113 | 'used_cpu_user' => '6.98',
114 | 'used_cpu_sys_children' => '0.06',
115 | 'used_cpu_user_children' => '0.01',
116 | ),
117 | 'Cluster' => array(
118 | 'cluster_enabled' => '0',
119 | ),
120 | 'Keyspace' => array(
121 | 'db0' => array(
122 | 'keys' => '1',
123 | 'expires' => '0',
124 | 'avg_ttl' => '0',
125 | ),
126 | ),
127 | );
128 |
--------------------------------------------------------------------------------
/tests/test-functions.php:
--------------------------------------------------------------------------------
1 | '127.0.0.1',
9 | 'port' => 6379,
10 | 'timeout' => 1000,
11 | 'retry_interval' => 100,
12 | );
13 |
14 | public function test_dependencies() {
15 | $result = WP_Predis\check_client_dependencies();
16 | if ( class_exists( 'Predis\Client' ) ) {
17 | $this->assertTrue( $result );
18 | } else {
19 | $this->assertTrue( is_string( $result ) );
20 | }
21 | }
22 |
23 | public function test_socket_params() {
24 | $socket_path = '/path/to/redis.sock';
25 | $args = array(
26 | 'host' => $socket_path,
27 | 'port' => null,
28 | );
29 | $expected = array(
30 | 'scheme' => 'unix',
31 | 'path' => $socket_path,
32 | );
33 | $actual = WP_Predis\build_params( $args );
34 | $this->assertTrue( arrays_are_similar( $expected, $actual ) );
35 | }
36 |
37 | public function test_tls_params() {
38 | $host = '127.0.0.1';
39 | $ssl = array(
40 | 'cafile' => 'private.pem',
41 | 'verify_peer' => true,
42 | );
43 | $args = array(
44 | 'host' => $host,
45 | 'port' => 6379,
46 | 'ssl' => $ssl,
47 | );
48 | $expected = array(
49 | 'scheme' => 'tls',
50 | 'host' => $host,
51 | 'port' => 6379,
52 | 'ssl' => $ssl,
53 | );
54 | $actual = WP_Predis\build_params( $args );
55 | $this->assertTrue( arrays_are_similar( $expected, $actual ) );
56 | }
57 |
58 | public function test_redis_client_connection() {
59 | $redis = WP_Predis\prepare_client_connection( self::$client_parameters );
60 | $redis->connect();
61 | $this->assertTrue( $redis->isConnected() );
62 | }
63 |
64 | public function test_perform_connection() {
65 | $redis = WP_Predis\prepare_client_connection( self::$client_parameters );
66 | $isSetUp = WP_Predis\perform_client_connection( $redis, array(), array(
67 | // we test the 'exists' function gets called and we pass
68 | // self::$client_parameters['host'] as the argument. We only care
69 | // about if calling 'exists' throws an exception or not
70 | 'exists' => 'host',
71 | ) );
72 | $this->assertTrue( $isSetUp );
73 | }
74 |
75 | // we test that 'database' gets passed by setting up 2 connections, one to
76 | // the default and the other to a different database and modifying the same
77 | // key and testing that they're different
78 | public function test_setup_second_database() {
79 | $redis = WP_Predis\prepare_client_connection( self::$client_parameters );
80 | $second_db = array_merge( self::$client_parameters, array(
81 | 'database' => 2,
82 | ) );
83 | $redis2 = WP_Predis\prepare_client_connection( $second_db );
84 | $keys_methods = array(
85 | 'database' => 'select',
86 | );
87 | WP_Predis\perform_client_connection( $redis, self::$client_parameters, $keys_methods );
88 | WP_Predis\perform_client_connection( $redis2, $second_db, $keys_methods );
89 | $redis->set( 'foo', 'bar' );
90 | $redis2->set( 'foo', 'baz' );
91 | $this->assertEquals( $redis->get( 'foo' ), 'bar' );
92 | $this->assertEquals( $redis2->get( 'foo' ), 'baz' );
93 | $redis->del( 'foo' );
94 | $redis2->del( 'foo' );
95 | }
96 |
97 | // we test that auth gets passed by the fact that auth will fail with a bad
98 | // password
99 | public function test_setup_connection_auth() {
100 | $auth = array_merge( self::$client_parameters, array(
101 | 'auth' => 'thiswillfail',
102 | ) );
103 | $redis = WP_Predis\prepare_client_connection( $auth );
104 | $keys_methods = array(
105 | 'auth' => 'auth',
106 | );
107 | $this->expectException( 'Exception' );
108 | WP_Predis\perform_client_connection( $redis, $auth, $keys_methods );
109 | }
110 |
111 | public function test_append_error_messages() {
112 | $expected = array(
113 | '/^Connection refused/',
114 | );
115 | $actual = WP_Predis\append_error_messages(array(
116 | 'error',
117 | ));
118 | $this->assertEquals( $expected, $actual );
119 | }
120 |
121 | public function test_check_client_dependencies_callback() {
122 | $this->assertEquals( WP_Predis\check_client_dependencies_callback(), 'WP_Predis\check_client_dependencies' );
123 | }
124 |
125 | public function test_client_connection_callback() {
126 | $this->assertEquals( WP_Predis\prepare_client_connection_callback(), 'WP_Predis\prepare_client_connection' );
127 | }
128 |
129 | public function test_setup_client_connection_callback() {
130 | $this->assertEquals( WP_Predis\perform_client_connection_callback(), 'WP_Predis\perform_client_connection' );
131 | }
132 | }
133 |
--------------------------------------------------------------------------------
/tests/test-wp-predis-decorator.php:
--------------------------------------------------------------------------------
1 | '127.0.0.1',
9 | 'port' => 6379,
10 | );
11 |
12 | protected static $options = array();
13 |
14 | public function setUp() {
15 | parent::setUp();
16 | $client = new Predis\Client( self::$arguments, self::$options );
17 | $this->client = new WP_Predis\Decorator( $client );
18 | }
19 |
20 | public function test_is_connected() {
21 | $this->client->connect();
22 | $this->assertTrue( $this->client->isConnected() );
23 | }
24 |
25 | public function test_hexists() {
26 | $key = 'test';
27 | $field = 'foo';
28 |
29 | $exists = $this->client->hexists( $key, $field );
30 | $this->assertFalse( $exists );
31 | }
32 |
33 | public function test_exists() {
34 | $key = 'test';
35 |
36 | $exists = $this->client->exists( $key );
37 | $this->assertFalse( $exists );
38 | }
39 |
40 | public function test_get() {
41 | $key = 'test';
42 |
43 | $value = $this->client->get( $key );
44 | $this->assertFalse( $value );
45 | }
46 |
47 | public function test_hget() {
48 | $key = 'test';
49 | $field = 'foo';
50 |
51 | $value = $this->client->hget( $key, $field );
52 | $this->assertFalse( $value );
53 | }
54 |
55 | public function test_setex() {
56 | $key = 'foo';
57 | $value = 'bar';
58 |
59 | $result = $this->client->setex( $key, 100, $value );
60 | $this->assertTrue( $result );
61 | }
62 |
63 | public function test_set() {
64 | $key = 'foo';
65 | $value = 'bar';
66 |
67 | $result = $this->client->set( $key, $value );
68 | $this->assertTrue( $result );
69 | }
70 |
71 | public function test_delete() {
72 | $this->client->mset( array(
73 | 'foo' => 'bar',
74 | 'bar' => 'baz',
75 | 'baz' => 'qux',
76 | ));
77 |
78 | $deleted = $this->client->del( 'foo', 'bar', 'baz' );
79 | $this->assertEquals( 3, $deleted );
80 | }
81 |
82 | public function test_hdelete() {
83 | $key = 'test';
84 | $fields = array(
85 | 'foo',
86 | 'bar',
87 | 'baz',
88 | );
89 |
90 | $this->client->hmset( $key, array(
91 | 'foo' => 'bar',
92 | 'bar' => 'baz',
93 | 'baz' => 'qux',
94 | ));
95 |
96 | $deleted = $this->client->hdel( $key, 'foo', 'bar', 'baz' );
97 | $this->assertEquals( 3, $deleted );
98 | }
99 |
100 | public function test_info() {
101 | $phpredis_info = require( dirname( __FILE__ ) . '/fixtures/phpredis-info.php' );
102 | $predis_info = require( dirname( __FILE__ ) . '/fixtures/predis-info.php' );
103 | $actual = $this->client->transform_info( $predis_info );
104 | $this->assertEquals( array_keys( $phpredis_info ), array_keys( $actual ) );
105 | $this->assertEquals( $phpredis_info['db0'], $actual['db0'] );
106 | }
107 |
108 | public function test_close() {
109 | $this->assertEquals( null, $this->client->close() );
110 | }
111 |
112 | public function tearDown() {
113 | parent::tearDown();
114 | $this->client->flushall();
115 | }
116 | }
117 |
--------------------------------------------------------------------------------