├── .gitignore
├── .scrutinizer.yml
├── .travis.yml
├── CHANGELOG.md
├── LICENSE
├── README.md
├── composer.json
├── composer.lock
├── phpcs.xml.dist
├── phpunit.xml.dist
├── src
├── Exceptions
│ └── InlineKeyboardPaginationException.php
├── InlineKeyboardPagination.php
└── InlineKeyboardPaginator.php
└── tests
└── InlineKeyboardPaginationTest.php
/.gitignore:
--------------------------------------------------------------------------------
1 | /.idea
2 | /.phpunit.result.cache
3 | /composer.phar
4 | /coverage.xml
5 | /phpcs.xml
6 | /phpunit.xml
7 | /vendor/
8 |
--------------------------------------------------------------------------------
/.scrutinizer.yml:
--------------------------------------------------------------------------------
1 | build:
2 | environment:
3 | php: 7.4.0
4 | nodes:
5 | analysis:
6 | tests:
7 | override:
8 | - php-scrutinizer-run
9 |
10 | filter:
11 | paths:
12 | - src/
13 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | dist: xenial
2 | sudo: required
3 | language: php
4 |
5 | cache:
6 | directories:
7 | - vendor
8 | - $HOME/.composer/cache
9 |
10 | php:
11 | - 7.4
12 | - 8.0
13 | - nightly
14 |
15 | jobs:
16 | allow_failures:
17 | - php: nightly
18 | fast_finish: true
19 |
20 | notifications:
21 | on_success: never
22 | on_failure: always
23 |
24 | git:
25 | depth: 1
26 |
27 | install:
28 | - travis_retry composer install --prefer-dist --no-interaction
29 |
30 | script:
31 | - composer check-code
32 | - if [ "$TRAVIS_PHP_VERSION" == "8.0" ]; then composer test-cov; else composer test; fi
33 |
34 | after_success:
35 | - if [ "$TRAVIS_PHP_VERSION" == "8.0" ]; then composer test-cov-upload; fi
36 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 | The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/).
3 |
4 | Exclamation symbols (:exclamation:) note something of importance e.g. breaking changes. Click them to learn more.
5 |
6 | ## [Unreleased]
7 | ### Added
8 | ### Changed
9 | ### Deprecated
10 | ### Removed
11 | ### Fixed
12 | ### Security
13 |
14 | ## [1.1.0] - 2021-07-10
15 | ### Added
16 | - Bump minimum PHP to 7.4 and support PHP 8. (@MyZik) (#8)
17 | ### Changed
18 | - Bump development dependencies, update tests. (#11, #12)
19 | - Improve all development configurations. (#11)
20 | ### Fixed
21 | - Strange behaviour with page 3. (#12)
22 | ### Security
23 | - Minimum PHP 7.4. (@MyZik) (#8)
24 |
25 | ## [1.0.0] - 2017-09-08
26 | ### Added
27 | - Initial version!
28 |
29 | [Unreleased]: https://github.com/php-telegram-bot/inline-keyboard-pagination/compare/master...develop
30 | [1.1.0]: https://github.com/php-telegram-bot/inline-keyboard-pagination/compare/1.0.0...1.1.0
31 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 | Copyright (c) 2016 Artem Beliankin
3 |
4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
5 |
6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
7 |
8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # [Telegram Bot Inline Keyboard Pagination][github-tgbot-ikp]
2 |
3 | [![Scrutinizer Code Quality][code-quality-badge]][code-quality]
4 | [![Codecov][code-coverage-badge]][code-coverage]
5 | [![Build Status][build-status-badge]][build-status]
6 |
7 | [![Latest Stable Version][latest-version-badge]][packagist-tgbot-ikp]
8 | [![Total Downloads][total-downloads-badge]][packagist-tgbot-ikp]
9 | [![License][license-badge]][license]
10 |
11 | - [Installation](#installation)
12 | - [Composer](#composer)
13 | - [Usage](#usage)
14 | - [Test Data](#test-data)
15 | - [How To Use](#how-to-use)
16 | - [Code Quality](#code-quality)
17 | - [License](#license)
18 |
19 | ## Installation
20 |
21 | ### Composer
22 |
23 | ```bash
24 | composer require php-telegram-bot/inline-keyboard-pagination
25 | ```
26 |
27 | ## Usage
28 |
29 | ### Test Data
30 |
31 | ```php
32 | $items = range(1, 100); // required.
33 | $command = 'testCommand'; // optional. Default: pagination
34 | $selectedPage = 10; // optional. Default: 1
35 | $labels = [ // optional. Change button labels (showing defaults)
36 | 'default' => '%d',
37 | 'first' => '« %d',
38 | 'previous' => '‹ %d',
39 | 'current' => '· %d ·',
40 | 'next' => '%d ›',
41 | 'last' => '%d »',
42 | ];
43 |
44 | // optional. Change the callback_data format, adding placeholders for data (showing default)
45 | $callbackDataFormat = 'command={COMMAND}&oldPage={OLD_PAGE}&newPage={NEW_PAGE}'
46 | ```
47 |
48 | ### How To Use
49 |
50 | ```php
51 | // Define inline keyboard pagination.
52 | $ikp = new InlineKeyboardPagination($items, $command);
53 | $ikp->setMaxButtons(7, true); // Second parameter set to always show 7 buttons if possible.
54 | $ikp->setLabels($labels);
55 | $ikp->setCallbackDataFormat($callbackDataFormat);
56 |
57 | // Get pagination.
58 | $pagination = $ikp->getPagination($selectedPage);
59 |
60 | // or, in 2 steps.
61 | $ikp->setSelectedPage($selectedPage);
62 | $pagination = $ikp->getPagination();
63 | ```
64 |
65 | Now, `$pagination['keyboard']` is basically a row that contains the pagination.
66 |
67 | ```php
68 | // Use it in your request.
69 | if (!empty($pagination['keyboard'])) {
70 | //$pagination['keyboard'][0]['callback_data']; // command=testCommand&oldPage=10&newPage=1
71 | //$pagination['keyboard'][1]['callback_data']; // command=testCommand&oldPage=10&newPage=7
72 |
73 | ...
74 | $data['reply_markup'] = [
75 | 'inline_keyboard' => [
76 | $pagination['keyboard'],
77 | ],
78 | ];
79 | ...
80 | }
81 | ```
82 |
83 | To get the callback data, you can use the provided helper method (only works when using the default callback data format):
84 |
85 | ```php
86 | // e.g. Callback data.
87 | $callback_data = 'command=testCommand&oldPage=10&newPage=1';
88 |
89 | $params = InlineKeyboardPagination::getParametersFromCallbackData($callbackData);
90 |
91 | //$params = [
92 | // 'command' => 'testCommand',
93 | // 'oldPage' => '10',
94 | // 'newPage' => '1',
95 | //];
96 |
97 | // or, just use PHP directly if you like. (literally what the helper does!)
98 | parse_str($callbackData, $params);
99 | ```
100 |
101 | ## Code Quality
102 |
103 | Run the PHPUnit tests via Composer script.
104 |
105 | ```bash
106 | composer test
107 | ```
108 |
109 | ## License
110 |
111 | The MIT License (MIT). Please see [License File][license] for more information.
112 |
113 | Project based on [Telegram Bot Pagination][github-lartie-tbp] by [lartie][github-lartie].
114 |
115 |
116 | [github-tgbot-ikp]: https://github.com/php-telegram-bot/inline-keyboard-pagination "PHP Telegram Bot Inline Keyboard Pagination on GitHub"
117 | [packagist-tgbot-ikp]: https://packagist.org/packages/php-telegram-bot/inline-keyboard-pagination "PHP Telegram Bot Inline Keyboard Pagination on Packagist"
118 | [license]: https://github.com/php-telegram-bot/inline-keyboard-pagination/blob/master/LICENSE "PHP Telegram Bot Inline Keyboard Pagination license"
119 |
120 | [code-quality-badge]: https://img.shields.io/scrutinizer/g/php-telegram-bot/inline-keyboard-pagination.svg
121 | [code-quality]: https://scrutinizer-ci.com/g/php-telegram-bot/inline-keyboard-pagination/?branch=master "Code quality on Scrutinizer"
122 | [code-coverage-badge]: https://img.shields.io/codecov/c/github/php-telegram-bot/inline-keyboard-pagination.svg
123 | [code-coverage]: https://codecov.io/gh/php-telegram-bot/inline-keyboard-pagination "Code coverage on Codecov"
124 | [build-status-badge]: https://img.shields.io/travis/php-telegram-bot/inline-keyboard-pagination.svg
125 | [build-status]: https://travis-ci.com/php-telegram-bot/inline-keyboard-pagination "Build status on Travis-CI"
126 |
127 | [latest-version-badge]: https://img.shields.io/packagist/v/php-telegram-bot/inline-keyboard-pagination.svg
128 | [total-downloads-badge]: https://img.shields.io/packagist/dt/php-telegram-bot/inline-keyboard-pagination.svg
129 | [license-badge]: https://img.shields.io/packagist/l/php-telegram-bot/inline-keyboard-pagination.svg
130 |
131 | [github-lartie-tbp]: https://github.com/lartie/Telegram-Bot-Pagination "Telegram Bot Pagination by Lartie on GitHub"
132 | [github-lartie]: https://github.com/lartie "Lartie on GitHub"
133 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "php-telegram-bot/inline-keyboard-pagination",
3 | "type": "library",
4 | "description": "PHP Telegram Bot InlineKeyboard Pagination",
5 | "keywords": ["telegram", "bot", "inline", "keyboard", "pagination", "callback", "query"],
6 | "license": "MIT",
7 | "homepage": "https://github.com/php-telegram-bot/inline-keyboard-pagination",
8 | "support": {
9 | "issues": "https://github.com/php-telegram-bot/inline-keyboard-pagination/issues",
10 | "source": "https://github.com/php-telegram-bot/inline-keyboard-pagination"
11 | },
12 | "authors": [
13 | {
14 | "name": "Armando Lüscher",
15 | "email": "armando@noplanman.ch",
16 | "homepage": "https://noplanman.ch",
17 | "role": "Developer"
18 | },
19 | {
20 | "name": "Artie",
21 | "email": "log.wil.log@gmail.com",
22 | "homepage": "https://github.com/lartie",
23 | "role": "Original developer"
24 | }
25 | ],
26 | "require": {
27 | "php": "^7.4|^8.0"
28 | },
29 | "require-dev": {
30 | "php-parallel-lint/php-parallel-lint": "^1.3",
31 | "phpunit/phpunit": "^9.5",
32 | "squizlabs/php_codesniffer": "^3.6"
33 | },
34 | "autoload": {
35 | "psr-4": {
36 | "TelegramBot\\InlineKeyboardPagination\\": "src"
37 | }
38 | },
39 | "autoload-dev": {
40 | "psr-4": {
41 | "TelegramBot\\InlineKeyboardPagination\\Tests\\": "tests"
42 | }
43 | },
44 | "scripts": {
45 | "check-code": [
46 | "vendor/bin/parallel-lint . --exclude vendor",
47 | "vendor/bin/phpcs"
48 | ],
49 | "test": [
50 | "vendor/bin/phpunit"
51 | ],
52 | "test-cov": [
53 | "@putenv XDEBUG_MODE=coverage",
54 | "vendor/bin/phpunit --coverage-clover coverage.xml"
55 | ],
56 | "test-cov-upload": [
57 | "curl -s https://codecov.io/bash | bash"
58 | ]
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/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": "c183adbe8af902616e4294de1b0dfd8c",
8 | "packages": [],
9 | "packages-dev": [
10 | {
11 | "name": "doctrine/instantiator",
12 | "version": "1.4.0",
13 | "source": {
14 | "type": "git",
15 | "url": "https://github.com/doctrine/instantiator.git",
16 | "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b"
17 | },
18 | "dist": {
19 | "type": "zip",
20 | "url": "https://api.github.com/repos/doctrine/instantiator/zipball/d56bf6102915de5702778fe20f2de3b2fe570b5b",
21 | "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b",
22 | "shasum": ""
23 | },
24 | "require": {
25 | "php": "^7.1 || ^8.0"
26 | },
27 | "require-dev": {
28 | "doctrine/coding-standard": "^8.0",
29 | "ext-pdo": "*",
30 | "ext-phar": "*",
31 | "phpbench/phpbench": "^0.13 || 1.0.0-alpha2",
32 | "phpstan/phpstan": "^0.12",
33 | "phpstan/phpstan-phpunit": "^0.12",
34 | "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0"
35 | },
36 | "type": "library",
37 | "autoload": {
38 | "psr-4": {
39 | "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/"
40 | }
41 | },
42 | "notification-url": "https://packagist.org/downloads/",
43 | "license": [
44 | "MIT"
45 | ],
46 | "authors": [
47 | {
48 | "name": "Marco Pivetta",
49 | "email": "ocramius@gmail.com",
50 | "homepage": "https://ocramius.github.io/"
51 | }
52 | ],
53 | "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors",
54 | "homepage": "https://www.doctrine-project.org/projects/instantiator.html",
55 | "keywords": [
56 | "constructor",
57 | "instantiate"
58 | ],
59 | "support": {
60 | "issues": "https://github.com/doctrine/instantiator/issues",
61 | "source": "https://github.com/doctrine/instantiator/tree/1.4.0"
62 | },
63 | "funding": [
64 | {
65 | "url": "https://www.doctrine-project.org/sponsorship.html",
66 | "type": "custom"
67 | },
68 | {
69 | "url": "https://www.patreon.com/phpdoctrine",
70 | "type": "patreon"
71 | },
72 | {
73 | "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator",
74 | "type": "tidelift"
75 | }
76 | ],
77 | "time": "2020-11-10T18:47:58+00:00"
78 | },
79 | {
80 | "name": "myclabs/deep-copy",
81 | "version": "1.10.2",
82 | "source": {
83 | "type": "git",
84 | "url": "https://github.com/myclabs/DeepCopy.git",
85 | "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220"
86 | },
87 | "dist": {
88 | "type": "zip",
89 | "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/776f831124e9c62e1a2c601ecc52e776d8bb7220",
90 | "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220",
91 | "shasum": ""
92 | },
93 | "require": {
94 | "php": "^7.1 || ^8.0"
95 | },
96 | "replace": {
97 | "myclabs/deep-copy": "self.version"
98 | },
99 | "require-dev": {
100 | "doctrine/collections": "^1.0",
101 | "doctrine/common": "^2.6",
102 | "phpunit/phpunit": "^7.1"
103 | },
104 | "type": "library",
105 | "autoload": {
106 | "psr-4": {
107 | "DeepCopy\\": "src/DeepCopy/"
108 | },
109 | "files": [
110 | "src/DeepCopy/deep_copy.php"
111 | ]
112 | },
113 | "notification-url": "https://packagist.org/downloads/",
114 | "license": [
115 | "MIT"
116 | ],
117 | "description": "Create deep copies (clones) of your objects",
118 | "keywords": [
119 | "clone",
120 | "copy",
121 | "duplicate",
122 | "object",
123 | "object graph"
124 | ],
125 | "support": {
126 | "issues": "https://github.com/myclabs/DeepCopy/issues",
127 | "source": "https://github.com/myclabs/DeepCopy/tree/1.10.2"
128 | },
129 | "funding": [
130 | {
131 | "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy",
132 | "type": "tidelift"
133 | }
134 | ],
135 | "time": "2020-11-13T09:40:50+00:00"
136 | },
137 | {
138 | "name": "nikic/php-parser",
139 | "version": "v4.11.0",
140 | "source": {
141 | "type": "git",
142 | "url": "https://github.com/nikic/PHP-Parser.git",
143 | "reference": "fe14cf3672a149364fb66dfe11bf6549af899f94"
144 | },
145 | "dist": {
146 | "type": "zip",
147 | "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/fe14cf3672a149364fb66dfe11bf6549af899f94",
148 | "reference": "fe14cf3672a149364fb66dfe11bf6549af899f94",
149 | "shasum": ""
150 | },
151 | "require": {
152 | "ext-tokenizer": "*",
153 | "php": ">=7.0"
154 | },
155 | "require-dev": {
156 | "ircmaxell/php-yacc": "^0.0.7",
157 | "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0"
158 | },
159 | "bin": [
160 | "bin/php-parse"
161 | ],
162 | "type": "library",
163 | "extra": {
164 | "branch-alias": {
165 | "dev-master": "4.9-dev"
166 | }
167 | },
168 | "autoload": {
169 | "psr-4": {
170 | "PhpParser\\": "lib/PhpParser"
171 | }
172 | },
173 | "notification-url": "https://packagist.org/downloads/",
174 | "license": [
175 | "BSD-3-Clause"
176 | ],
177 | "authors": [
178 | {
179 | "name": "Nikita Popov"
180 | }
181 | ],
182 | "description": "A PHP parser written in PHP",
183 | "keywords": [
184 | "parser",
185 | "php"
186 | ],
187 | "support": {
188 | "issues": "https://github.com/nikic/PHP-Parser/issues",
189 | "source": "https://github.com/nikic/PHP-Parser/tree/v4.11.0"
190 | },
191 | "time": "2021-07-03T13:36:55+00:00"
192 | },
193 | {
194 | "name": "phar-io/manifest",
195 | "version": "2.0.1",
196 | "source": {
197 | "type": "git",
198 | "url": "https://github.com/phar-io/manifest.git",
199 | "reference": "85265efd3af7ba3ca4b2a2c34dbfc5788dd29133"
200 | },
201 | "dist": {
202 | "type": "zip",
203 | "url": "https://api.github.com/repos/phar-io/manifest/zipball/85265efd3af7ba3ca4b2a2c34dbfc5788dd29133",
204 | "reference": "85265efd3af7ba3ca4b2a2c34dbfc5788dd29133",
205 | "shasum": ""
206 | },
207 | "require": {
208 | "ext-dom": "*",
209 | "ext-phar": "*",
210 | "ext-xmlwriter": "*",
211 | "phar-io/version": "^3.0.1",
212 | "php": "^7.2 || ^8.0"
213 | },
214 | "type": "library",
215 | "extra": {
216 | "branch-alias": {
217 | "dev-master": "2.0.x-dev"
218 | }
219 | },
220 | "autoload": {
221 | "classmap": [
222 | "src/"
223 | ]
224 | },
225 | "notification-url": "https://packagist.org/downloads/",
226 | "license": [
227 | "BSD-3-Clause"
228 | ],
229 | "authors": [
230 | {
231 | "name": "Arne Blankerts",
232 | "email": "arne@blankerts.de",
233 | "role": "Developer"
234 | },
235 | {
236 | "name": "Sebastian Heuer",
237 | "email": "sebastian@phpeople.de",
238 | "role": "Developer"
239 | },
240 | {
241 | "name": "Sebastian Bergmann",
242 | "email": "sebastian@phpunit.de",
243 | "role": "Developer"
244 | }
245 | ],
246 | "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)",
247 | "support": {
248 | "issues": "https://github.com/phar-io/manifest/issues",
249 | "source": "https://github.com/phar-io/manifest/tree/master"
250 | },
251 | "time": "2020-06-27T14:33:11+00:00"
252 | },
253 | {
254 | "name": "phar-io/version",
255 | "version": "3.1.0",
256 | "source": {
257 | "type": "git",
258 | "url": "https://github.com/phar-io/version.git",
259 | "reference": "bae7c545bef187884426f042434e561ab1ddb182"
260 | },
261 | "dist": {
262 | "type": "zip",
263 | "url": "https://api.github.com/repos/phar-io/version/zipball/bae7c545bef187884426f042434e561ab1ddb182",
264 | "reference": "bae7c545bef187884426f042434e561ab1ddb182",
265 | "shasum": ""
266 | },
267 | "require": {
268 | "php": "^7.2 || ^8.0"
269 | },
270 | "type": "library",
271 | "autoload": {
272 | "classmap": [
273 | "src/"
274 | ]
275 | },
276 | "notification-url": "https://packagist.org/downloads/",
277 | "license": [
278 | "BSD-3-Clause"
279 | ],
280 | "authors": [
281 | {
282 | "name": "Arne Blankerts",
283 | "email": "arne@blankerts.de",
284 | "role": "Developer"
285 | },
286 | {
287 | "name": "Sebastian Heuer",
288 | "email": "sebastian@phpeople.de",
289 | "role": "Developer"
290 | },
291 | {
292 | "name": "Sebastian Bergmann",
293 | "email": "sebastian@phpunit.de",
294 | "role": "Developer"
295 | }
296 | ],
297 | "description": "Library for handling version information and constraints",
298 | "support": {
299 | "issues": "https://github.com/phar-io/version/issues",
300 | "source": "https://github.com/phar-io/version/tree/3.1.0"
301 | },
302 | "time": "2021-02-23T14:00:09+00:00"
303 | },
304 | {
305 | "name": "php-parallel-lint/php-parallel-lint",
306 | "version": "v1.3.0",
307 | "source": {
308 | "type": "git",
309 | "url": "https://github.com/php-parallel-lint/PHP-Parallel-Lint.git",
310 | "reference": "772a954e5f119f6f5871d015b23eabed8cbdadfb"
311 | },
312 | "dist": {
313 | "type": "zip",
314 | "url": "https://api.github.com/repos/php-parallel-lint/PHP-Parallel-Lint/zipball/772a954e5f119f6f5871d015b23eabed8cbdadfb",
315 | "reference": "772a954e5f119f6f5871d015b23eabed8cbdadfb",
316 | "shasum": ""
317 | },
318 | "require": {
319 | "ext-json": "*",
320 | "php": ">=5.3.0"
321 | },
322 | "replace": {
323 | "grogy/php-parallel-lint": "*",
324 | "jakub-onderka/php-parallel-lint": "*"
325 | },
326 | "require-dev": {
327 | "nette/tester": "^1.3 || ^2.0",
328 | "php-parallel-lint/php-console-highlighter": "~0.3",
329 | "squizlabs/php_codesniffer": "^3.5"
330 | },
331 | "suggest": {
332 | "php-parallel-lint/php-console-highlighter": "Highlight syntax in code snippet"
333 | },
334 | "bin": [
335 | "parallel-lint"
336 | ],
337 | "type": "library",
338 | "autoload": {
339 | "classmap": [
340 | "./"
341 | ]
342 | },
343 | "notification-url": "https://packagist.org/downloads/",
344 | "license": [
345 | "BSD-2-Clause"
346 | ],
347 | "authors": [
348 | {
349 | "name": "Jakub Onderka",
350 | "email": "ahoj@jakubonderka.cz"
351 | }
352 | ],
353 | "description": "This tool check syntax of PHP files about 20x faster than serial check.",
354 | "homepage": "https://github.com/php-parallel-lint/PHP-Parallel-Lint",
355 | "support": {
356 | "issues": "https://github.com/php-parallel-lint/PHP-Parallel-Lint/issues",
357 | "source": "https://github.com/php-parallel-lint/PHP-Parallel-Lint/tree/v1.3.0"
358 | },
359 | "time": "2021-04-07T14:42:48+00:00"
360 | },
361 | {
362 | "name": "phpdocumentor/reflection-common",
363 | "version": "2.2.0",
364 | "source": {
365 | "type": "git",
366 | "url": "https://github.com/phpDocumentor/ReflectionCommon.git",
367 | "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b"
368 | },
369 | "dist": {
370 | "type": "zip",
371 | "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b",
372 | "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b",
373 | "shasum": ""
374 | },
375 | "require": {
376 | "php": "^7.2 || ^8.0"
377 | },
378 | "type": "library",
379 | "extra": {
380 | "branch-alias": {
381 | "dev-2.x": "2.x-dev"
382 | }
383 | },
384 | "autoload": {
385 | "psr-4": {
386 | "phpDocumentor\\Reflection\\": "src/"
387 | }
388 | },
389 | "notification-url": "https://packagist.org/downloads/",
390 | "license": [
391 | "MIT"
392 | ],
393 | "authors": [
394 | {
395 | "name": "Jaap van Otterdijk",
396 | "email": "opensource@ijaap.nl"
397 | }
398 | ],
399 | "description": "Common reflection classes used by phpdocumentor to reflect the code structure",
400 | "homepage": "http://www.phpdoc.org",
401 | "keywords": [
402 | "FQSEN",
403 | "phpDocumentor",
404 | "phpdoc",
405 | "reflection",
406 | "static analysis"
407 | ],
408 | "support": {
409 | "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues",
410 | "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x"
411 | },
412 | "time": "2020-06-27T09:03:43+00:00"
413 | },
414 | {
415 | "name": "phpdocumentor/reflection-docblock",
416 | "version": "5.2.2",
417 | "source": {
418 | "type": "git",
419 | "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
420 | "reference": "069a785b2141f5bcf49f3e353548dc1cce6df556"
421 | },
422 | "dist": {
423 | "type": "zip",
424 | "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/069a785b2141f5bcf49f3e353548dc1cce6df556",
425 | "reference": "069a785b2141f5bcf49f3e353548dc1cce6df556",
426 | "shasum": ""
427 | },
428 | "require": {
429 | "ext-filter": "*",
430 | "php": "^7.2 || ^8.0",
431 | "phpdocumentor/reflection-common": "^2.2",
432 | "phpdocumentor/type-resolver": "^1.3",
433 | "webmozart/assert": "^1.9.1"
434 | },
435 | "require-dev": {
436 | "mockery/mockery": "~1.3.2"
437 | },
438 | "type": "library",
439 | "extra": {
440 | "branch-alias": {
441 | "dev-master": "5.x-dev"
442 | }
443 | },
444 | "autoload": {
445 | "psr-4": {
446 | "phpDocumentor\\Reflection\\": "src"
447 | }
448 | },
449 | "notification-url": "https://packagist.org/downloads/",
450 | "license": [
451 | "MIT"
452 | ],
453 | "authors": [
454 | {
455 | "name": "Mike van Riel",
456 | "email": "me@mikevanriel.com"
457 | },
458 | {
459 | "name": "Jaap van Otterdijk",
460 | "email": "account@ijaap.nl"
461 | }
462 | ],
463 | "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.",
464 | "support": {
465 | "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues",
466 | "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/master"
467 | },
468 | "time": "2020-09-03T19:13:55+00:00"
469 | },
470 | {
471 | "name": "phpdocumentor/type-resolver",
472 | "version": "1.4.0",
473 | "source": {
474 | "type": "git",
475 | "url": "https://github.com/phpDocumentor/TypeResolver.git",
476 | "reference": "6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0"
477 | },
478 | "dist": {
479 | "type": "zip",
480 | "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0",
481 | "reference": "6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0",
482 | "shasum": ""
483 | },
484 | "require": {
485 | "php": "^7.2 || ^8.0",
486 | "phpdocumentor/reflection-common": "^2.0"
487 | },
488 | "require-dev": {
489 | "ext-tokenizer": "*"
490 | },
491 | "type": "library",
492 | "extra": {
493 | "branch-alias": {
494 | "dev-1.x": "1.x-dev"
495 | }
496 | },
497 | "autoload": {
498 | "psr-4": {
499 | "phpDocumentor\\Reflection\\": "src"
500 | }
501 | },
502 | "notification-url": "https://packagist.org/downloads/",
503 | "license": [
504 | "MIT"
505 | ],
506 | "authors": [
507 | {
508 | "name": "Mike van Riel",
509 | "email": "me@mikevanriel.com"
510 | }
511 | ],
512 | "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names",
513 | "support": {
514 | "issues": "https://github.com/phpDocumentor/TypeResolver/issues",
515 | "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.4.0"
516 | },
517 | "time": "2020-09-17T18:55:26+00:00"
518 | },
519 | {
520 | "name": "phpspec/prophecy",
521 | "version": "1.13.0",
522 | "source": {
523 | "type": "git",
524 | "url": "https://github.com/phpspec/prophecy.git",
525 | "reference": "be1996ed8adc35c3fd795488a653f4b518be70ea"
526 | },
527 | "dist": {
528 | "type": "zip",
529 | "url": "https://api.github.com/repos/phpspec/prophecy/zipball/be1996ed8adc35c3fd795488a653f4b518be70ea",
530 | "reference": "be1996ed8adc35c3fd795488a653f4b518be70ea",
531 | "shasum": ""
532 | },
533 | "require": {
534 | "doctrine/instantiator": "^1.2",
535 | "php": "^7.2 || ~8.0, <8.1",
536 | "phpdocumentor/reflection-docblock": "^5.2",
537 | "sebastian/comparator": "^3.0 || ^4.0",
538 | "sebastian/recursion-context": "^3.0 || ^4.0"
539 | },
540 | "require-dev": {
541 | "phpspec/phpspec": "^6.0",
542 | "phpunit/phpunit": "^8.0 || ^9.0"
543 | },
544 | "type": "library",
545 | "extra": {
546 | "branch-alias": {
547 | "dev-master": "1.11.x-dev"
548 | }
549 | },
550 | "autoload": {
551 | "psr-4": {
552 | "Prophecy\\": "src/Prophecy"
553 | }
554 | },
555 | "notification-url": "https://packagist.org/downloads/",
556 | "license": [
557 | "MIT"
558 | ],
559 | "authors": [
560 | {
561 | "name": "Konstantin Kudryashov",
562 | "email": "ever.zet@gmail.com",
563 | "homepage": "http://everzet.com"
564 | },
565 | {
566 | "name": "Marcello Duarte",
567 | "email": "marcello.duarte@gmail.com"
568 | }
569 | ],
570 | "description": "Highly opinionated mocking framework for PHP 5.3+",
571 | "homepage": "https://github.com/phpspec/prophecy",
572 | "keywords": [
573 | "Double",
574 | "Dummy",
575 | "fake",
576 | "mock",
577 | "spy",
578 | "stub"
579 | ],
580 | "support": {
581 | "issues": "https://github.com/phpspec/prophecy/issues",
582 | "source": "https://github.com/phpspec/prophecy/tree/1.13.0"
583 | },
584 | "time": "2021-03-17T13:42:18+00:00"
585 | },
586 | {
587 | "name": "phpunit/php-code-coverage",
588 | "version": "9.2.6",
589 | "source": {
590 | "type": "git",
591 | "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
592 | "reference": "f6293e1b30a2354e8428e004689671b83871edde"
593 | },
594 | "dist": {
595 | "type": "zip",
596 | "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/f6293e1b30a2354e8428e004689671b83871edde",
597 | "reference": "f6293e1b30a2354e8428e004689671b83871edde",
598 | "shasum": ""
599 | },
600 | "require": {
601 | "ext-dom": "*",
602 | "ext-libxml": "*",
603 | "ext-xmlwriter": "*",
604 | "nikic/php-parser": "^4.10.2",
605 | "php": ">=7.3",
606 | "phpunit/php-file-iterator": "^3.0.3",
607 | "phpunit/php-text-template": "^2.0.2",
608 | "sebastian/code-unit-reverse-lookup": "^2.0.2",
609 | "sebastian/complexity": "^2.0",
610 | "sebastian/environment": "^5.1.2",
611 | "sebastian/lines-of-code": "^1.0.3",
612 | "sebastian/version": "^3.0.1",
613 | "theseer/tokenizer": "^1.2.0"
614 | },
615 | "require-dev": {
616 | "phpunit/phpunit": "^9.3"
617 | },
618 | "suggest": {
619 | "ext-pcov": "*",
620 | "ext-xdebug": "*"
621 | },
622 | "type": "library",
623 | "extra": {
624 | "branch-alias": {
625 | "dev-master": "9.2-dev"
626 | }
627 | },
628 | "autoload": {
629 | "classmap": [
630 | "src/"
631 | ]
632 | },
633 | "notification-url": "https://packagist.org/downloads/",
634 | "license": [
635 | "BSD-3-Clause"
636 | ],
637 | "authors": [
638 | {
639 | "name": "Sebastian Bergmann",
640 | "email": "sebastian@phpunit.de",
641 | "role": "lead"
642 | }
643 | ],
644 | "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.",
645 | "homepage": "https://github.com/sebastianbergmann/php-code-coverage",
646 | "keywords": [
647 | "coverage",
648 | "testing",
649 | "xunit"
650 | ],
651 | "support": {
652 | "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues",
653 | "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.6"
654 | },
655 | "funding": [
656 | {
657 | "url": "https://github.com/sebastianbergmann",
658 | "type": "github"
659 | }
660 | ],
661 | "time": "2021-03-28T07:26:59+00:00"
662 | },
663 | {
664 | "name": "phpunit/php-file-iterator",
665 | "version": "3.0.5",
666 | "source": {
667 | "type": "git",
668 | "url": "https://github.com/sebastianbergmann/php-file-iterator.git",
669 | "reference": "aa4be8575f26070b100fccb67faabb28f21f66f8"
670 | },
671 | "dist": {
672 | "type": "zip",
673 | "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/aa4be8575f26070b100fccb67faabb28f21f66f8",
674 | "reference": "aa4be8575f26070b100fccb67faabb28f21f66f8",
675 | "shasum": ""
676 | },
677 | "require": {
678 | "php": ">=7.3"
679 | },
680 | "require-dev": {
681 | "phpunit/phpunit": "^9.3"
682 | },
683 | "type": "library",
684 | "extra": {
685 | "branch-alias": {
686 | "dev-master": "3.0-dev"
687 | }
688 | },
689 | "autoload": {
690 | "classmap": [
691 | "src/"
692 | ]
693 | },
694 | "notification-url": "https://packagist.org/downloads/",
695 | "license": [
696 | "BSD-3-Clause"
697 | ],
698 | "authors": [
699 | {
700 | "name": "Sebastian Bergmann",
701 | "email": "sebastian@phpunit.de",
702 | "role": "lead"
703 | }
704 | ],
705 | "description": "FilterIterator implementation that filters files based on a list of suffixes.",
706 | "homepage": "https://github.com/sebastianbergmann/php-file-iterator/",
707 | "keywords": [
708 | "filesystem",
709 | "iterator"
710 | ],
711 | "support": {
712 | "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues",
713 | "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.5"
714 | },
715 | "funding": [
716 | {
717 | "url": "https://github.com/sebastianbergmann",
718 | "type": "github"
719 | }
720 | ],
721 | "time": "2020-09-28T05:57:25+00:00"
722 | },
723 | {
724 | "name": "phpunit/php-invoker",
725 | "version": "3.1.1",
726 | "source": {
727 | "type": "git",
728 | "url": "https://github.com/sebastianbergmann/php-invoker.git",
729 | "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67"
730 | },
731 | "dist": {
732 | "type": "zip",
733 | "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/5a10147d0aaf65b58940a0b72f71c9ac0423cc67",
734 | "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67",
735 | "shasum": ""
736 | },
737 | "require": {
738 | "php": ">=7.3"
739 | },
740 | "require-dev": {
741 | "ext-pcntl": "*",
742 | "phpunit/phpunit": "^9.3"
743 | },
744 | "suggest": {
745 | "ext-pcntl": "*"
746 | },
747 | "type": "library",
748 | "extra": {
749 | "branch-alias": {
750 | "dev-master": "3.1-dev"
751 | }
752 | },
753 | "autoload": {
754 | "classmap": [
755 | "src/"
756 | ]
757 | },
758 | "notification-url": "https://packagist.org/downloads/",
759 | "license": [
760 | "BSD-3-Clause"
761 | ],
762 | "authors": [
763 | {
764 | "name": "Sebastian Bergmann",
765 | "email": "sebastian@phpunit.de",
766 | "role": "lead"
767 | }
768 | ],
769 | "description": "Invoke callables with a timeout",
770 | "homepage": "https://github.com/sebastianbergmann/php-invoker/",
771 | "keywords": [
772 | "process"
773 | ],
774 | "support": {
775 | "issues": "https://github.com/sebastianbergmann/php-invoker/issues",
776 | "source": "https://github.com/sebastianbergmann/php-invoker/tree/3.1.1"
777 | },
778 | "funding": [
779 | {
780 | "url": "https://github.com/sebastianbergmann",
781 | "type": "github"
782 | }
783 | ],
784 | "time": "2020-09-28T05:58:55+00:00"
785 | },
786 | {
787 | "name": "phpunit/php-text-template",
788 | "version": "2.0.4",
789 | "source": {
790 | "type": "git",
791 | "url": "https://github.com/sebastianbergmann/php-text-template.git",
792 | "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28"
793 | },
794 | "dist": {
795 | "type": "zip",
796 | "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28",
797 | "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28",
798 | "shasum": ""
799 | },
800 | "require": {
801 | "php": ">=7.3"
802 | },
803 | "require-dev": {
804 | "phpunit/phpunit": "^9.3"
805 | },
806 | "type": "library",
807 | "extra": {
808 | "branch-alias": {
809 | "dev-master": "2.0-dev"
810 | }
811 | },
812 | "autoload": {
813 | "classmap": [
814 | "src/"
815 | ]
816 | },
817 | "notification-url": "https://packagist.org/downloads/",
818 | "license": [
819 | "BSD-3-Clause"
820 | ],
821 | "authors": [
822 | {
823 | "name": "Sebastian Bergmann",
824 | "email": "sebastian@phpunit.de",
825 | "role": "lead"
826 | }
827 | ],
828 | "description": "Simple template engine.",
829 | "homepage": "https://github.com/sebastianbergmann/php-text-template/",
830 | "keywords": [
831 | "template"
832 | ],
833 | "support": {
834 | "issues": "https://github.com/sebastianbergmann/php-text-template/issues",
835 | "source": "https://github.com/sebastianbergmann/php-text-template/tree/2.0.4"
836 | },
837 | "funding": [
838 | {
839 | "url": "https://github.com/sebastianbergmann",
840 | "type": "github"
841 | }
842 | ],
843 | "time": "2020-10-26T05:33:50+00:00"
844 | },
845 | {
846 | "name": "phpunit/php-timer",
847 | "version": "5.0.3",
848 | "source": {
849 | "type": "git",
850 | "url": "https://github.com/sebastianbergmann/php-timer.git",
851 | "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2"
852 | },
853 | "dist": {
854 | "type": "zip",
855 | "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2",
856 | "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2",
857 | "shasum": ""
858 | },
859 | "require": {
860 | "php": ">=7.3"
861 | },
862 | "require-dev": {
863 | "phpunit/phpunit": "^9.3"
864 | },
865 | "type": "library",
866 | "extra": {
867 | "branch-alias": {
868 | "dev-master": "5.0-dev"
869 | }
870 | },
871 | "autoload": {
872 | "classmap": [
873 | "src/"
874 | ]
875 | },
876 | "notification-url": "https://packagist.org/downloads/",
877 | "license": [
878 | "BSD-3-Clause"
879 | ],
880 | "authors": [
881 | {
882 | "name": "Sebastian Bergmann",
883 | "email": "sebastian@phpunit.de",
884 | "role": "lead"
885 | }
886 | ],
887 | "description": "Utility class for timing",
888 | "homepage": "https://github.com/sebastianbergmann/php-timer/",
889 | "keywords": [
890 | "timer"
891 | ],
892 | "support": {
893 | "issues": "https://github.com/sebastianbergmann/php-timer/issues",
894 | "source": "https://github.com/sebastianbergmann/php-timer/tree/5.0.3"
895 | },
896 | "funding": [
897 | {
898 | "url": "https://github.com/sebastianbergmann",
899 | "type": "github"
900 | }
901 | ],
902 | "time": "2020-10-26T13:16:10+00:00"
903 | },
904 | {
905 | "name": "phpunit/phpunit",
906 | "version": "9.5.6",
907 | "source": {
908 | "type": "git",
909 | "url": "https://github.com/sebastianbergmann/phpunit.git",
910 | "reference": "fb9b8333f14e3dce976a60ef6a7e05c7c7ed8bfb"
911 | },
912 | "dist": {
913 | "type": "zip",
914 | "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/fb9b8333f14e3dce976a60ef6a7e05c7c7ed8bfb",
915 | "reference": "fb9b8333f14e3dce976a60ef6a7e05c7c7ed8bfb",
916 | "shasum": ""
917 | },
918 | "require": {
919 | "doctrine/instantiator": "^1.3.1",
920 | "ext-dom": "*",
921 | "ext-json": "*",
922 | "ext-libxml": "*",
923 | "ext-mbstring": "*",
924 | "ext-xml": "*",
925 | "ext-xmlwriter": "*",
926 | "myclabs/deep-copy": "^1.10.1",
927 | "phar-io/manifest": "^2.0.1",
928 | "phar-io/version": "^3.0.2",
929 | "php": ">=7.3",
930 | "phpspec/prophecy": "^1.12.1",
931 | "phpunit/php-code-coverage": "^9.2.3",
932 | "phpunit/php-file-iterator": "^3.0.5",
933 | "phpunit/php-invoker": "^3.1.1",
934 | "phpunit/php-text-template": "^2.0.3",
935 | "phpunit/php-timer": "^5.0.2",
936 | "sebastian/cli-parser": "^1.0.1",
937 | "sebastian/code-unit": "^1.0.6",
938 | "sebastian/comparator": "^4.0.5",
939 | "sebastian/diff": "^4.0.3",
940 | "sebastian/environment": "^5.1.3",
941 | "sebastian/exporter": "^4.0.3",
942 | "sebastian/global-state": "^5.0.1",
943 | "sebastian/object-enumerator": "^4.0.3",
944 | "sebastian/resource-operations": "^3.0.3",
945 | "sebastian/type": "^2.3.4",
946 | "sebastian/version": "^3.0.2"
947 | },
948 | "require-dev": {
949 | "ext-pdo": "*",
950 | "phpspec/prophecy-phpunit": "^2.0.1"
951 | },
952 | "suggest": {
953 | "ext-soap": "*",
954 | "ext-xdebug": "*"
955 | },
956 | "bin": [
957 | "phpunit"
958 | ],
959 | "type": "library",
960 | "extra": {
961 | "branch-alias": {
962 | "dev-master": "9.5-dev"
963 | }
964 | },
965 | "autoload": {
966 | "classmap": [
967 | "src/"
968 | ],
969 | "files": [
970 | "src/Framework/Assert/Functions.php"
971 | ]
972 | },
973 | "notification-url": "https://packagist.org/downloads/",
974 | "license": [
975 | "BSD-3-Clause"
976 | ],
977 | "authors": [
978 | {
979 | "name": "Sebastian Bergmann",
980 | "email": "sebastian@phpunit.de",
981 | "role": "lead"
982 | }
983 | ],
984 | "description": "The PHP Unit Testing framework.",
985 | "homepage": "https://phpunit.de/",
986 | "keywords": [
987 | "phpunit",
988 | "testing",
989 | "xunit"
990 | ],
991 | "support": {
992 | "issues": "https://github.com/sebastianbergmann/phpunit/issues",
993 | "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.6"
994 | },
995 | "funding": [
996 | {
997 | "url": "https://phpunit.de/donate.html",
998 | "type": "custom"
999 | },
1000 | {
1001 | "url": "https://github.com/sebastianbergmann",
1002 | "type": "github"
1003 | }
1004 | ],
1005 | "time": "2021-06-23T05:14:38+00:00"
1006 | },
1007 | {
1008 | "name": "sebastian/cli-parser",
1009 | "version": "1.0.1",
1010 | "source": {
1011 | "type": "git",
1012 | "url": "https://github.com/sebastianbergmann/cli-parser.git",
1013 | "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2"
1014 | },
1015 | "dist": {
1016 | "type": "zip",
1017 | "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/442e7c7e687e42adc03470c7b668bc4b2402c0b2",
1018 | "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2",
1019 | "shasum": ""
1020 | },
1021 | "require": {
1022 | "php": ">=7.3"
1023 | },
1024 | "require-dev": {
1025 | "phpunit/phpunit": "^9.3"
1026 | },
1027 | "type": "library",
1028 | "extra": {
1029 | "branch-alias": {
1030 | "dev-master": "1.0-dev"
1031 | }
1032 | },
1033 | "autoload": {
1034 | "classmap": [
1035 | "src/"
1036 | ]
1037 | },
1038 | "notification-url": "https://packagist.org/downloads/",
1039 | "license": [
1040 | "BSD-3-Clause"
1041 | ],
1042 | "authors": [
1043 | {
1044 | "name": "Sebastian Bergmann",
1045 | "email": "sebastian@phpunit.de",
1046 | "role": "lead"
1047 | }
1048 | ],
1049 | "description": "Library for parsing CLI options",
1050 | "homepage": "https://github.com/sebastianbergmann/cli-parser",
1051 | "support": {
1052 | "issues": "https://github.com/sebastianbergmann/cli-parser/issues",
1053 | "source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.1"
1054 | },
1055 | "funding": [
1056 | {
1057 | "url": "https://github.com/sebastianbergmann",
1058 | "type": "github"
1059 | }
1060 | ],
1061 | "time": "2020-09-28T06:08:49+00:00"
1062 | },
1063 | {
1064 | "name": "sebastian/code-unit",
1065 | "version": "1.0.8",
1066 | "source": {
1067 | "type": "git",
1068 | "url": "https://github.com/sebastianbergmann/code-unit.git",
1069 | "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120"
1070 | },
1071 | "dist": {
1072 | "type": "zip",
1073 | "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/1fc9f64c0927627ef78ba436c9b17d967e68e120",
1074 | "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120",
1075 | "shasum": ""
1076 | },
1077 | "require": {
1078 | "php": ">=7.3"
1079 | },
1080 | "require-dev": {
1081 | "phpunit/phpunit": "^9.3"
1082 | },
1083 | "type": "library",
1084 | "extra": {
1085 | "branch-alias": {
1086 | "dev-master": "1.0-dev"
1087 | }
1088 | },
1089 | "autoload": {
1090 | "classmap": [
1091 | "src/"
1092 | ]
1093 | },
1094 | "notification-url": "https://packagist.org/downloads/",
1095 | "license": [
1096 | "BSD-3-Clause"
1097 | ],
1098 | "authors": [
1099 | {
1100 | "name": "Sebastian Bergmann",
1101 | "email": "sebastian@phpunit.de",
1102 | "role": "lead"
1103 | }
1104 | ],
1105 | "description": "Collection of value objects that represent the PHP code units",
1106 | "homepage": "https://github.com/sebastianbergmann/code-unit",
1107 | "support": {
1108 | "issues": "https://github.com/sebastianbergmann/code-unit/issues",
1109 | "source": "https://github.com/sebastianbergmann/code-unit/tree/1.0.8"
1110 | },
1111 | "funding": [
1112 | {
1113 | "url": "https://github.com/sebastianbergmann",
1114 | "type": "github"
1115 | }
1116 | ],
1117 | "time": "2020-10-26T13:08:54+00:00"
1118 | },
1119 | {
1120 | "name": "sebastian/code-unit-reverse-lookup",
1121 | "version": "2.0.3",
1122 | "source": {
1123 | "type": "git",
1124 | "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git",
1125 | "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5"
1126 | },
1127 | "dist": {
1128 | "type": "zip",
1129 | "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5",
1130 | "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5",
1131 | "shasum": ""
1132 | },
1133 | "require": {
1134 | "php": ">=7.3"
1135 | },
1136 | "require-dev": {
1137 | "phpunit/phpunit": "^9.3"
1138 | },
1139 | "type": "library",
1140 | "extra": {
1141 | "branch-alias": {
1142 | "dev-master": "2.0-dev"
1143 | }
1144 | },
1145 | "autoload": {
1146 | "classmap": [
1147 | "src/"
1148 | ]
1149 | },
1150 | "notification-url": "https://packagist.org/downloads/",
1151 | "license": [
1152 | "BSD-3-Clause"
1153 | ],
1154 | "authors": [
1155 | {
1156 | "name": "Sebastian Bergmann",
1157 | "email": "sebastian@phpunit.de"
1158 | }
1159 | ],
1160 | "description": "Looks up which function or method a line of code belongs to",
1161 | "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/",
1162 | "support": {
1163 | "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues",
1164 | "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/2.0.3"
1165 | },
1166 | "funding": [
1167 | {
1168 | "url": "https://github.com/sebastianbergmann",
1169 | "type": "github"
1170 | }
1171 | ],
1172 | "time": "2020-09-28T05:30:19+00:00"
1173 | },
1174 | {
1175 | "name": "sebastian/comparator",
1176 | "version": "4.0.6",
1177 | "source": {
1178 | "type": "git",
1179 | "url": "https://github.com/sebastianbergmann/comparator.git",
1180 | "reference": "55f4261989e546dc112258c7a75935a81a7ce382"
1181 | },
1182 | "dist": {
1183 | "type": "zip",
1184 | "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/55f4261989e546dc112258c7a75935a81a7ce382",
1185 | "reference": "55f4261989e546dc112258c7a75935a81a7ce382",
1186 | "shasum": ""
1187 | },
1188 | "require": {
1189 | "php": ">=7.3",
1190 | "sebastian/diff": "^4.0",
1191 | "sebastian/exporter": "^4.0"
1192 | },
1193 | "require-dev": {
1194 | "phpunit/phpunit": "^9.3"
1195 | },
1196 | "type": "library",
1197 | "extra": {
1198 | "branch-alias": {
1199 | "dev-master": "4.0-dev"
1200 | }
1201 | },
1202 | "autoload": {
1203 | "classmap": [
1204 | "src/"
1205 | ]
1206 | },
1207 | "notification-url": "https://packagist.org/downloads/",
1208 | "license": [
1209 | "BSD-3-Clause"
1210 | ],
1211 | "authors": [
1212 | {
1213 | "name": "Sebastian Bergmann",
1214 | "email": "sebastian@phpunit.de"
1215 | },
1216 | {
1217 | "name": "Jeff Welch",
1218 | "email": "whatthejeff@gmail.com"
1219 | },
1220 | {
1221 | "name": "Volker Dusch",
1222 | "email": "github@wallbash.com"
1223 | },
1224 | {
1225 | "name": "Bernhard Schussek",
1226 | "email": "bschussek@2bepublished.at"
1227 | }
1228 | ],
1229 | "description": "Provides the functionality to compare PHP values for equality",
1230 | "homepage": "https://github.com/sebastianbergmann/comparator",
1231 | "keywords": [
1232 | "comparator",
1233 | "compare",
1234 | "equality"
1235 | ],
1236 | "support": {
1237 | "issues": "https://github.com/sebastianbergmann/comparator/issues",
1238 | "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.6"
1239 | },
1240 | "funding": [
1241 | {
1242 | "url": "https://github.com/sebastianbergmann",
1243 | "type": "github"
1244 | }
1245 | ],
1246 | "time": "2020-10-26T15:49:45+00:00"
1247 | },
1248 | {
1249 | "name": "sebastian/complexity",
1250 | "version": "2.0.2",
1251 | "source": {
1252 | "type": "git",
1253 | "url": "https://github.com/sebastianbergmann/complexity.git",
1254 | "reference": "739b35e53379900cc9ac327b2147867b8b6efd88"
1255 | },
1256 | "dist": {
1257 | "type": "zip",
1258 | "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/739b35e53379900cc9ac327b2147867b8b6efd88",
1259 | "reference": "739b35e53379900cc9ac327b2147867b8b6efd88",
1260 | "shasum": ""
1261 | },
1262 | "require": {
1263 | "nikic/php-parser": "^4.7",
1264 | "php": ">=7.3"
1265 | },
1266 | "require-dev": {
1267 | "phpunit/phpunit": "^9.3"
1268 | },
1269 | "type": "library",
1270 | "extra": {
1271 | "branch-alias": {
1272 | "dev-master": "2.0-dev"
1273 | }
1274 | },
1275 | "autoload": {
1276 | "classmap": [
1277 | "src/"
1278 | ]
1279 | },
1280 | "notification-url": "https://packagist.org/downloads/",
1281 | "license": [
1282 | "BSD-3-Clause"
1283 | ],
1284 | "authors": [
1285 | {
1286 | "name": "Sebastian Bergmann",
1287 | "email": "sebastian@phpunit.de",
1288 | "role": "lead"
1289 | }
1290 | ],
1291 | "description": "Library for calculating the complexity of PHP code units",
1292 | "homepage": "https://github.com/sebastianbergmann/complexity",
1293 | "support": {
1294 | "issues": "https://github.com/sebastianbergmann/complexity/issues",
1295 | "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.2"
1296 | },
1297 | "funding": [
1298 | {
1299 | "url": "https://github.com/sebastianbergmann",
1300 | "type": "github"
1301 | }
1302 | ],
1303 | "time": "2020-10-26T15:52:27+00:00"
1304 | },
1305 | {
1306 | "name": "sebastian/diff",
1307 | "version": "4.0.4",
1308 | "source": {
1309 | "type": "git",
1310 | "url": "https://github.com/sebastianbergmann/diff.git",
1311 | "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d"
1312 | },
1313 | "dist": {
1314 | "type": "zip",
1315 | "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/3461e3fccc7cfdfc2720be910d3bd73c69be590d",
1316 | "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d",
1317 | "shasum": ""
1318 | },
1319 | "require": {
1320 | "php": ">=7.3"
1321 | },
1322 | "require-dev": {
1323 | "phpunit/phpunit": "^9.3",
1324 | "symfony/process": "^4.2 || ^5"
1325 | },
1326 | "type": "library",
1327 | "extra": {
1328 | "branch-alias": {
1329 | "dev-master": "4.0-dev"
1330 | }
1331 | },
1332 | "autoload": {
1333 | "classmap": [
1334 | "src/"
1335 | ]
1336 | },
1337 | "notification-url": "https://packagist.org/downloads/",
1338 | "license": [
1339 | "BSD-3-Clause"
1340 | ],
1341 | "authors": [
1342 | {
1343 | "name": "Sebastian Bergmann",
1344 | "email": "sebastian@phpunit.de"
1345 | },
1346 | {
1347 | "name": "Kore Nordmann",
1348 | "email": "mail@kore-nordmann.de"
1349 | }
1350 | ],
1351 | "description": "Diff implementation",
1352 | "homepage": "https://github.com/sebastianbergmann/diff",
1353 | "keywords": [
1354 | "diff",
1355 | "udiff",
1356 | "unidiff",
1357 | "unified diff"
1358 | ],
1359 | "support": {
1360 | "issues": "https://github.com/sebastianbergmann/diff/issues",
1361 | "source": "https://github.com/sebastianbergmann/diff/tree/4.0.4"
1362 | },
1363 | "funding": [
1364 | {
1365 | "url": "https://github.com/sebastianbergmann",
1366 | "type": "github"
1367 | }
1368 | ],
1369 | "time": "2020-10-26T13:10:38+00:00"
1370 | },
1371 | {
1372 | "name": "sebastian/environment",
1373 | "version": "5.1.3",
1374 | "source": {
1375 | "type": "git",
1376 | "url": "https://github.com/sebastianbergmann/environment.git",
1377 | "reference": "388b6ced16caa751030f6a69e588299fa09200ac"
1378 | },
1379 | "dist": {
1380 | "type": "zip",
1381 | "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/388b6ced16caa751030f6a69e588299fa09200ac",
1382 | "reference": "388b6ced16caa751030f6a69e588299fa09200ac",
1383 | "shasum": ""
1384 | },
1385 | "require": {
1386 | "php": ">=7.3"
1387 | },
1388 | "require-dev": {
1389 | "phpunit/phpunit": "^9.3"
1390 | },
1391 | "suggest": {
1392 | "ext-posix": "*"
1393 | },
1394 | "type": "library",
1395 | "extra": {
1396 | "branch-alias": {
1397 | "dev-master": "5.1-dev"
1398 | }
1399 | },
1400 | "autoload": {
1401 | "classmap": [
1402 | "src/"
1403 | ]
1404 | },
1405 | "notification-url": "https://packagist.org/downloads/",
1406 | "license": [
1407 | "BSD-3-Clause"
1408 | ],
1409 | "authors": [
1410 | {
1411 | "name": "Sebastian Bergmann",
1412 | "email": "sebastian@phpunit.de"
1413 | }
1414 | ],
1415 | "description": "Provides functionality to handle HHVM/PHP environments",
1416 | "homepage": "http://www.github.com/sebastianbergmann/environment",
1417 | "keywords": [
1418 | "Xdebug",
1419 | "environment",
1420 | "hhvm"
1421 | ],
1422 | "support": {
1423 | "issues": "https://github.com/sebastianbergmann/environment/issues",
1424 | "source": "https://github.com/sebastianbergmann/environment/tree/5.1.3"
1425 | },
1426 | "funding": [
1427 | {
1428 | "url": "https://github.com/sebastianbergmann",
1429 | "type": "github"
1430 | }
1431 | ],
1432 | "time": "2020-09-28T05:52:38+00:00"
1433 | },
1434 | {
1435 | "name": "sebastian/exporter",
1436 | "version": "4.0.3",
1437 | "source": {
1438 | "type": "git",
1439 | "url": "https://github.com/sebastianbergmann/exporter.git",
1440 | "reference": "d89cc98761b8cb5a1a235a6b703ae50d34080e65"
1441 | },
1442 | "dist": {
1443 | "type": "zip",
1444 | "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/d89cc98761b8cb5a1a235a6b703ae50d34080e65",
1445 | "reference": "d89cc98761b8cb5a1a235a6b703ae50d34080e65",
1446 | "shasum": ""
1447 | },
1448 | "require": {
1449 | "php": ">=7.3",
1450 | "sebastian/recursion-context": "^4.0"
1451 | },
1452 | "require-dev": {
1453 | "ext-mbstring": "*",
1454 | "phpunit/phpunit": "^9.3"
1455 | },
1456 | "type": "library",
1457 | "extra": {
1458 | "branch-alias": {
1459 | "dev-master": "4.0-dev"
1460 | }
1461 | },
1462 | "autoload": {
1463 | "classmap": [
1464 | "src/"
1465 | ]
1466 | },
1467 | "notification-url": "https://packagist.org/downloads/",
1468 | "license": [
1469 | "BSD-3-Clause"
1470 | ],
1471 | "authors": [
1472 | {
1473 | "name": "Sebastian Bergmann",
1474 | "email": "sebastian@phpunit.de"
1475 | },
1476 | {
1477 | "name": "Jeff Welch",
1478 | "email": "whatthejeff@gmail.com"
1479 | },
1480 | {
1481 | "name": "Volker Dusch",
1482 | "email": "github@wallbash.com"
1483 | },
1484 | {
1485 | "name": "Adam Harvey",
1486 | "email": "aharvey@php.net"
1487 | },
1488 | {
1489 | "name": "Bernhard Schussek",
1490 | "email": "bschussek@gmail.com"
1491 | }
1492 | ],
1493 | "description": "Provides the functionality to export PHP variables for visualization",
1494 | "homepage": "http://www.github.com/sebastianbergmann/exporter",
1495 | "keywords": [
1496 | "export",
1497 | "exporter"
1498 | ],
1499 | "support": {
1500 | "issues": "https://github.com/sebastianbergmann/exporter/issues",
1501 | "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.3"
1502 | },
1503 | "funding": [
1504 | {
1505 | "url": "https://github.com/sebastianbergmann",
1506 | "type": "github"
1507 | }
1508 | ],
1509 | "time": "2020-09-28T05:24:23+00:00"
1510 | },
1511 | {
1512 | "name": "sebastian/global-state",
1513 | "version": "5.0.3",
1514 | "source": {
1515 | "type": "git",
1516 | "url": "https://github.com/sebastianbergmann/global-state.git",
1517 | "reference": "23bd5951f7ff26f12d4e3242864df3e08dec4e49"
1518 | },
1519 | "dist": {
1520 | "type": "zip",
1521 | "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/23bd5951f7ff26f12d4e3242864df3e08dec4e49",
1522 | "reference": "23bd5951f7ff26f12d4e3242864df3e08dec4e49",
1523 | "shasum": ""
1524 | },
1525 | "require": {
1526 | "php": ">=7.3",
1527 | "sebastian/object-reflector": "^2.0",
1528 | "sebastian/recursion-context": "^4.0"
1529 | },
1530 | "require-dev": {
1531 | "ext-dom": "*",
1532 | "phpunit/phpunit": "^9.3"
1533 | },
1534 | "suggest": {
1535 | "ext-uopz": "*"
1536 | },
1537 | "type": "library",
1538 | "extra": {
1539 | "branch-alias": {
1540 | "dev-master": "5.0-dev"
1541 | }
1542 | },
1543 | "autoload": {
1544 | "classmap": [
1545 | "src/"
1546 | ]
1547 | },
1548 | "notification-url": "https://packagist.org/downloads/",
1549 | "license": [
1550 | "BSD-3-Clause"
1551 | ],
1552 | "authors": [
1553 | {
1554 | "name": "Sebastian Bergmann",
1555 | "email": "sebastian@phpunit.de"
1556 | }
1557 | ],
1558 | "description": "Snapshotting of global state",
1559 | "homepage": "http://www.github.com/sebastianbergmann/global-state",
1560 | "keywords": [
1561 | "global state"
1562 | ],
1563 | "support": {
1564 | "issues": "https://github.com/sebastianbergmann/global-state/issues",
1565 | "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.3"
1566 | },
1567 | "funding": [
1568 | {
1569 | "url": "https://github.com/sebastianbergmann",
1570 | "type": "github"
1571 | }
1572 | ],
1573 | "time": "2021-06-11T13:31:12+00:00"
1574 | },
1575 | {
1576 | "name": "sebastian/lines-of-code",
1577 | "version": "1.0.3",
1578 | "source": {
1579 | "type": "git",
1580 | "url": "https://github.com/sebastianbergmann/lines-of-code.git",
1581 | "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc"
1582 | },
1583 | "dist": {
1584 | "type": "zip",
1585 | "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/c1c2e997aa3146983ed888ad08b15470a2e22ecc",
1586 | "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc",
1587 | "shasum": ""
1588 | },
1589 | "require": {
1590 | "nikic/php-parser": "^4.6",
1591 | "php": ">=7.3"
1592 | },
1593 | "require-dev": {
1594 | "phpunit/phpunit": "^9.3"
1595 | },
1596 | "type": "library",
1597 | "extra": {
1598 | "branch-alias": {
1599 | "dev-master": "1.0-dev"
1600 | }
1601 | },
1602 | "autoload": {
1603 | "classmap": [
1604 | "src/"
1605 | ]
1606 | },
1607 | "notification-url": "https://packagist.org/downloads/",
1608 | "license": [
1609 | "BSD-3-Clause"
1610 | ],
1611 | "authors": [
1612 | {
1613 | "name": "Sebastian Bergmann",
1614 | "email": "sebastian@phpunit.de",
1615 | "role": "lead"
1616 | }
1617 | ],
1618 | "description": "Library for counting the lines of code in PHP source code",
1619 | "homepage": "https://github.com/sebastianbergmann/lines-of-code",
1620 | "support": {
1621 | "issues": "https://github.com/sebastianbergmann/lines-of-code/issues",
1622 | "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.3"
1623 | },
1624 | "funding": [
1625 | {
1626 | "url": "https://github.com/sebastianbergmann",
1627 | "type": "github"
1628 | }
1629 | ],
1630 | "time": "2020-11-28T06:42:11+00:00"
1631 | },
1632 | {
1633 | "name": "sebastian/object-enumerator",
1634 | "version": "4.0.4",
1635 | "source": {
1636 | "type": "git",
1637 | "url": "https://github.com/sebastianbergmann/object-enumerator.git",
1638 | "reference": "5c9eeac41b290a3712d88851518825ad78f45c71"
1639 | },
1640 | "dist": {
1641 | "type": "zip",
1642 | "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/5c9eeac41b290a3712d88851518825ad78f45c71",
1643 | "reference": "5c9eeac41b290a3712d88851518825ad78f45c71",
1644 | "shasum": ""
1645 | },
1646 | "require": {
1647 | "php": ">=7.3",
1648 | "sebastian/object-reflector": "^2.0",
1649 | "sebastian/recursion-context": "^4.0"
1650 | },
1651 | "require-dev": {
1652 | "phpunit/phpunit": "^9.3"
1653 | },
1654 | "type": "library",
1655 | "extra": {
1656 | "branch-alias": {
1657 | "dev-master": "4.0-dev"
1658 | }
1659 | },
1660 | "autoload": {
1661 | "classmap": [
1662 | "src/"
1663 | ]
1664 | },
1665 | "notification-url": "https://packagist.org/downloads/",
1666 | "license": [
1667 | "BSD-3-Clause"
1668 | ],
1669 | "authors": [
1670 | {
1671 | "name": "Sebastian Bergmann",
1672 | "email": "sebastian@phpunit.de"
1673 | }
1674 | ],
1675 | "description": "Traverses array structures and object graphs to enumerate all referenced objects",
1676 | "homepage": "https://github.com/sebastianbergmann/object-enumerator/",
1677 | "support": {
1678 | "issues": "https://github.com/sebastianbergmann/object-enumerator/issues",
1679 | "source": "https://github.com/sebastianbergmann/object-enumerator/tree/4.0.4"
1680 | },
1681 | "funding": [
1682 | {
1683 | "url": "https://github.com/sebastianbergmann",
1684 | "type": "github"
1685 | }
1686 | ],
1687 | "time": "2020-10-26T13:12:34+00:00"
1688 | },
1689 | {
1690 | "name": "sebastian/object-reflector",
1691 | "version": "2.0.4",
1692 | "source": {
1693 | "type": "git",
1694 | "url": "https://github.com/sebastianbergmann/object-reflector.git",
1695 | "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7"
1696 | },
1697 | "dist": {
1698 | "type": "zip",
1699 | "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/b4f479ebdbf63ac605d183ece17d8d7fe49c15c7",
1700 | "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7",
1701 | "shasum": ""
1702 | },
1703 | "require": {
1704 | "php": ">=7.3"
1705 | },
1706 | "require-dev": {
1707 | "phpunit/phpunit": "^9.3"
1708 | },
1709 | "type": "library",
1710 | "extra": {
1711 | "branch-alias": {
1712 | "dev-master": "2.0-dev"
1713 | }
1714 | },
1715 | "autoload": {
1716 | "classmap": [
1717 | "src/"
1718 | ]
1719 | },
1720 | "notification-url": "https://packagist.org/downloads/",
1721 | "license": [
1722 | "BSD-3-Clause"
1723 | ],
1724 | "authors": [
1725 | {
1726 | "name": "Sebastian Bergmann",
1727 | "email": "sebastian@phpunit.de"
1728 | }
1729 | ],
1730 | "description": "Allows reflection of object attributes, including inherited and non-public ones",
1731 | "homepage": "https://github.com/sebastianbergmann/object-reflector/",
1732 | "support": {
1733 | "issues": "https://github.com/sebastianbergmann/object-reflector/issues",
1734 | "source": "https://github.com/sebastianbergmann/object-reflector/tree/2.0.4"
1735 | },
1736 | "funding": [
1737 | {
1738 | "url": "https://github.com/sebastianbergmann",
1739 | "type": "github"
1740 | }
1741 | ],
1742 | "time": "2020-10-26T13:14:26+00:00"
1743 | },
1744 | {
1745 | "name": "sebastian/recursion-context",
1746 | "version": "4.0.4",
1747 | "source": {
1748 | "type": "git",
1749 | "url": "https://github.com/sebastianbergmann/recursion-context.git",
1750 | "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172"
1751 | },
1752 | "dist": {
1753 | "type": "zip",
1754 | "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/cd9d8cf3c5804de4341c283ed787f099f5506172",
1755 | "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172",
1756 | "shasum": ""
1757 | },
1758 | "require": {
1759 | "php": ">=7.3"
1760 | },
1761 | "require-dev": {
1762 | "phpunit/phpunit": "^9.3"
1763 | },
1764 | "type": "library",
1765 | "extra": {
1766 | "branch-alias": {
1767 | "dev-master": "4.0-dev"
1768 | }
1769 | },
1770 | "autoload": {
1771 | "classmap": [
1772 | "src/"
1773 | ]
1774 | },
1775 | "notification-url": "https://packagist.org/downloads/",
1776 | "license": [
1777 | "BSD-3-Clause"
1778 | ],
1779 | "authors": [
1780 | {
1781 | "name": "Sebastian Bergmann",
1782 | "email": "sebastian@phpunit.de"
1783 | },
1784 | {
1785 | "name": "Jeff Welch",
1786 | "email": "whatthejeff@gmail.com"
1787 | },
1788 | {
1789 | "name": "Adam Harvey",
1790 | "email": "aharvey@php.net"
1791 | }
1792 | ],
1793 | "description": "Provides functionality to recursively process PHP variables",
1794 | "homepage": "http://www.github.com/sebastianbergmann/recursion-context",
1795 | "support": {
1796 | "issues": "https://github.com/sebastianbergmann/recursion-context/issues",
1797 | "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.4"
1798 | },
1799 | "funding": [
1800 | {
1801 | "url": "https://github.com/sebastianbergmann",
1802 | "type": "github"
1803 | }
1804 | ],
1805 | "time": "2020-10-26T13:17:30+00:00"
1806 | },
1807 | {
1808 | "name": "sebastian/resource-operations",
1809 | "version": "3.0.3",
1810 | "source": {
1811 | "type": "git",
1812 | "url": "https://github.com/sebastianbergmann/resource-operations.git",
1813 | "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8"
1814 | },
1815 | "dist": {
1816 | "type": "zip",
1817 | "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8",
1818 | "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8",
1819 | "shasum": ""
1820 | },
1821 | "require": {
1822 | "php": ">=7.3"
1823 | },
1824 | "require-dev": {
1825 | "phpunit/phpunit": "^9.0"
1826 | },
1827 | "type": "library",
1828 | "extra": {
1829 | "branch-alias": {
1830 | "dev-master": "3.0-dev"
1831 | }
1832 | },
1833 | "autoload": {
1834 | "classmap": [
1835 | "src/"
1836 | ]
1837 | },
1838 | "notification-url": "https://packagist.org/downloads/",
1839 | "license": [
1840 | "BSD-3-Clause"
1841 | ],
1842 | "authors": [
1843 | {
1844 | "name": "Sebastian Bergmann",
1845 | "email": "sebastian@phpunit.de"
1846 | }
1847 | ],
1848 | "description": "Provides a list of PHP built-in functions that operate on resources",
1849 | "homepage": "https://www.github.com/sebastianbergmann/resource-operations",
1850 | "support": {
1851 | "issues": "https://github.com/sebastianbergmann/resource-operations/issues",
1852 | "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.3"
1853 | },
1854 | "funding": [
1855 | {
1856 | "url": "https://github.com/sebastianbergmann",
1857 | "type": "github"
1858 | }
1859 | ],
1860 | "time": "2020-09-28T06:45:17+00:00"
1861 | },
1862 | {
1863 | "name": "sebastian/type",
1864 | "version": "2.3.4",
1865 | "source": {
1866 | "type": "git",
1867 | "url": "https://github.com/sebastianbergmann/type.git",
1868 | "reference": "b8cd8a1c753c90bc1a0f5372170e3e489136f914"
1869 | },
1870 | "dist": {
1871 | "type": "zip",
1872 | "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/b8cd8a1c753c90bc1a0f5372170e3e489136f914",
1873 | "reference": "b8cd8a1c753c90bc1a0f5372170e3e489136f914",
1874 | "shasum": ""
1875 | },
1876 | "require": {
1877 | "php": ">=7.3"
1878 | },
1879 | "require-dev": {
1880 | "phpunit/phpunit": "^9.3"
1881 | },
1882 | "type": "library",
1883 | "extra": {
1884 | "branch-alias": {
1885 | "dev-master": "2.3-dev"
1886 | }
1887 | },
1888 | "autoload": {
1889 | "classmap": [
1890 | "src/"
1891 | ]
1892 | },
1893 | "notification-url": "https://packagist.org/downloads/",
1894 | "license": [
1895 | "BSD-3-Clause"
1896 | ],
1897 | "authors": [
1898 | {
1899 | "name": "Sebastian Bergmann",
1900 | "email": "sebastian@phpunit.de",
1901 | "role": "lead"
1902 | }
1903 | ],
1904 | "description": "Collection of value objects that represent the types of the PHP type system",
1905 | "homepage": "https://github.com/sebastianbergmann/type",
1906 | "support": {
1907 | "issues": "https://github.com/sebastianbergmann/type/issues",
1908 | "source": "https://github.com/sebastianbergmann/type/tree/2.3.4"
1909 | },
1910 | "funding": [
1911 | {
1912 | "url": "https://github.com/sebastianbergmann",
1913 | "type": "github"
1914 | }
1915 | ],
1916 | "time": "2021-06-15T12:49:02+00:00"
1917 | },
1918 | {
1919 | "name": "sebastian/version",
1920 | "version": "3.0.2",
1921 | "source": {
1922 | "type": "git",
1923 | "url": "https://github.com/sebastianbergmann/version.git",
1924 | "reference": "c6c1022351a901512170118436c764e473f6de8c"
1925 | },
1926 | "dist": {
1927 | "type": "zip",
1928 | "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c6c1022351a901512170118436c764e473f6de8c",
1929 | "reference": "c6c1022351a901512170118436c764e473f6de8c",
1930 | "shasum": ""
1931 | },
1932 | "require": {
1933 | "php": ">=7.3"
1934 | },
1935 | "type": "library",
1936 | "extra": {
1937 | "branch-alias": {
1938 | "dev-master": "3.0-dev"
1939 | }
1940 | },
1941 | "autoload": {
1942 | "classmap": [
1943 | "src/"
1944 | ]
1945 | },
1946 | "notification-url": "https://packagist.org/downloads/",
1947 | "license": [
1948 | "BSD-3-Clause"
1949 | ],
1950 | "authors": [
1951 | {
1952 | "name": "Sebastian Bergmann",
1953 | "email": "sebastian@phpunit.de",
1954 | "role": "lead"
1955 | }
1956 | ],
1957 | "description": "Library that helps with managing the version number of Git-hosted PHP projects",
1958 | "homepage": "https://github.com/sebastianbergmann/version",
1959 | "support": {
1960 | "issues": "https://github.com/sebastianbergmann/version/issues",
1961 | "source": "https://github.com/sebastianbergmann/version/tree/3.0.2"
1962 | },
1963 | "funding": [
1964 | {
1965 | "url": "https://github.com/sebastianbergmann",
1966 | "type": "github"
1967 | }
1968 | ],
1969 | "time": "2020-09-28T06:39:44+00:00"
1970 | },
1971 | {
1972 | "name": "squizlabs/php_codesniffer",
1973 | "version": "3.6.0",
1974 | "source": {
1975 | "type": "git",
1976 | "url": "https://github.com/squizlabs/PHP_CodeSniffer.git",
1977 | "reference": "ffced0d2c8fa8e6cdc4d695a743271fab6c38625"
1978 | },
1979 | "dist": {
1980 | "type": "zip",
1981 | "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/ffced0d2c8fa8e6cdc4d695a743271fab6c38625",
1982 | "reference": "ffced0d2c8fa8e6cdc4d695a743271fab6c38625",
1983 | "shasum": ""
1984 | },
1985 | "require": {
1986 | "ext-simplexml": "*",
1987 | "ext-tokenizer": "*",
1988 | "ext-xmlwriter": "*",
1989 | "php": ">=5.4.0"
1990 | },
1991 | "require-dev": {
1992 | "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0"
1993 | },
1994 | "bin": [
1995 | "bin/phpcs",
1996 | "bin/phpcbf"
1997 | ],
1998 | "type": "library",
1999 | "extra": {
2000 | "branch-alias": {
2001 | "dev-master": "3.x-dev"
2002 | }
2003 | },
2004 | "notification-url": "https://packagist.org/downloads/",
2005 | "license": [
2006 | "BSD-3-Clause"
2007 | ],
2008 | "authors": [
2009 | {
2010 | "name": "Greg Sherwood",
2011 | "role": "lead"
2012 | }
2013 | ],
2014 | "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.",
2015 | "homepage": "https://github.com/squizlabs/PHP_CodeSniffer",
2016 | "keywords": [
2017 | "phpcs",
2018 | "standards"
2019 | ],
2020 | "support": {
2021 | "issues": "https://github.com/squizlabs/PHP_CodeSniffer/issues",
2022 | "source": "https://github.com/squizlabs/PHP_CodeSniffer",
2023 | "wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki"
2024 | },
2025 | "time": "2021-04-09T00:54:41+00:00"
2026 | },
2027 | {
2028 | "name": "symfony/polyfill-ctype",
2029 | "version": "v1.23.0",
2030 | "source": {
2031 | "type": "git",
2032 | "url": "https://github.com/symfony/polyfill-ctype.git",
2033 | "reference": "46cd95797e9df938fdd2b03693b5fca5e64b01ce"
2034 | },
2035 | "dist": {
2036 | "type": "zip",
2037 | "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/46cd95797e9df938fdd2b03693b5fca5e64b01ce",
2038 | "reference": "46cd95797e9df938fdd2b03693b5fca5e64b01ce",
2039 | "shasum": ""
2040 | },
2041 | "require": {
2042 | "php": ">=7.1"
2043 | },
2044 | "suggest": {
2045 | "ext-ctype": "For best performance"
2046 | },
2047 | "type": "library",
2048 | "extra": {
2049 | "branch-alias": {
2050 | "dev-main": "1.23-dev"
2051 | },
2052 | "thanks": {
2053 | "name": "symfony/polyfill",
2054 | "url": "https://github.com/symfony/polyfill"
2055 | }
2056 | },
2057 | "autoload": {
2058 | "psr-4": {
2059 | "Symfony\\Polyfill\\Ctype\\": ""
2060 | },
2061 | "files": [
2062 | "bootstrap.php"
2063 | ]
2064 | },
2065 | "notification-url": "https://packagist.org/downloads/",
2066 | "license": [
2067 | "MIT"
2068 | ],
2069 | "authors": [
2070 | {
2071 | "name": "Gert de Pagter",
2072 | "email": "BackEndTea@gmail.com"
2073 | },
2074 | {
2075 | "name": "Symfony Community",
2076 | "homepage": "https://symfony.com/contributors"
2077 | }
2078 | ],
2079 | "description": "Symfony polyfill for ctype functions",
2080 | "homepage": "https://symfony.com",
2081 | "keywords": [
2082 | "compatibility",
2083 | "ctype",
2084 | "polyfill",
2085 | "portable"
2086 | ],
2087 | "support": {
2088 | "source": "https://github.com/symfony/polyfill-ctype/tree/v1.23.0"
2089 | },
2090 | "funding": [
2091 | {
2092 | "url": "https://symfony.com/sponsor",
2093 | "type": "custom"
2094 | },
2095 | {
2096 | "url": "https://github.com/fabpot",
2097 | "type": "github"
2098 | },
2099 | {
2100 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
2101 | "type": "tidelift"
2102 | }
2103 | ],
2104 | "time": "2021-02-19T12:13:01+00:00"
2105 | },
2106 | {
2107 | "name": "theseer/tokenizer",
2108 | "version": "1.2.0",
2109 | "source": {
2110 | "type": "git",
2111 | "url": "https://github.com/theseer/tokenizer.git",
2112 | "reference": "75a63c33a8577608444246075ea0af0d052e452a"
2113 | },
2114 | "dist": {
2115 | "type": "zip",
2116 | "url": "https://api.github.com/repos/theseer/tokenizer/zipball/75a63c33a8577608444246075ea0af0d052e452a",
2117 | "reference": "75a63c33a8577608444246075ea0af0d052e452a",
2118 | "shasum": ""
2119 | },
2120 | "require": {
2121 | "ext-dom": "*",
2122 | "ext-tokenizer": "*",
2123 | "ext-xmlwriter": "*",
2124 | "php": "^7.2 || ^8.0"
2125 | },
2126 | "type": "library",
2127 | "autoload": {
2128 | "classmap": [
2129 | "src/"
2130 | ]
2131 | },
2132 | "notification-url": "https://packagist.org/downloads/",
2133 | "license": [
2134 | "BSD-3-Clause"
2135 | ],
2136 | "authors": [
2137 | {
2138 | "name": "Arne Blankerts",
2139 | "email": "arne@blankerts.de",
2140 | "role": "Developer"
2141 | }
2142 | ],
2143 | "description": "A small library for converting tokenized PHP source code into XML and potentially other formats",
2144 | "support": {
2145 | "issues": "https://github.com/theseer/tokenizer/issues",
2146 | "source": "https://github.com/theseer/tokenizer/tree/master"
2147 | },
2148 | "funding": [
2149 | {
2150 | "url": "https://github.com/theseer",
2151 | "type": "github"
2152 | }
2153 | ],
2154 | "time": "2020-07-12T23:59:07+00:00"
2155 | },
2156 | {
2157 | "name": "webmozart/assert",
2158 | "version": "1.10.0",
2159 | "source": {
2160 | "type": "git",
2161 | "url": "https://github.com/webmozarts/assert.git",
2162 | "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25"
2163 | },
2164 | "dist": {
2165 | "type": "zip",
2166 | "url": "https://api.github.com/repos/webmozarts/assert/zipball/6964c76c7804814a842473e0c8fd15bab0f18e25",
2167 | "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25",
2168 | "shasum": ""
2169 | },
2170 | "require": {
2171 | "php": "^7.2 || ^8.0",
2172 | "symfony/polyfill-ctype": "^1.8"
2173 | },
2174 | "conflict": {
2175 | "phpstan/phpstan": "<0.12.20",
2176 | "vimeo/psalm": "<4.6.1 || 4.6.2"
2177 | },
2178 | "require-dev": {
2179 | "phpunit/phpunit": "^8.5.13"
2180 | },
2181 | "type": "library",
2182 | "extra": {
2183 | "branch-alias": {
2184 | "dev-master": "1.10-dev"
2185 | }
2186 | },
2187 | "autoload": {
2188 | "psr-4": {
2189 | "Webmozart\\Assert\\": "src/"
2190 | }
2191 | },
2192 | "notification-url": "https://packagist.org/downloads/",
2193 | "license": [
2194 | "MIT"
2195 | ],
2196 | "authors": [
2197 | {
2198 | "name": "Bernhard Schussek",
2199 | "email": "bschussek@gmail.com"
2200 | }
2201 | ],
2202 | "description": "Assertions to validate method input/output with nice error messages.",
2203 | "keywords": [
2204 | "assert",
2205 | "check",
2206 | "validate"
2207 | ],
2208 | "support": {
2209 | "issues": "https://github.com/webmozarts/assert/issues",
2210 | "source": "https://github.com/webmozarts/assert/tree/1.10.0"
2211 | },
2212 | "time": "2021-03-09T10:59:23+00:00"
2213 | }
2214 | ],
2215 | "aliases": [],
2216 | "minimum-stability": "stable",
2217 | "stability-flags": [],
2218 | "prefer-stable": false,
2219 | "prefer-lowest": false,
2220 | "platform": {
2221 | "php": "^7.4|^8.0"
2222 | },
2223 | "platform-dev": [],
2224 | "plugin-api-version": "2.1.0"
2225 | }
2226 |
--------------------------------------------------------------------------------
/phpcs.xml.dist:
--------------------------------------------------------------------------------
1 |
2 |
3 | PHP Code Sniffer
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | src/
13 | tests/
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/phpunit.xml.dist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | ./src
6 |
7 |
8 | ./src/Exception
9 |
10 |
11 |
12 |
13 | ./tests
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/src/Exceptions/InlineKeyboardPaginationException.php:
--------------------------------------------------------------------------------
1 | '%d',
23 | 'first' => '« %d',
24 | 'previous' => '‹ %d',
25 | 'current' => '· %d ·',
26 | 'next' => '%d ›',
27 | 'last' => '%d »',
28 | ];
29 |
30 | /**
31 | * @param int $maxButtons
32 | * @param bool $forceButtonCount
33 | *
34 | * @return self
35 | * @throws InlineKeyboardPaginationException
36 | */
37 | public function setMaxButtons(int $maxButtons = 5, bool $forceButtonCount = false): self
38 | {
39 | if ($maxButtons < 5 || $maxButtons > 8) {
40 | throw InlineKeyboardPaginationException::invalidMaxButtons();
41 | }
42 |
43 | $this->maxButtons = $maxButtons;
44 | $this->forceButtonCount = $forceButtonCount;
45 |
46 | return $this;
47 | }
48 |
49 | /**
50 | * Get the current callback format.
51 | *
52 | * @return string
53 | */
54 | public function getCallbackDataFormat(): string
55 | {
56 | return $this->callbackDataFormat;
57 | }
58 |
59 | /**
60 | * Set the callback_data format.
61 | *
62 | * @param string $callbackDataFormat
63 | *
64 | * @return self
65 | */
66 | public function setCallbackDataFormat(string $callbackDataFormat): self
67 | {
68 | $this->callbackDataFormat = $callbackDataFormat;
69 |
70 | return $this;
71 | }
72 |
73 | /**
74 | * Return list of keyboard button labels.
75 | *
76 | * @return array
77 | */
78 | public function getLabels(): array
79 | {
80 | return $this->labels;
81 | }
82 |
83 | /**
84 | * Set the keyboard button labels.
85 | *
86 | * @param array $labels
87 | *
88 | * @return self
89 | */
90 | public function setLabels(array $labels): self
91 | {
92 | $this->labels = $labels;
93 |
94 | return $this;
95 | }
96 |
97 | /**
98 | * @inheritdoc
99 | */
100 | public function setCommand(string $command = 'pagination'): self
101 | {
102 | $this->command = $command;
103 |
104 | return $this;
105 | }
106 |
107 | /**
108 | * @inheritdoc
109 | * @throws InlineKeyboardPaginationException
110 | */
111 | public function setSelectedPage(int $selectedPage): self
112 | {
113 | $numberOfPages = $this->getNumberOfPages();
114 | if ($selectedPage < 1 || $selectedPage > $numberOfPages) {
115 | throw InlineKeyboardPaginationException::pageMustBeBetween(1, $numberOfPages);
116 | }
117 |
118 | $this->selectedPage = $selectedPage;
119 |
120 | return $this;
121 | }
122 |
123 | /**
124 | * Get the number of items shown per page.
125 | *
126 | * @return int
127 | */
128 | public function getItemsPerPage(): int
129 | {
130 | return $this->itemsPerPage;
131 | }
132 |
133 | /**
134 | * Set how many items should be shown per page.
135 | *
136 | * @param int $itemsPerPage
137 | *
138 | * @return self
139 | * @throws InlineKeyboardPaginationException
140 | */
141 | public function setItemsPerPage(int $itemsPerPage): self
142 | {
143 | if ($itemsPerPage <= 0) {
144 | throw InlineKeyboardPaginationException::invalidItemsPerPage();
145 | }
146 |
147 | $this->itemsPerPage = $itemsPerPage;
148 |
149 | return $this;
150 | }
151 |
152 | /**
153 | * Set the items for the pagination.
154 | *
155 | * @param array $items
156 | *
157 | * @return self
158 | * @throws InlineKeyboardPaginationException
159 | */
160 | public function setItems(array $items): self
161 | {
162 | if (empty($items)) {
163 | throw InlineKeyboardPaginationException::noItems();
164 | }
165 |
166 | $this->items = $items;
167 |
168 | return $this;
169 | }
170 |
171 | /**
172 | * Calculate and return the number of pages.
173 | *
174 | * @return int
175 | */
176 | public function getNumberOfPages(): int
177 | {
178 | return (int) ceil(count($this->items) / $this->itemsPerPage);
179 | }
180 |
181 | /**
182 | * TelegramBotPagination constructor.
183 | *
184 | * @inheritdoc
185 | * @throws InlineKeyboardPaginationException
186 | */
187 | public function __construct(
188 | array $items,
189 | string $command = 'pagination',
190 | int $selectedPage = 1,
191 | int $itemsPerPage = 5
192 | ) {
193 | $this->setCommand($command);
194 | $this->setItemsPerPage($itemsPerPage);
195 | $this->setItems($items);
196 | $this->setSelectedPage($selectedPage);
197 | }
198 |
199 | /**
200 | * @inheritdoc
201 | * @throws InlineKeyboardPaginationException
202 | */
203 | public function getPagination(int $selectedPage = null): array
204 | {
205 | if ($selectedPage !== null) {
206 | $this->setSelectedPage($selectedPage);
207 | }
208 |
209 | return [
210 | 'items' => $this->getPreparedItems(),
211 | 'keyboard' => $this->generateKeyboard(),
212 | ];
213 | }
214 |
215 | /**
216 | * Generate the keyboard with the correctly labelled buttons.
217 | *
218 | * @return array
219 | */
220 | protected function generateKeyboard(): array
221 | {
222 | $buttons = $this->generateButtons();
223 | $buttons = $this->applyButtonLabels($buttons);
224 |
225 | return array_values(array_filter($buttons));
226 | }
227 |
228 | /**
229 | * Generate all buttons for this inline keyboard.
230 | *
231 | * @return array
232 | */
233 | protected function generateButtons(): array
234 | {
235 | $numberOfPages = $this->getNumberOfPages();
236 |
237 | $range = ['from' => 2, 'to' => $numberOfPages - 1];
238 |
239 | if ($numberOfPages > $this->maxButtons) {
240 | $range = $this->generateRange();
241 | }
242 |
243 | $buttons[1] = $this->generateButton(1);
244 | for ($i = $range['from']; $i <= $range['to']; $i++) {
245 | $buttons[$i] = $this->generateButton($i);
246 | }
247 | $buttons[$numberOfPages] = $this->generateButton($numberOfPages);
248 |
249 | return $buttons;
250 | }
251 |
252 | /**
253 | * Apply correct text labels to the keyboard buttons.
254 | *
255 | * @param array $buttons
256 | *
257 | * @return array
258 | */
259 | protected function applyButtonLabels(array $buttons): array
260 | {
261 | $numberOfPages = $this->getNumberOfPages();
262 |
263 | foreach ($buttons as $page => &$button) {
264 | $inFirstBlock = max($this->selectedPage, $page) <= 3;
265 | $inLastBlock = min($this->selectedPage, $page) >= $numberOfPages - 2;
266 |
267 | $labelKey = 'next';
268 | if ($page === $this->selectedPage) {
269 | $labelKey = 'current';
270 | } elseif ($inFirstBlock || $inLastBlock) {
271 | $labelKey = 'default';
272 | } elseif ($page === 1) {
273 | $labelKey = 'first';
274 | } elseif ($page === $numberOfPages) {
275 | $labelKey = 'last';
276 | } elseif ($page < $this->selectedPage) {
277 | $labelKey = 'previous';
278 | }
279 |
280 | $label = $this->labels[$labelKey] ?? '';
281 |
282 | // Remove button for undefined labels.
283 | if ($label === '') {
284 | $button = null;
285 | continue;
286 | }
287 |
288 | $button['text'] = sprintf($label, $page);
289 | }
290 |
291 | return $buttons;
292 | }
293 |
294 | /**
295 | * Get the range of intermediate buttons for the keyboard.
296 | *
297 | * @return array
298 | */
299 | protected function generateRange(): array
300 | {
301 | $numberOfIntermediateButtons = $this->maxButtons - 2; // Minus first and last buttons.
302 | $numberOfPages = $this->getNumberOfPages();
303 |
304 | $from = $this->selectedPage - 1;
305 | $to = $this->selectedPage + 1;
306 |
307 | if ($this->selectedPage === 1) {
308 | $from = 2;
309 | $to = $this->maxButtons - 1;
310 | } elseif ($this->selectedPage === $numberOfPages) {
311 | $from = $numberOfPages - $numberOfIntermediateButtons;
312 | $to = $numberOfPages - 1;
313 | } elseif ($this->selectedPage === 3) {
314 | // Special case because this button is in the center of a flexible pagination.
315 | $to += $numberOfIntermediateButtons - 3;
316 | } elseif ($this->selectedPage < 3) {
317 | // First half.
318 | $from = $this->selectedPage;
319 | $to = $this->selectedPage + $numberOfIntermediateButtons - 1;
320 | } elseif (($numberOfPages - $this->selectedPage) < 3) {
321 | // Last half.
322 | $from = $numberOfPages - $numberOfIntermediateButtons;
323 | $to = $numberOfPages - 1;
324 | } elseif ($this->forceButtonCount) {
325 | $from = (int) max(2, $this->selectedPage - floor($numberOfIntermediateButtons / 2));
326 | $to = $from + $numberOfIntermediateButtons - 1;
327 | }
328 |
329 | return compact('from', 'to');
330 | }
331 |
332 | /**
333 | * Generate the button for the passed page.
334 | *
335 | * @param int $page
336 | *
337 | * @return array
338 | */
339 | protected function generateButton(int $page): array
340 | {
341 | return [
342 | 'text' => $page,
343 | 'callback_data' => $this->generateCallbackData($page),
344 | ];
345 | }
346 |
347 | /**
348 | * Generate the callback data for the passed page.
349 | *
350 | * @param int $page
351 | *
352 | * @return string
353 | */
354 | protected function generateCallbackData(int $page): string
355 | {
356 | return str_replace(
357 | ['{COMMAND}', '{OLD_PAGE}', '{NEW_PAGE}'],
358 | [$this->command, $this->selectedPage, $page],
359 | $this->callbackDataFormat
360 | );
361 | }
362 |
363 | /**
364 | * Get the prepared items for the selected page.
365 | *
366 | * @return array
367 | */
368 | protected function getPreparedItems(): array
369 | {
370 | return array_slice($this->items, $this->getOffset(), $this->itemsPerPage);
371 | }
372 |
373 | /**
374 | * Get the items offset for the selected page.
375 | *
376 | * @return int
377 | */
378 | protected function getOffset(): int
379 | {
380 | return $this->itemsPerPage * ($this->selectedPage - 1);
381 | }
382 |
383 | /**
384 | * Get the parameters from the callback query.
385 | *
386 | * @todo Possibly make it work for custom formats too?
387 | *
388 | * @param string $data
389 | *
390 | * @return array
391 | */
392 | public static function getParametersFromCallbackData(string $data): array
393 | {
394 | parse_str($data, $params);
395 |
396 | return $params;
397 | }
398 | }
399 |
--------------------------------------------------------------------------------
/src/InlineKeyboardPaginator.php:
--------------------------------------------------------------------------------
1 | ikp = new InlineKeyboardPagination($this->items, $this->command, $this->selectedPage, $this->itemsPerPage);
24 | }
25 |
26 | public function testValidConstructor(): void
27 | {
28 | $data = $this->ikp->getPagination();
29 |
30 | self::assertCount($this->itemsPerPage, $data['items']);
31 | self::assertStringStartsWith("command={$this->command}", $data['keyboard'][0]['callback_data']);
32 | }
33 |
34 | public function testInvalidConstructor(): void
35 | {
36 | $this->expectException(InlineKeyboardPaginationException::class);
37 | $this->expectExceptionMessage('Invalid page selected, must be between 1 and 10.');
38 |
39 | new InlineKeyboardPagination(range(1, 10), 'command', 10000, 1);
40 | }
41 |
42 | public function testEmptyItemsConstructor(): void
43 | {
44 | $this->expectException(InlineKeyboardPaginationException::class);
45 | $this->expectExceptionMessage('Items list empty.');
46 |
47 | new InlineKeyboardPagination([]);
48 | }
49 |
50 | public function testCallbackDataFormat(): void
51 | {
52 | $ikp = new InlineKeyboardPagination(range(1, 10), 'cmd', 2, 5);
53 |
54 | self::assertAllButtonPropertiesEqual([
55 | [
56 | 'command=cmd&oldPage=2&newPage=1',
57 | 'command=cmd&oldPage=2&newPage=2',
58 | ],
59 | ], 'callback_data', [$ikp->getPagination()['keyboard']]);
60 |
61 | $ikp->setCallbackDataFormat('{COMMAND};{OLD_PAGE};{NEW_PAGE}');
62 |
63 | self::assertAllButtonPropertiesEqual([
64 | [
65 | 'cmd;2;1',
66 | 'cmd;2;2',
67 | ],
68 | ], 'callback_data', [$ikp->getPagination()['keyboard']]);
69 | }
70 |
71 | public function testCallbackDataParser(): void
72 | {
73 | $data = $this->ikp->getPagination();
74 |
75 | $callback_data = $this->ikp::getParametersFromCallbackData($data['keyboard'][0]['callback_data']);
76 |
77 | self::assertSame([
78 | 'command' => $this->command,
79 | 'oldPage' => (string) $this->selectedPage,
80 | 'newPage' => '1', // because we're getting the button at position 0, which is page 1
81 | ], $callback_data);
82 | }
83 |
84 | public function testValidPagination(): void
85 | {
86 | $length = (int) ceil(count($this->items) / $this->itemsPerPage);
87 |
88 | for ($i = 1; $i < $length; $i++) {
89 | $this->ikp->getPagination($i);
90 | }
91 |
92 | $this->assertSame($length, $this->ikp->getNumberOfPages());
93 | }
94 |
95 | public function testInvalidPagination(): void
96 | {
97 | $this->expectException(InlineKeyboardPaginationException::class);
98 | $this->expectExceptionMessage('Invalid page selected, must be between 1 and 20.');
99 |
100 | $ikp = new InlineKeyboardPagination(range(1, 20), 'command', 1, 1);
101 | $ikp->getPagination($ikp->getNumberOfPages() + 1);
102 | }
103 |
104 | public function testSetMaxButtons(): void
105 | {
106 | $this->ikp->setMaxButtons(5);
107 | $this->ikp->setMaxButtons(6);
108 | $this->ikp->setMaxButtons(7);
109 | $this->ikp->setMaxButtons(8);
110 |
111 | self::assertTrue(true);
112 | }
113 |
114 | public function testMaxButtonsTooSmall(): void
115 | {
116 | $this->expectException(InlineKeyboardPaginationException::class);
117 | $this->expectExceptionMessage('Invalid max buttons, must be between 5 and 8.');
118 |
119 | $this->ikp->setMaxButtons(4);
120 | }
121 |
122 | public function testMaxButtonsTooBig(): void
123 | {
124 | $this->expectException(InlineKeyboardPaginationException::class);
125 | $this->expectExceptionMessage('Invalid max buttons, must be between 5 and 8.');
126 |
127 | $this->ikp->setMaxButtons(9);
128 | }
129 |
130 | public function testForceButtonsCountWith10Pages(): void
131 | {
132 | $datas = [
133 | [8, 1, ['· 1 ·', '2', '3', '4 ›', '5 ›', '6 ›', '7 ›', '10 »']],
134 | [8, 2, ['1', '· 2 ·', '3', '4 ›', '5 ›', '6 ›', '7 ›', '10 »']],
135 | [8, 3, ['1', '2', '· 3 ·', '4 ›', '5 ›', '6 ›', '7 ›', '10 »']],
136 | [8, 4, ['« 1', '‹ 2', '‹ 3', '· 4 ·', '5 ›', '6 ›', '7 ›', '10 »']],
137 | [8, 5, ['« 1', '‹ 2', '‹ 3', '‹ 4', '· 5 ·', '6 ›', '7 ›', '10 »']],
138 | [8, 6, ['« 1', '‹ 3', '‹ 4', '‹ 5', '· 6 ·', '7 ›', '8 ›', '10 »']],
139 | [8, 7, ['« 1', '‹ 4', '‹ 5', '‹ 6', '· 7 ·', '8 ›', '9 ›', '10 »']],
140 | [8, 8, ['« 1', '‹ 4', '‹ 5', '‹ 6', '‹ 7', '· 8 ·', '9', '10']],
141 | [8, 9, ['« 1', '‹ 4', '‹ 5', '‹ 6', '‹ 7', '8', '· 9 ·', '10']],
142 | [8, 10, ['« 1', '‹ 4', '‹ 5', '‹ 6', '‹ 7', '8', '9', '· 10 ·']],
143 | [7, 1, ['· 1 ·', '2', '3', '4 ›', '5 ›', '6 ›', '10 »']],
144 | [7, 2, ['1', '· 2 ·', '3', '4 ›', '5 ›', '6 ›', '10 »']],
145 | [7, 3, ['1', '2', '· 3 ·', '4 ›', '5 ›', '6 ›', '10 »']],
146 | [7, 4, ['« 1', '‹ 2', '‹ 3', '· 4 ·', '5 ›', '6 ›', '10 »']],
147 | [7, 5, ['« 1', '‹ 3', '‹ 4', '· 5 ·', '6 ›', '7 ›', '10 »']],
148 | [7, 6, ['« 1', '‹ 4', '‹ 5', '· 6 ·', '7 ›', '8 ›', '10 »']],
149 | [7, 7, ['« 1', '‹ 5', '‹ 6', '· 7 ·', '8 ›', '9 ›', '10 »']],
150 | [7, 8, ['« 1', '‹ 5', '‹ 6', '‹ 7', '· 8 ·', '9', '10']],
151 | [7, 9, ['« 1', '‹ 5', '‹ 6', '‹ 7', '8', '· 9 ·', '10']],
152 | [7, 10, ['« 1', '‹ 5', '‹ 6', '‹ 7', '8', '9', '· 10 ·']],
153 | [6, 1, ['· 1 ·', '2', '3', '4 ›', '5 ›', '10 »']],
154 | [6, 2, ['1', '· 2 ·', '3', '4 ›', '5 ›', '10 »']],
155 | [6, 3, ['1', '2', '· 3 ·', '4 ›', '5 ›', '10 »']],
156 | [6, 4, ['« 1', '‹ 2', '‹ 3', '· 4 ·', '5 ›', '10 »']],
157 | [6, 5, ['« 1', '‹ 3', '‹ 4', '· 5 ·', '6 ›', '10 »']],
158 | [6, 6, ['« 1', '‹ 4', '‹ 5', '· 6 ·', '7 ›', '10 »']],
159 | [6, 7, ['« 1', '‹ 5', '‹ 6', '· 7 ·', '8 ›', '10 »']],
160 | [6, 8, ['« 1', '‹ 6', '‹ 7', '· 8 ·', '9', '10']],
161 | [6, 9, ['« 1', '‹ 6', '‹ 7', '8', '· 9 ·', '10']],
162 | [6, 10, ['« 1', '‹ 6', '‹ 7', '8', '9', '· 10 ·']],
163 | [5, 1, ['· 1 ·', '2', '3', '4 ›', '10 »']],
164 | [5, 2, ['1', '· 2 ·', '3', '4 ›', '10 »']],
165 | [5, 3, ['1', '2', '· 3 ·', '4 ›', '10 »']],
166 | [5, 4, ['« 1', '‹ 3', '· 4 ·', '5 ›', '10 »']],
167 | [5, 5, ['« 1', '‹ 4', '· 5 ·', '6 ›', '10 »']],
168 | [5, 6, ['« 1', '‹ 5', '· 6 ·', '7 ›', '10 »']],
169 | [5, 7, ['« 1', '‹ 6', '· 7 ·', '8 ›', '10 »']],
170 | [5, 8, ['« 1', '‹ 7', '· 8 ·', '9', '10']],
171 | [5, 9, ['« 1', '‹ 7', '8', '· 9 ·', '10']],
172 | [5, 10, ['« 1', '‹ 7', '8', '9', '· 10 ·']],
173 | ];
174 |
175 | $ikp = new InlineKeyboardPagination(range(1, 10), 'cbdata', 1, 1);
176 |
177 | foreach ($datas as $data) {
178 | [$max_buttons, $page, $buttons] = $data;
179 |
180 | $ikp->setMaxButtons($max_buttons, true);
181 | self::assertAllButtonPropertiesEqual(
182 | [$buttons],
183 | 'text',
184 | [$ikp->getPagination($page)['keyboard']],
185 | "MaxButtons: {$max_buttons}, Page: {$page}"
186 | );
187 | }
188 | }
189 |
190 | public function testForceButtonsCountWith3Pages(): void
191 | {
192 | $datas = [
193 | [8, 1, ['· 1 ·', '2', '3']],
194 | [8, 2, ['1', '· 2 ·', '3']],
195 | [8, 3, ['1', '2', '· 3 ·']],
196 | [7, 1, ['· 1 ·', '2', '3']],
197 | [7, 2, ['1', '· 2 ·', '3']],
198 | [7, 3, ['1', '2', '· 3 ·']],
199 | [6, 1, ['· 1 ·', '2', '3']],
200 | [6, 2, ['1', '· 2 ·', '3']],
201 | [6, 3, ['1', '2', '· 3 ·']],
202 | [5, 1, ['· 1 ·', '2', '3']],
203 | [5, 2, ['1', '· 2 ·', '3']],
204 | [5, 3, ['1', '2', '· 3 ·']],
205 | ];
206 |
207 | $ikp = new InlineKeyboardPagination(range(1, 3), 'cbdata', 1, 1);
208 |
209 | foreach ($datas as $data) {
210 | [$max_buttons, $page, $buttons] = $data;
211 |
212 | $ikp->setMaxButtons($max_buttons, true);
213 | self::assertAllButtonPropertiesEqual(
214 | [$buttons],
215 | 'text',
216 | [$ikp->getPagination($page)['keyboard']],
217 | "MaxButtons: {$max_buttons}, Page: {$page}"
218 | );
219 | }
220 | }
221 |
222 | public function testFlexibleButtonsCount(): void
223 | {
224 | $datas = [
225 | [8, 1, ['· 1 ·', '2', '3', '4 ›', '5 ›', '6 ›', '7 ›', '10 »']],
226 | [8, 2, ['1', '· 2 ·', '3', '4 ›', '5 ›', '6 ›', '7 ›', '10 »']],
227 | [8, 3, ['1', '2', '· 3 ·', '4 ›', '5 ›', '6 ›', '7 ›', '10 »']],
228 | [8, 4, ['« 1', '‹ 3', '· 4 ·', '5 ›', '10 »']],
229 | [8, 5, ['« 1', '‹ 4', '· 5 ·', '6 ›', '10 »']],
230 | [8, 6, ['« 1', '‹ 5', '· 6 ·', '7 ›', '10 »']],
231 | [8, 7, ['« 1', '‹ 6', '· 7 ·', '8 ›', '10 »']],
232 | [8, 8, ['« 1', '‹ 4', '‹ 5', '‹ 6', '‹ 7', '· 8 ·', '9', '10']],
233 | [8, 9, ['« 1', '‹ 4', '‹ 5', '‹ 6', '‹ 7', '8', '· 9 ·', '10']],
234 | [8, 10, ['« 1', '‹ 4', '‹ 5', '‹ 6', '‹ 7', '8', '9', '· 10 ·']],
235 | [7, 1, ['· 1 ·', '2', '3', '4 ›', '5 ›', '6 ›', '10 »']],
236 | [7, 2, ['1', '· 2 ·', '3', '4 ›', '5 ›', '6 ›', '10 »']],
237 | [7, 3, ['1', '2', '· 3 ·', '4 ›', '5 ›', '6 ›', '10 »']],
238 | [7, 4, ['« 1', '‹ 3', '· 4 ·', '5 ›', '10 »']],
239 | [7, 5, ['« 1', '‹ 4', '· 5 ·', '6 ›', '10 »']],
240 | [7, 6, ['« 1', '‹ 5', '· 6 ·', '7 ›', '10 »']],
241 | [7, 7, ['« 1', '‹ 6', '· 7 ·', '8 ›', '10 »']],
242 | [7, 8, ['« 1', '‹ 5', '‹ 6', '‹ 7', '· 8 ·', '9', '10']],
243 | [7, 9, ['« 1', '‹ 5', '‹ 6', '‹ 7', '8', '· 9 ·', '10']],
244 | [7, 10, ['« 1', '‹ 5', '‹ 6', '‹ 7', '8', '9', '· 10 ·']],
245 | [6, 1, ['· 1 ·', '2', '3', '4 ›', '5 ›', '10 »']],
246 | [6, 2, ['1', '· 2 ·', '3', '4 ›', '5 ›', '10 »']],
247 | [6, 3, ['1', '2', '· 3 ·', '4 ›', '5 ›', '10 »']],
248 | [6, 4, ['« 1', '‹ 3', '· 4 ·', '5 ›', '10 »']],
249 | [6, 5, ['« 1', '‹ 4', '· 5 ·', '6 ›', '10 »']],
250 | [6, 6, ['« 1', '‹ 5', '· 6 ·', '7 ›', '10 »']],
251 | [6, 7, ['« 1', '‹ 6', '· 7 ·', '8 ›', '10 »']],
252 | [6, 8, ['« 1', '‹ 6', '‹ 7', '· 8 ·', '9', '10']],
253 | [6, 9, ['« 1', '‹ 6', '‹ 7', '8', '· 9 ·', '10']],
254 | [6, 10, ['« 1', '‹ 6', '‹ 7', '8', '9', '· 10 ·']],
255 | [5, 1, ['· 1 ·', '2', '3', '4 ›', '10 »']],
256 | [5, 2, ['1', '· 2 ·', '3', '4 ›', '10 »']],
257 | [5, 3, ['1', '2', '· 3 ·', '4 ›', '10 »']],
258 | [5, 4, ['« 1', '‹ 3', '· 4 ·', '5 ›', '10 »']],
259 | [5, 5, ['« 1', '‹ 4', '· 5 ·', '6 ›', '10 »']],
260 | [5, 6, ['« 1', '‹ 5', '· 6 ·', '7 ›', '10 »']],
261 | [5, 7, ['« 1', '‹ 6', '· 7 ·', '8 ›', '10 »']],
262 | [5, 8, ['« 1', '‹ 7', '· 8 ·', '9', '10']],
263 | [5, 9, ['« 1', '‹ 7', '8', '· 9 ·', '10']],
264 | [5, 10, ['« 1', '‹ 7', '8', '9', '· 10 ·']],
265 | ];
266 |
267 | $ikp = new InlineKeyboardPagination(range(1, 10), 'cbdata', 1, 1);
268 |
269 | foreach ($datas as $data) {
270 | [$max_buttons, $page, $buttons] = $data;
271 |
272 | $ikp->setMaxButtons($max_buttons, false);
273 | self::assertAllButtonPropertiesEqual(
274 | [$buttons],
275 | 'text',
276 | [$ikp->getPagination($page)['keyboard']],
277 | "MaxButtons: {$max_buttons}, Page: {$page}"
278 | );
279 | }
280 | }
281 |
282 | public function testGetCallbackDataFormat(): void
283 | {
284 | // Test default value.
285 | self::assertSame(
286 | 'command={COMMAND}&oldPage={OLD_PAGE}&newPage={NEW_PAGE}',
287 | $this->ikp->getCallbackDataFormat()
288 | );
289 |
290 | // Test custom value.
291 | $customCallbackDataFormat = 'c={COMMAND}&op={OLD_PAGE}&np={NEW_PAGE}';
292 | $this->ikp->setCallbackDataFormat($customCallbackDataFormat);
293 | self::assertSame(
294 | $customCallbackDataFormat,
295 | $this->ikp->getCallbackDataFormat()
296 | );
297 | }
298 |
299 | public function testSelectedPageTooLow(): void
300 | {
301 | $this->expectException(InlineKeyboardPaginationException::class);
302 | $this->expectExceptionMessage('Invalid page selected, must be between 1 and 10.');
303 |
304 | $ikp = new InlineKeyboardPagination(range(1, 10), 'command', 1, 1);
305 | $ikp->setSelectedPage(0);
306 | }
307 |
308 | public function testSelectedPageTooHigh(): void
309 | {
310 | $this->expectException(InlineKeyboardPaginationException::class);
311 | $this->expectExceptionMessage('Invalid page selected, must be between 1 and 10.');
312 |
313 | $ikp = new InlineKeyboardPagination(range(1, 10), 'command', 1, 1);
314 | $ikp->setSelectedPage(11);
315 | }
316 |
317 | public function testGetItemsPerPage(): void
318 | {
319 | $ikp = new InlineKeyboardPagination(range(1, 10), 'command', 1, 4);
320 |
321 | self::assertEquals(4, $ikp->getItemsPerPage());
322 |
323 | $ikp->setItemsPerPage(2);
324 |
325 | self::assertEquals(2, $ikp->getItemsPerPage());
326 | }
327 |
328 | public function testInvalidItemsPerPage(): void
329 | {
330 | $this->expectException(InlineKeyboardPaginationException::class);
331 | $this->expectExceptionMessage('Invalid number of items per page, must be at least 1.');
332 |
333 | $this->ikp->setItemsPerPage(0);
334 | }
335 |
336 | public function testButtonLabels(): void
337 | {
338 | $cbdata = 'command=%s&oldPage=%d&newPage=%d';
339 | $command = 'cbdata';
340 | $ikp1 = new InlineKeyboardPagination(range(1, 1), $command, 1, $this->itemsPerPage);
341 | $ikp10 = new InlineKeyboardPagination(range(1, $this->itemsPerPage * 10), $command, 1, $this->itemsPerPage);
342 |
343 | // current
344 | $keyboard = [$ikp1->getPagination(1)['keyboard']];
345 | self::assertAllButtonPropertiesEqual([
346 | ['· 1 ·'],
347 | ], 'text', $keyboard);
348 | self::assertAllButtonPropertiesEqual([
349 | [
350 | sprintf($cbdata, $command, 1, 1),
351 | ],
352 | ], 'callback_data', $keyboard);
353 |
354 | // first, previous, current, next, last
355 | $keyboard = [$ikp10->getPagination(5)['keyboard']];
356 | self::assertAllButtonPropertiesEqual([
357 | ['« 1', '‹ 4', '· 5 ·', '6 ›', '10 »'],
358 | ], 'text', $keyboard);
359 | self::assertAllButtonPropertiesEqual([
360 | [
361 | sprintf($cbdata, $command, 5, 1),
362 | sprintf($cbdata, $command, 5, 4),
363 | sprintf($cbdata, $command, 5, 5),
364 | sprintf($cbdata, $command, 5, 6),
365 | sprintf($cbdata, $command, 5, 10),
366 | ],
367 | ], 'callback_data', $keyboard);
368 |
369 | // first, previous, current, last
370 | $keyboard = [$ikp10->getPagination(9)['keyboard']];
371 | self::assertAllButtonPropertiesEqual([
372 | ['« 1', '‹ 7', '8', '· 9 ·', '10'],
373 | ], 'text', $keyboard);
374 | self::assertAllButtonPropertiesEqual([
375 | [
376 | sprintf($cbdata, $command, 9, 1),
377 | sprintf($cbdata, $command, 9, 7),
378 | sprintf($cbdata, $command, 9, 8),
379 | sprintf($cbdata, $command, 9, 9),
380 | sprintf($cbdata, $command, 9, 10),
381 | ],
382 | ], 'callback_data', $keyboard);
383 |
384 | // first, previous, current
385 | $keyboard = [$ikp10->getPagination(10)['keyboard']];
386 | self::assertAllButtonPropertiesEqual([
387 | ['« 1', '‹ 7', '8', '9', '· 10 ·'],
388 | ], 'text', $keyboard);
389 | self::assertAllButtonPropertiesEqual([
390 | [
391 | sprintf($cbdata, $command, 10, 1),
392 | sprintf($cbdata, $command, 10, 7),
393 | sprintf($cbdata, $command, 10, 8),
394 | sprintf($cbdata, $command, 10, 9),
395 | sprintf($cbdata, $command, 10, 10),
396 | ],
397 | ], 'callback_data', $keyboard);
398 |
399 | // custom labels, skipping some buttons
400 | // first, previous, current, next, last
401 | $labels = [
402 | 'first' => '',
403 | 'previous' => 'previous %d',
404 | 'current' => null,
405 | 'next' => '%d next',
406 | 'last' => 'last',
407 | ];
408 | $ikp10->setLabels($labels);
409 | self::assertEquals($labels, $ikp10->getLabels());
410 |
411 | $keyboard = [$ikp10->getPagination(5)['keyboard']];
412 | self::assertAllButtonPropertiesEqual([
413 | ['previous 4', '6 next', 'last'],
414 | ], 'text', $keyboard);
415 | self::assertAllButtonPropertiesEqual([
416 | [
417 | sprintf($cbdata, $command, 5, 4),
418 | sprintf($cbdata, $command, 5, 6),
419 | sprintf($cbdata, $command, 5, 10),
420 | ],
421 | ], 'callback_data', $keyboard);
422 | }
423 |
424 | public static function assertButtonPropertiesEqual($value, $property, $keyboard, $row, $column, $message = ''): void
425 | {
426 | $row_raw = array_values($keyboard)[$row];
427 | $column_raw = array_values($row_raw)[$column];
428 |
429 | self::assertSame($value, $column_raw[$property], $message);
430 | }
431 |
432 | public static function assertRowButtonPropertiesEqual(array $values, $property, $keyboard, $row, $message = ''): void
433 | {
434 | $column = 0;
435 | foreach ($values as $value) {
436 | self::assertButtonPropertiesEqual($value, $property, $keyboard, $row, $column++, $message);
437 | }
438 | self::assertCount(count(array_values($keyboard)[$row]), $values);
439 | }
440 |
441 | public static function assertAllButtonPropertiesEqual(array $all_values, $property, $keyboard, $message = ''): void
442 | {
443 | $row = 0;
444 | foreach ($all_values as $values) {
445 | self::assertRowButtonPropertiesEqual($values, $property, $keyboard, $row++, $message);
446 | }
447 | self::assertCount(count($keyboard), $all_values);
448 | }
449 | }
450 |
--------------------------------------------------------------------------------