Passed
Pull Request — 1.x (#334)
by Akihito
12:50 queued 10:32
created

CompleteContext   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 93
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 47
dl 0
loc 93
rs 10
c 1
b 0
f 0
wmc 10

3 Methods

Rating   Name   Duplication   Size   Complexity  
B __construct() 0 44 6
A jsonSerialize() 0 21 3
A create() 0 3 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace BEAR\Resource\SemanticLog\Profile\Verbose;
6
7
use BEAR\Resource\ResourceObject;
8
use BEAR\Resource\Types;
9
use JsonSerializable;
10
use Koriym\SemanticLogger\AbstractContext;
11
use Override;
12
13
use function file_exists;
14
use function file_put_contents;
15
use function function_exists;
16
use function is_string;
17
use function serialize;
18
use function sprintf;
19
use function str_replace;
20
use function sys_get_temp_dir;
21
use function uniqid;
22
use function xdebug_stop_trace;
23
use function xhprof_disable;
24
25
/**
26
 * @psalm-import-type Headers from Types
27
 * @psalm-import-type HttpBody from Types
28
 */
29
final class CompleteContext extends AbstractContext implements JsonSerializable
30
{
31
    /** @psalm-suppress InvalidClassConstantType */
32
    public const TYPE = 'bear_resource_complete';
33
34
    /** @psalm-suppress InvalidClassConstantType */
35
    public const SCHEMA_URL = 'https://bearsunday.github.io/BEAR.Resource/schemas/complete-context.json';
36
37
    public readonly string $uri;
38
    public readonly int $code;
39
40
    /** @var Headers */
0 ignored issues
show
Bug introduced by
The type BEAR\Resource\SemanticLog\Profile\Verbose\Headers was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
41
    public readonly array $headers;
42
43
    /** @var HttpBody  */
0 ignored issues
show
Bug introduced by
The type BEAR\Resource\SemanticLog\Profile\Verbose\HttpBody was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
44
    public readonly mixed $body;
45
    public readonly string $view;
46
    public ?string $xhprofFile = null;
47
    public ?string $xdebugTraceFile = null;
48
49
    public function __construct(ResourceObject $resource, OpenContext $openContext)
50
    {
51
        // Trigger rendering to get view
52
        $resourceString = (string) $resource;
53
        unset($resourceString);
54
        $this->uri = (string) $resource->uri;
0 ignored issues
show
Bug introduced by
The property uri is declared read-only in BEAR\Resource\SemanticLo...Verbose\CompleteContext.
Loading history...
55
        $this->code = $resource->code;
0 ignored issues
show
Bug introduced by
The property code is declared read-only in BEAR\Resource\SemanticLo...Verbose\CompleteContext.
Loading history...
56
        $this->headers = $resource->headers;
0 ignored issues
show
Bug introduced by
The property headers is declared read-only in BEAR\Resource\SemanticLo...Verbose\CompleteContext.
Loading history...
57
        /** @psalm-suppress MixedAssignment */
58
        /** @phpstan-ignore-next-line */
59
        $this->body = $resource->body;
0 ignored issues
show
Bug introduced by
The property body is declared read-only in BEAR\Resource\SemanticLo...Verbose\CompleteContext.
Loading history...
60
        /** @psalm-suppress PossiblyNullPropertyAssignmentValue */
61
        $this->view = $resource->view ?? '';
0 ignored issues
show
Bug introduced by
The property view is declared read-only in BEAR\Resource\SemanticLo...Verbose\CompleteContext.
Loading history...
62
        // Stop profiling and save files
63
        $this->xhprofFile = null;
64
        $this->xdebugTraceFile = null;
65
66
        if (function_exists('xhprof_disable')) {
67
            $xhprofData = xhprof_disable();
68
            $filename = sprintf(
69
                '%s/xhprof_%s_%s.xhprof',
70
                sys_get_temp_dir(),
71
                str_replace(['/', ':', '?'], '_', $openContext->uri),
72
                uniqid('', true),
73
            );
74
75
            if (file_put_contents($filename, serialize($xhprofData)) !== false) {
76
                $this->xhprofFile = $filename;
77
            }
78
        }
79
80
        // Handle Xdebug trace
81
        $xdebugId = $openContext->getXdebugId();
82
        if ($xdebugId === null) {
83
            return; // @codeCoverageIgnore
84
        }
85
86
        /** @var string|null $traceFile */
87
        $traceFile = @xdebug_stop_trace(); // @phpstan-ignore-line
88
        if (! is_string($traceFile) || ! file_exists($traceFile)) {
0 ignored issues
show
introduced by
The condition is_string($traceFile) is always true.
Loading history...
89
            return;
90
        }
91
92
        $this->xdebugTraceFile = $traceFile; // @codeCoverageIgnore
93
    }
94
95
    public static function create(ResourceObject $resource, OpenContext $openContext): self
96
    {
97
        return new self($resource, $openContext);
98
    }
99
100
    /** @return array<string, mixed> */
101
    #[Override]
102
    public function jsonSerialize(): array
103
    {
104
        $data = [
105
            'uri' => $this->uri,
106
            'code' => $this->code,
107
            'headers' => $this->headers,
108
            'body' => $this->body,
109
            'view' => $this->view,
110
        ];
111
112
        // Only include profiling files if they exist
113
        if ($this->xhprofFile !== null) {
114
            $data['xhprofFile'] = $this->xhprofFile;
115
        }
116
117
        if ($this->xdebugTraceFile !== null) {
118
            $data['xdebugTraceFile'] = $this->xdebugTraceFile; // @codeCoverageIgnore
119
        }
120
121
        return $data;
122
    }
123
}
124