Passed
Push — master ( 90aec0...26fb73 )
by Arthur
03:07
created

src/Blocks/FormRequest.php (5 issues)

1
<?php
2
3
namespace SoliDry\Blocks;
4
5
use SoliDry\Controllers\BaseCommand;
6
use SoliDry\Extension\BaseFormRequest;
7
use SoliDry\Extension\JSONApiInterface;
8
use SoliDry\Helpers\Console;
9
use SoliDry\Helpers\MethodOptions;
10
use SoliDry\ApiGenerator;
11
use SoliDry\Helpers\Classes;
12
use SoliDry\Types\ConfigInterface;
13
use SoliDry\Types\CustomsInterface;
14
use SoliDry\Types\DefaultInterface;
15
use SoliDry\Types\DirsInterface;
16
use SoliDry\Types\HTTPMethodsInterface;
17
use SoliDry\Types\MethodsInterface;
18
use SoliDry\Types\FromRequestInterface;
19
use SoliDry\Types\PhpInterface;
20
use SoliDry\Types\ApiInterface;
21
22
/**
23
 * Class FormRequest
24
 *
25
 * @package SoliDry\Blocks
26
 * @property ApiGenerator generator
27
 */
28
class FormRequest extends FormRequestModel
29
{
30
    use ContentManager;
0 ignored issues
show
The trait SoliDry\Blocks\ContentManager requires some properties which are not provided by SoliDry\Blocks\FormRequest: $options, $version, $modulesDir
Loading history...
31
32
    protected $sourceCode    = '';
33
    protected $resourceCode  = '';
34
    protected $generator;
35
    private $additionalProps = [
36
        'id' => [
37
            'type' => 'integer',
38
        ],
39
    ];
40
    private $className;
41
42
    /**
43
     * FormRequest constructor.
44
     * @param BaseCommand $generator
45
     */
46
    public function __construct(BaseCommand $generator)
47
    {
48
        $this->generator = $generator;
0 ignored issues
show
Documentation Bug introduced by
$generator is of type SoliDry\Controllers\BaseCommand, but the property $generator was declared to be of type SoliDry\ApiGenerator. Are you sure that you always receive this specific sub-class here, or does it make sense to add an instanceof check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a given class or a super-class is assigned to a property that is type hinted more strictly.

Either this assignment is in error or an instanceof check should be added for that assignment.

class Alien {}

class Dalek extends Alien {}

class Plot
{
    /** @var  Dalek */
    public $villain;
}

$alien = new Alien();
$plot = new Plot();
if ($alien instanceof Dalek) {
    $plot->villain = $alien;
}
Loading history...
49
        $this->className = Classes::getClassName($this->generator->objectName);
50
    }
51
52
    /**
53
     * @param $generator
54
     */
55
    public function setCodeState($generator)
56
    {
57
        $this->generator = $generator;
58
    }
59
60
    /**
61
     * @param null $relationTypes
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $relationTypes is correct as it would always require null to be passed?
Loading history...
62
     */
63
    private function setProps($relationTypes = null)
64
    {
65
        $this->setAdditionalProps();
66
        // properties creation
67
        $this->setPropsContent();
68
        // related props
69
        $this->setRelationTypes($relationTypes);
70
    }
71
72
    /**
73
     *  Sets an additional props e.g.: id
74
     */
75
    private function setAdditionalProps()
76
    {
77
        // additional props
78
        if (!empty($this->additionalProps)) {
79
            foreach ($this->additionalProps as $prop => $propVal) {
80
                $this->createProperty($prop, PhpInterface::PHP_MODIFIER_PUBLIC);
81
            }
82
        }
83
    }
84
85
    /**
86
     *  Sets props values
87
     */
88
    private function setPropsContent()
89
    {
90
        $this->setComment(CustomsInterface::CUSTOM_TYPES_ATTRIBUTES);
91
92
        /** @var array $objectProps */
93
        $objectProps = $this->generator->types[$this->generator->objectProps[ApiInterface::RAML_ATTRS]][ApiInterface::RAML_PROPS];
94
        foreach ($objectProps as $propKey => $propVal) {
95
96
            if (is_array($propVal)) {
97
                $this->createProperty($propKey, PhpInterface::PHP_MODIFIER_PUBLIC);
98
99
                if (empty($propVal[ApiInterface::RAML_FACETS][ConfigInterface::BIT_MASK]) === false) {
100
                    $this->setComment(ConfigInterface::BIT_MASK);
101
102
                    foreach ($propVal[ApiInterface::RAML_FACETS][ConfigInterface::BIT_MASK] as $flag => $bit) {
103
                        $this->createProperty($flag, PhpInterface::PHP_MODIFIER_PUBLIC, $bit);
104
                    }
105
                }
106
            }
107
        }
108
    }
109
110
    /**
111
     * Sets relation types
112
     *
113
     * @param $relationTypes
114
     */
115
    private function setRelationTypes($relationTypes)
116
    {
117
        // related props
118
        if ($relationTypes !== null) {
119
            $this->sourceCode .= PhpInterface::TAB_PSR4 . PhpInterface::COMMENT . ' Relations' . PHP_EOL;
120
121
            foreach ($relationTypes as $attrKey => $attrVal) {
122
                // determine attr
123
                if ($attrKey !== ApiInterface::RAML_ID && $attrKey !== ApiInterface::RAML_TYPE) {
124
                    $this->createProperty($attrKey, PhpInterface::PHP_MODIFIER_PUBLIC);
125
                }
126
            }
127
            $this->sourceCode .= PHP_EOL;
128
        }
129
    }
130
131
    /**
132
     *  Sets all rules for this FormRequest
133
     */
134
    private function constructRules()
135
    {
136
        // Authorize method - defaults to false
137
        $methodOptions = new MethodOptions();
138
        $methodOptions->setName(PhpInterface::PHP_AUTHORIZE);
139
        $methodOptions->setReturnType(PhpInterface::PHP_TYPES_BOOL);
140
        $this->startMethod($methodOptions);
141
        $this->setMethodReturn(PhpInterface::PHP_TYPES_BOOL_TRUE);
142
        $this->endMethod();
143
144
        // Rules method
145
        $methodOptions->setName(PhpInterface::PHP_RULES);
146
        $methodOptions->setReturnType(PhpInterface::PHP_TYPES_ARRAY);
147
        $this->startMethod($methodOptions);
148
        // attrs validation
149
        $this->startArray();
150
        // gather Types and constraints
151
        $this->setPropertyFilters();
152
        $this->endArray();
153
        $this->endMethod();
154
    }
155
156
    /**
157
     * Sets all relations for Entity via FormRequests
158
     *
159
     * @param $relationTypes
160
     */
161
    private function constructRelations($relationTypes)
162
    {
163
        $methodOptions = new MethodOptions();
164
        $methodOptions->setName(MethodsInterface::RELATIONS);
165
        $methodOptions->setReturnType(PhpInterface::PHP_TYPES_ARRAY);
166
        $this->startMethod($methodOptions);
167
        // attrs validation
168
        $this->startArray();
169
        if (empty($relationTypes) === false) {
170
            $rel = empty($relationTypes[ApiInterface::RAML_TYPE]) ? $relationTypes :
171
                $relationTypes[ApiInterface::RAML_TYPE];
172
173
            $rels = explode(PhpInterface::PIPE, str_replace('[]', '', $rel));
174
            foreach ($rels as $k => $rel) {
175
                $this->setRelations(strtolower(trim(str_replace(CustomsInterface::CUSTOM_TYPES_RELATIONSHIPS, '', $rel))));
176
                if (empty($rels[$k + 1]) === false) {
177
                    $this->sourceCode .= PHP_EOL;
178
                }
179
            }
180
        }
181
        $this->endArray();
182
        $this->endMethod(1);
183
    }
184
185
    /**
186
     * @param $relationTypes
187
     */
188
    private function setRelations($relationTypes)
189
    {
190
        $this->setTabs(3);
191
        $this->sourceCode .= PhpInterface::QUOTES . $relationTypes .
192
            PhpInterface::QUOTES
193
            . PhpInterface::COMMA;
194
    }
195
196
    /**
197
     *  Sets content of *FormRequest
198
     */
199
    private function setContent()
0 ignored issues
show
The method setContent() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
200
    {
201
        $this->setTag();
202
        $this->setNamespace(
203
            $this->generator->httpDir .
204
            PhpInterface::BACKSLASH .
205
            $this->generator->formRequestDir
206
        );
207
208
        $baseFullForm = BaseFormRequest::class;
209
        $baseFormName = Classes::getName($baseFullForm);
210
        $this->setUse($baseFullForm, false, true);
211
        $this->startClass($this->className . DefaultInterface::FORM_REQUEST_POSTFIX, $baseFormName);
212
213
        $this->setComment(DefaultInterface::PROPS_START);
214
        if (empty($this->generator->objectProps[ApiInterface::RAML_RELATIONSHIPS][ApiInterface::RAML_TYPE]) === false
215
            && empty($this->generator->types[$this->generator->objectProps[ApiInterface::RAML_RELATIONSHIPS][ApiInterface::RAML_TYPE]]) === false) {
216
            $this->setProps(
217
                $this->generator->types[$this->generator->objectProps[ApiInterface::RAML_RELATIONSHIPS][ApiInterface::RAML_TYPE]]
218
                [ApiInterface::RAML_PROPS][ApiInterface::RAML_DATA][ApiInterface::RAML_ITEMS]
219
            );
220
        } else {
221
            $this->setProps();
222
        }
223
        $this->setComment(DefaultInterface::PROPS_END);
224
        $this->sourceCode .= PHP_EOL;
225
        $this->setComment(DefaultInterface::METHOD_START);
226
        $this->constructRules();
227
        $relTypes = empty($this->generator->objectProps[ApiInterface::RAML_RELATIONSHIPS][ApiInterface::RAML_TYPE])
228
            ? [] : $this->generator->objectProps[ApiInterface::RAML_RELATIONSHIPS][ApiInterface::RAML_TYPE];
229
        $this->constructRelations($relTypes);
230
        $this->setComment(DefaultInterface::METHOD_END);
231
        // create closing brace
232
        $this->endClass();
233
    }
234
235
    /**
236
     *  Sets content of *FormRequest
237
     */
238
    private function resetContent()
0 ignored issues
show
The method resetContent() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
239
    {
240
        $this->setBeforeProps($this->getEntityFile($this->generator->formatRequestsPath(),
241
            DefaultInterface::FORM_REQUEST_POSTFIX));
242
        $this->setComment(DefaultInterface::PROPS_START, 0);
243
        if (empty($this->generator->objectProps[ApiInterface::RAML_RELATIONSHIPS][ApiInterface::RAML_TYPE]) === false
244
            && empty($this->generator->types[$this->generator->objectProps[ApiInterface::RAML_RELATIONSHIPS][ApiInterface::RAML_TYPE]]) === false) {
245
            $this->setProps(
246
                $this->generator->types[$this->generator->objectProps[ApiInterface::RAML_RELATIONSHIPS][ApiInterface::RAML_TYPE]]
247
                [ApiInterface::RAML_PROPS][ApiInterface::RAML_DATA][ApiInterface::RAML_ITEMS]
248
            );
249
        } else {
250
            $this->setProps();
251
        }
252
        $this->setAfterProps(DefaultInterface::METHOD_START);
253
        $this->setComment(DefaultInterface::METHOD_START, 0);
254
        $this->constructRules();
255
        $relTypes = empty($this->generator->objectProps[ApiInterface::RAML_RELATIONSHIPS][ApiInterface::RAML_TYPE])
256
            ? [] : $this->generator->objectProps[ApiInterface::RAML_RELATIONSHIPS][ApiInterface::RAML_TYPE];
257
        $this->constructRelations($relTypes);
258
        $this->setAfterMethods();
259
    }
260
261
    /**
262
     *  Creates an ApiRequestToken Requests class
263
     */
264
    public function createAccessToken()
265
    {
266
        if (empty($this->generator->types[CustomsInterface::CUSTOM_TYPES_QUERY_PARAMS][ApiInterface::RAML_PROPS]
267
                  [JSONApiInterface::PARAM_ACCESS_TOKEN][ApiInterface::RAML_KEY_DEFAULT]) === false
268
        ) {
269
            $this->setAccessTokenContent();
270
            $fileForm  = FileManager::getModulePath($this->generator, true) . $this->generator->formRequestDir
271
                . PhpInterface::SLASH . JSONApiInterface::CLASS_API_ACCESS_TOKEN
272
                . PhpInterface::PHP_EXT;
273
274
            $isCreated = FileManager::createFile(
275
                $fileForm, $this->sourceCode,
276
                FileManager::isRegenerated($this->generator->options)
277
            );
278
279
            if ($isCreated) {
280
                Console::out($fileForm . PhpInterface::SPACE . Console::CREATED, Console::COLOR_GREEN);
281
            }
282
        }
283
    }
284
285
    /**
286
     *  Sets content for ApiRequestToken Requests class
287
     */
288
    private function setAccessTokenContent()
289
    {
290
        $this->setTag();
291
        $this->sourceCode .= PhpInterface::PHP_NAMESPACE . PhpInterface::SPACE .
292
            DirsInterface::APPLICATION_DIR . PhpInterface::BACKSLASH . $this->generator->httpDir .
293
            PhpInterface::BACKSLASH . $this->generator->formRequestDir
294
            . PhpInterface::SEMICOLON . PHP_EOL . PHP_EOL;
295
296
        $this->setUse(PhpInterface::CLASS_CLOSURE, false, true);
297
        $this->startClass(JSONApiInterface::CLASS_API_ACCESS_TOKEN);
298
        $methodOptions = new MethodOptions();
299
        $methodOptions->setName(FromRequestInterface::METHOD_HANDLE);
300
        $methodOptions->setParams([
301
            FromRequestInterface::METHOD_PARAM_REQUEST,
302
            PhpInterface::CLASS_CLOSURE => FromRequestInterface::METHOD_PARAM_NEXT,
303
        ]);
304
        $this->startMethod($methodOptions);
305
        $this->setHandleMethodContent();
306
        $this->endMethod();
307
        $this->endClass();
308
    }
309
310
    /**
311
     *  Sets content for ApiRequestToken Requests class handle() method
312
     */
313
    private function setHandleMethodContent()
314
    {
315
        $this->setTabs(2);
316
        $this->sourceCode .= PhpInterface::IF . PhpInterface::SPACE . PhpInterface::OPEN_PARENTHESES
317
            . PhpInterface::OPEN_PARENTHESES . PhpInterface::PHP_TYPES_STRING . PhpInterface::CLOSE_PARENTHESES
318
            . PhpInterface::SPACE . PhpInterface::DOLLAR_SIGN . FromRequestInterface::METHOD_PARAM_REQUEST
319
            . PhpInterface::ARROW . JSONApiInterface::PARAM_ACCESS_TOKEN . PhpInterface::SPACE . PhpInterface::EXCLAMATION
320
            . PhpInterface::EQUALS . PhpInterface::EQUALS . PhpInterface::SPACE
321
            . PhpInterface::OPEN_PARENTHESES . PhpInterface::PHP_TYPES_STRING . PhpInterface::CLOSE_PARENTHESES
322
            . PhpInterface::SPACE . MethodsInterface::CONFIG . PhpInterface::OPEN_PARENTHESES . PhpInterface::QUOTES
323
            . $this->generator->version . PhpInterface::DOT . ConfigInterface::QUERY_PARAMS . PhpInterface::DOT
324
            . JSONApiInterface::PARAM_ACCESS_TOKEN . PhpInterface::QUOTES
325
            . PhpInterface::CLOSE_PARENTHESES . PhpInterface::CLOSE_PARENTHESES . PHP_EOL;
326
        $this->setTabs(2);
327
        $this->sourceCode .= PhpInterface::OPEN_BRACE . PHP_EOL;
328
        // response body
329
        $this->setTabs(3);
330
        $this->sourceCode .= MethodsInterface::HEADER . PhpInterface::OPEN_PARENTHESES . PhpInterface::QUOTES
331
            . HTTPMethodsInterface::HTTP_11 . PhpInterface::SPACE . JSONApiInterface::HTTP_RESPONSE_CODE_ACCESS_FORBIDDEN
332
            . PhpInterface::SPACE . JSONApiInterface::FORBIDDEN
333
            . PhpInterface::QUOTES . PhpInterface::CLOSE_PARENTHESES
334
            . PhpInterface::SEMICOLON . PHP_EOL;
335
        $this->setTabs(3);
336
        $this->setEchoString('Access forbidden.');
337
        $this->setTabs(3);
338
        $this->sourceCode .= PhpInterface::DIE . PhpInterface::SEMICOLON . PHP_EOL;
339
        $this->setTabs(2);
340
        $this->sourceCode .= PhpInterface::CLOSE_BRACE . PHP_EOL . PHP_EOL;
341
        $this->setMethodReturn(PhpInterface::DOLLAR_SIGN . FromRequestInterface::METHOD_PARAM_NEXT
342
            . PhpInterface::OPEN_PARENTHESES . PhpInterface::DOLLAR_SIGN . FromRequestInterface::METHOD_PARAM_REQUEST
343
            . PhpInterface::CLOSE_PARENTHESES);
344
345
    }
346
}