PluginProbe
Media Cloud Sync / 1.2.5
Media Cloud Sync v1.2.5
1.4.2 1.4.1 1.4.0 1.3.12 1.3.11 1.3.10 trunk 1.0.0 1.0.1 1.0.2 1.0.3 1.1.0 1.1.1 1.2.0 1.2.10 1.2.11 1.2.12 1.2.13 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.2.7 1.2.8 All 36 releases
media-cloud-sync / includes / sdk / google / monolog / monolog / src / Monolog / Handler / PHPConsoleHandler.php

PHPConsoleHandler.php in Media Cloud Sync 1.2.5, at includes/sdk/google/monolog/monolog/src/Monolog/Handler/PHPConsoleHandler.php

256 lines 10.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 declare (strict_types=1);
4 /*
5 * This file is part of the Monolog package.
6 *
7 * (c) Jordi Boggiano <[email protected]>
8 *
9 * For the full copyright and license information, please view the LICENSE
10 * file that was distributed with this source code.
11 */
12 namespace Dudlewebs\WPMCS\Monolog\Handler;
13
14 use Dudlewebs\WPMCS\Monolog\Formatter\LineFormatter;
15 use Dudlewebs\WPMCS\Monolog\Formatter\FormatterInterface;
16 use Dudlewebs\WPMCS\Monolog\Logger;
17 use Dudlewebs\WPMCS\Monolog\Utils;
18 use Dudlewebs\WPMCS\PhpConsole\Connector;
19 use Dudlewebs\WPMCS\PhpConsole\Handler as VendorPhpConsoleHandler;
20 use Dudlewebs\WPMCS\PhpConsole\Helper;
21 /**
22 * Monolog handler for Google Chrome extension "PHP Console"
23 *
24 * Display PHP error/debug log messages in Google Chrome console and notification popups, executes PHP code remotely
25 *
26 * Usage:
27 * 1. Install Google Chrome extension [now dead and removed from the chrome store]
28 * 2. See overview https://github.com/barbushin/php-console#overview
29 * 3. Install PHP Console library https://github.com/barbushin/php-console#installation
30 * 4. Example (result will looks like http://i.hizliresim.com/vg3Pz4.png)
31 *
32 * $logger = new \Monolog\Logger('all', array(new \Monolog\Handler\PHPConsoleHandler()));
33 * \Monolog\ErrorHandler::register($logger);
34 * echo $undefinedVar;
35 * $logger->debug('SELECT * FROM users', array('db', 'time' => 0.012));
36 * PC::debug($_SERVER); // PHP Console debugger for any type of vars
37 *
38 * @author Sergey Barbushin https://www.linkedin.com/in/barbushin
39 *
40 * @phpstan-import-type Record from \Monolog\Logger
41 * @deprecated Since 2.8.0 and 3.2.0, PHPConsole is abandoned and thus we will drop this handler in Monolog 4
42 */
43 class PHPConsoleHandler extends AbstractProcessingHandler
44 {
45 /** @var array<string, mixed> */
46 private $options = [
47 'enabled' => \true,
48 // bool Is PHP Console server enabled
49 'classesPartialsTraceIgnore' => ['Monolog\\'],
50 // array Hide calls of classes started with...
51 'debugTagsKeysInContext' => [0, 'tag'],
52 // bool Is PHP Console server enabled
53 'useOwnErrorsHandler' => \false,
54 // bool Enable errors handling
55 'useOwnExceptionsHandler' => \false,
56 // bool Enable exceptions handling
57 'sourcesBasePath' => null,
58 // string Base path of all project sources to strip in errors source paths
59 'registerHelper' => \true,
60 // bool Register PhpConsole\Helper that allows short debug calls like PC::debug($var, 'ta.g.s')
61 'serverEncoding' => null,
62 // string|null Server internal encoding
63 'headersLimit' => null,
64 // int|null Set headers size limit for your web-server
65 'password' => null,
66 // string|null Protect PHP Console connection by password
67 'enableSslOnlyMode' => \false,
68 // bool Force connection by SSL for clients with PHP Console installed
69 'ipMasks' => [],
70 // array Set IP masks of clients that will be allowed to connect to PHP Console: array('192.168.*.*', '127.0.0.1')
71 'enableEvalListener' => \false,
72 // bool Enable eval request to be handled by eval dispatcher(if enabled, 'password' option is also required)
73 'dumperDetectCallbacks' => \false,
74 // bool Convert callback items in dumper vars to (callback SomeClass::someMethod) strings
75 'dumperLevelLimit' => 5,
76 // int Maximum dumped vars array or object nested dump level
77 'dumperItemsCountLimit' => 100,
78 // int Maximum dumped var same level array items or object properties number
79 'dumperItemSizeLimit' => 5000,
80 // int Maximum length of any string or dumped array item
81 'dumperDumpSizeLimit' => 500000,
82 // int Maximum approximate size of dumped vars result formatted in JSON
83 'detectDumpTraceAndSource' => \false,
84 // bool Autodetect and append trace data to debug
85 'dataStorage' => null,
86 ];
87 /** @var Connector */
88 private $connector;
89 /**
90 * @param array<string, mixed> $options See \Monolog\Handler\PHPConsoleHandler::$options for more details
91 * @param Connector|null $connector Instance of \PhpConsole\Connector class (optional)
92 * @throws \RuntimeException
93 */
94 public function __construct(array $options = [], ?Connector $connector = null, $level = Logger::DEBUG, bool $bubble = \true)
95 {
96 if (!class_exists('Dudlewebs\WPMCS\PhpConsole\Connector')) {
97 throw new \RuntimeException('PHP Console library not found. See https://github.com/barbushin/php-console#installation');
98 }
99 parent::__construct($level, $bubble);
100 $this->options = $this->initOptions($options);
101 $this->connector = $this->initConnector($connector);
102 }
103 /**
104 * @param array<string, mixed> $options
105 *
106 * @return array<string, mixed>
107 */
108 private function initOptions(array $options): array
109 {
110 $wrongOptions = array_diff(array_keys($options), array_keys($this->options));
111 if ($wrongOptions) {
112 throw new \RuntimeException('Unknown options: ' . implode(', ', $wrongOptions));
113 }
114 return array_replace($this->options, $options);
115 }
116 private function initConnector(?Connector $connector = null): Connector
117 {
118 if (!$connector) {
119 if ($this->options['dataStorage']) {
120 Connector::setPostponeStorage($this->options['dataStorage']);
121 }
122 $connector = Connector::getInstance();
123 }
124 if ($this->options['registerHelper'] && !Helper::isRegistered()) {
125 Helper::register();
126 }
127 if ($this->options['enabled'] && $connector->isActiveClient()) {
128 if ($this->options['useOwnErrorsHandler'] || $this->options['useOwnExceptionsHandler']) {
129 $handler = VendorPhpConsoleHandler::getInstance();
130 $handler->setHandleErrors($this->options['useOwnErrorsHandler']);
131 $handler->setHandleExceptions($this->options['useOwnExceptionsHandler']);
132 $handler->start();
133 }
134 if ($this->options['sourcesBasePath']) {
135 $connector->setSourcesBasePath($this->options['sourcesBasePath']);
136 }
137 if ($this->options['serverEncoding']) {
138 $connector->setServerEncoding($this->options['serverEncoding']);
139 }
140 if ($this->options['password']) {
141 $connector->setPassword($this->options['password']);
142 }
143 if ($this->options['enableSslOnlyMode']) {
144 $connector->enableSslOnlyMode();
145 }
146 if ($this->options['ipMasks']) {
147 $connector->setAllowedIpMasks($this->options['ipMasks']);
148 }
149 if ($this->options['headersLimit']) {
150 $connector->setHeadersLimit($this->options['headersLimit']);
151 }
152 if ($this->options['detectDumpTraceAndSource']) {
153 $connector->getDebugDispatcher()->detectTraceAndSource = \true;
154 }
155 $dumper = $connector->getDumper();
156 $dumper->levelLimit = $this->options['dumperLevelLimit'];
157 $dumper->itemsCountLimit = $this->options['dumperItemsCountLimit'];
158 $dumper->itemSizeLimit = $this->options['dumperItemSizeLimit'];
159 $dumper->dumpSizeLimit = $this->options['dumperDumpSizeLimit'];
160 $dumper->detectCallbacks = $this->options['dumperDetectCallbacks'];
161 if ($this->options['enableEvalListener']) {
162 $connector->startEvalRequestsListener();
163 }
164 }
165 return $connector;
166 }
167 public function getConnector(): Connector
168 {
169 return $this->connector;
170 }
171 /**
172 * @return array<string, mixed>
173 */
174 public function getOptions(): array
175 {
176 return $this->options;
177 }
178 public function handle(array $record): bool
179 {
180 if ($this->options['enabled'] && $this->connector->isActiveClient()) {
181 return parent::handle($record);
182 }
183 return !$this->bubble;
184 }
185 /**
186 * Writes the record down to the log of the implementing handler
187 */
188 protected function write(array $record): void
189 {
190 if ($record['level'] < Logger::NOTICE) {
191 $this->handleDebugRecord($record);
192 } elseif (isset($record['context']['exception']) && $record['context']['exception'] instanceof \Throwable) {
193 $this->handleExceptionRecord($record);
194 } else {
195 $this->handleErrorRecord($record);
196 }
197 }
198 /**
199 * @phpstan-param Record $record
200 */
201 private function handleDebugRecord(array $record): void
202 {
203 $tags = $this->getRecordTags($record);
204 $message = $record['message'];
205 if ($record['context']) {
206 $message .= ' ' . Utils::jsonEncode($this->connector->getDumper()->dump(array_filter($record['context'])), null, \true);
207 }
208 $this->connector->getDebugDispatcher()->dispatchDebug($message, $tags, $this->options['classesPartialsTraceIgnore']);
209 }
210 /**
211 * @phpstan-param Record $record
212 */
213 private function handleExceptionRecord(array $record): void
214 {
215 $this->connector->getErrorsDispatcher()->dispatchException($record['context']['exception']);
216 }
217 /**
218 * @phpstan-param Record $record
219 */
220 private function handleErrorRecord(array $record): void
221 {
222 $context = $record['context'];
223 $this->connector->getErrorsDispatcher()->dispatchError($context['code'] ?? null, $context['message'] ?? $record['message'], $context['file'] ?? null, $context['line'] ?? null, $this->options['classesPartialsTraceIgnore']);
224 }
225 /**
226 * @phpstan-param Record $record
227 * @return string
228 */
229 private function getRecordTags(array &$record)
230 {
231 $tags = null;
232 if (!empty($record['context'])) {
233 $context =& $record['context'];
234 foreach ($this->options['debugTagsKeysInContext'] as $key) {
235 if (!empty($context[$key])) {
236 $tags = $context[$key];
237 if ($key === 0) {
238 array_shift($context);
239 } else {
240 unset($context[$key]);
241 }
242 break;
243 }
244 }
245 }
246 return $tags ?: strtolower($record['level_name']);
247 }
248 /**
249 * {@inheritDoc}
250 */
251 protected function getDefaultFormatter(): FormatterInterface
252 {
253 return new LineFormatter('%message%');
254 }
255 }
256