├── .gitignore ├── phpunit.xml.dist ├── .github └── workflows │ └── test.yml ├── LICENSE ├── composer.json ├── tests ├── TelegramFormatterTest.php └── TelegramHandlerTest.php ├── README.md ├── src ├── TelegramFormatter.php └── TelegramHandler.php └── composer.lock /.gitignore: -------------------------------------------------------------------------------- 1 | /vendor 2 | /test.php 3 | /.env 4 | /.phpunit.result.cache 5 | -------------------------------------------------------------------------------- /phpunit.xml.dist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | ./src 6 | 7 | 8 | 9 | 10 | ./tests/ 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Test code 2 | 3 | on: 4 | push: 5 | pull_request: 6 | workflow_dispatch: 7 | 8 | jobs: 9 | tests: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: Checkout the repository 13 | uses: actions/checkout@v3 14 | 15 | - name: Cache Composer dependencies 16 | uses: actions/cache@v2 17 | with: 18 | path: /tmp/composer-cache 19 | key: ${{ runner.os }}-${{ hashFiles('**/composer.lock') }} 20 | 21 | - name: Install PHP dependencies through Composer 22 | uses: php-actions/composer@v6 23 | 24 | - name: Check code using PHP_CodeSniffer 25 | run: composer check-code 26 | 27 | - name: Run tests using PHPUnit 28 | run: composer test 29 | env: 30 | TELEGRAM_TOKEN: '${{ secrets.TELEGRAM_TOKEN }}' 31 | TELEGRAM_CHAT_ID: '${{ secrets.TELEGRAM_CHAT_ID }}' 32 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2018-2025 Jack'lul 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jacklul/monolog-telegram", 3 | "type": "library", 4 | "description": "Monolog handler that sends logs through Telegram bot to any chat in HTML format", 5 | "keywords": [ 6 | "monolog", 7 | "telegram", 8 | "log", 9 | "logging", 10 | "bot" 11 | ], 12 | "license": "MIT", 13 | "support": { 14 | "issues": "https://github.com/jacklul/monolog-telegram/issues", 15 | "source": "https://github.com/jacklul/monolog-telegram" 16 | }, 17 | "authors": [ 18 | { 19 | "name": "Jack'lul", 20 | "email": "jacklulcat@gmail.com", 21 | "homepage": "https://jacklul.github.io", 22 | "role": "Developer" 23 | } 24 | ], 25 | "require": { 26 | "php": "^8.1", 27 | "ext-json": "*", 28 | "ext-mbstring": "*", 29 | "monolog/monolog": "^3.0" 30 | }, 31 | "require-dev": { 32 | "ext-curl": "*", 33 | "squizlabs/php_codesniffer": "^3.2", 34 | "phpunit/phpunit": "^9.0", 35 | "vlucas/phpdotenv": "^5.0" 36 | }, 37 | "suggest": { 38 | "ext-curl": "cURL generally works better and is recommended" 39 | }, 40 | "autoload": { 41 | "psr-4": { 42 | "jacklul\\MonologTelegramHandler\\": "src/" 43 | } 44 | }, 45 | "autoload-dev": { 46 | "psr-4": { 47 | "jacklul\\MonologTelegramHandler\\Tests\\": "tests/" 48 | } 49 | }, 50 | "scripts": { 51 | "check-code": [ 52 | "\"vendor/bin/phpcs\" -snp --standard=PSR2 --encoding=utf-8 --report-width=150 src/ tests/" 53 | ], 54 | "test": [ 55 | "\"vendor/bin/phpunit\"" 56 | ] 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /tests/TelegramFormatterTest.php: -------------------------------------------------------------------------------- 1 | record = new LogRecord( 17 | new \DateTimeImmutable(), 18 | 'test channel', 19 | Level::Error, 20 | 'PHP Fatal error: Uncaught Exception: test in /tmp/test/test.php:17 21 | Stack trace: 22 | #0 /tmp/test/testclass.php(91): send() 23 | #1 /tmp/test/testclass.php(31): prepare() 24 | #2 {main} 25 | thrown in /tmp/test/test.php on line 17', 26 | ['type' => 'exception'], 27 | ['extra' => 'parameter'] 28 | ); 29 | 30 | parent::__construct($name, $data, $dataName); 31 | } 32 | 33 | public function testFormatter(): void 34 | { 35 | $formatter = new TelegramFormatter(); 36 | $output = $formatter->format($this->record); 37 | 38 | $this->assertStringContainsString('ERROR (test channel) ', $output); 39 | $this->assertStringContainsString('Context: {"type":"exception"}', $output); 40 | $this->assertStringContainsString('Extra: {"extra":"parameter"}', $output); 41 | 42 | $formatter = new TelegramFormatter(false); 43 | $output = $formatter->format($this->record); 44 | 45 | $this->assertStringContainsString('ERROR (test channel) ', $output); 46 | $this->assertStringContainsString('Context: {"type":"exception"}', $output); 47 | $this->assertStringContainsString('Extra: {"extra":"parameter"}', $output); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Monolog Telegram Handler 2 | 3 | Send your logs through Telegram bot to any chat and make them look fancy! 4 | 5 | #### Features: 6 | - [Continous logging](https://i.imgur.com/8EnxO90.jpg) and [batch logging](https://i.imgur.com/4C9Y6cT.jpg) support 7 | - Standard stack traces wrapped in `` tags 8 | - Automatic splitting of the message when it exceeds maximum limit 9 | 10 | ## Prerequisites 11 | 12 | - Telegram Bot API token - [see here](https://core.telegram.org/bots#creating-a-new-bot) to learn how to obtain one 13 | - ID of the chat to which you want to send the logs - see below 14 | 15 | #### Obtaining chat ID 16 | 17 | One of the simplest ways to do that is to interact with the bot in the target chat: 18 | - private and group chats - send any dummy command 19 | - channels - post something in it 20 | 21 | After interacting visit `https://api.telegram.org/botTOKEN/getUpdates` (replace `TOKEN` with your actual bot token), you will be able to find the chat id (`chat_id`) in the result JSON. 22 | 23 | ## Installation 24 | 25 | Install with [Composer](https://github.com/composer/composer): 26 | 27 | ```bash 28 | $ composer require jacklul/monolog-telegram 29 | ``` 30 | 31 | ## Usage 32 | 33 | To use this handler you just have to add it like every other **Monolog** handler: 34 | 35 | ```php 36 | require 'vendor/autoload.php'; 37 | 38 | $logger = new Logger('My project'); 39 | $handler = new TelegramHandler( 40 | '123456789:teMbvbETojnSG93jDhnynvH8pT28H9TIB1h', // Bot API token 41 | 987654321, // Target Chat ID 42 | Logger::ERROR, // Log level, default: DEBUG 43 | true, // Bubble up the stack or not, default: true 44 | true, // Use cURL or not? default: true = use when available 45 | 10, // Timeout for API requests, default: 10 46 | true // Verify SSL certificate or not? default: true, false only useful for development - avoid in production 47 | 2, // (optional) Target Thread ID for group chats with Topics enabled 48 | ); 49 | 50 | $handler->setFormatter(new TelegramFormatter()); // Usage of this formatter is optional but recommended if you want better message layout 51 | $logger->pushHandler($handler); 52 | 53 | $logger->error('Error!'); 54 | ``` 55 | 56 | To prevent spamming the chat and hitting Telegram's API limits it is advised to use 57 | [DeduplicationHandler](https://github.com/Seldaek/monolog/blob/master/src/Monolog/Handler/DeduplicationHandler.php) and/or [BufferHandler](https://github.com/Seldaek/monolog/blob/master/src/Monolog/Handler/BufferHandler.php), ideal solution for production use would be: 58 | 59 | ```php 60 | $handler = new TelegramHandler('TOKEN', 123456789); 61 | $handler->setFormatter(new TelegramFormatter()); 62 | 63 | // Combine all log entries into one and force batch processing 64 | $handler = new BufferHandler($handler); 65 | 66 | // Make sure that particular log stack wasn't sent before 67 | $handler = new DeduplicationHandler($handler); 68 | 69 | // Keep collecting logs until ERROR occurs, after that send collected logs to $handler 70 | $handler = new FingersCrossedHandler($handler, new ErrorLevelActivationStrategy(Logger::ERROR)); 71 | 72 | $logger->pushHandler($handler); 73 | ``` 74 | 75 | You can customize the formatter: 76 | 77 | ```php 78 | $html = true; // Choose whether to send the message in HTMl format 79 | $format = "%emoji% %level_name% (%channel%) [%date%]\n\n%message%\n\n%context%%extra%"; // EMOJI ERROR (My project) [2018-05-01 15:55:15 UTC] 80 | $date_format = 'Y-m-d H:i:s e'; // 2018-05-01 15:55:15 UTC, format must be supported by DateTime::format 81 | $separator = '-'; // Seperation character for batch processing - when empty one empty line is used 82 | $emojis = [ // Override any level emoji 83 | 'NOTICE' => '🤖' 84 | ]; 85 | 86 | $handler->setFormatter(new TelegramFormatter($html, $format, $date_format, $separator, $emojis)); 87 | ``` 88 | 89 | ## Running tests 90 | 91 | Create `.env` file: 92 | ``` 93 | TELEGRAM_TOKEN=BOT_TOKEN 94 | TELEGRAM_CHAT_ID=CHAT_ID_THE_BOT_WILL_SPAM; 95 | ``` 96 | 97 | Run `composer check-code` and `composer test`. 98 | 99 | ## License 100 | 101 | See [LICENSE](LICENSE). 102 | -------------------------------------------------------------------------------- /tests/TelegramHandlerTest.php: -------------------------------------------------------------------------------- 1 | load(); 22 | } 23 | 24 | $this->token = $_ENV['TELEGRAM_TOKEN'] ?? getenv('TELEGRAM_TOKEN'); 25 | $this->chat_id = (int) ($_ENV['TELEGRAM_CHAT_ID'] ?? getenv('TELEGRAM_CHAT_ID')); 26 | 27 | parent::__construct($name, $data, $dataName); 28 | } 29 | 30 | public function testWithValidArguments(): void 31 | { 32 | if (empty($this->token) || empty($this->chat_id)) { 33 | $this->markTestSkipped('Either token or chat id was not provided'); 34 | } 35 | 36 | $logger = new Logger('PHPUnit'); 37 | $handler = new TelegramHandler($this->token, $this->chat_id, Level::Debug, true, false); 38 | $logger->pushHandler($handler); 39 | 40 | try { 41 | $logger->debug('PHPUnit - test with valid arguments: ' . PHP_EOL . str_repeat('-', 4096)); 42 | } catch (\Exception $e) { 43 | $this->fail('Exception was thrown: ' . $e->getMessage()); 44 | } 45 | 46 | sleep(1); 47 | 48 | if (extension_loaded('curl')) { 49 | $logger = new Logger('PHPUnit'); 50 | $handler = new TelegramHandler($this->token, $this->chat_id, Level::Debug); 51 | $logger->pushHandler($handler); 52 | 53 | try { 54 | $logger->debug('PHPUnit - test with valid arguments using cURL: ' . PHP_EOL . str_repeat('-', 4096)); 55 | } catch (\Exception $e) { 56 | $this->fail('Exception was thrown: ' . $e->getMessage()); 57 | } 58 | 59 | $this->assertTrue(true); 60 | 61 | sleep(1); 62 | } 63 | 64 | $this->assertTrue(true); 65 | 66 | $logger = new Logger('PHPUnit'); 67 | $handler = new TelegramHandler($this->token, $this->chat_id, Level::Debug); 68 | $handler = new BufferHandler($handler); 69 | $logger->pushHandler($handler); 70 | 71 | try { 72 | $logger->debug('PHPUnit - Batch processing test 1'); 73 | $logger->debug('PHPUnit - Batch processing test 2'); 74 | $logger->debug('PHPUnit - Batch processing test 3'); 75 | $handler->close(); 76 | } catch (\Exception $e) { 77 | $this->fail('Exception was thrown: ' . $e->getMessage()); 78 | } 79 | 80 | $this->assertTrue(true); 81 | } 82 | 83 | public function testWithInvalidToken(): void 84 | { 85 | sleep(1); 86 | 87 | $this->expectException(\RuntimeException::class); 88 | $this->expectExceptionMessage('Not Found'); 89 | 90 | if (extension_loaded('curl')) { 91 | $logger = new Logger('PHPUnit'); 92 | $handler = new TelegramHandler('token', $this->chat_id, Level::Debug); 93 | $logger->pushHandler($handler); 94 | 95 | $logger->debug('PHPUnit'); 96 | } 97 | 98 | $logger = new Logger('PHPUnit'); 99 | $handler = new TelegramHandler('token', $this->chat_id, Level::Debug, true, false); 100 | $logger->pushHandler($handler); 101 | 102 | $logger->debug('PHPUnit'); 103 | } 104 | 105 | public function testWithInvalidChatId(): void 106 | { 107 | sleep(1); 108 | 109 | if (empty($this->token)) { 110 | $this->markTestSkipped('Token was not provided'); 111 | } 112 | 113 | $this->expectException(\RuntimeException::class); 114 | $this->expectExceptionMessage('Bad Request'); 115 | 116 | if (extension_loaded('curl')) { 117 | $logger = new Logger('PHPUnit'); 118 | $handler = new TelegramHandler($this->token, 123, Level::Debug); 119 | $logger->pushHandler($handler); 120 | 121 | $logger->debug('PHPUnit'); 122 | } 123 | 124 | $logger = new Logger('PHPUnit'); 125 | $handler = new TelegramHandler($this->token, 123, Level::Debug, true, false); 126 | $logger->pushHandler($handler); 127 | 128 | $logger->debug('PHPUnit'); 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /src/TelegramFormatter.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace jacklul\MonologTelegramHandler; 13 | 14 | use Monolog\Formatter\FormatterInterface; 15 | use Monolog\Formatter\LineFormatter; 16 | use Monolog\LogRecord; 17 | 18 | /** 19 | * Formats a message to output suitable for Telegram chat 20 | */ 21 | class TelegramFormatter implements FormatterInterface 22 | { 23 | const MESSAGE_FORMAT = "%emoji% %level_name% (%channel%) [%date%]\n\n%message%\n\n%context%%extra%"; 24 | const DATE_FORMAT = 'Y-m-d H:i:s e'; 25 | 26 | /** 27 | * @var bool 28 | */ 29 | private $html; 30 | 31 | /** 32 | * @var string 33 | */ 34 | private $format; 35 | 36 | /** 37 | * @var string 38 | */ 39 | private $dateFormat; 40 | 41 | /** 42 | * @var string 43 | */ 44 | private $separator; 45 | 46 | /** 47 | * @var array 48 | */ 49 | private $emojis = [ 50 | 'DEBUG' => '🐞', 51 | 'INFO' => 'ℹ️', 52 | 'NOTICE' => '📌', 53 | 'WARNING' => '⚠️', 54 | 'ERROR' => '❌', 55 | 'CRITICAL' => '💀', 56 | 'ALERT' => '🛎️', 57 | 'EMERGENCY' => '🚨', 58 | ]; 59 | 60 | /** 61 | * Formatter constructor 62 | * 63 | * @param bool $html Format as HTML or not 64 | * @param string|null $format The format of the message 65 | * @param string|null $dateFormat The format of the timestamp: one supported by DateTime::format 66 | * @param string $separator Record separator used when sending batch of logs in one message 67 | * @param array|null $emojiArray Array containing emojis for each record level name 68 | */ 69 | public function __construct(bool $html = true, ?string $format = null, ?string $dateFormat = null, string $separator = '-', ?array $emojiArray = null) 70 | { 71 | $this->html = $html; 72 | $this->format = $format ?: self::MESSAGE_FORMAT; 73 | $this->dateFormat = $dateFormat ?: self::DATE_FORMAT; 74 | $this->separator = $separator; 75 | $emojiArray !== null && $this->emojis = array_replace($this->emojis, $emojiArray); 76 | } 77 | 78 | /** 79 | * {@inheritdoc} 80 | */ 81 | public function format(LogRecord $record): string 82 | { 83 | $message = $this->format; 84 | $lineFormatter = new LineFormatter(); 85 | 86 | $tmpmessage = preg_replace('/<([^<]+)>/', '<$1>', $record['message']); // Replace '<' and '>' with their special codes 87 | $tmpmessage = preg_replace('/^Stack trace:\n((^#\d.*\n?)*)$/m', "\nStack trace:\n$1", $tmpmessage); // Put the stack trace inside tags 88 | $message = str_replace('%message%', $tmpmessage, $message); 89 | 90 | if ($record['context']) { 91 | $context = 'Context: '; 92 | $context .= $lineFormatter->stringify($record['context']); 93 | $message = str_replace('%context%', $context . "\n", $message); 94 | } else { 95 | $message = str_replace('%context%', '', $message); 96 | } 97 | 98 | if ($record['extra']) { 99 | $extra = 'Extra: '; 100 | $extra .= $lineFormatter->stringify($record['extra']); 101 | $message = str_replace('%extra%', $extra . "\n", $message); 102 | } else { 103 | $message = str_replace('%extra%', '', $message); 104 | } 105 | 106 | $emoji = $this->emojis[$record['level_name']] ?? $this->emojis['DEFAULT'] ?? '🐞'; 107 | 108 | /** @param \DateTimeImmutable $record['datetime'] */ 109 | $message = str_replace(['%emoji%', '%level_name%', '%channel%', '%date%'], [$emoji, $record['level_name'], $record['channel'], $record['datetime']->format($this->dateFormat)], $message); 110 | 111 | if ($this->html === false) { 112 | $message = strip_tags($message); 113 | } 114 | 115 | return $message; 116 | } 117 | 118 | /** 119 | * {@inheritdoc} 120 | */ 121 | public function formatBatch(array $records): string 122 | { 123 | $message = ''; 124 | foreach ($records as $record) { 125 | if (!empty($message)) { 126 | $message .= str_repeat($this->separator, 15) . "\n"; 127 | } 128 | 129 | $message .= $this->format($record); 130 | } 131 | 132 | return $message; 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /src/TelegramHandler.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | namespace jacklul\MonologTelegramHandler; 12 | 13 | use Monolog\Handler\AbstractProcessingHandler; 14 | use Monolog\Level; 15 | use Monolog\LogRecord; 16 | 17 | /** 18 | * Sends logs to chats through Telegram bot 19 | * 20 | * $logger = new Logger('telegram-logger'); 21 | * $handler = new TelegramHandler('123456789:teMbvbETojnSG93jDhnynvH8pT28H9TIB1h', 1234567); 22 | * $handler->setFormatter(new TelegramFormatter()); 23 | * $logger->pushHandler($handler); 24 | */ 25 | class TelegramHandler extends AbstractProcessingHandler 26 | { 27 | const BASE_URI = 'https://api.telegram.org'; 28 | 29 | /** 30 | * Bot API token 31 | * 32 | * @var string 33 | */ 34 | private string $token; 35 | 36 | /** 37 | * Chat ID 38 | * 39 | * @var int 40 | */ 41 | private int $chatId; 42 | 43 | /** 44 | * Use cURL extension? 45 | * 46 | * @var bool 47 | */ 48 | private bool $useCurl; 49 | 50 | /** 51 | * Timeout for requests 52 | * 53 | * @var int 54 | */ 55 | private int $timeout; 56 | 57 | /** 58 | * Verify SSL certificate? 59 | * 60 | * @var bool 61 | */ 62 | private bool $verifyPeer; 63 | 64 | /** 65 | * Thread ID for group chats with Topics feature enabled. 66 | * 67 | * Allows to send a message in a specific thread, instead of "General". 68 | * 69 | * @var int|null 70 | */ 71 | private ?int $messageThreadId; 72 | 73 | /** 74 | * @param string $token Telegram bot API token 75 | * @param int $chatId Chat ID to which logs will be sent 76 | * @param int|string|Level $level The minimum logging level at which this handler will be triggered 77 | * @param bool $bubble Whether the messages that are handled can bubble up the stack or not 78 | * @param bool $useCurl Whether to use cURL extension when available or not 79 | * @param int $timeout Maximum time to wait for requests to finish 80 | * @param bool $verifyPeer Whether to use SSL certificate verification or not 81 | * @param int|null $messageThreadId Thread ID for group chats with Topics feature enabled 82 | */ 83 | public function __construct(string $token, int $chatId, int|string|Level $level = Level::Debug, bool $bubble = true, bool $useCurl = true, int $timeout = 10, bool $verifyPeer = true, ?int $messageThreadId = null) 84 | { 85 | $this->token = $token; 86 | $this->chatId = $chatId; 87 | $this->useCurl = $useCurl; 88 | $this->timeout = $timeout; 89 | $this->verifyPeer = $verifyPeer; 90 | $this->messageThreadId = $messageThreadId; 91 | 92 | parent::__construct($level, $bubble); 93 | } 94 | 95 | /** 96 | * {@inheritdoc} 97 | */ 98 | protected function write(LogRecord $record): void 99 | { 100 | $message = $record['formatted'] ?? $record['message']; 101 | 102 | // When message is too long we have to remove HTML tags so that the message can be properly split 103 | if (mb_strlen($message, 'UTF-8') > 4096) { 104 | $message = strip_tags($message); 105 | } 106 | 107 | // Split the message and send it in parts when needed 108 | do { 109 | $message_part = mb_substr($message, 0, 4096); 110 | $this->send($message_part); 111 | $message = mb_substr($message, 4096); 112 | } while ($message !== ''); 113 | } 114 | 115 | /** 116 | * {@inheritdoc} 117 | */ 118 | public function handleBatch(array $records): void 119 | { 120 | $messages = []; 121 | foreach ($records as $record) { 122 | if ($record['level'] < $this->level) { 123 | continue; 124 | } 125 | 126 | $messages[] = $this->processRecord($record); 127 | } 128 | 129 | if (!empty($messages)) { 130 | $datetime = new \DateTimeImmutable(); 131 | 132 | $this->write( 133 | new LogRecord( 134 | $datetime, 135 | '', 136 | Level::Debug, 137 | '', 138 | [], 139 | [], 140 | $this->getFormatter()->formatBatch($messages) 141 | ) 142 | ); 143 | } 144 | } 145 | 146 | /** 147 | * Send sendMessage request to Telegram Bot API 148 | * 149 | * @param string $message The message to send 150 | * 151 | * @return bool 152 | */ 153 | private function send(string $message): bool 154 | { 155 | $url = self::BASE_URI . '/bot' . $this->token . '/sendMessage'; 156 | $data = [ 157 | 'chat_id' => $this->chatId, 158 | 'text' => $message, 159 | 'disable_web_page_preview' => true // Just in case there is a link in the message 160 | ]; 161 | 162 | // Set HTML parse mode when HTML code is detected 163 | if (preg_match('/<[^<]+>/', $data['text']) !== false) { 164 | $data['parse_mode'] = 'HTML'; 165 | } 166 | 167 | if ($this->messageThreadId) { 168 | $data['message_thread_id'] = $this->messageThreadId; 169 | } 170 | 171 | if ($this->useCurl === true && extension_loaded('curl')) { 172 | $ch = curl_init(); 173 | 174 | curl_setopt($ch, CURLOPT_URL, $url); 175 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 176 | curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data)); 177 | curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, $this->verifyPeer); 178 | curl_setopt($ch, CURLOPT_TIMEOUT, $this->timeout); 179 | 180 | $result = curl_exec($ch); 181 | if (!$result) { 182 | throw new \RuntimeException('Request to Telegram API failed: ' . curl_error($ch)); 183 | } 184 | } else { 185 | $opts = [ 186 | 'http' => [ 187 | 'method' => 'POST', 188 | 'header' => 'Content-type: application/x-www-form-urlencoded', 189 | 'content' => http_build_query($data), 190 | 'timeout' => $this->timeout, 191 | ], 192 | 'ssl' => [ 193 | 'verify_peer' => $this->verifyPeer, 194 | 'verify_peer_name' => $this->verifyPeer, 195 | ], 196 | ]; 197 | 198 | $result = @file_get_contents($url, false, stream_context_create($opts)); 199 | if (!$result) { 200 | $error = error_get_last(); 201 | if (isset($error['message'])) { 202 | throw new \RuntimeException('Request to Telegram API failed: ' . $error['message']); 203 | } 204 | 205 | throw new \RuntimeException('Request to Telegram API failed'); 206 | } 207 | } 208 | 209 | $result = json_decode($result, true); 210 | if (isset($result['ok']) && $result['ok'] === true) { 211 | return true; 212 | } 213 | 214 | if (isset($result['description'])) { 215 | throw new \RuntimeException('Telegram API error: ' . $result['description']); 216 | } 217 | 218 | return false; 219 | } 220 | } 221 | -------------------------------------------------------------------------------- /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": "a46a49e06a6601c8d5fb563aefc07c8e", 8 | "packages": [ 9 | { 10 | "name": "monolog/monolog", 11 | "version": "3.2.0", 12 | "source": { 13 | "type": "git", 14 | "url": "https://github.com/Seldaek/monolog.git", 15 | "reference": "305444bc6fb6c89e490f4b34fa6e979584d7fa81" 16 | }, 17 | "dist": { 18 | "type": "zip", 19 | "url": "https://api.github.com/repos/Seldaek/monolog/zipball/305444bc6fb6c89e490f4b34fa6e979584d7fa81", 20 | "reference": "305444bc6fb6c89e490f4b34fa6e979584d7fa81", 21 | "shasum": "" 22 | }, 23 | "require": { 24 | "php": ">=8.1", 25 | "psr/log": "^2.0 || ^3.0" 26 | }, 27 | "provide": { 28 | "psr/log-implementation": "3.0.0" 29 | }, 30 | "require-dev": { 31 | "aws/aws-sdk-php": "^3.0", 32 | "doctrine/couchdb": "~1.0@dev", 33 | "elasticsearch/elasticsearch": "^7 || ^8", 34 | "ext-json": "*", 35 | "graylog2/gelf-php": "^1.4.2", 36 | "guzzlehttp/guzzle": "^7.4", 37 | "guzzlehttp/psr7": "^2.2", 38 | "mongodb/mongodb": "^1.8", 39 | "php-amqplib/php-amqplib": "~2.4 || ^3", 40 | "phpstan/phpstan": "^1.4", 41 | "phpstan/phpstan-deprecation-rules": "^1.0", 42 | "phpstan/phpstan-strict-rules": "^1.1", 43 | "phpunit/phpunit": "^9.5.16", 44 | "predis/predis": "^1.1", 45 | "ruflin/elastica": "^7", 46 | "symfony/mailer": "^5.4 || ^6", 47 | "symfony/mime": "^5.4 || ^6" 48 | }, 49 | "suggest": { 50 | "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB", 51 | "doctrine/couchdb": "Allow sending log messages to a CouchDB server", 52 | "elasticsearch/elasticsearch": "Allow sending log messages to an Elasticsearch server via official client", 53 | "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)", 54 | "ext-curl": "Required to send log messages using the IFTTTHandler, the LogglyHandler, the SendGridHandler, the SlackWebhookHandler or the TelegramBotHandler", 55 | "ext-mbstring": "Allow to work properly with unicode symbols", 56 | "ext-mongodb": "Allow sending log messages to a MongoDB server (via driver)", 57 | "ext-openssl": "Required to send log messages using SSL", 58 | "ext-sockets": "Allow sending log messages to a Syslog server (via UDP driver)", 59 | "graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server", 60 | "mongodb/mongodb": "Allow sending log messages to a MongoDB server (via library)", 61 | "php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib", 62 | "rollbar/rollbar": "Allow sending log messages to Rollbar", 63 | "ruflin/elastica": "Allow sending log messages to an Elastic Search server" 64 | }, 65 | "type": "library", 66 | "extra": { 67 | "branch-alias": { 68 | "dev-main": "3.x-dev" 69 | } 70 | }, 71 | "autoload": { 72 | "psr-4": { 73 | "Monolog\\": "src/Monolog" 74 | } 75 | }, 76 | "notification-url": "https://packagist.org/downloads/", 77 | "license": [ 78 | "MIT" 79 | ], 80 | "authors": [ 81 | { 82 | "name": "Jordi Boggiano", 83 | "email": "j.boggiano@seld.be", 84 | "homepage": "https://seld.be" 85 | } 86 | ], 87 | "description": "Sends your logs to files, sockets, inboxes, databases and various web services", 88 | "homepage": "https://github.com/Seldaek/monolog", 89 | "keywords": [ 90 | "log", 91 | "logging", 92 | "psr-3" 93 | ], 94 | "support": { 95 | "issues": "https://github.com/Seldaek/monolog/issues", 96 | "source": "https://github.com/Seldaek/monolog/tree/3.2.0" 97 | }, 98 | "funding": [ 99 | { 100 | "url": "https://github.com/Seldaek", 101 | "type": "github" 102 | }, 103 | { 104 | "url": "https://tidelift.com/funding/github/packagist/monolog/monolog", 105 | "type": "tidelift" 106 | } 107 | ], 108 | "time": "2022-07-24T12:00:55+00:00" 109 | }, 110 | { 111 | "name": "psr/log", 112 | "version": "3.0.0", 113 | "source": { 114 | "type": "git", 115 | "url": "https://github.com/php-fig/log.git", 116 | "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001" 117 | }, 118 | "dist": { 119 | "type": "zip", 120 | "url": "https://api.github.com/repos/php-fig/log/zipball/fe5ea303b0887d5caefd3d431c3e61ad47037001", 121 | "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001", 122 | "shasum": "" 123 | }, 124 | "require": { 125 | "php": ">=8.0.0" 126 | }, 127 | "type": "library", 128 | "extra": { 129 | "branch-alias": { 130 | "dev-master": "3.x-dev" 131 | } 132 | }, 133 | "autoload": { 134 | "psr-4": { 135 | "Psr\\Log\\": "src" 136 | } 137 | }, 138 | "notification-url": "https://packagist.org/downloads/", 139 | "license": [ 140 | "MIT" 141 | ], 142 | "authors": [ 143 | { 144 | "name": "PHP-FIG", 145 | "homepage": "https://www.php-fig.org/" 146 | } 147 | ], 148 | "description": "Common interface for logging libraries", 149 | "homepage": "https://github.com/php-fig/log", 150 | "keywords": [ 151 | "log", 152 | "psr", 153 | "psr-3" 154 | ], 155 | "support": { 156 | "source": "https://github.com/php-fig/log/tree/3.0.0" 157 | }, 158 | "time": "2021-07-14T16:46:02+00:00" 159 | } 160 | ], 161 | "packages-dev": [ 162 | { 163 | "name": "doctrine/instantiator", 164 | "version": "2.0.0", 165 | "source": { 166 | "type": "git", 167 | "url": "https://github.com/doctrine/instantiator.git", 168 | "reference": "c6222283fa3f4ac679f8b9ced9a4e23f163e80d0" 169 | }, 170 | "dist": { 171 | "type": "zip", 172 | "url": "https://api.github.com/repos/doctrine/instantiator/zipball/c6222283fa3f4ac679f8b9ced9a4e23f163e80d0", 173 | "reference": "c6222283fa3f4ac679f8b9ced9a4e23f163e80d0", 174 | "shasum": "" 175 | }, 176 | "require": { 177 | "php": "^8.1" 178 | }, 179 | "require-dev": { 180 | "doctrine/coding-standard": "^11", 181 | "ext-pdo": "*", 182 | "ext-phar": "*", 183 | "phpbench/phpbench": "^1.2", 184 | "phpstan/phpstan": "^1.9.4", 185 | "phpstan/phpstan-phpunit": "^1.3", 186 | "phpunit/phpunit": "^9.5.27", 187 | "vimeo/psalm": "^5.4" 188 | }, 189 | "type": "library", 190 | "autoload": { 191 | "psr-4": { 192 | "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" 193 | } 194 | }, 195 | "notification-url": "https://packagist.org/downloads/", 196 | "license": [ 197 | "MIT" 198 | ], 199 | "authors": [ 200 | { 201 | "name": "Marco Pivetta", 202 | "email": "ocramius@gmail.com", 203 | "homepage": "https://ocramius.github.io/" 204 | } 205 | ], 206 | "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", 207 | "homepage": "https://www.doctrine-project.org/projects/instantiator.html", 208 | "keywords": [ 209 | "constructor", 210 | "instantiate" 211 | ], 212 | "support": { 213 | "issues": "https://github.com/doctrine/instantiator/issues", 214 | "source": "https://github.com/doctrine/instantiator/tree/2.0.0" 215 | }, 216 | "funding": [ 217 | { 218 | "url": "https://www.doctrine-project.org/sponsorship.html", 219 | "type": "custom" 220 | }, 221 | { 222 | "url": "https://www.patreon.com/phpdoctrine", 223 | "type": "patreon" 224 | }, 225 | { 226 | "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator", 227 | "type": "tidelift" 228 | } 229 | ], 230 | "time": "2022-12-30T00:23:10+00:00" 231 | }, 232 | { 233 | "name": "graham-campbell/result-type", 234 | "version": "v1.1.0", 235 | "source": { 236 | "type": "git", 237 | "url": "https://github.com/GrahamCampbell/Result-Type.git", 238 | "reference": "a878d45c1914464426dc94da61c9e1d36ae262a8" 239 | }, 240 | "dist": { 241 | "type": "zip", 242 | "url": "https://api.github.com/repos/GrahamCampbell/Result-Type/zipball/a878d45c1914464426dc94da61c9e1d36ae262a8", 243 | "reference": "a878d45c1914464426dc94da61c9e1d36ae262a8", 244 | "shasum": "" 245 | }, 246 | "require": { 247 | "php": "^7.2.5 || ^8.0", 248 | "phpoption/phpoption": "^1.9" 249 | }, 250 | "require-dev": { 251 | "phpunit/phpunit": "^8.5.28 || ^9.5.21" 252 | }, 253 | "type": "library", 254 | "autoload": { 255 | "psr-4": { 256 | "GrahamCampbell\\ResultType\\": "src/" 257 | } 258 | }, 259 | "notification-url": "https://packagist.org/downloads/", 260 | "license": [ 261 | "MIT" 262 | ], 263 | "authors": [ 264 | { 265 | "name": "Graham Campbell", 266 | "email": "hello@gjcampbell.co.uk", 267 | "homepage": "https://github.com/GrahamCampbell" 268 | } 269 | ], 270 | "description": "An Implementation Of The Result Type", 271 | "keywords": [ 272 | "Graham Campbell", 273 | "GrahamCampbell", 274 | "Result Type", 275 | "Result-Type", 276 | "result" 277 | ], 278 | "support": { 279 | "issues": "https://github.com/GrahamCampbell/Result-Type/issues", 280 | "source": "https://github.com/GrahamCampbell/Result-Type/tree/v1.1.0" 281 | }, 282 | "funding": [ 283 | { 284 | "url": "https://github.com/GrahamCampbell", 285 | "type": "github" 286 | }, 287 | { 288 | "url": "https://tidelift.com/funding/github/packagist/graham-campbell/result-type", 289 | "type": "tidelift" 290 | } 291 | ], 292 | "time": "2022-07-30T15:56:11+00:00" 293 | }, 294 | { 295 | "name": "myclabs/deep-copy", 296 | "version": "1.11.0", 297 | "source": { 298 | "type": "git", 299 | "url": "https://github.com/myclabs/DeepCopy.git", 300 | "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614" 301 | }, 302 | "dist": { 303 | "type": "zip", 304 | "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/14daed4296fae74d9e3201d2c4925d1acb7aa614", 305 | "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614", 306 | "shasum": "" 307 | }, 308 | "require": { 309 | "php": "^7.1 || ^8.0" 310 | }, 311 | "conflict": { 312 | "doctrine/collections": "<1.6.8", 313 | "doctrine/common": "<2.13.3 || >=3,<3.2.2" 314 | }, 315 | "require-dev": { 316 | "doctrine/collections": "^1.6.8", 317 | "doctrine/common": "^2.13.3 || ^3.2.2", 318 | "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" 319 | }, 320 | "type": "library", 321 | "autoload": { 322 | "files": [ 323 | "src/DeepCopy/deep_copy.php" 324 | ], 325 | "psr-4": { 326 | "DeepCopy\\": "src/DeepCopy/" 327 | } 328 | }, 329 | "notification-url": "https://packagist.org/downloads/", 330 | "license": [ 331 | "MIT" 332 | ], 333 | "description": "Create deep copies (clones) of your objects", 334 | "keywords": [ 335 | "clone", 336 | "copy", 337 | "duplicate", 338 | "object", 339 | "object graph" 340 | ], 341 | "support": { 342 | "issues": "https://github.com/myclabs/DeepCopy/issues", 343 | "source": "https://github.com/myclabs/DeepCopy/tree/1.11.0" 344 | }, 345 | "funding": [ 346 | { 347 | "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", 348 | "type": "tidelift" 349 | } 350 | ], 351 | "time": "2022-03-03T13:19:32+00:00" 352 | }, 353 | { 354 | "name": "nikic/php-parser", 355 | "version": "v4.15.3", 356 | "source": { 357 | "type": "git", 358 | "url": "https://github.com/nikic/PHP-Parser.git", 359 | "reference": "570e980a201d8ed0236b0a62ddf2c9cbb2034039" 360 | }, 361 | "dist": { 362 | "type": "zip", 363 | "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/570e980a201d8ed0236b0a62ddf2c9cbb2034039", 364 | "reference": "570e980a201d8ed0236b0a62ddf2c9cbb2034039", 365 | "shasum": "" 366 | }, 367 | "require": { 368 | "ext-tokenizer": "*", 369 | "php": ">=7.0" 370 | }, 371 | "require-dev": { 372 | "ircmaxell/php-yacc": "^0.0.7", 373 | "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0" 374 | }, 375 | "bin": [ 376 | "bin/php-parse" 377 | ], 378 | "type": "library", 379 | "extra": { 380 | "branch-alias": { 381 | "dev-master": "4.9-dev" 382 | } 383 | }, 384 | "autoload": { 385 | "psr-4": { 386 | "PhpParser\\": "lib/PhpParser" 387 | } 388 | }, 389 | "notification-url": "https://packagist.org/downloads/", 390 | "license": [ 391 | "BSD-3-Clause" 392 | ], 393 | "authors": [ 394 | { 395 | "name": "Nikita Popov" 396 | } 397 | ], 398 | "description": "A PHP parser written in PHP", 399 | "keywords": [ 400 | "parser", 401 | "php" 402 | ], 403 | "support": { 404 | "issues": "https://github.com/nikic/PHP-Parser/issues", 405 | "source": "https://github.com/nikic/PHP-Parser/tree/v4.15.3" 406 | }, 407 | "time": "2023-01-16T22:05:37+00:00" 408 | }, 409 | { 410 | "name": "phar-io/manifest", 411 | "version": "2.0.3", 412 | "source": { 413 | "type": "git", 414 | "url": "https://github.com/phar-io/manifest.git", 415 | "reference": "97803eca37d319dfa7826cc2437fc020857acb53" 416 | }, 417 | "dist": { 418 | "type": "zip", 419 | "url": "https://api.github.com/repos/phar-io/manifest/zipball/97803eca37d319dfa7826cc2437fc020857acb53", 420 | "reference": "97803eca37d319dfa7826cc2437fc020857acb53", 421 | "shasum": "" 422 | }, 423 | "require": { 424 | "ext-dom": "*", 425 | "ext-phar": "*", 426 | "ext-xmlwriter": "*", 427 | "phar-io/version": "^3.0.1", 428 | "php": "^7.2 || ^8.0" 429 | }, 430 | "type": "library", 431 | "extra": { 432 | "branch-alias": { 433 | "dev-master": "2.0.x-dev" 434 | } 435 | }, 436 | "autoload": { 437 | "classmap": [ 438 | "src/" 439 | ] 440 | }, 441 | "notification-url": "https://packagist.org/downloads/", 442 | "license": [ 443 | "BSD-3-Clause" 444 | ], 445 | "authors": [ 446 | { 447 | "name": "Arne Blankerts", 448 | "email": "arne@blankerts.de", 449 | "role": "Developer" 450 | }, 451 | { 452 | "name": "Sebastian Heuer", 453 | "email": "sebastian@phpeople.de", 454 | "role": "Developer" 455 | }, 456 | { 457 | "name": "Sebastian Bergmann", 458 | "email": "sebastian@phpunit.de", 459 | "role": "Developer" 460 | } 461 | ], 462 | "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", 463 | "support": { 464 | "issues": "https://github.com/phar-io/manifest/issues", 465 | "source": "https://github.com/phar-io/manifest/tree/2.0.3" 466 | }, 467 | "time": "2021-07-20T11:28:43+00:00" 468 | }, 469 | { 470 | "name": "phar-io/version", 471 | "version": "3.2.1", 472 | "source": { 473 | "type": "git", 474 | "url": "https://github.com/phar-io/version.git", 475 | "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74" 476 | }, 477 | "dist": { 478 | "type": "zip", 479 | "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74", 480 | "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74", 481 | "shasum": "" 482 | }, 483 | "require": { 484 | "php": "^7.2 || ^8.0" 485 | }, 486 | "type": "library", 487 | "autoload": { 488 | "classmap": [ 489 | "src/" 490 | ] 491 | }, 492 | "notification-url": "https://packagist.org/downloads/", 493 | "license": [ 494 | "BSD-3-Clause" 495 | ], 496 | "authors": [ 497 | { 498 | "name": "Arne Blankerts", 499 | "email": "arne@blankerts.de", 500 | "role": "Developer" 501 | }, 502 | { 503 | "name": "Sebastian Heuer", 504 | "email": "sebastian@phpeople.de", 505 | "role": "Developer" 506 | }, 507 | { 508 | "name": "Sebastian Bergmann", 509 | "email": "sebastian@phpunit.de", 510 | "role": "Developer" 511 | } 512 | ], 513 | "description": "Library for handling version information and constraints", 514 | "support": { 515 | "issues": "https://github.com/phar-io/version/issues", 516 | "source": "https://github.com/phar-io/version/tree/3.2.1" 517 | }, 518 | "time": "2022-02-21T01:04:05+00:00" 519 | }, 520 | { 521 | "name": "phpoption/phpoption", 522 | "version": "1.9.0", 523 | "source": { 524 | "type": "git", 525 | "url": "https://github.com/schmittjoh/php-option.git", 526 | "reference": "dc5ff11e274a90cc1c743f66c9ad700ce50db9ab" 527 | }, 528 | "dist": { 529 | "type": "zip", 530 | "url": "https://api.github.com/repos/schmittjoh/php-option/zipball/dc5ff11e274a90cc1c743f66c9ad700ce50db9ab", 531 | "reference": "dc5ff11e274a90cc1c743f66c9ad700ce50db9ab", 532 | "shasum": "" 533 | }, 534 | "require": { 535 | "php": "^7.2.5 || ^8.0" 536 | }, 537 | "require-dev": { 538 | "bamarni/composer-bin-plugin": "^1.8", 539 | "phpunit/phpunit": "^8.5.28 || ^9.5.21" 540 | }, 541 | "type": "library", 542 | "extra": { 543 | "bamarni-bin": { 544 | "bin-links": true, 545 | "forward-command": true 546 | }, 547 | "branch-alias": { 548 | "dev-master": "1.9-dev" 549 | } 550 | }, 551 | "autoload": { 552 | "psr-4": { 553 | "PhpOption\\": "src/PhpOption/" 554 | } 555 | }, 556 | "notification-url": "https://packagist.org/downloads/", 557 | "license": [ 558 | "Apache-2.0" 559 | ], 560 | "authors": [ 561 | { 562 | "name": "Johannes M. Schmitt", 563 | "email": "schmittjoh@gmail.com", 564 | "homepage": "https://github.com/schmittjoh" 565 | }, 566 | { 567 | "name": "Graham Campbell", 568 | "email": "hello@gjcampbell.co.uk", 569 | "homepage": "https://github.com/GrahamCampbell" 570 | } 571 | ], 572 | "description": "Option Type for PHP", 573 | "keywords": [ 574 | "language", 575 | "option", 576 | "php", 577 | "type" 578 | ], 579 | "support": { 580 | "issues": "https://github.com/schmittjoh/php-option/issues", 581 | "source": "https://github.com/schmittjoh/php-option/tree/1.9.0" 582 | }, 583 | "funding": [ 584 | { 585 | "url": "https://github.com/GrahamCampbell", 586 | "type": "github" 587 | }, 588 | { 589 | "url": "https://tidelift.com/funding/github/packagist/phpoption/phpoption", 590 | "type": "tidelift" 591 | } 592 | ], 593 | "time": "2022-07-30T15:51:26+00:00" 594 | }, 595 | { 596 | "name": "phpunit/php-code-coverage", 597 | "version": "9.2.24", 598 | "source": { 599 | "type": "git", 600 | "url": "https://github.com/sebastianbergmann/php-code-coverage.git", 601 | "reference": "2cf940ebc6355a9d430462811b5aaa308b174bed" 602 | }, 603 | "dist": { 604 | "type": "zip", 605 | "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/2cf940ebc6355a9d430462811b5aaa308b174bed", 606 | "reference": "2cf940ebc6355a9d430462811b5aaa308b174bed", 607 | "shasum": "" 608 | }, 609 | "require": { 610 | "ext-dom": "*", 611 | "ext-libxml": "*", 612 | "ext-xmlwriter": "*", 613 | "nikic/php-parser": "^4.14", 614 | "php": ">=7.3", 615 | "phpunit/php-file-iterator": "^3.0.3", 616 | "phpunit/php-text-template": "^2.0.2", 617 | "sebastian/code-unit-reverse-lookup": "^2.0.2", 618 | "sebastian/complexity": "^2.0", 619 | "sebastian/environment": "^5.1.2", 620 | "sebastian/lines-of-code": "^1.0.3", 621 | "sebastian/version": "^3.0.1", 622 | "theseer/tokenizer": "^1.2.0" 623 | }, 624 | "require-dev": { 625 | "phpunit/phpunit": "^9.3" 626 | }, 627 | "suggest": { 628 | "ext-pcov": "*", 629 | "ext-xdebug": "*" 630 | }, 631 | "type": "library", 632 | "extra": { 633 | "branch-alias": { 634 | "dev-master": "9.2-dev" 635 | } 636 | }, 637 | "autoload": { 638 | "classmap": [ 639 | "src/" 640 | ] 641 | }, 642 | "notification-url": "https://packagist.org/downloads/", 643 | "license": [ 644 | "BSD-3-Clause" 645 | ], 646 | "authors": [ 647 | { 648 | "name": "Sebastian Bergmann", 649 | "email": "sebastian@phpunit.de", 650 | "role": "lead" 651 | } 652 | ], 653 | "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", 654 | "homepage": "https://github.com/sebastianbergmann/php-code-coverage", 655 | "keywords": [ 656 | "coverage", 657 | "testing", 658 | "xunit" 659 | ], 660 | "support": { 661 | "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", 662 | "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.24" 663 | }, 664 | "funding": [ 665 | { 666 | "url": "https://github.com/sebastianbergmann", 667 | "type": "github" 668 | } 669 | ], 670 | "time": "2023-01-26T08:26:55+00:00" 671 | }, 672 | { 673 | "name": "phpunit/php-file-iterator", 674 | "version": "3.0.6", 675 | "source": { 676 | "type": "git", 677 | "url": "https://github.com/sebastianbergmann/php-file-iterator.git", 678 | "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf" 679 | }, 680 | "dist": { 681 | "type": "zip", 682 | "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", 683 | "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", 684 | "shasum": "" 685 | }, 686 | "require": { 687 | "php": ">=7.3" 688 | }, 689 | "require-dev": { 690 | "phpunit/phpunit": "^9.3" 691 | }, 692 | "type": "library", 693 | "extra": { 694 | "branch-alias": { 695 | "dev-master": "3.0-dev" 696 | } 697 | }, 698 | "autoload": { 699 | "classmap": [ 700 | "src/" 701 | ] 702 | }, 703 | "notification-url": "https://packagist.org/downloads/", 704 | "license": [ 705 | "BSD-3-Clause" 706 | ], 707 | "authors": [ 708 | { 709 | "name": "Sebastian Bergmann", 710 | "email": "sebastian@phpunit.de", 711 | "role": "lead" 712 | } 713 | ], 714 | "description": "FilterIterator implementation that filters files based on a list of suffixes.", 715 | "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", 716 | "keywords": [ 717 | "filesystem", 718 | "iterator" 719 | ], 720 | "support": { 721 | "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", 722 | "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.6" 723 | }, 724 | "funding": [ 725 | { 726 | "url": "https://github.com/sebastianbergmann", 727 | "type": "github" 728 | } 729 | ], 730 | "time": "2021-12-02T12:48:52+00:00" 731 | }, 732 | { 733 | "name": "phpunit/php-invoker", 734 | "version": "3.1.1", 735 | "source": { 736 | "type": "git", 737 | "url": "https://github.com/sebastianbergmann/php-invoker.git", 738 | "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67" 739 | }, 740 | "dist": { 741 | "type": "zip", 742 | "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/5a10147d0aaf65b58940a0b72f71c9ac0423cc67", 743 | "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67", 744 | "shasum": "" 745 | }, 746 | "require": { 747 | "php": ">=7.3" 748 | }, 749 | "require-dev": { 750 | "ext-pcntl": "*", 751 | "phpunit/phpunit": "^9.3" 752 | }, 753 | "suggest": { 754 | "ext-pcntl": "*" 755 | }, 756 | "type": "library", 757 | "extra": { 758 | "branch-alias": { 759 | "dev-master": "3.1-dev" 760 | } 761 | }, 762 | "autoload": { 763 | "classmap": [ 764 | "src/" 765 | ] 766 | }, 767 | "notification-url": "https://packagist.org/downloads/", 768 | "license": [ 769 | "BSD-3-Clause" 770 | ], 771 | "authors": [ 772 | { 773 | "name": "Sebastian Bergmann", 774 | "email": "sebastian@phpunit.de", 775 | "role": "lead" 776 | } 777 | ], 778 | "description": "Invoke callables with a timeout", 779 | "homepage": "https://github.com/sebastianbergmann/php-invoker/", 780 | "keywords": [ 781 | "process" 782 | ], 783 | "support": { 784 | "issues": "https://github.com/sebastianbergmann/php-invoker/issues", 785 | "source": "https://github.com/sebastianbergmann/php-invoker/tree/3.1.1" 786 | }, 787 | "funding": [ 788 | { 789 | "url": "https://github.com/sebastianbergmann", 790 | "type": "github" 791 | } 792 | ], 793 | "time": "2020-09-28T05:58:55+00:00" 794 | }, 795 | { 796 | "name": "phpunit/php-text-template", 797 | "version": "2.0.4", 798 | "source": { 799 | "type": "git", 800 | "url": "https://github.com/sebastianbergmann/php-text-template.git", 801 | "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28" 802 | }, 803 | "dist": { 804 | "type": "zip", 805 | "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", 806 | "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", 807 | "shasum": "" 808 | }, 809 | "require": { 810 | "php": ">=7.3" 811 | }, 812 | "require-dev": { 813 | "phpunit/phpunit": "^9.3" 814 | }, 815 | "type": "library", 816 | "extra": { 817 | "branch-alias": { 818 | "dev-master": "2.0-dev" 819 | } 820 | }, 821 | "autoload": { 822 | "classmap": [ 823 | "src/" 824 | ] 825 | }, 826 | "notification-url": "https://packagist.org/downloads/", 827 | "license": [ 828 | "BSD-3-Clause" 829 | ], 830 | "authors": [ 831 | { 832 | "name": "Sebastian Bergmann", 833 | "email": "sebastian@phpunit.de", 834 | "role": "lead" 835 | } 836 | ], 837 | "description": "Simple template engine.", 838 | "homepage": "https://github.com/sebastianbergmann/php-text-template/", 839 | "keywords": [ 840 | "template" 841 | ], 842 | "support": { 843 | "issues": "https://github.com/sebastianbergmann/php-text-template/issues", 844 | "source": "https://github.com/sebastianbergmann/php-text-template/tree/2.0.4" 845 | }, 846 | "funding": [ 847 | { 848 | "url": "https://github.com/sebastianbergmann", 849 | "type": "github" 850 | } 851 | ], 852 | "time": "2020-10-26T05:33:50+00:00" 853 | }, 854 | { 855 | "name": "phpunit/php-timer", 856 | "version": "5.0.3", 857 | "source": { 858 | "type": "git", 859 | "url": "https://github.com/sebastianbergmann/php-timer.git", 860 | "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2" 861 | }, 862 | "dist": { 863 | "type": "zip", 864 | "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", 865 | "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", 866 | "shasum": "" 867 | }, 868 | "require": { 869 | "php": ">=7.3" 870 | }, 871 | "require-dev": { 872 | "phpunit/phpunit": "^9.3" 873 | }, 874 | "type": "library", 875 | "extra": { 876 | "branch-alias": { 877 | "dev-master": "5.0-dev" 878 | } 879 | }, 880 | "autoload": { 881 | "classmap": [ 882 | "src/" 883 | ] 884 | }, 885 | "notification-url": "https://packagist.org/downloads/", 886 | "license": [ 887 | "BSD-3-Clause" 888 | ], 889 | "authors": [ 890 | { 891 | "name": "Sebastian Bergmann", 892 | "email": "sebastian@phpunit.de", 893 | "role": "lead" 894 | } 895 | ], 896 | "description": "Utility class for timing", 897 | "homepage": "https://github.com/sebastianbergmann/php-timer/", 898 | "keywords": [ 899 | "timer" 900 | ], 901 | "support": { 902 | "issues": "https://github.com/sebastianbergmann/php-timer/issues", 903 | "source": "https://github.com/sebastianbergmann/php-timer/tree/5.0.3" 904 | }, 905 | "funding": [ 906 | { 907 | "url": "https://github.com/sebastianbergmann", 908 | "type": "github" 909 | } 910 | ], 911 | "time": "2020-10-26T13:16:10+00:00" 912 | }, 913 | { 914 | "name": "phpunit/phpunit", 915 | "version": "9.5.28", 916 | "source": { 917 | "type": "git", 918 | "url": "https://github.com/sebastianbergmann/phpunit.git", 919 | "reference": "954ca3113a03bf780d22f07bf055d883ee04b65e" 920 | }, 921 | "dist": { 922 | "type": "zip", 923 | "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/954ca3113a03bf780d22f07bf055d883ee04b65e", 924 | "reference": "954ca3113a03bf780d22f07bf055d883ee04b65e", 925 | "shasum": "" 926 | }, 927 | "require": { 928 | "doctrine/instantiator": "^1.3.1 || ^2", 929 | "ext-dom": "*", 930 | "ext-json": "*", 931 | "ext-libxml": "*", 932 | "ext-mbstring": "*", 933 | "ext-xml": "*", 934 | "ext-xmlwriter": "*", 935 | "myclabs/deep-copy": "^1.10.1", 936 | "phar-io/manifest": "^2.0.3", 937 | "phar-io/version": "^3.0.2", 938 | "php": ">=7.3", 939 | "phpunit/php-code-coverage": "^9.2.13", 940 | "phpunit/php-file-iterator": "^3.0.5", 941 | "phpunit/php-invoker": "^3.1.1", 942 | "phpunit/php-text-template": "^2.0.3", 943 | "phpunit/php-timer": "^5.0.2", 944 | "sebastian/cli-parser": "^1.0.1", 945 | "sebastian/code-unit": "^1.0.6", 946 | "sebastian/comparator": "^4.0.8", 947 | "sebastian/diff": "^4.0.3", 948 | "sebastian/environment": "^5.1.3", 949 | "sebastian/exporter": "^4.0.5", 950 | "sebastian/global-state": "^5.0.1", 951 | "sebastian/object-enumerator": "^4.0.3", 952 | "sebastian/resource-operations": "^3.0.3", 953 | "sebastian/type": "^3.2", 954 | "sebastian/version": "^3.0.2" 955 | }, 956 | "suggest": { 957 | "ext-soap": "*", 958 | "ext-xdebug": "*" 959 | }, 960 | "bin": [ 961 | "phpunit" 962 | ], 963 | "type": "library", 964 | "extra": { 965 | "branch-alias": { 966 | "dev-master": "9.5-dev" 967 | } 968 | }, 969 | "autoload": { 970 | "files": [ 971 | "src/Framework/Assert/Functions.php" 972 | ], 973 | "classmap": [ 974 | "src/" 975 | ] 976 | }, 977 | "notification-url": "https://packagist.org/downloads/", 978 | "license": [ 979 | "BSD-3-Clause" 980 | ], 981 | "authors": [ 982 | { 983 | "name": "Sebastian Bergmann", 984 | "email": "sebastian@phpunit.de", 985 | "role": "lead" 986 | } 987 | ], 988 | "description": "The PHP Unit Testing framework.", 989 | "homepage": "https://phpunit.de/", 990 | "keywords": [ 991 | "phpunit", 992 | "testing", 993 | "xunit" 994 | ], 995 | "support": { 996 | "issues": "https://github.com/sebastianbergmann/phpunit/issues", 997 | "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.28" 998 | }, 999 | "funding": [ 1000 | { 1001 | "url": "https://phpunit.de/sponsors.html", 1002 | "type": "custom" 1003 | }, 1004 | { 1005 | "url": "https://github.com/sebastianbergmann", 1006 | "type": "github" 1007 | }, 1008 | { 1009 | "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit", 1010 | "type": "tidelift" 1011 | } 1012 | ], 1013 | "time": "2023-01-14T12:32:24+00:00" 1014 | }, 1015 | { 1016 | "name": "sebastian/cli-parser", 1017 | "version": "1.0.1", 1018 | "source": { 1019 | "type": "git", 1020 | "url": "https://github.com/sebastianbergmann/cli-parser.git", 1021 | "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2" 1022 | }, 1023 | "dist": { 1024 | "type": "zip", 1025 | "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/442e7c7e687e42adc03470c7b668bc4b2402c0b2", 1026 | "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2", 1027 | "shasum": "" 1028 | }, 1029 | "require": { 1030 | "php": ">=7.3" 1031 | }, 1032 | "require-dev": { 1033 | "phpunit/phpunit": "^9.3" 1034 | }, 1035 | "type": "library", 1036 | "extra": { 1037 | "branch-alias": { 1038 | "dev-master": "1.0-dev" 1039 | } 1040 | }, 1041 | "autoload": { 1042 | "classmap": [ 1043 | "src/" 1044 | ] 1045 | }, 1046 | "notification-url": "https://packagist.org/downloads/", 1047 | "license": [ 1048 | "BSD-3-Clause" 1049 | ], 1050 | "authors": [ 1051 | { 1052 | "name": "Sebastian Bergmann", 1053 | "email": "sebastian@phpunit.de", 1054 | "role": "lead" 1055 | } 1056 | ], 1057 | "description": "Library for parsing CLI options", 1058 | "homepage": "https://github.com/sebastianbergmann/cli-parser", 1059 | "support": { 1060 | "issues": "https://github.com/sebastianbergmann/cli-parser/issues", 1061 | "source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.1" 1062 | }, 1063 | "funding": [ 1064 | { 1065 | "url": "https://github.com/sebastianbergmann", 1066 | "type": "github" 1067 | } 1068 | ], 1069 | "time": "2020-09-28T06:08:49+00:00" 1070 | }, 1071 | { 1072 | "name": "sebastian/code-unit", 1073 | "version": "1.0.8", 1074 | "source": { 1075 | "type": "git", 1076 | "url": "https://github.com/sebastianbergmann/code-unit.git", 1077 | "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120" 1078 | }, 1079 | "dist": { 1080 | "type": "zip", 1081 | "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/1fc9f64c0927627ef78ba436c9b17d967e68e120", 1082 | "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120", 1083 | "shasum": "" 1084 | }, 1085 | "require": { 1086 | "php": ">=7.3" 1087 | }, 1088 | "require-dev": { 1089 | "phpunit/phpunit": "^9.3" 1090 | }, 1091 | "type": "library", 1092 | "extra": { 1093 | "branch-alias": { 1094 | "dev-master": "1.0-dev" 1095 | } 1096 | }, 1097 | "autoload": { 1098 | "classmap": [ 1099 | "src/" 1100 | ] 1101 | }, 1102 | "notification-url": "https://packagist.org/downloads/", 1103 | "license": [ 1104 | "BSD-3-Clause" 1105 | ], 1106 | "authors": [ 1107 | { 1108 | "name": "Sebastian Bergmann", 1109 | "email": "sebastian@phpunit.de", 1110 | "role": "lead" 1111 | } 1112 | ], 1113 | "description": "Collection of value objects that represent the PHP code units", 1114 | "homepage": "https://github.com/sebastianbergmann/code-unit", 1115 | "support": { 1116 | "issues": "https://github.com/sebastianbergmann/code-unit/issues", 1117 | "source": "https://github.com/sebastianbergmann/code-unit/tree/1.0.8" 1118 | }, 1119 | "funding": [ 1120 | { 1121 | "url": "https://github.com/sebastianbergmann", 1122 | "type": "github" 1123 | } 1124 | ], 1125 | "time": "2020-10-26T13:08:54+00:00" 1126 | }, 1127 | { 1128 | "name": "sebastian/code-unit-reverse-lookup", 1129 | "version": "2.0.3", 1130 | "source": { 1131 | "type": "git", 1132 | "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", 1133 | "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5" 1134 | }, 1135 | "dist": { 1136 | "type": "zip", 1137 | "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", 1138 | "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", 1139 | "shasum": "" 1140 | }, 1141 | "require": { 1142 | "php": ">=7.3" 1143 | }, 1144 | "require-dev": { 1145 | "phpunit/phpunit": "^9.3" 1146 | }, 1147 | "type": "library", 1148 | "extra": { 1149 | "branch-alias": { 1150 | "dev-master": "2.0-dev" 1151 | } 1152 | }, 1153 | "autoload": { 1154 | "classmap": [ 1155 | "src/" 1156 | ] 1157 | }, 1158 | "notification-url": "https://packagist.org/downloads/", 1159 | "license": [ 1160 | "BSD-3-Clause" 1161 | ], 1162 | "authors": [ 1163 | { 1164 | "name": "Sebastian Bergmann", 1165 | "email": "sebastian@phpunit.de" 1166 | } 1167 | ], 1168 | "description": "Looks up which function or method a line of code belongs to", 1169 | "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", 1170 | "support": { 1171 | "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", 1172 | "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/2.0.3" 1173 | }, 1174 | "funding": [ 1175 | { 1176 | "url": "https://github.com/sebastianbergmann", 1177 | "type": "github" 1178 | } 1179 | ], 1180 | "time": "2020-09-28T05:30:19+00:00" 1181 | }, 1182 | { 1183 | "name": "sebastian/comparator", 1184 | "version": "4.0.8", 1185 | "source": { 1186 | "type": "git", 1187 | "url": "https://github.com/sebastianbergmann/comparator.git", 1188 | "reference": "fa0f136dd2334583309d32b62544682ee972b51a" 1189 | }, 1190 | "dist": { 1191 | "type": "zip", 1192 | "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/fa0f136dd2334583309d32b62544682ee972b51a", 1193 | "reference": "fa0f136dd2334583309d32b62544682ee972b51a", 1194 | "shasum": "" 1195 | }, 1196 | "require": { 1197 | "php": ">=7.3", 1198 | "sebastian/diff": "^4.0", 1199 | "sebastian/exporter": "^4.0" 1200 | }, 1201 | "require-dev": { 1202 | "phpunit/phpunit": "^9.3" 1203 | }, 1204 | "type": "library", 1205 | "extra": { 1206 | "branch-alias": { 1207 | "dev-master": "4.0-dev" 1208 | } 1209 | }, 1210 | "autoload": { 1211 | "classmap": [ 1212 | "src/" 1213 | ] 1214 | }, 1215 | "notification-url": "https://packagist.org/downloads/", 1216 | "license": [ 1217 | "BSD-3-Clause" 1218 | ], 1219 | "authors": [ 1220 | { 1221 | "name": "Sebastian Bergmann", 1222 | "email": "sebastian@phpunit.de" 1223 | }, 1224 | { 1225 | "name": "Jeff Welch", 1226 | "email": "whatthejeff@gmail.com" 1227 | }, 1228 | { 1229 | "name": "Volker Dusch", 1230 | "email": "github@wallbash.com" 1231 | }, 1232 | { 1233 | "name": "Bernhard Schussek", 1234 | "email": "bschussek@2bepublished.at" 1235 | } 1236 | ], 1237 | "description": "Provides the functionality to compare PHP values for equality", 1238 | "homepage": "https://github.com/sebastianbergmann/comparator", 1239 | "keywords": [ 1240 | "comparator", 1241 | "compare", 1242 | "equality" 1243 | ], 1244 | "support": { 1245 | "issues": "https://github.com/sebastianbergmann/comparator/issues", 1246 | "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.8" 1247 | }, 1248 | "funding": [ 1249 | { 1250 | "url": "https://github.com/sebastianbergmann", 1251 | "type": "github" 1252 | } 1253 | ], 1254 | "time": "2022-09-14T12:41:17+00:00" 1255 | }, 1256 | { 1257 | "name": "sebastian/complexity", 1258 | "version": "2.0.2", 1259 | "source": { 1260 | "type": "git", 1261 | "url": "https://github.com/sebastianbergmann/complexity.git", 1262 | "reference": "739b35e53379900cc9ac327b2147867b8b6efd88" 1263 | }, 1264 | "dist": { 1265 | "type": "zip", 1266 | "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/739b35e53379900cc9ac327b2147867b8b6efd88", 1267 | "reference": "739b35e53379900cc9ac327b2147867b8b6efd88", 1268 | "shasum": "" 1269 | }, 1270 | "require": { 1271 | "nikic/php-parser": "^4.7", 1272 | "php": ">=7.3" 1273 | }, 1274 | "require-dev": { 1275 | "phpunit/phpunit": "^9.3" 1276 | }, 1277 | "type": "library", 1278 | "extra": { 1279 | "branch-alias": { 1280 | "dev-master": "2.0-dev" 1281 | } 1282 | }, 1283 | "autoload": { 1284 | "classmap": [ 1285 | "src/" 1286 | ] 1287 | }, 1288 | "notification-url": "https://packagist.org/downloads/", 1289 | "license": [ 1290 | "BSD-3-Clause" 1291 | ], 1292 | "authors": [ 1293 | { 1294 | "name": "Sebastian Bergmann", 1295 | "email": "sebastian@phpunit.de", 1296 | "role": "lead" 1297 | } 1298 | ], 1299 | "description": "Library for calculating the complexity of PHP code units", 1300 | "homepage": "https://github.com/sebastianbergmann/complexity", 1301 | "support": { 1302 | "issues": "https://github.com/sebastianbergmann/complexity/issues", 1303 | "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.2" 1304 | }, 1305 | "funding": [ 1306 | { 1307 | "url": "https://github.com/sebastianbergmann", 1308 | "type": "github" 1309 | } 1310 | ], 1311 | "time": "2020-10-26T15:52:27+00:00" 1312 | }, 1313 | { 1314 | "name": "sebastian/diff", 1315 | "version": "4.0.4", 1316 | "source": { 1317 | "type": "git", 1318 | "url": "https://github.com/sebastianbergmann/diff.git", 1319 | "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d" 1320 | }, 1321 | "dist": { 1322 | "type": "zip", 1323 | "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/3461e3fccc7cfdfc2720be910d3bd73c69be590d", 1324 | "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d", 1325 | "shasum": "" 1326 | }, 1327 | "require": { 1328 | "php": ">=7.3" 1329 | }, 1330 | "require-dev": { 1331 | "phpunit/phpunit": "^9.3", 1332 | "symfony/process": "^4.2 || ^5" 1333 | }, 1334 | "type": "library", 1335 | "extra": { 1336 | "branch-alias": { 1337 | "dev-master": "4.0-dev" 1338 | } 1339 | }, 1340 | "autoload": { 1341 | "classmap": [ 1342 | "src/" 1343 | ] 1344 | }, 1345 | "notification-url": "https://packagist.org/downloads/", 1346 | "license": [ 1347 | "BSD-3-Clause" 1348 | ], 1349 | "authors": [ 1350 | { 1351 | "name": "Sebastian Bergmann", 1352 | "email": "sebastian@phpunit.de" 1353 | }, 1354 | { 1355 | "name": "Kore Nordmann", 1356 | "email": "mail@kore-nordmann.de" 1357 | } 1358 | ], 1359 | "description": "Diff implementation", 1360 | "homepage": "https://github.com/sebastianbergmann/diff", 1361 | "keywords": [ 1362 | "diff", 1363 | "udiff", 1364 | "unidiff", 1365 | "unified diff" 1366 | ], 1367 | "support": { 1368 | "issues": "https://github.com/sebastianbergmann/diff/issues", 1369 | "source": "https://github.com/sebastianbergmann/diff/tree/4.0.4" 1370 | }, 1371 | "funding": [ 1372 | { 1373 | "url": "https://github.com/sebastianbergmann", 1374 | "type": "github" 1375 | } 1376 | ], 1377 | "time": "2020-10-26T13:10:38+00:00" 1378 | }, 1379 | { 1380 | "name": "sebastian/environment", 1381 | "version": "5.1.4", 1382 | "source": { 1383 | "type": "git", 1384 | "url": "https://github.com/sebastianbergmann/environment.git", 1385 | "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7" 1386 | }, 1387 | "dist": { 1388 | "type": "zip", 1389 | "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/1b5dff7bb151a4db11d49d90e5408e4e938270f7", 1390 | "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7", 1391 | "shasum": "" 1392 | }, 1393 | "require": { 1394 | "php": ">=7.3" 1395 | }, 1396 | "require-dev": { 1397 | "phpunit/phpunit": "^9.3" 1398 | }, 1399 | "suggest": { 1400 | "ext-posix": "*" 1401 | }, 1402 | "type": "library", 1403 | "extra": { 1404 | "branch-alias": { 1405 | "dev-master": "5.1-dev" 1406 | } 1407 | }, 1408 | "autoload": { 1409 | "classmap": [ 1410 | "src/" 1411 | ] 1412 | }, 1413 | "notification-url": "https://packagist.org/downloads/", 1414 | "license": [ 1415 | "BSD-3-Clause" 1416 | ], 1417 | "authors": [ 1418 | { 1419 | "name": "Sebastian Bergmann", 1420 | "email": "sebastian@phpunit.de" 1421 | } 1422 | ], 1423 | "description": "Provides functionality to handle HHVM/PHP environments", 1424 | "homepage": "http://www.github.com/sebastianbergmann/environment", 1425 | "keywords": [ 1426 | "Xdebug", 1427 | "environment", 1428 | "hhvm" 1429 | ], 1430 | "support": { 1431 | "issues": "https://github.com/sebastianbergmann/environment/issues", 1432 | "source": "https://github.com/sebastianbergmann/environment/tree/5.1.4" 1433 | }, 1434 | "funding": [ 1435 | { 1436 | "url": "https://github.com/sebastianbergmann", 1437 | "type": "github" 1438 | } 1439 | ], 1440 | "time": "2022-04-03T09:37:03+00:00" 1441 | }, 1442 | { 1443 | "name": "sebastian/exporter", 1444 | "version": "4.0.5", 1445 | "source": { 1446 | "type": "git", 1447 | "url": "https://github.com/sebastianbergmann/exporter.git", 1448 | "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d" 1449 | }, 1450 | "dist": { 1451 | "type": "zip", 1452 | "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", 1453 | "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", 1454 | "shasum": "" 1455 | }, 1456 | "require": { 1457 | "php": ">=7.3", 1458 | "sebastian/recursion-context": "^4.0" 1459 | }, 1460 | "require-dev": { 1461 | "ext-mbstring": "*", 1462 | "phpunit/phpunit": "^9.3" 1463 | }, 1464 | "type": "library", 1465 | "extra": { 1466 | "branch-alias": { 1467 | "dev-master": "4.0-dev" 1468 | } 1469 | }, 1470 | "autoload": { 1471 | "classmap": [ 1472 | "src/" 1473 | ] 1474 | }, 1475 | "notification-url": "https://packagist.org/downloads/", 1476 | "license": [ 1477 | "BSD-3-Clause" 1478 | ], 1479 | "authors": [ 1480 | { 1481 | "name": "Sebastian Bergmann", 1482 | "email": "sebastian@phpunit.de" 1483 | }, 1484 | { 1485 | "name": "Jeff Welch", 1486 | "email": "whatthejeff@gmail.com" 1487 | }, 1488 | { 1489 | "name": "Volker Dusch", 1490 | "email": "github@wallbash.com" 1491 | }, 1492 | { 1493 | "name": "Adam Harvey", 1494 | "email": "aharvey@php.net" 1495 | }, 1496 | { 1497 | "name": "Bernhard Schussek", 1498 | "email": "bschussek@gmail.com" 1499 | } 1500 | ], 1501 | "description": "Provides the functionality to export PHP variables for visualization", 1502 | "homepage": "https://www.github.com/sebastianbergmann/exporter", 1503 | "keywords": [ 1504 | "export", 1505 | "exporter" 1506 | ], 1507 | "support": { 1508 | "issues": "https://github.com/sebastianbergmann/exporter/issues", 1509 | "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.5" 1510 | }, 1511 | "funding": [ 1512 | { 1513 | "url": "https://github.com/sebastianbergmann", 1514 | "type": "github" 1515 | } 1516 | ], 1517 | "time": "2022-09-14T06:03:37+00:00" 1518 | }, 1519 | { 1520 | "name": "sebastian/global-state", 1521 | "version": "5.0.5", 1522 | "source": { 1523 | "type": "git", 1524 | "url": "https://github.com/sebastianbergmann/global-state.git", 1525 | "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2" 1526 | }, 1527 | "dist": { 1528 | "type": "zip", 1529 | "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/0ca8db5a5fc9c8646244e629625ac486fa286bf2", 1530 | "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2", 1531 | "shasum": "" 1532 | }, 1533 | "require": { 1534 | "php": ">=7.3", 1535 | "sebastian/object-reflector": "^2.0", 1536 | "sebastian/recursion-context": "^4.0" 1537 | }, 1538 | "require-dev": { 1539 | "ext-dom": "*", 1540 | "phpunit/phpunit": "^9.3" 1541 | }, 1542 | "suggest": { 1543 | "ext-uopz": "*" 1544 | }, 1545 | "type": "library", 1546 | "extra": { 1547 | "branch-alias": { 1548 | "dev-master": "5.0-dev" 1549 | } 1550 | }, 1551 | "autoload": { 1552 | "classmap": [ 1553 | "src/" 1554 | ] 1555 | }, 1556 | "notification-url": "https://packagist.org/downloads/", 1557 | "license": [ 1558 | "BSD-3-Clause" 1559 | ], 1560 | "authors": [ 1561 | { 1562 | "name": "Sebastian Bergmann", 1563 | "email": "sebastian@phpunit.de" 1564 | } 1565 | ], 1566 | "description": "Snapshotting of global state", 1567 | "homepage": "http://www.github.com/sebastianbergmann/global-state", 1568 | "keywords": [ 1569 | "global state" 1570 | ], 1571 | "support": { 1572 | "issues": "https://github.com/sebastianbergmann/global-state/issues", 1573 | "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.5" 1574 | }, 1575 | "funding": [ 1576 | { 1577 | "url": "https://github.com/sebastianbergmann", 1578 | "type": "github" 1579 | } 1580 | ], 1581 | "time": "2022-02-14T08:28:10+00:00" 1582 | }, 1583 | { 1584 | "name": "sebastian/lines-of-code", 1585 | "version": "1.0.3", 1586 | "source": { 1587 | "type": "git", 1588 | "url": "https://github.com/sebastianbergmann/lines-of-code.git", 1589 | "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc" 1590 | }, 1591 | "dist": { 1592 | "type": "zip", 1593 | "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/c1c2e997aa3146983ed888ad08b15470a2e22ecc", 1594 | "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc", 1595 | "shasum": "" 1596 | }, 1597 | "require": { 1598 | "nikic/php-parser": "^4.6", 1599 | "php": ">=7.3" 1600 | }, 1601 | "require-dev": { 1602 | "phpunit/phpunit": "^9.3" 1603 | }, 1604 | "type": "library", 1605 | "extra": { 1606 | "branch-alias": { 1607 | "dev-master": "1.0-dev" 1608 | } 1609 | }, 1610 | "autoload": { 1611 | "classmap": [ 1612 | "src/" 1613 | ] 1614 | }, 1615 | "notification-url": "https://packagist.org/downloads/", 1616 | "license": [ 1617 | "BSD-3-Clause" 1618 | ], 1619 | "authors": [ 1620 | { 1621 | "name": "Sebastian Bergmann", 1622 | "email": "sebastian@phpunit.de", 1623 | "role": "lead" 1624 | } 1625 | ], 1626 | "description": "Library for counting the lines of code in PHP source code", 1627 | "homepage": "https://github.com/sebastianbergmann/lines-of-code", 1628 | "support": { 1629 | "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", 1630 | "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.3" 1631 | }, 1632 | "funding": [ 1633 | { 1634 | "url": "https://github.com/sebastianbergmann", 1635 | "type": "github" 1636 | } 1637 | ], 1638 | "time": "2020-11-28T06:42:11+00:00" 1639 | }, 1640 | { 1641 | "name": "sebastian/object-enumerator", 1642 | "version": "4.0.4", 1643 | "source": { 1644 | "type": "git", 1645 | "url": "https://github.com/sebastianbergmann/object-enumerator.git", 1646 | "reference": "5c9eeac41b290a3712d88851518825ad78f45c71" 1647 | }, 1648 | "dist": { 1649 | "type": "zip", 1650 | "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/5c9eeac41b290a3712d88851518825ad78f45c71", 1651 | "reference": "5c9eeac41b290a3712d88851518825ad78f45c71", 1652 | "shasum": "" 1653 | }, 1654 | "require": { 1655 | "php": ">=7.3", 1656 | "sebastian/object-reflector": "^2.0", 1657 | "sebastian/recursion-context": "^4.0" 1658 | }, 1659 | "require-dev": { 1660 | "phpunit/phpunit": "^9.3" 1661 | }, 1662 | "type": "library", 1663 | "extra": { 1664 | "branch-alias": { 1665 | "dev-master": "4.0-dev" 1666 | } 1667 | }, 1668 | "autoload": { 1669 | "classmap": [ 1670 | "src/" 1671 | ] 1672 | }, 1673 | "notification-url": "https://packagist.org/downloads/", 1674 | "license": [ 1675 | "BSD-3-Clause" 1676 | ], 1677 | "authors": [ 1678 | { 1679 | "name": "Sebastian Bergmann", 1680 | "email": "sebastian@phpunit.de" 1681 | } 1682 | ], 1683 | "description": "Traverses array structures and object graphs to enumerate all referenced objects", 1684 | "homepage": "https://github.com/sebastianbergmann/object-enumerator/", 1685 | "support": { 1686 | "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", 1687 | "source": "https://github.com/sebastianbergmann/object-enumerator/tree/4.0.4" 1688 | }, 1689 | "funding": [ 1690 | { 1691 | "url": "https://github.com/sebastianbergmann", 1692 | "type": "github" 1693 | } 1694 | ], 1695 | "time": "2020-10-26T13:12:34+00:00" 1696 | }, 1697 | { 1698 | "name": "sebastian/object-reflector", 1699 | "version": "2.0.4", 1700 | "source": { 1701 | "type": "git", 1702 | "url": "https://github.com/sebastianbergmann/object-reflector.git", 1703 | "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7" 1704 | }, 1705 | "dist": { 1706 | "type": "zip", 1707 | "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", 1708 | "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", 1709 | "shasum": "" 1710 | }, 1711 | "require": { 1712 | "php": ">=7.3" 1713 | }, 1714 | "require-dev": { 1715 | "phpunit/phpunit": "^9.3" 1716 | }, 1717 | "type": "library", 1718 | "extra": { 1719 | "branch-alias": { 1720 | "dev-master": "2.0-dev" 1721 | } 1722 | }, 1723 | "autoload": { 1724 | "classmap": [ 1725 | "src/" 1726 | ] 1727 | }, 1728 | "notification-url": "https://packagist.org/downloads/", 1729 | "license": [ 1730 | "BSD-3-Clause" 1731 | ], 1732 | "authors": [ 1733 | { 1734 | "name": "Sebastian Bergmann", 1735 | "email": "sebastian@phpunit.de" 1736 | } 1737 | ], 1738 | "description": "Allows reflection of object attributes, including inherited and non-public ones", 1739 | "homepage": "https://github.com/sebastianbergmann/object-reflector/", 1740 | "support": { 1741 | "issues": "https://github.com/sebastianbergmann/object-reflector/issues", 1742 | "source": "https://github.com/sebastianbergmann/object-reflector/tree/2.0.4" 1743 | }, 1744 | "funding": [ 1745 | { 1746 | "url": "https://github.com/sebastianbergmann", 1747 | "type": "github" 1748 | } 1749 | ], 1750 | "time": "2020-10-26T13:14:26+00:00" 1751 | }, 1752 | { 1753 | "name": "sebastian/recursion-context", 1754 | "version": "4.0.4", 1755 | "source": { 1756 | "type": "git", 1757 | "url": "https://github.com/sebastianbergmann/recursion-context.git", 1758 | "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172" 1759 | }, 1760 | "dist": { 1761 | "type": "zip", 1762 | "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/cd9d8cf3c5804de4341c283ed787f099f5506172", 1763 | "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172", 1764 | "shasum": "" 1765 | }, 1766 | "require": { 1767 | "php": ">=7.3" 1768 | }, 1769 | "require-dev": { 1770 | "phpunit/phpunit": "^9.3" 1771 | }, 1772 | "type": "library", 1773 | "extra": { 1774 | "branch-alias": { 1775 | "dev-master": "4.0-dev" 1776 | } 1777 | }, 1778 | "autoload": { 1779 | "classmap": [ 1780 | "src/" 1781 | ] 1782 | }, 1783 | "notification-url": "https://packagist.org/downloads/", 1784 | "license": [ 1785 | "BSD-3-Clause" 1786 | ], 1787 | "authors": [ 1788 | { 1789 | "name": "Sebastian Bergmann", 1790 | "email": "sebastian@phpunit.de" 1791 | }, 1792 | { 1793 | "name": "Jeff Welch", 1794 | "email": "whatthejeff@gmail.com" 1795 | }, 1796 | { 1797 | "name": "Adam Harvey", 1798 | "email": "aharvey@php.net" 1799 | } 1800 | ], 1801 | "description": "Provides functionality to recursively process PHP variables", 1802 | "homepage": "http://www.github.com/sebastianbergmann/recursion-context", 1803 | "support": { 1804 | "issues": "https://github.com/sebastianbergmann/recursion-context/issues", 1805 | "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.4" 1806 | }, 1807 | "funding": [ 1808 | { 1809 | "url": "https://github.com/sebastianbergmann", 1810 | "type": "github" 1811 | } 1812 | ], 1813 | "time": "2020-10-26T13:17:30+00:00" 1814 | }, 1815 | { 1816 | "name": "sebastian/resource-operations", 1817 | "version": "3.0.3", 1818 | "source": { 1819 | "type": "git", 1820 | "url": "https://github.com/sebastianbergmann/resource-operations.git", 1821 | "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8" 1822 | }, 1823 | "dist": { 1824 | "type": "zip", 1825 | "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", 1826 | "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", 1827 | "shasum": "" 1828 | }, 1829 | "require": { 1830 | "php": ">=7.3" 1831 | }, 1832 | "require-dev": { 1833 | "phpunit/phpunit": "^9.0" 1834 | }, 1835 | "type": "library", 1836 | "extra": { 1837 | "branch-alias": { 1838 | "dev-master": "3.0-dev" 1839 | } 1840 | }, 1841 | "autoload": { 1842 | "classmap": [ 1843 | "src/" 1844 | ] 1845 | }, 1846 | "notification-url": "https://packagist.org/downloads/", 1847 | "license": [ 1848 | "BSD-3-Clause" 1849 | ], 1850 | "authors": [ 1851 | { 1852 | "name": "Sebastian Bergmann", 1853 | "email": "sebastian@phpunit.de" 1854 | } 1855 | ], 1856 | "description": "Provides a list of PHP built-in functions that operate on resources", 1857 | "homepage": "https://www.github.com/sebastianbergmann/resource-operations", 1858 | "support": { 1859 | "issues": "https://github.com/sebastianbergmann/resource-operations/issues", 1860 | "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.3" 1861 | }, 1862 | "funding": [ 1863 | { 1864 | "url": "https://github.com/sebastianbergmann", 1865 | "type": "github" 1866 | } 1867 | ], 1868 | "time": "2020-09-28T06:45:17+00:00" 1869 | }, 1870 | { 1871 | "name": "sebastian/type", 1872 | "version": "3.2.0", 1873 | "source": { 1874 | "type": "git", 1875 | "url": "https://github.com/sebastianbergmann/type.git", 1876 | "reference": "fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e" 1877 | }, 1878 | "dist": { 1879 | "type": "zip", 1880 | "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e", 1881 | "reference": "fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e", 1882 | "shasum": "" 1883 | }, 1884 | "require": { 1885 | "php": ">=7.3" 1886 | }, 1887 | "require-dev": { 1888 | "phpunit/phpunit": "^9.5" 1889 | }, 1890 | "type": "library", 1891 | "extra": { 1892 | "branch-alias": { 1893 | "dev-master": "3.2-dev" 1894 | } 1895 | }, 1896 | "autoload": { 1897 | "classmap": [ 1898 | "src/" 1899 | ] 1900 | }, 1901 | "notification-url": "https://packagist.org/downloads/", 1902 | "license": [ 1903 | "BSD-3-Clause" 1904 | ], 1905 | "authors": [ 1906 | { 1907 | "name": "Sebastian Bergmann", 1908 | "email": "sebastian@phpunit.de", 1909 | "role": "lead" 1910 | } 1911 | ], 1912 | "description": "Collection of value objects that represent the types of the PHP type system", 1913 | "homepage": "https://github.com/sebastianbergmann/type", 1914 | "support": { 1915 | "issues": "https://github.com/sebastianbergmann/type/issues", 1916 | "source": "https://github.com/sebastianbergmann/type/tree/3.2.0" 1917 | }, 1918 | "funding": [ 1919 | { 1920 | "url": "https://github.com/sebastianbergmann", 1921 | "type": "github" 1922 | } 1923 | ], 1924 | "time": "2022-09-12T14:47:03+00:00" 1925 | }, 1926 | { 1927 | "name": "sebastian/version", 1928 | "version": "3.0.2", 1929 | "source": { 1930 | "type": "git", 1931 | "url": "https://github.com/sebastianbergmann/version.git", 1932 | "reference": "c6c1022351a901512170118436c764e473f6de8c" 1933 | }, 1934 | "dist": { 1935 | "type": "zip", 1936 | "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c6c1022351a901512170118436c764e473f6de8c", 1937 | "reference": "c6c1022351a901512170118436c764e473f6de8c", 1938 | "shasum": "" 1939 | }, 1940 | "require": { 1941 | "php": ">=7.3" 1942 | }, 1943 | "type": "library", 1944 | "extra": { 1945 | "branch-alias": { 1946 | "dev-master": "3.0-dev" 1947 | } 1948 | }, 1949 | "autoload": { 1950 | "classmap": [ 1951 | "src/" 1952 | ] 1953 | }, 1954 | "notification-url": "https://packagist.org/downloads/", 1955 | "license": [ 1956 | "BSD-3-Clause" 1957 | ], 1958 | "authors": [ 1959 | { 1960 | "name": "Sebastian Bergmann", 1961 | "email": "sebastian@phpunit.de", 1962 | "role": "lead" 1963 | } 1964 | ], 1965 | "description": "Library that helps with managing the version number of Git-hosted PHP projects", 1966 | "homepage": "https://github.com/sebastianbergmann/version", 1967 | "support": { 1968 | "issues": "https://github.com/sebastianbergmann/version/issues", 1969 | "source": "https://github.com/sebastianbergmann/version/tree/3.0.2" 1970 | }, 1971 | "funding": [ 1972 | { 1973 | "url": "https://github.com/sebastianbergmann", 1974 | "type": "github" 1975 | } 1976 | ], 1977 | "time": "2020-09-28T06:39:44+00:00" 1978 | }, 1979 | { 1980 | "name": "squizlabs/php_codesniffer", 1981 | "version": "3.7.1", 1982 | "source": { 1983 | "type": "git", 1984 | "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", 1985 | "reference": "1359e176e9307e906dc3d890bcc9603ff6d90619" 1986 | }, 1987 | "dist": { 1988 | "type": "zip", 1989 | "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/1359e176e9307e906dc3d890bcc9603ff6d90619", 1990 | "reference": "1359e176e9307e906dc3d890bcc9603ff6d90619", 1991 | "shasum": "" 1992 | }, 1993 | "require": { 1994 | "ext-simplexml": "*", 1995 | "ext-tokenizer": "*", 1996 | "ext-xmlwriter": "*", 1997 | "php": ">=5.4.0" 1998 | }, 1999 | "require-dev": { 2000 | "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" 2001 | }, 2002 | "bin": [ 2003 | "bin/phpcs", 2004 | "bin/phpcbf" 2005 | ], 2006 | "type": "library", 2007 | "extra": { 2008 | "branch-alias": { 2009 | "dev-master": "3.x-dev" 2010 | } 2011 | }, 2012 | "notification-url": "https://packagist.org/downloads/", 2013 | "license": [ 2014 | "BSD-3-Clause" 2015 | ], 2016 | "authors": [ 2017 | { 2018 | "name": "Greg Sherwood", 2019 | "role": "lead" 2020 | } 2021 | ], 2022 | "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", 2023 | "homepage": "https://github.com/squizlabs/PHP_CodeSniffer", 2024 | "keywords": [ 2025 | "phpcs", 2026 | "standards" 2027 | ], 2028 | "support": { 2029 | "issues": "https://github.com/squizlabs/PHP_CodeSniffer/issues", 2030 | "source": "https://github.com/squizlabs/PHP_CodeSniffer", 2031 | "wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki" 2032 | }, 2033 | "time": "2022-06-18T07:21:10+00:00" 2034 | }, 2035 | { 2036 | "name": "symfony/polyfill-ctype", 2037 | "version": "v1.27.0", 2038 | "source": { 2039 | "type": "git", 2040 | "url": "https://github.com/symfony/polyfill-ctype.git", 2041 | "reference": "5bbc823adecdae860bb64756d639ecfec17b050a" 2042 | }, 2043 | "dist": { 2044 | "type": "zip", 2045 | "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/5bbc823adecdae860bb64756d639ecfec17b050a", 2046 | "reference": "5bbc823adecdae860bb64756d639ecfec17b050a", 2047 | "shasum": "" 2048 | }, 2049 | "require": { 2050 | "php": ">=7.1" 2051 | }, 2052 | "provide": { 2053 | "ext-ctype": "*" 2054 | }, 2055 | "suggest": { 2056 | "ext-ctype": "For best performance" 2057 | }, 2058 | "type": "library", 2059 | "extra": { 2060 | "branch-alias": { 2061 | "dev-main": "1.27-dev" 2062 | }, 2063 | "thanks": { 2064 | "name": "symfony/polyfill", 2065 | "url": "https://github.com/symfony/polyfill" 2066 | } 2067 | }, 2068 | "autoload": { 2069 | "files": [ 2070 | "bootstrap.php" 2071 | ], 2072 | "psr-4": { 2073 | "Symfony\\Polyfill\\Ctype\\": "" 2074 | } 2075 | }, 2076 | "notification-url": "https://packagist.org/downloads/", 2077 | "license": [ 2078 | "MIT" 2079 | ], 2080 | "authors": [ 2081 | { 2082 | "name": "Gert de Pagter", 2083 | "email": "BackEndTea@gmail.com" 2084 | }, 2085 | { 2086 | "name": "Symfony Community", 2087 | "homepage": "https://symfony.com/contributors" 2088 | } 2089 | ], 2090 | "description": "Symfony polyfill for ctype functions", 2091 | "homepage": "https://symfony.com", 2092 | "keywords": [ 2093 | "compatibility", 2094 | "ctype", 2095 | "polyfill", 2096 | "portable" 2097 | ], 2098 | "support": { 2099 | "source": "https://github.com/symfony/polyfill-ctype/tree/v1.27.0" 2100 | }, 2101 | "funding": [ 2102 | { 2103 | "url": "https://symfony.com/sponsor", 2104 | "type": "custom" 2105 | }, 2106 | { 2107 | "url": "https://github.com/fabpot", 2108 | "type": "github" 2109 | }, 2110 | { 2111 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 2112 | "type": "tidelift" 2113 | } 2114 | ], 2115 | "time": "2022-11-03T14:55:06+00:00" 2116 | }, 2117 | { 2118 | "name": "symfony/polyfill-mbstring", 2119 | "version": "v1.27.0", 2120 | "source": { 2121 | "type": "git", 2122 | "url": "https://github.com/symfony/polyfill-mbstring.git", 2123 | "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534" 2124 | }, 2125 | "dist": { 2126 | "type": "zip", 2127 | "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/8ad114f6b39e2c98a8b0e3bd907732c207c2b534", 2128 | "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534", 2129 | "shasum": "" 2130 | }, 2131 | "require": { 2132 | "php": ">=7.1" 2133 | }, 2134 | "provide": { 2135 | "ext-mbstring": "*" 2136 | }, 2137 | "suggest": { 2138 | "ext-mbstring": "For best performance" 2139 | }, 2140 | "type": "library", 2141 | "extra": { 2142 | "branch-alias": { 2143 | "dev-main": "1.27-dev" 2144 | }, 2145 | "thanks": { 2146 | "name": "symfony/polyfill", 2147 | "url": "https://github.com/symfony/polyfill" 2148 | } 2149 | }, 2150 | "autoload": { 2151 | "files": [ 2152 | "bootstrap.php" 2153 | ], 2154 | "psr-4": { 2155 | "Symfony\\Polyfill\\Mbstring\\": "" 2156 | } 2157 | }, 2158 | "notification-url": "https://packagist.org/downloads/", 2159 | "license": [ 2160 | "MIT" 2161 | ], 2162 | "authors": [ 2163 | { 2164 | "name": "Nicolas Grekas", 2165 | "email": "p@tchwork.com" 2166 | }, 2167 | { 2168 | "name": "Symfony Community", 2169 | "homepage": "https://symfony.com/contributors" 2170 | } 2171 | ], 2172 | "description": "Symfony polyfill for the Mbstring extension", 2173 | "homepage": "https://symfony.com", 2174 | "keywords": [ 2175 | "compatibility", 2176 | "mbstring", 2177 | "polyfill", 2178 | "portable", 2179 | "shim" 2180 | ], 2181 | "support": { 2182 | "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.27.0" 2183 | }, 2184 | "funding": [ 2185 | { 2186 | "url": "https://symfony.com/sponsor", 2187 | "type": "custom" 2188 | }, 2189 | { 2190 | "url": "https://github.com/fabpot", 2191 | "type": "github" 2192 | }, 2193 | { 2194 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 2195 | "type": "tidelift" 2196 | } 2197 | ], 2198 | "time": "2022-11-03T14:55:06+00:00" 2199 | }, 2200 | { 2201 | "name": "symfony/polyfill-php80", 2202 | "version": "v1.27.0", 2203 | "source": { 2204 | "type": "git", 2205 | "url": "https://github.com/symfony/polyfill-php80.git", 2206 | "reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936" 2207 | }, 2208 | "dist": { 2209 | "type": "zip", 2210 | "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936", 2211 | "reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936", 2212 | "shasum": "" 2213 | }, 2214 | "require": { 2215 | "php": ">=7.1" 2216 | }, 2217 | "type": "library", 2218 | "extra": { 2219 | "branch-alias": { 2220 | "dev-main": "1.27-dev" 2221 | }, 2222 | "thanks": { 2223 | "name": "symfony/polyfill", 2224 | "url": "https://github.com/symfony/polyfill" 2225 | } 2226 | }, 2227 | "autoload": { 2228 | "files": [ 2229 | "bootstrap.php" 2230 | ], 2231 | "psr-4": { 2232 | "Symfony\\Polyfill\\Php80\\": "" 2233 | }, 2234 | "classmap": [ 2235 | "Resources/stubs" 2236 | ] 2237 | }, 2238 | "notification-url": "https://packagist.org/downloads/", 2239 | "license": [ 2240 | "MIT" 2241 | ], 2242 | "authors": [ 2243 | { 2244 | "name": "Ion Bazan", 2245 | "email": "ion.bazan@gmail.com" 2246 | }, 2247 | { 2248 | "name": "Nicolas Grekas", 2249 | "email": "p@tchwork.com" 2250 | }, 2251 | { 2252 | "name": "Symfony Community", 2253 | "homepage": "https://symfony.com/contributors" 2254 | } 2255 | ], 2256 | "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", 2257 | "homepage": "https://symfony.com", 2258 | "keywords": [ 2259 | "compatibility", 2260 | "polyfill", 2261 | "portable", 2262 | "shim" 2263 | ], 2264 | "support": { 2265 | "source": "https://github.com/symfony/polyfill-php80/tree/v1.27.0" 2266 | }, 2267 | "funding": [ 2268 | { 2269 | "url": "https://symfony.com/sponsor", 2270 | "type": "custom" 2271 | }, 2272 | { 2273 | "url": "https://github.com/fabpot", 2274 | "type": "github" 2275 | }, 2276 | { 2277 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 2278 | "type": "tidelift" 2279 | } 2280 | ], 2281 | "time": "2022-11-03T14:55:06+00:00" 2282 | }, 2283 | { 2284 | "name": "theseer/tokenizer", 2285 | "version": "1.2.1", 2286 | "source": { 2287 | "type": "git", 2288 | "url": "https://github.com/theseer/tokenizer.git", 2289 | "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e" 2290 | }, 2291 | "dist": { 2292 | "type": "zip", 2293 | "url": "https://api.github.com/repos/theseer/tokenizer/zipball/34a41e998c2183e22995f158c581e7b5e755ab9e", 2294 | "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e", 2295 | "shasum": "" 2296 | }, 2297 | "require": { 2298 | "ext-dom": "*", 2299 | "ext-tokenizer": "*", 2300 | "ext-xmlwriter": "*", 2301 | "php": "^7.2 || ^8.0" 2302 | }, 2303 | "type": "library", 2304 | "autoload": { 2305 | "classmap": [ 2306 | "src/" 2307 | ] 2308 | }, 2309 | "notification-url": "https://packagist.org/downloads/", 2310 | "license": [ 2311 | "BSD-3-Clause" 2312 | ], 2313 | "authors": [ 2314 | { 2315 | "name": "Arne Blankerts", 2316 | "email": "arne@blankerts.de", 2317 | "role": "Developer" 2318 | } 2319 | ], 2320 | "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", 2321 | "support": { 2322 | "issues": "https://github.com/theseer/tokenizer/issues", 2323 | "source": "https://github.com/theseer/tokenizer/tree/1.2.1" 2324 | }, 2325 | "funding": [ 2326 | { 2327 | "url": "https://github.com/theseer", 2328 | "type": "github" 2329 | } 2330 | ], 2331 | "time": "2021-07-28T10:34:58+00:00" 2332 | }, 2333 | { 2334 | "name": "vlucas/phpdotenv", 2335 | "version": "v5.5.0", 2336 | "source": { 2337 | "type": "git", 2338 | "url": "https://github.com/vlucas/phpdotenv.git", 2339 | "reference": "1a7ea2afc49c3ee6d87061f5a233e3a035d0eae7" 2340 | }, 2341 | "dist": { 2342 | "type": "zip", 2343 | "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/1a7ea2afc49c3ee6d87061f5a233e3a035d0eae7", 2344 | "reference": "1a7ea2afc49c3ee6d87061f5a233e3a035d0eae7", 2345 | "shasum": "" 2346 | }, 2347 | "require": { 2348 | "ext-pcre": "*", 2349 | "graham-campbell/result-type": "^1.0.2", 2350 | "php": "^7.1.3 || ^8.0", 2351 | "phpoption/phpoption": "^1.8", 2352 | "symfony/polyfill-ctype": "^1.23", 2353 | "symfony/polyfill-mbstring": "^1.23.1", 2354 | "symfony/polyfill-php80": "^1.23.1" 2355 | }, 2356 | "require-dev": { 2357 | "bamarni/composer-bin-plugin": "^1.4.1", 2358 | "ext-filter": "*", 2359 | "phpunit/phpunit": "^7.5.20 || ^8.5.30 || ^9.5.25" 2360 | }, 2361 | "suggest": { 2362 | "ext-filter": "Required to use the boolean validator." 2363 | }, 2364 | "type": "library", 2365 | "extra": { 2366 | "bamarni-bin": { 2367 | "bin-links": true, 2368 | "forward-command": true 2369 | }, 2370 | "branch-alias": { 2371 | "dev-master": "5.5-dev" 2372 | } 2373 | }, 2374 | "autoload": { 2375 | "psr-4": { 2376 | "Dotenv\\": "src/" 2377 | } 2378 | }, 2379 | "notification-url": "https://packagist.org/downloads/", 2380 | "license": [ 2381 | "BSD-3-Clause" 2382 | ], 2383 | "authors": [ 2384 | { 2385 | "name": "Graham Campbell", 2386 | "email": "hello@gjcampbell.co.uk", 2387 | "homepage": "https://github.com/GrahamCampbell" 2388 | }, 2389 | { 2390 | "name": "Vance Lucas", 2391 | "email": "vance@vancelucas.com", 2392 | "homepage": "https://github.com/vlucas" 2393 | } 2394 | ], 2395 | "description": "Loads environment variables from `.env` to `getenv()`, `$_ENV` and `$_SERVER` automagically.", 2396 | "keywords": [ 2397 | "dotenv", 2398 | "env", 2399 | "environment" 2400 | ], 2401 | "support": { 2402 | "issues": "https://github.com/vlucas/phpdotenv/issues", 2403 | "source": "https://github.com/vlucas/phpdotenv/tree/v5.5.0" 2404 | }, 2405 | "funding": [ 2406 | { 2407 | "url": "https://github.com/GrahamCampbell", 2408 | "type": "github" 2409 | }, 2410 | { 2411 | "url": "https://tidelift.com/funding/github/packagist/vlucas/phpdotenv", 2412 | "type": "tidelift" 2413 | } 2414 | ], 2415 | "time": "2022-10-16T01:01:54+00:00" 2416 | } 2417 | ], 2418 | "aliases": [], 2419 | "minimum-stability": "stable", 2420 | "stability-flags": [], 2421 | "prefer-stable": false, 2422 | "prefer-lowest": false, 2423 | "platform": { 2424 | "php": "^8.1", 2425 | "ext-json": "*", 2426 | "ext-mbstring": "*" 2427 | }, 2428 | "platform-dev": { 2429 | "ext-curl": "*" 2430 | }, 2431 | "plugin-api-version": "2.3.0" 2432 | } 2433 | --------------------------------------------------------------------------------