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

src/Blocks/FormRequest.php (2 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;
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()
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()
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
}