Passed
Push — master ( 7add85...9336e3 )
by Viacheslav
18:01 queued 08:00
created

Base::loadSchema()   B

Complexity

Conditions 10
Paths 12

Size

Total Lines 53
Code Lines 31

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 110

Importance

Changes 0
Metric Value
cc 10
eloc 31
nc 12
nop 2
dl 0
loc 53
ccs 0
cts 0
cp 0
crap 110
rs 7.6666
c 0
b 0
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\JsonCli;
4
5
use Swaggest\JsonCli\Json\LoadFile;
6
use Swaggest\JsonCli\JsonSchema\ResolverMux;
7
use Swaggest\JsonDiff\Exception;
8
use Swaggest\JsonSchema\Context;
9
use Swaggest\JsonSchema\RemoteRef\BasicFetcher;
10
use Swaggest\JsonSchema\RemoteRef\Preloaded;
11
use Swaggest\JsonSchema\Schema;
12
use Swaggest\PhpCodeBuilder\Markdown\TypeBuilder;
13
use Symfony\Component\Yaml\Yaml;
14
use Yaoi\Command;
15
use Yaoi\Io\Response;
16
17
abstract class Base extends Command
18
{
19 1
    use LoadFile;
20
21 1
    public $pretty;
22 1
    public $toYaml;
23 1
    public $toSerialized;
24 1
    public $output;
25 1
    public $schemaResolver;
26 1
27 1
    /**
28
     * @param Command\Definition $definition
29
     * @param \stdClass|static $options
30
     */
31
    static function setUpDefinition(Command\Definition $definition, $options)
32 6
    {
33
        $options->pretty = Command\Option::create()
34 6
            ->setDescription('Pretty-print result JSON');
35
        $options->output = Command\Option::create()->setType()
36
            ->setDescription('Path to output result, default STDOUT');
37
        $options->schemaResolver = Command\Option::create()->setType()
38 6
            ->setDescription('Path to schema resolver JSON file. Schema:');
39 6
        $tb = new TypeBuilder();
40
        $tb->getTypeString(SchemaResolver::schema()->exportSchema());
41
        $options->schemaResolver->description .= "\n" . trim(substr($tb->file, 77)); // Stripping header.
42
43 6
44
        $options->toYaml = Command\Option::create()->setDescription('Output in YAML format');
45 6
        $options->toSerialized = Command\Option::create()->setDescription('Output in PHP serialized format');
46
    }
47
48 6
49
    protected $out;
50
51 6
    /**
52
     * @param string $path
53
     * @return mixed
54 8
     * @throws ExitCode
55
     */
56 8
    protected function readData($path)
57 8
    {
58 5
        return self::readJsonOrYaml($path, $this->response);
59
    }
60
61 8
    /**
62
     * @param string $path
63 8
     * @param Response $response
64
     * @return mixed
65
     * @throws ExitCode
66 8
     */
67
    public static function readJsonOrYaml($path, $response)
68
    {
69 8
        $fileData = file_get_contents($path);
70
        if (!$fileData) {
71
            $response->error('Unable to read ' . $path);
72 8
            throw new ExitCode('', 1);
73
        }
74 8
        if (substr($path, -5) === '.yaml' || substr($path, -4) === '.yml') {
75
            $jsonData = Yaml::parse($fileData, Yaml::PARSE_OBJECT + Yaml::PARSE_OBJECT_FOR_MAP);
76
        } elseif (substr($path, -11) === '.serialized') {
77
            $jsonData = unserialize($fileData);
78
        } else {
79
            $jsonData = json_decode($fileData);
80
        }
81
82
        return $jsonData;
83
    }
84
85
86
    protected function postPerform()
87
    {
88
        $options = JSON_UNESCAPED_SLASHES + JSON_UNESCAPED_UNICODE;
89
        if ($this->pretty) {
90
            $options += JSON_PRETTY_PRINT;
91
        }
92
93
        if ($this->toYaml) {
94
            $result = Yaml::dump($this->out, 2, 2, Yaml::DUMP_OBJECT_AS_MAP);
95
        } elseif ($this->toSerialized) {
96
            $result = serialize($this->out);
97
        } else {
98
            $result = json_encode($this->out, $options);
99
        }
100
101
        if ($this->output) {
102
            file_put_contents($this->output, $result);
103
        } else {
104
            echo $result, "\n";
105
        }
106
    }
107
108
109
    /** @var string */
110
    public $schema;
111
    /** @var string[] */
112
    public $defPtr = ['#/definitions'];
113
    /** @var string[] */
114
    public $ptrInSchema;
115
116
    /**
117
     * @param Command\Definition $definition
118
     * @param static|mixed $options
119
     */
120
    protected static function setupGenOptions(Command\Definition $definition, $options)
0 ignored issues
show
Unused Code introduced by
The parameter $definition is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

120
    protected static function setupGenOptions(/** @scrutinizer ignore-unused */ Command\Definition $definition, $options)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
121
    {
122
        $options->schema = Command\Option::create()
0 ignored issues
show
Documentation Bug introduced by
It seems like Yaoi\Command\Option::cre...amed()->setIsRequired() of type Yaoi\Command\Option is incompatible with the declared type string of property $schema.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
123
            ->setDescription('Path to JSON schema file, use `-` for STDIN')->setIsUnnamed()->setIsRequired();
124
125
        $options->ptrInSchema = Command\Option::create()->setType()->setIsVariadic()
0 ignored issues
show
Documentation Bug introduced by
It seems like Yaoi\Command\Option::cre...oot schema, default #') of type Yaoi\Command\Option is incompatible with the declared type string[] of property $ptrInSchema.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
126
            ->setDescription('JSON pointers to structure in root schema, default #');
127
128
        $options->defPtr = Command\Option::create()->setType()->setIsVariadic()
0 ignored issues
show
Documentation Bug introduced by
It seems like Yaoi\Command\Option::cre...default #/definitions') of type Yaoi\Command\Option is incompatible with the declared type string[] of property $defPtr.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
129
            ->setDescription('Definitions pointers to strip from symbol names, default #/definitions');
130
131
        $options->schemaResolver = Command\Option::create()->setType()
132
            ->setDescription('Path to schema resolver JSON file. Schema:');
133
        $tb = new TypeBuilder();
134
        $tb->getTypeString(SchemaResolver::schema()->exportSchema());
135
        $options->schemaResolver->description .= "\n" . trim(substr($tb->file, 77)); // Stripping header.
136
137
        static::setupLoadFileOptions($options);
138
    }
139
140
    /**
141
     * @param bool $skipRoot
142
     * @param string $baseName
143
     * @return \Swaggest\JsonSchema\SchemaContract
144
     * @throws Exception
145
     * @throws ExitCode
146
     * @throws \Swaggest\JsonSchema\Exception
147
     * @throws \Swaggest\JsonSchema\InvalidValue
148
     */
149
    protected function loadSchema(&$skipRoot, &$baseName)
150
    {
151
        if ($this->schema === '-') {
152
            $this->schema = 'php://stdin';
153
        }
154
155
        $resolver = new ResolverMux();
156
        $preloaded = new Preloaded();
157
158
        if ($this->schemaResolver !== null) {
159
            $data = file_get_contents($this->schemaResolver);
160
            if (empty($data)) {
161
                throw new ExitCode("empty or missing schema resolver file", 1);
162
            }
163
            $json = json_decode($data);
164
            if (empty($json)) {
165
                throw new ExitCode("invalid json in schema resolver file", 1);
166
            }
167
168
            $schemaResolver = SchemaResolver::import($json);
169
170
            foreach ($schemaResolver->schemaData as $url => $data) {
171
                $preloaded->setSchemaData($url, $data);
172
            }
173
174
            foreach ($schemaResolver->schemaFiles as $url => $file) {
175
                $preloaded->setSchemaFile($url, $file);
176
            }
177
        }
178
179
        $resolver->resolvers[] = $preloaded;
180
181
        $dataValue = $this->loadFile();
182
        $data = $dataValue;
183
184
        if (!empty($this->ptrInSchema)) {
185
            $baseName = basename($this->schema);
186
            $skipRoot = true;
187
            $preloaded->setSchemaData($baseName, $dataValue);
188
            $data = new \stdClass();
189
190
            foreach ($this->defPtr as $defPtr) {
191
                $this->defPtr[] = $baseName . $defPtr;
192
            }
193
            $this->defPtr[] = $baseName;
194
195
            foreach ($this->ptrInSchema as $i => $ptr) {
196
                $data->oneOf[$i] = (object)[Schema::PROP_REF => $baseName . $ptr];
197
            }
198
        }
199
200
        $resolver->resolvers[] = new BasicFetcher();
201
        return Schema::import($data, new Context($resolver));
202
    }
203
}