SchemaModel::getRecordOriginExceptionOfField()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 0
cts 2
cp 0
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
crap 2
1
<?php
2
/**
3
 * Model based on Graviton\RestBundle\Model\DocumentModel.
4
 */
5
6
namespace Graviton\SchemaBundle\Model;
7
8
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
9
use Symfony\Component\DependencyInjection\ContainerInterface;
10
11
/**
12
 * Model based on Graviton\RestBundle\Model\DocumentModel.
13
 *
14
 * @author   List of contributors <https://github.com/libgraviton/graviton/graphs/contributors>
15
 * @license  https://opensource.org/licenses/MIT MIT License
16
 * @link     http://swisscom.ch
17
 */
18
class SchemaModel implements ContainerAwareInterface
19
{
20
    /**
21
     * object
22
     */
23
    private $schema;
24
25
    /**
26
     * @var ContainerInterface
27
     */
28
    private $container;
29
30
    /**
31
     * load some schema info for the model
32
     */
33
    public function __construct()
34
    {
35
        list(, $bundle, , $model) = explode('\\', get_called_class());
36
        $file = __DIR__ . '/../../' . $bundle . '/Resources/config/schema/' . $model . '.json';
37
38
        if (!file_exists($file)) {
39
            $reflection = new \ReflectionClass($this);
40
            $file = dirname($reflection->getFileName()).'/../Resources/config/schema/' . $model . '.json';
41
        }
42
43
        if (!file_exists($file)) {
44
            // fallback try on model property (this should be available on some generated classes)
45
            if (isset($this->_modelPath)) {
46
                // try to find schema.json relative to the model involved..
47
                $file = dirname($this->_modelPath) . '/../Resources/config/schema/' . $model . '.json';
48
            }
49
50
            if (!file_exists($file)) {
51
                throw new \LogicException('Please create the schema file ' . $file);
52
            }
53
        }
54
55
        $this->schema = \json_decode(file_get_contents($file));
56
57
        if (is_null($this->schema)) {
58
            throw new \LogicException('The file ' . $file . ' doe not contain valid json');
59
        }
60
    }
61
62
    /**
63
     * inject container
64
     *
65
     * @param ContainerInterface $container service container
0 ignored issues
show
Documentation introduced by
Should the type for parameter $container not be null|ContainerInterface?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
66
     *
67
     * @return self
68
     */
69
    public function setContainer(ContainerInterface $container = null)
70
    {
71
        $this->container = $container;
72
73
        return $this;
74
    }
75
76
    /**
77
     * get Title
78
     *
79
     * @return string
80
     */
81
    public function getTitle()
82
    {
83
        return $this->schema->title;
84
    }
85
86
    /**
87
     * get description
88
     *
89
     * @return string Description
90
     */
91
    public function getDescription()
92
    {
93
        return $this->schema->description;
94
    }
95
96
    /**
97
     * get recordOriginModifiable
98
     *
99
     * @return bool
100
     */
101
    public function getRecordOriginModifiable()
102
    {
103
        if (isset($this->schema->recordOriginModifiable)) {
104
            return $this->schema->recordOriginModifiable;
105
        }
106
        return true;
107
    }
108
109
    /**
110
     * get isVersioning
111
     *
112
     * @return bool
113
     */
114
    public function isVersioning()
115
    {
116
        $isVersioning = false;
117
        if (isset($this->schema->{'x-versioning'})) {
118
            $isVersioning = $this->schema->{'x-versioning'};
119
        }
120
        return $isVersioning;
121
    }
122
123
    /**
124
     * Returns the bare schema
125
     *
126
     * @return \stdClass Schema
127
     */
128
    public function getSchema()
129
    {
130
        return $this->schema;
131
    }
132
133
    /**
134
     * get title for a given field
135
     *
136
     * @param string $field field name
137
     *
138
     * @return string
139
     */
140
    public function getTitleOfField($field)
141
    {
142
        return $this->getSchemaField($field, 'title');
143
    }
144
145
    /**
146
     * get description for a given field
147
     *
148
     * @param string $field field name
149
     *
150
     * @return string
151
     */
152
    public function getDescriptionOfField($field)
153
    {
154
        return $this->getSchemaField($field, 'description');
155
    }
156
157
    /**
158
     * get groups for a given field
159
     *
160
     * @param string $field field name
161
     *
162
     * @return array<string> group names
163
     */
164
    public function getGroupsOfField($field)
165
    {
166
        return $this->getSchemaField($field, 'x-groups', []);
167
    }
168
169
    /**
170
     * get property model for embedded field
171
     *
172
     * @param string $mapping name of mapping class
173
     *
174
     * @return $this
175
     */
176
    public function manyPropertyModelForTarget($mapping)
177
    {
178
        // @todo refactor to get rid of container dependency (maybe remove from here)
179
        list($app, $bundle, , $document) = explode('\\', $mapping);
180
        $app = strtolower($app);
181
        $bundle = strtolower(substr($bundle, 0, -6));
182
        $document = strtolower($document);
183
        $propertyService = implode('.', array($app, $bundle, 'model', $document));
184
        $propertyModel = $this->container->get($propertyService);
185
186
        return $propertyModel;
187
    }
188
189
    /**
190
     * get required fields for this object
191
     *
192
     * @param string $variationName a variation that can alter which fields are required
0 ignored issues
show
Documentation introduced by
Should the type for parameter $variationName not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
193
     *
194
     * @return string[]
195
     */
196
    public function getRequiredFields($variationName = null)
197
    {
198
        if (is_null($variationName)) {
199
            return $this->schema->required;
200
        }
201
202
        /* compose required fields based on variation */
203
        $requiredFields = $this->getRequiredFields();
204
        foreach ($this->schema->properties as $fieldName => $fieldAttributes) {
205
            $onVariation = $this->getOnVariaton($fieldName);
206
207
            if (is_object($onVariation) && isset($onVariation->{$variationName}->required)) {
208
                $thisRequired = $onVariation->{$variationName}->required;
209
210
                if ($thisRequired === true) {
211
                    $requiredFields[] = $fieldName;
212
                }
213
214
                if ($thisRequired === false) {
215
                    // see if its set
216
                    $fieldIndex = array_search($fieldName, $requiredFields);
217
                    if ($fieldName !== false) {
218
                        unset($requiredFields[$fieldIndex]);
219
                    }
220
                }
221
            }
222
        }
223
224
        return array_values(
225
            array_unique(
226
                $requiredFields
227
            )
228
        );
229
    }
230
231
    /**
232
     * get a collection of service names that can extref refer to
233
     *
234
     * @param string $field field name
235
     *
236
     * @return array
237
     */
238
    public function getRefCollectionOfField($field)
239
    {
240
        return $this->getSchemaField($field, 'collection', array());
241
    }
242
243
    /**
244
     * get readOnly flag for a given field
245
     *
246
     * @param string $field field name
247
     *
248
     * @return boolean the readOnly flag
249
     */
250
    public function getReadOnlyOfField($field)
251
    {
252
        return $this->getSchemaField($field, 'readOnly', false);
253
    }
254
255
    /**
256
     * get readOnly flag for a given field
257
     *
258
     * @param string $field field name
259
     *
260
     * @return boolean the readOnly flag
261
     */
262
    public function getRecordOriginExceptionOfField($field)
263
    {
264
        return $this->getSchemaField($field, 'recordOriginException', false);
265
    }
266
267
    /**
268
     * get searchable flag for a given field, weight based.
269
     *
270
     * @param string $field field name
271
     *
272
     * @return integer the searchable flag
273
     */
274
    public function getSearchableOfField($field)
275
    {
276
        return (int) $this->getSchemaField($field, 'searchable', 0);
277
    }
278
279
    /**
280
     * tell us if a model what to be exposed using a key as field
281
     *
282
     * @param string $field field that we check for dynamic-key spec
283
     *
284
     * @return boolean
285
     */
286
    public function hasDynamicKey($field)
287
    {
288
        return $this->getSchemaField($field, 'x-dynamic-key', false) !== false;
289
    }
290
291
    /**
292
     * Get field used for setting stringy key value
293
     *
294
     * @param string $field field that we get dynamic-key spec from
295
     *
296
     * @return object
297
     */
298
    public function getDynamicKeySpec($field)
299
    {
300
        return $this->getSchemaField($field, 'x-dynamic-key');
301
    }
302
303
    /**
304
     * Gets the defined document class in shortform from schema
305
     *
306
     * @return string|false either the document class or false it not given
307
     */
308
    public function getDocumentClass()
309
    {
310
        $documentClass = false;
311
        if (isset($this->schema->{'x-documentClass'})) {
312
            $documentClass = $this->schema->{'x-documentClass'};
313
        }
314
        return $documentClass;
315
    }
316
317
    /**
318
     * Get defined constraints on this field (if any)
319
     *
320
     * @param string $field field that we get constraints spec from
321
     *
322
     * @return object
323
     */
324
    public function getConstraints($field)
325
    {
326
        return $this->getSchemaField($field, 'x-constraints', false);
327
    }
328
329
    /**
330
     * Get defined onVariation on this field (if any)
331
     *
332
     * @param string $field field that we get constraints spec from
333
     *
334
     * @return object
335
     */
336
    public function getOnVariaton($field)
337
    {
338
        return $this->getSchemaField($field, 'x-onvariation', null);
339
    }
340
341
    /**
342
     * get variations
343
     *
344
     * @return array variations
345
     */
346
    public function getVariations()
347
    {
348
        if (isset($this->schema->{'x-variations'})) {
349
            return $this->schema->{'x-variations'};
350
        }
351
        return [];
352
    }
353
354
    /**
355
     * Tells us if in this model, the ID can be given on a POST request or not (in the payload).
356
     * This basically depends on if the "id" property is given in the JSON definition or not.
357
     *
358
     * @return bool true if yes, false otherwise
359
     */
360
    public function isIdInPostAllowed()
361
    {
362
        $isAllowed = true;
363
        if (isset($this->schema->{'x-id-in-post-allowed'})) {
364
            $isAllowed = $this->schema->{'x-id-in-post-allowed'};
365
        }
366
        return $isAllowed;
367
    }
368
369
    /**
370
     * get schema field value
371
     *
372
     * @param string $field         field name
373
     * @param string $property      property name
374
     * @param mixed  $fallbackValue fallback value if property isn't set
375
     *
376
     * @return mixed
377
     */
378
    private function getSchemaField($field, $property, $fallbackValue = '')
379
    {
380
        if (isset($this->schema->properties->$field->$property)) {
381
            $fallbackValue = $this->schema->properties->$field->$property;
382
        }
383
384
        return $fallbackValue;
385
    }
386
387
    /**
388
     * get searchable fields for this object
389
     *
390
     * @return string[]
391
     */
392
    public function getSearchableFields()
393
    {
394
        return $this->schema->searchable;
395
    }
396
}
397