PluginProbe
WCPOS – Point of Sale (POS) plugin for WooCommerce / 1.10.17
WCPOS – Point of Sale (POS) plugin for WooCommerce v1.10.17
1.10.27 1.10.26 1.10.25 1.10.24 1.10.23 1.10.22 1.10.21 1.10.20 1.10.19 1.10.18 1.10.17 1.10.16 1.10.15 1.10.13 1.10.14 1.10.12 1.10.11 1.10.10 1.10.9 1.10.8 untagged-3d9b7ccddc54df87c672 1.10.7 1.10.6 1.10.5 1.10.3 All 171 releases
woocommerce-pos / vendor_prefixed / sentry / sentry / src / Integration / FrameContextifierIntegration.php

FrameContextifierIntegration.php in WCPOS – Point of Sale (POS) plugin for WooCommerce 1.10.17, at vendor_prefixed/sentry/sentry/src/Integration/FrameContextifierIntegration.php

137 lines 4.9 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 namespace WCPOS\Vendor\Sentry\Integration;
5
6 use WCPOS\Vendor\Psr\Log\LoggerInterface;
7 use WCPOS\Vendor\Psr\Log\NullLogger;
8 use WCPOS\Vendor\Sentry\Event;
9 use WCPOS\Vendor\Sentry\Frame;
10 use WCPOS\Vendor\Sentry\SentrySdk;
11 use WCPOS\Vendor\Sentry\Stacktrace;
12 use WCPOS\Vendor\Sentry\State\Scope;
13 /**
14 * This integration reads excerpts of code around the line that originated an
15 * error.
16 *
17 * @author Stefano Arlandini <[email protected]>
18 */
19 final class FrameContextifierIntegration implements IntegrationInterface
20 {
21 /**
22 * @var LoggerInterface A PSR-3 logger
23 */
24 private $logger;
25 /**
26 * Creates a new instance of this integration.
27 *
28 * @param LoggerInterface|null $logger A PSR-3 logger
29 */
30 public function __construct(?LoggerInterface $logger = null)
31 {
32 $this->logger = $logger ?? new NullLogger();
33 }
34 /**
35 * {@inheritdoc}
36 */
37 public function setupOnce() : void
38 {
39 Scope::addGlobalEventProcessor(static function (Event $event) : Event {
40 $client = SentrySdk::getCurrentHub()->getClient();
41 if ($client === null) {
42 return $event;
43 }
44 $maxContextLines = $client->getOptions()->getContextLines();
45 $integration = $client->getIntegration(self::class);
46 if ($integration === null || $maxContextLines === null) {
47 return $event;
48 }
49 $stacktrace = $event->getStacktrace();
50 if ($stacktrace !== null) {
51 $integration->addContextToStacktraceFrames($maxContextLines, $stacktrace);
52 }
53 foreach ($event->getExceptions() as $exception) {
54 if ($exception->getStacktrace() !== null) {
55 $integration->addContextToStacktraceFrames($maxContextLines, $exception->getStacktrace());
56 }
57 }
58 return $event;
59 });
60 }
61 /**
62 * Contextifies the frames of the given stacktrace.
63 *
64 * @param int $maxContextLines The maximum number of lines of code to read
65 * @param Stacktrace $stacktrace The stacktrace object
66 */
67 private function addContextToStacktraceFrames(int $maxContextLines, Stacktrace $stacktrace) : void
68 {
69 foreach ($stacktrace->getFrames() as $frame) {
70 if ($frame->isInternal()) {
71 continue;
72 }
73 $this->addContextToStacktraceFrame($maxContextLines, $frame);
74 }
75 }
76 /**
77 * Contextifies the given frame.
78 *
79 * @param int $maxContextLines The maximum number of lines of code to read
80 */
81 private function addContextToStacktraceFrame(int $maxContextLines, Frame $frame) : void
82 {
83 if ($frame->getAbsoluteFilePath() === null) {
84 return;
85 }
86 $sourceCodeExcerpt = $this->getSourceCodeExcerpt($maxContextLines, $frame->getAbsoluteFilePath(), $frame->getLine());
87 $frame->setPreContext($sourceCodeExcerpt['pre_context']);
88 $frame->setContextLine($sourceCodeExcerpt['context_line']);
89 $frame->setPostContext($sourceCodeExcerpt['post_context']);
90 }
91 /**
92 * Gets an excerpt of the source code around a given line.
93 *
94 * @param int $maxContextLines The maximum number of lines of code to read
95 * @param string $filePath The file path
96 * @param int $lineNumber The line to centre about
97 *
98 * @return array<string, mixed>
99 *
100 * @phpstan-return array{
101 * pre_context: string[],
102 * context_line: string|null,
103 * post_context: string[]
104 * }
105 */
106 private function getSourceCodeExcerpt(int $maxContextLines, string $filePath, int $lineNumber) : array
107 {
108 $frame = ['pre_context' => [], 'context_line' => null, 'post_context' => []];
109 $target = \max(0, $lineNumber - ($maxContextLines + 1));
110 $currentLineNumber = $target + 1;
111 try {
112 $file = new \SplFileObject($filePath);
113 $file->seek($target);
114 while (!$file->eof()) {
115 /** @var string $line */
116 $line = $file->current();
117 $line = \rtrim($line, "\r\n");
118 if ($currentLineNumber === $lineNumber) {
119 $frame['context_line'] = $line;
120 } elseif ($currentLineNumber < $lineNumber) {
121 $frame['pre_context'][] = $line;
122 } elseif ($currentLineNumber > $lineNumber) {
123 $frame['post_context'][] = $line;
124 }
125 ++$currentLineNumber;
126 if ($currentLineNumber > $lineNumber + $maxContextLines) {
127 break;
128 }
129 $file->next();
130 }
131 } catch (\Throwable $exception) {
132 $this->logger->warning(\sprintf('Failed to get the source code excerpt for the file "%s".', $filePath), ['exception' => $exception]);
133 }
134 return $frame;
135 }
136 }
137