Completed
Push — feature/other-validation ( 582c96...3c7e86 )
by Narcotic
109:38 queued 43:32
created

Schema::setType()   C

Complexity

Conditions 8
Paths 42

Size

Total Lines 35
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 72

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 35
ccs 0
cts 18
cp 0
rs 5.3846
cc 8
eloc 20
nc 42
nop 1
crap 72
1
<?php
2
/**
3
 * Graviton Schema Document
4
 */
5
6
namespace Graviton\SchemaBundle\Document;
7
8
use \Doctrine\Common\Collections\ArrayCollection;
9
10
/**
11
 * Graviton\SchemaBundle\Document\Schema
12
 *
13
 * @author   List of contributors <https://github.com/libgraviton/graviton/graphs/contributors>
14
 * @license  http://opensource.org/licenses/gpl-license.php GNU Public License
15
 * @link     http://swisscom.ch
16
 */
17
class Schema
18
{
19
    /**
20
     * @var string
21
     */
22
    protected $title;
23
24
    /**
25
     * @var string
26
     */
27
    protected $description;
28
29
    /**
30
     * @var string
31
     */
32
    protected $type;
33
34
    /**
35
     * @var string
36
     */
37
    protected $format;
38
39
    /**
40
     * @var Schema
41
     */
42
    protected $items;
43
44
    /**
45
     * @var ArrayCollection
46
     */
47
    protected $properties;
48
49
    /**
50
     * @var SchemaAdditionalProperties
51
     */
52
    protected $additionalProperties;
53
54
    /**
55
     * @var string[]
56
     */
57
    protected $required = array();
58
59
    /**
60
     * @var boolean
61
     */
62
    protected $translatable;
63
64
    /**
65
     * @var array
66
     */
67
    protected $refCollection = array();
68
69
    /**
70
     * possible event names this collection implements (queue events)
71
     *
72
     * @var array
73
     */
74
    protected $eventNames = array();
75
76
    /**
77
     * @var bool
78
     */
79
    protected $readOnly = false;
80
81
    /**
82
     * @var string[]
83
     */
84
    protected $searchable = array();
85
86
    /**
87
     * @var int
88
     */
89
    protected $minLength;
90
91
    /**
92
     * @var int
93
     */
94
    protected $maxLength;
95
96
    /**
97
     * @var int
98
     */
99
    protected $minItems;
100
101
    /**
102
     * @var int
103
     */
104
    protected $maxItems;
105
106
    /**
107
     * @var float
108
     */
109
    protected $numericMinimum;
110
111
    /**
112
     * @var float
113
     */
114
    protected $numericMaximum;
115
116
    /**
117
     * @var SchemaEnum
118
     */
119
    protected $enum;
120
121
    /**
122
     * @var string
123
     */
124
    protected $regexPattern;
125
126
    /**
127
     * @var
128
     */
129
    protected $documentClass;
130
131
    /**
132
     * these are the BSON primitive types.
133
     * http://json-schema.org/latest/json-schema-core.html#anchor8
134
     * every type set *not* in this set will be carried over to 'format'
135
     *
136
     * @var string[]
137
     */
138
    protected $primitiveTypes = [
139
        'array',
140
        'boolean',
141
        'integer',
142
        'number',
143
        'null',
144
        'object',
145
        'string'
146
    ];
147
148
    /**
149
     * those are types that when they are required, a minimal length
150
     * shall be specified in schema
151
     *
152
     * @var array
153
     */
154
    protected $minLengthTypes = [
155
        'integer',
156
        'number',
157
        'string'
158
    ];
159
160
    /**
161
     * known non-primitive types we map to primitives here.
162
     * the type itself is set to the format.
163
     *
164
     * @var string[]
165
     */
166
    protected $specialTypeMapping = [
167
        'extref' => 'string',
168
        'translatable' => 'object',
169
        'date' => 'string',
170
        'float' => 'number',
171
        'double' => 'number',
172
        'decimal' => 'number'
173
    ];
174
175
    protected $formatOverrides = [
176
        'date' => 'date-time'
177 2
    ];
178
179 2
    /**
180 2
     * Build properties
181
     */
182
    public function __construct()
183
    {
184
        $this->properties = new ArrayCollection();
185
    }
186
187
    /**
188
     * set title
189 2
     *
190
     * @param string $title title
191 2
     *
192 2
     * @return void
193
     */
194
    public function setTitle($title)
195
    {
196
        $this->title = $title;
197
    }
198
199 2
    /**
200
     * get title
201 2
     *
202
     * @return string
203
     */
204
    public function getTitle()
205
    {
206
        return $this->title;
207
    }
208
209
    /**
210
     * set description
211
     *
212
     * @param string $description description
213
     *
214
     * @return void
215
     */
216
    public function setDescription($description)
217
    {
218
        $this->description = $description;
219
    }
220
221
    /**
222
     * get description
223
     *
224
     * @return string
225
     */
226
    public function getDescription()
227
    {
228
        return $this->description;
229
    }
230
231
    /**
232
     * set type
233
     *
234
     * @param string|array $types types
235
     *
236
     * @return void
237
     */
238
    public function setType($types)
239
    {
240
        if (!is_array($types)) {
241
            $types = [$types];
242
        }
243
244
        $typesToSet = [];
245
        foreach ($types as $type) {
246
            if ($type === 'int') {
247
                $type = 'integer';
248
            }
249
            if ($type === 'hash') {
250
                $type = 'object';
251
            }
252
253
            // handle non-primitive types
254
            if (!in_array($type, $this->primitiveTypes)) {
255
                $setType = 'string';
256
                if (isset($this->specialTypeMapping[$type])) {
257
                    $setType = $this->specialTypeMapping[$type];
258
                }
259
                $typesToSet[] = $setType;
260
261
                if (isset($this->formatOverrides[$type])) {
262
                    $type = $this->formatOverrides[$type];
263
                }
264
265
                $this->setFormat($type);
266
            } else {
267
                $typesToSet[] = $type;
268
            }
269
        }
270
271
        $this->type = new SchemaType($typesToSet);
0 ignored issues
show
Documentation Bug introduced by
It seems like new \Graviton\SchemaBund...SchemaType($typesToSet) of type object<Graviton\SchemaBundle\Document\SchemaType> is incompatible with the declared type string of property $type.

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...
272
    }
273
274
    /**
275
     * get type
276
     *
277
     * @return SchemaType type
0 ignored issues
show
Documentation introduced by
Should the return type not be string?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
278
     */
279
    public function getType()
280
    {
281
        return $this->type;
282
    }
283
284
    /**
285
     * get MinLengthTypes
286
     *
287
     * @return array MinLengthTypes
288
     */
289
    public function getMinLengthTypes()
290
    {
291
        return $this->minLengthTypes;
292
    }
293
294
    /**
295
     * get format
296
     *
297
     * @return string format
298
     */
299
    public function getFormat()
300
    {
301
        return $this->format;
302
    }
303
304
    /**
305
     * sets format
306
     *
307
     * @param string $format format
308
     *
309
     * @return void
310
     */
311
    public function setFormat($format)
312
    {
313
        $this->format = $format;
314
    }
315
316
    /**
317
     * get numeric minimum
318
     *
319
     * @return float numeric minimum
320
     */
321
    public function getNumericMinimum()
322
    {
323
        return $this->numericMinimum;
324
    }
325
326
    /**
327
     * set numeric minimum
328
     *
329
     * @param float $numericMinimum numeric mimimum
330
     *
331
     * @return void
332
     */
333
    public function setNumericMinimum($numericMinimum)
334
    {
335
        $this->numericMinimum = $numericMinimum;
336
    }
337
338
    /**
339
     * get numeric maximum
340
     *
341
     * @return float numeric maximum
342
     */
343
    public function getNumericMaximum()
344
    {
345
        return $this->numericMaximum;
346
    }
347
348
    /**
349
     * set numeric maximum
350
     *
351
     * @param float $numericMaximum maximum
352
     *
353
     * @return void
354
     */
355
    public function setNumericMaximum($numericMaximum)
356
    {
357
        $this->numericMaximum = $numericMaximum;
358
    }
359
360
    /**
361
     * set min length
362
     *
363
     * @return int length
364
     */
365
    public function getMinLength()
366
    {
367
        return $this->minLength;
368
    }
369
370
    /**
371
     * get min length
372
     *
373
     * @param int $minLength length
374
     *
375
     * @return void
376
     */
377
    public function setMinLength($minLength)
378
    {
379
        $this->minLength = $minLength;
380
    }
381
382
    /**
383
     * gets maxlength
384
     *
385
     * @return int length
386
     */
387
    public function getMaxLength()
388
    {
389
        return $this->maxLength;
390
    }
391
392
    /**
393
     * set maxlength
394
     *
395
     * @param int $maxLength length
396
     *
397
     * @return void
398
     */
399
    public function setMaxLength($maxLength)
400
    {
401
        $this->maxLength = $maxLength;
402
    }
403
404
    /**
405
     * set min Items
406
     *
407
     * @return int Items
408
     */
409
    public function getMinItems()
410
    {
411
        return $this->minItems;
412
    }
413
414
    /**
415
     * get min Items
416
     *
417
     * @param int $minItems length
418
     *
419
     * @return void
420
     */
421
    public function setMinItems($minItems)
422
    {
423
        $this->minItems = $minItems;
424
    }
425
426
    /**
427
     * gets maxItems
428
     *
429
     * @return int Items
430
     */
431
    public function getMaxItems()
432
    {
433
        return $this->maxItems;
434
    }
435
436
    /**
437
     * set maxItems
438
     *
439
     * @param int $maxItems Items
440
     *
441
     * @return void
442
     */
443
    public function setMaxItems($maxItems)
444
    {
445
        $this->maxItems = $maxItems;
446
    }
447
448
    /**
449
     * get Enum
450
     *
451
     * @return array Enum
0 ignored issues
show
Documentation introduced by
Should the return type not be SchemaEnum?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
452
     */
453
    public function getEnum()
454
    {
455
        return $this->enum;
456
    }
457
458
    /**
459
     * set Enum
460
     *
461
     * @param array $enum enum
462
     *
463
     * @return void
464
     */
465
    public function setEnum(array $enum)
466
    {
467
        $this->enum = new SchemaEnum($enum);
468
    }
469
470
    /**
471
     * get regex pattern
472
     *
473
     * @return string pattern
474
     */
475
    public function getRegexPattern()
476
    {
477
        return $this->regexPattern;
478
    }
479
480
    /**
481
     * set regex pattern
482
     *
483
     * @param string $regexPattern regex pattern
484
     *
485
     * @return void
486
     */
487
    public function setRegexPattern($regexPattern)
488
    {
489
        $this->regexPattern = $regexPattern;
490
    }
491
492
    /**
493
     * get DocumentClass
494
     *
495
     * @return string DocumentClass
496
     */
497
    public function getDocumentClass()
498
    {
499
        return $this->documentClass;
500
    }
501
502
    /**
503
     * set DocumentClass
504
     *
505
     * @param string $documentClass documentClass
506
     *
507
     * @return void
508
     */
509
    public function setDocumentClass($documentClass)
510
    {
511
        $this->documentClass = $documentClass;
512
    }
513
514
    /**
515
     * set items
516
     *
517
     * @param Schema $items items schema
518
     *
519
     * @return void
520
     */
521
    public function setItems($items)
522
    {
523
        $this->items = $items;
524
    }
525
526
    /**
527
     * get items
528
     *
529
     * @return Schema
530
     */
531
    public function getItems()
532
    {
533
        return $this->items;
534
    }
535
536
    /**
537
     * add a property
538
     *
539
     * @param string $name     property name
540
     * @param Schema $property property
541
     *
542
     * @return void
543
     */
544
    public function addProperty($name, $property)
545
    {
546
        $this->properties->set($name, $property);
547
    }
548
549
    /**
550
     * removes a property
551
     *
552
     * @param string $name property name
553
     *
554
     * @return void
555
     */
556
    public function removeProperty($name)
557
    {
558
        if (!$this->properties->containsKey($name)) {
559
            $this->properties->remove($this->properties->get($name));
560
        }
561
    }
562
563
    /**
564
     * returns a property
565
     *
566
     * @param string $name property name
567
     *
568
     * @return void|Schema property
569
     */
570
    public function getProperty($name)
571
    {
572
        return $this->properties->get($name);
573
    }
574
575
    /**
576
     * get properties
577
     *
578
     * @return ArrayCollection|null
579
     */
580
    public function getProperties()
581
    {
582
        if ($this->properties->isEmpty()) {
583
            return null;
584
        } else {
585
            return $this->properties;
586
        }
587
    }
588
589
    /**
590
     * set additionalProperties on schema
591
     *
592
     * @param SchemaAdditionalProperties $additionalProperties additional properties
593
     *
594
     * @return void
595
     */
596
    public function setAdditionalProperties(SchemaAdditionalProperties $additionalProperties)
597
    {
598
        $this->additionalProperties = $additionalProperties;
599
    }
600
601
    /**
602
     * get addtionalProperties for schema
603
     *
604
     * @return SchemaAdditionalProperties
605
     */
606
    public function getAdditionalProperties()
607
    {
608
        return $this->additionalProperties;
609
    }
610
611
    /**
612
     * set required variables
613
     *
614
     * @param string[] $required array of required fields
615
     *
616
     * @return void
617
     */
618
    public function setRequired(array $required)
619
    {
620
        // needed as indexes could we off and we want to enforce an array after json_encode
621
        $this->required = array_values($required);
622
    }
623
624
    /**
625
     * get required fields
626
     *
627
     * @return string[]|null
628
     */
629
    public function getRequired()
630
    {
631
        $required = $this->required;
632
        if (empty($required)) {
633
            $required = null;
634
        }
635
636
        return $required;
637
    }
638
639
    /**
640
     * set translatable flag
641
     *
642
     * This flag is a local extension to json schema.
643
     *
644
     * @param boolean $translatable translatable flag
645
     *
646
     * @return void
647
     */
648
    public function setTranslatable($translatable)
649
    {
650
        if ($translatable === true) {
651
            $this->setType('translatable');
652
        } else {
653
            $this->setType('string');
654
        }
655
    }
656
657
    /**
658
     * get translatable flag
659
     *
660
     * @return boolean
661
     */
662
    public function isTranslatable()
663
    {
664
        $ret = false;
665
        if ($this->getFormat() == 'translatable') {
666
            $ret = true;
667
        }
668
669
        return $ret;
670
    }
671
672
    /**
673
     * set a array of urls that can extref refer to
674
     *
675
     * @param array $refCollection urls
676
     *
677
     * @return void
678
     */
679
    public function setRefCollection(array $refCollection)
680
    {
681
        $this->refCollection = $refCollection;
682
    }
683
684
    /**
685
     * get a collection of urls that can extref refer to
686
     *
687
     * @return array
0 ignored issues
show
Documentation introduced by
Should the return type not be null|array? Also, consider making the array more specific, something like array<String>, or String[].

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

If the return type contains the type array, this check recommends the use of a more specific type like String[] or array<String>.

Loading history...
688
     */
689
    public function getRefCollection()
690
    {
691
        $collection = $this->refCollection;
692
        if (empty($collection)) {
693
            $collection = null;
694
        }
695
696
        return $collection;
697
    }
698
699
    /**
700
     * set an array of possible event names
701
     *
702
     * @param array $eventNames event names
703
     *
704
     * @return void
705
     */
706
    public function setEventNames(array $eventNames)
707
    {
708
        $this->eventNames = array_values($eventNames);
709
    }
710
711
    /**
712
     * get a collection of possible event names
713
     *
714
     * @return array
0 ignored issues
show
Documentation introduced by
Should the return type not be null|array? Also, consider making the array more specific, something like array<String>, or String[].

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

If the return type contains the type array, this check recommends the use of a more specific type like String[] or array<String>.

Loading history...
715
     */
716
    public function getEventNames()
717
    {
718
        $collection = $this->eventNames;
719
        if (empty($collection)) {
720
            $collection = null;
721
        }
722
723
        return $collection;
724
    }
725
726
    /**
727
     * Set the readOnly flag
728
     *
729
     * @param bool $readOnly ReadOnly flag
730
     *
731
     * @return void
732
     */
733
    public function setReadOnly($readOnly)
734
    {
735
        $this->readOnly = (bool) $readOnly;
736
    }
737
738
    /**
739
     * Get the readOnly flag.
740
     * Returns null if the flag is set to false so the serializer will ignore it.
741
     *
742
     * @return bool|null true if readOnly isset to true or null if not
743
     */
744
    public function getReadOnly()
745
    {
746
        return $this->readOnly ? true : null;
747
    }
748
749
    /**
750
     * set searchable variables
751
     *
752
     * @param string[] $searchable arary of searchable fields
753
     *
754
     * @return void
755
     */
756
    public function setSearchable($searchable)
757
    {
758
        $this->searchable = $searchable;
759
    }
760
761
    /**
762
     * get searchable fields
763
     *
764
     * @return string[]|null
765
     */
766
    public function getSearchable()
767
    {
768
        $searchable = $this->searchable;
769
        if (empty($searchable)) {
770
            $searchable = null;
771
        }
772
773
        return $searchable;
774
    }
775
}
776