SchemaExporterInterface::process()   D
last analyzed

Complexity

Conditions 21
Paths 42

Size

Total Lines 73
Code Lines 46

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 41
CRAP Score 21.0059

Importance

Changes 3
Bugs 1 Features 0
Metric Value
cc 21
eloc 46
nc 42
nop 3
dl 0
loc 73
ccs 41
cts 42
cp 0.9762
crap 21.0059
rs 4.1666
c 3
b 1
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Swaggest\PhpCodeBuilder\JsonSchema;
4
5
use Swaggest\CodeBuilder\PlaceholderString;
6
use Swaggest\JsonSchema\Schema;
7
use Swaggest\JsonSchema\SchemaExporter;
8
use Swaggest\PhpCodeBuilder\PhpClass;
9
use Swaggest\PhpCodeBuilder\PhpClassProperty;
10
use Swaggest\PhpCodeBuilder\PhpCode;
11
use Swaggest\PhpCodeBuilder\PhpFlags;
12
use Swaggest\PhpCodeBuilder\PhpFunction;
13
use Swaggest\PhpCodeBuilder\PhpInterface;
14
use Swaggest\PhpCodeBuilder\Types\TypeOf;
15
16
/**
17
 * Implements SchemaExporter if class has at least 5 intersecting properties with JsonSchema
18
 */
19
class SchemaExporterInterface implements PhpBuilderClassHook
20 2
{
21
    public function process(PhpClass $class, $path, $schema)
22 2
    {
23
        $schemaProperties = Schema::properties();
24 2
25 2
        $propertiesFound = array();
26 2
        foreach ($class->getProperties() as $property) {
27
            $schemaName = $property->getNamedVar()->getName();
28
            //$schemaName = $property->getMeta(PhpBuilder::PROPERTY_NAME);
29 2
            /** @var Schema $propertySchema */
30
            $propertySchema = $property->getMeta(PhpBuilder::SCHEMA);
31 2
32 2
            $schemaProperty = $schemaProperties[$schemaName];
33
            if ($schemaProperty instanceof SchemaExporter) {
34
                $schemaProperty = $schemaProperty->exportSchema();
35 2
            }
36 2
            if ($schemaProperty !== null) {
37 2
                if (empty($schemaProperty->type)
38 2
                    || ($schemaProperty->type == $propertySchema->type)
39
                    || (is_array($schemaProperty->type) && in_array($propertySchema->type, $schemaProperty->type))
40 2
                ) {
41
                    $propertiesFound[] = $property->getNamedVar()->getName();
42
                }
43
            }
44
        }
45 2
46 2
        if (count($propertiesFound) > 5) {
47 2
            $prop = new PhpClassProperty(
48 2
                'schemaStorage',
49 2
                PhpClass::byFQN(\SplObjectStorage::class),
50
                PhpFlags::VIS_PRIVATE
51
            );
52 2
            $prop->setIsStatic(true);
53
            $prop->setDescription('Schema storage keeps exported schemas to avoid infinite cycle recursions.');
54
            $class->addProperty($prop);
55 2
56 2
            $func = new PhpFunction('exportSchema');
57 2
            $func->setResult(PhpClass::byFQN(Schema::class));
58 2
            $body = (new PhpCode())->addSnippet($this->buildHead());
59 2
60 2
            $names = Schema::names();
61 2
            foreach ($propertiesFound as $name) {
62 2
                if ($name === $names->items
63 2
                    || $name === $names->additionalProperties
64 2
                    || $name === $names->additionalItems
65 2
                    || $name === $names->not
66 2
                    || $name === $names->if
67
                    || $name === $names->then
68
                    || $name === $names->else) {
69
                    $body->addSnippet($this->buildSchemaProperty($name));
70
                    continue;
71 2
                }
72
73
                if ($name === $names->allOf || $name === $names->oneOf || $name === $names->anyOf) {
74 2
                    $body->addSnippet($this->buildSchemasProperty($name));
75 2
                    continue;
76 2
                }
77 2
78
79 2
                if ($name === $names->properties) {
80
                    $body->addSnippet($this->buildProperties());
81
                    continue;
82
                }
83
84
85
                $body->addSnippet($this->buildDefault($name));
86 2
87
            }
88
89
            $body->addSnippet($this->buildTail());
90 2
91 2
            $func->setBody($body);
92 2
            $class->addMethod($func);
93 2
            $class->addImplements(PhpInterface::byFQN(SchemaExporter::class));
94
        }
95
96
    }
97
98
    protected function buildHead()
99
    {
100
        return new PlaceholderString(<<<PHP
101
if (null === self::\$schemaStorage) {
102 2
    self::\$schemaStorage = new SplObjectStorage();
103
}
104
105
if (self::\$schemaStorage->contains(\$this)) {
106 2
    return self::\$schemaStorage->offsetGet(\$this);
107 2
} else {
108
    \$schema = new :schema();
109
    self::\$schemaStorage->attach(\$this, \$schema);
110
}
111
112
PHP
113
            , [':schema' => new TypeOf(PhpClass::byFQN(Schema::class))]
114 2
        );
115 2
    }
116
117
    protected function buildSchemaProperty($name)
118
    {
119
        return <<<PHP
120
if (\$this->$name !== null && \$this->$name instanceof SchemaExporter) {
121
    \$schema->$name = \$this->{$name}->exportSchema();
122 2
}
123 2
124 2
PHP;
125
    }
126
127 2
    protected function buildSchemasProperty($name)
128
    {
129
        return <<<PHP
130
if (!empty(\$this->$name)) {
131
    foreach (\$this->$name as \$i => \$item) {
132
        if (\$item instanceof SchemaExporter) {
133
            \$schema->{$name}[\$i] = \$item->exportSchema();
134
        }
135
    }
136
}
137
138
PHP;
139
    }
140
141
    protected function buildProperties()
142
    {
143
        return <<<PHP
144
if (!empty(\$this->properties)) {
145
    foreach (\$this->properties as \$propertyName => \$propertySchema) {
146
        if (is_string(\$propertyName) && \$propertySchema instanceof SchemaExporter) {
147
            \$schema->setProperty(\$propertyName, \$propertySchema->exportSchema());
148
        }
149
    }
150
}
151
152
PHP;
153
    }
154
155
    protected function buildDefault($name)
156
    {
157
        return <<<PHP
158
\$schema->$name = \$this->$name;
159
160
PHP;
161
    }
162
163
    protected function buildTail()
164
    {
165
        return <<<'PHP'
166
$schema->__fromRef = $this->__fromRef;
167
$schema->setDocumentPath($this->getDocumentPath());
168
$schema->addMeta($this, 'origin');
169
return $schema;
170
PHP;
171
    }
172
}