ControlType::fromSchema()   B
last analyzed

Complexity

Conditions 9
Paths 8

Size

Total Lines 30
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 9
eloc 19
nc 8
nop 2
dl 0
loc 30
rs 8.0555
c 0
b 0
f 0
1
<?php
2
/**
3
 * BEdita, API-first content management framework
4
 * Copyright 2020 ChannelWeb Srl, Chialab Srl
5
 *
6
 * This file is part of BEdita: you can redistribute it and/or modify
7
 * it under the terms of the GNU Lesser General Public License as published
8
 * by the Free Software Foundation, either version 3 of the License, or
9
 * (at your option) any later version.
10
 *
11
 * See LICENSE.LGPL or <http://gnu.org/licenses/lgpl-3.0.html> for more details.
12
 */
13
14
namespace App\Form;
15
16
use Cake\Utility\Hash;
17
18
/**
19
 * ControlType class provides methods to get control types per type, according to schema property data.
20
 * Used by SchemaHelper to build control options for a property schema (@see \App\View\Helper\SchemaHelper::controlOptions)
21
 */
22
class ControlType
23
{
24
    /**
25
     * Schema property types
26
     */
27
    public const SCHEMA_PROPERTY_TYPES = ['string', 'number', 'integer', 'boolean', 'array', 'object', 'byte'];
28
29
    /**
30
     * Map JSON Schema `contentMediaType` to supported control types
31
     *
32
     * @var array
33
     */
34
    public const CONTENT_MEDIA_TYPES = [
35
        'text/html' => 'richtext',
36
        'text/plain' => 'plaintext',
37
    ];
38
39
    /**
40
     * Infer control type from property schema
41
     * Possible return values:
42
     *
43
     *   'categories'
44
     *   'checkbox'
45
     *   'checkboxNullable'
46
     *   'date-time'
47
     *   'date'
48
     *   'enum'
49
     *   'json'
50
     *   'number'
51
     *   'plaintext'
52
     *   'richtext'
53
     *   'text'
54
     *
55
     * @param array|null $schema The property schema
56
     * @param bool|null $canBeNull Whether the property can be null
57
     * @return string
58
     */
59
    public static function fromSchema(?array $schema, ?bool $canBeNull = false): string
60
    {
61
        if ($schema === null) {
0 ignored issues
show
introduced by
The condition $schema === null is always false.
Loading history...
62
            return 'text';
63
        }
64
        if (empty($schema)) {
65
            return 'json';
66
        }
67
        $schemaType = (string)Hash::get($schema, 'type');
68
        if ($schemaType === 'categories') {
69
            return $schemaType;
70
        }
71
        if (!empty($schema['oneOf'])) {
72
            $nullable = false;
73
            foreach ($schema['oneOf'] as $subSchema) {
74
                if (!empty($subSchema['type']) && $subSchema['type'] === 'null') {
75
                    $nullable = true;
76
                    continue;
77
                }
78
79
                return ControlType::fromSchema($subSchema, $nullable);
80
            }
81
        }
82
        if (!in_array($schemaType, ControlType::SCHEMA_PROPERTY_TYPES)) {
83
            return 'text';
84
        }
85
        $callable = Form::getMethod(ControlType::class, sprintf('from%s', ucfirst($schemaType)));
86
        $args = [$schema + compact('canBeNull')];
87
88
        return call_user_func_array($callable, $args);
89
    }
90
91
    /**
92
     * Get control type per string, according to schema property data.
93
     * Possibilities:
94
     *
95
     *    format 'date-time' => 'date-time'
96
     *    format 'date' => 'date'
97
     *    contentMediaType 'text/plain' => 'plaintext'
98
     *    contentMediaType 'text/html' => 'richtext'
99
     *    schema.enum is an array => 'enum'
100
     *
101
     * Return 'text' otherwise.
102
     *
103
     * @param array $schema The property schema
104
     * @return string
105
     */
106
    public static function fromString(array $schema): string
107
    {
108
        if (!empty($schema['format']) && in_array($schema['format'], ['date', 'date-time'])) {
109
            return $schema['format'];
110
        }
111
        $contentType = (string)Hash::get($schema, 'contentMediaType');
112
        $controlType = (string)Hash::get(self::CONTENT_MEDIA_TYPES, $contentType);
113
        if (!empty($controlType)) {
114
            return $controlType;
115
        }
116
        if (!empty($schema['enum']) && is_array($schema['enum'])) {
117
            return 'enum';
118
        }
119
120
        return 'text';
121
    }
122
123
    /**
124
     * Return the type for number: 'number'
125
     *
126
     * @param array $schema Object schema array.
127
     * @return string
128
     */
129
    public static function fromNumber(array $schema): string
0 ignored issues
show
Unused Code introduced by
The parameter $schema is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

129
    public static function fromNumber(/** @scrutinizer ignore-unused */ array $schema): string

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
130
    {
131
        return 'number';
132
    }
133
134
    /**
135
     * Return the type for integer: 'integer'
136
     *
137
     * @param array $schema Object schema array.
138
     * @return string
139
     */
140
    public static function fromInteger(array $schema): string
0 ignored issues
show
Unused Code introduced by
The parameter $schema is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

140
    public static function fromInteger(/** @scrutinizer ignore-unused */ array $schema): string

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
141
    {
142
        return 'integer';
143
    }
144
145
    /**
146
     * Return the type for boolean: 'checkbox'
147
     *
148
     * @param array $schema Object schema array.
149
     * @return string
150
     */
151
    public static function fromBoolean(array $schema): string
152
    {
153
        if (Hash::get($schema, 'canBeNull') === true) {
154
            return 'checkboxNullable';
155
        }
156
157
        return 'checkbox';
158
    }
159
160
    /**
161
     * Return the type for array: 'checkbox'
162
     *
163
     * @param array $schema Object schema array.
164
     * @return string
165
     */
166
    public static function fromArray(array $schema): string
0 ignored issues
show
Unused Code introduced by
The parameter $schema is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

166
    public static function fromArray(/** @scrutinizer ignore-unused */ array $schema): string

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
167
    {
168
        return 'checkbox';
169
    }
170
171
    /**
172
     * Return the type for object: 'json'
173
     *
174
     * @param array $schema Object schema array.
175
     * @return string
176
     */
177
    public static function fromObject(array $schema): string
0 ignored issues
show
Unused Code introduced by
The parameter $schema is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

177
    public static function fromObject(/** @scrutinizer ignore-unused */ array $schema): string

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
178
    {
179
        return 'json';
180
    }
181
}
182