Completed
Push — master ( 290ae2...8ff748 )
by Viacheslav
14:11 queued 06:38
created

GenPhp::performAction()   C

Complexity

Conditions 15
Paths 14

Size

Total Lines 79
Code Lines 55

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 15
eloc 55
nc 14
nop 0
dl 0
loc 79
rs 5.9166
c 1
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\JsonSchema\ResolverMux;
6
use Swaggest\JsonSchema\Context;
7
use Swaggest\JsonSchema\RemoteRef\BasicFetcher;
8
use Swaggest\JsonSchema\RemoteRef\Preloaded;
9
use Swaggest\JsonSchema\Schema;
10
use Swaggest\PhpCodeBuilder\App\PhpApp;
11
use Swaggest\PhpCodeBuilder\JsonSchema\ClassHookCallback;
12
use Swaggest\PhpCodeBuilder\JsonSchema\PhpBuilder;
13
use Swaggest\PhpCodeBuilder\PhpClass;
14
use Swaggest\PhpCodeBuilder\PhpCode;
15
use Yaoi\Command;
16
17
class GenPhp extends Base
18
{
19
    /** @var string */
20
    public $ns;
21
    /** @var string */
22
    public $nsPath;
23
    /** @var string */
24
    public $rootName = 'Structure';
25
    /** @var bool */
26
    public $setters = false;
27
    /** @var bool */
28
    public $getters = false;
29
    /** @var bool */
30
    public $noEnumConst = false;
31
32
    /** @var bool */
33
    public $declarePropertyDefaults = false;
34
35
    /** @var bool */
36
    public $buildAdditionalPropertiesAccessors = false;
37
38
    /**
39
     * @param Command\Definition $definition
40
     * @param \stdClass|static $options
41
     */
42
    public static function setUpDefinition(Command\Definition $definition, $options)
43
    {
44
        $definition->description = 'Generate PHP code from JSON schema';
45
        Base::setupGenOptions($definition, $options);
46
47
        $options->ns = Command\Option::create()
0 ignored issues
show
Documentation Bug introduced by
It seems like Yaoi\Command\Option::cre...Type()->setIsRequired() of type Yaoi\Command\Option is incompatible with the declared type string of property $ns.

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...
48
            ->setDescription('Namespace to use for generated classes, example \MyClasses')->setType()->setIsRequired();
49
50
        $options->nsPath = Command\Option::create()
0 ignored issues
show
Documentation Bug introduced by
It seems like Yaoi\Command\Option::cre...Type()->setIsRequired() of type Yaoi\Command\Option is incompatible with the declared type string of property $nsPath.

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...
51
            ->setDescription('Path to store generated classes, example ./src/MyClasses')
52
            ->setType()
53
            ->setIsRequired();
54
55
        $options->rootName = Command\Option::create()->setType()
0 ignored issues
show
Documentation Bug introduced by
It seems like Yaoi\Command\Option::cre...ly used for # pointer') of type Yaoi\Command\Option is incompatible with the declared type string of property $rootName.

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...
56
            ->setDescription('Go root struct name, default "Structure", only used for # pointer');
57
58
        $options->setters = Command\Option::create()->setDescription('Build setters');
0 ignored issues
show
Documentation Bug introduced by
It seems like Yaoi\Command\Option::cre...iption('Build setters') of type Yaoi\Command\Option is incompatible with the declared type boolean of property $setters.

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...
59
        $options->getters = Command\Option::create()->setDescription('Build getters');
0 ignored issues
show
Documentation Bug introduced by
It seems like Yaoi\Command\Option::cre...iption('Build getters') of type Yaoi\Command\Option is incompatible with the declared type boolean of property $getters.

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...
60
        $options->noEnumConst = Command\Option::create()
0 ignored issues
show
Documentation Bug introduced by
It seems like Yaoi\Command\Option::cre...for enum/const values') of type Yaoi\Command\Option is incompatible with the declared type boolean of property $noEnumConst.

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...
61
            ->setDescription('Do not create constants for enum/const values');
62
63
        $options->declarePropertyDefaults = Command\Option::create()
0 ignored issues
show
Documentation Bug introduced by
It seems like Yaoi\Command\Option::cre...initialize properties') of type Yaoi\Command\Option is incompatible with the declared type boolean of property $declarePropertyDefaults.

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...
64
            ->setDescription('Use default values to initialize properties');
65
66
        $options->buildAdditionalPropertiesAccessors = Command\Option::create()
0 ignored issues
show
Documentation Bug introduced by
It seems like Yaoi\Command\Option::cre... additionalProperties') of type Yaoi\Command\Option is incompatible with the declared type boolean of property $buildAdditionalPropertiesAccessors.

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...
67
            ->setDescription('Build accessors for additionalProperties');
68
69
         Base::setupGenOptions($definition, $options);
70
    }
71
72
73
    public function performAction()
74
    {
75
        try {
76
            $skipRoot = false;
77
            $baseName = null;
78
            $schema = $this->loadSchema($skipRoot, $baseName);
79
80
            $appPath = realpath($this->nsPath);
81
            if (!$appPath) {
82
                $this->response->error('Could not find directory ' . $this->nsPath);
83
                throw new ExitCode('', 1);
84
            }
85
            $appNs = $this->ns;
86
87
            $app = new PhpApp();
88
            $app->setNamespaceRoot($appNs, '.');
89
90
            $builder = new PhpBuilder();
91
            $builder->buildSetters = $this->setters;
92
            $builder->buildGetters = $this->getters;
93
94
            $builder->makeEnumConstants = !$this->noEnumConst;
95
            $builder->declarePropertyDefaults = $this->declarePropertyDefaults;
96
            $builder->buildAdditionalPropertyMethodsOnTrue = $this->buildAdditionalPropertiesAccessors;
97
98
            $builder->classCreatedHook = new ClassHookCallback(function (PhpClass $class, $path, $schema)
99
            use ($app, $appNs, $skipRoot, $baseName) {
100
                if ($skipRoot && '#' === $path) {
101
                    return;
102
                }
103
104
                $desc = '';
105
                if ($schema->title) {
106
                    $desc = $schema->title;
107
                }
108
                if ($schema->description) {
109
                    $desc .= "\n" . $schema->description;
110
                }
111
                if ($fromRefs = $schema->getFromRefs()) {
112
                    $desc .= "\nBuilt from " . implode("\n" . ' <- ', $fromRefs);
113
                }
114
                $class->setDescription(trim($desc));
115
116
                $class->setNamespace($appNs);
117
                if ('#' === $path) {
118
                    $class->setName($this->rootName);
119
                } else {
120
                    if (!empty($fromRefs)) {
121
                        $path = $fromRefs[0];
122
                    }
123
                    foreach ($this->defPtr as $defPtr) {
124
                        if (isset($baseName)) {
125
                            $baseNameDefPtr = $baseName . $defPtr;
126
                            if ($baseNameDefPtr === substr($path, 0, strlen($baseNameDefPtr))) {
127
                                $path = substr($path, strlen($baseNameDefPtr));
128
                                $className = PhpCode::makePhpClassName($path);
129
                                $class->setName($className);
130
                            }
131
                        }
132
133
                        if ($defPtr === substr($path, 0, strlen($defPtr))) {
134
                            $className = PhpCode::makePhpClassName(substr($path, strlen($defPtr)));
135
                            $class->setName($className);
136
                        }
137
                    }
138
                }
139
                $app->addClass($class);
140
            });
141
142
            if (!$schema instanceof Schema) {
143
                $this->response->error('failed to assert Schema type, ' . get_class($schema) . ' received');
144
                throw new ExitCode('', 1);
145
            }
146
            $builder->getType($schema);
147
            $app->store($appPath);
148
            $this->response->success("Classes are generated in " . $appPath);
149
        } catch (\Exception $e) {
150
            $this->response->error($e->getMessage());
151
            throw new ExitCode('', 1);
152
        }
153
    }
154
}