Completed
Branch BUG/double-ampersand-in-regist... (7dce02)
by
unknown
131:59 queued 62:17
created

JsonModelSchema::__toString()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace EventEspresso\core\entities\models;
4
5
use EEM_Base;
6
use EE_Model_Field_Base;
7
use EE_Primary_Key_Field_Base;
8
use EE_Primary_Key_Int_Field;
9
use EE_Foreign_Key_Field_Base;
10
use EE_Model_Relation_Base;
11
use EEH_Inflector;
12
use EE_Belongs_To_Relation;
13
use EventEspresso\core\libraries\rest_api\CalculatedModelFields;
14
15
/**
16
 * This is used to generate an array that can be used to generate a schema for a given model.
17
 * The format for the generated array follows the structure given in the json-schema standard
18
 *
19
 * @see        http://json-schema.org
20
 * @package    EventEspresso
21
 * @subpackage core\db_models\helpers
22
 * @author     Darren Ethier
23
 * @since      4.9.24.rc.018
24
 */
25
class JsonModelSchema
26
{
27
28
    /**
29
     * @var EEM_Base
30
     */
31
    protected $model;
32
33
    /**
34
     * @var CalculatedModelFields
35
     */
36
    protected $fields_calculator;
37
38
39
    /**
40
     * JsonModelSchema constructor.
41
     *
42
     * @param EEM_Base              $model
43
     * @param CalculatedModelFields $fields_calculator
44
     */
45
    public function __construct(EEM_Base $model, CalculatedModelFields $fields_calculator)
46
    {
47
        $this->model = $model;
48
        $this->fields_calculator = $fields_calculator;
49
    }
50
51
52
    /**
53
     * Return the schema for a given model from a given model.
54
     *
55
     * @return array
56
     */
57
    public function getModelSchema()
58
    {
59
        return $this->getModelSchemaForRelations(
60
            $this->model->relation_settings(),
61
            $this->getModelSchemaForFields(
62
                $this->model->field_settings(),
63
                $this->getInitialSchemaStructure()
64
            )
65
        );
66
    }
67
68
69
    /**
70
     * Get the schema for a given set of model fields.
71
     *
72
     * @param EE_Model_Field_Base[] $model_fields
73
     * @param array                  $schema
74
     * @return array
75
     */
76
    public function getModelSchemaForFields(array $model_fields, array $schema)
77
    {
78
        foreach ($model_fields as $field => $model_field) {
79
            if (! $model_field instanceof EE_Model_Field_Base) {
80
                continue;
81
            }
82
            $schema['properties'][ $field ] = $model_field->getSchema();
83
84
            // if this is a primary key field add the primary key item
85
            if ($model_field instanceof EE_Primary_Key_Field_Base) {
86
                $schema['properties'][ $field ]['primary_key'] = true;
87
                if ($model_field instanceof EE_Primary_Key_Int_Field) {
88
                    $schema['properties'][ $field ]['readonly'] = true;
89
                }
90
            }
91
92
            // if this is a foreign key field add the foreign key item
93
            if ($model_field instanceof EE_Foreign_Key_Field_Base) {
94
                $schema['properties'][ $field ]['foreign_key'] = array(
95
                    'description' => esc_html__(
96
                        'This is a foreign key the points to the given models.',
97
                        'event_espresso'
98
                    ),
99
                    'type'        => 'array',
100
                    'enum'        => $model_field->get_model_class_names_pointed_to(),
101
                );
102
            }
103
        }
104
        return $schema;
105
    }
106
107
108
    /**
109
     * Get the schema for a given set of model relations
110
     *
111
     * @param EE_Model_Relation_Base[] $relations_on_model
112
     * @param array                    $schema
113
     * @return array
114
     */
115
    public function getModelSchemaForRelations(array $relations_on_model, array $schema)
116
    {
117
        foreach ($relations_on_model as $model_name => $relation) {
118
            if (! $relation instanceof EE_Model_Relation_Base) {
119
                continue;
120
            }
121
            $model_name_for_schema = $relation instanceof EE_Belongs_To_Relation
122
                ? strtolower($model_name)
123
                : EEH_Inflector::pluralize_and_lower($model_name);
124
            $schema['properties'][ $model_name_for_schema ] = $relation->getSchema();
125
            $schema['properties'][ $model_name_for_schema ]['relation_model'] = $model_name;
126
127
            // links schema
128
            $links_key = 'https://api.eventespresso.com/' . strtolower($model_name);
129
            $schema['properties']['_links']['properties'][ $links_key ] = array(
130
                'description' => esc_html__(
131
                    'Array of objects describing the link(s) for this relation resource.',
132
                    'event_espresso'
133
                ),
134
                'type' => 'array',
135
                'readonly' => true,
136
                'items' => array(
137
                    'type' => 'object',
138
                    'properties' => array(
139
                        'href' => array(
140
                            'type' => 'string',
141
                            'description' => sprintf(
142
                                // translators: placeholder is the model name for the relation.
143
                                esc_html__(
144
                                    'The link to the resource for the %s relation(s) to this entity',
145
                                    'event_espresso'
146
                                ),
147
                                $model_name
148
                            ),
149
                        ),
150
                        'single' => array(
151
                            'type' => 'boolean',
152
                            'description' => sprintf(
153
                                // translators: placeholder is the model name for the relation.
154
                                esc_html__(
155
                                    'Whether or not there is only a single %s relation to this entity',
156
                                    'event_espresso'
157
                                ),
158
                                $model_name
159
                            ),
160
                        ),
161
                    ),
162
                    'additionalProperties' => false
163
                ),
164
            );
165
        }
166
        return $schema;
167
    }
168
169
170
    /**
171
     * Outputs the schema header for a model.
172
     *
173
     * @return array
174
     */
175
    public function getInitialSchemaStructure()
176
    {
177
        return array(
178
            '$schema'    => 'http://json-schema.org/draft-04/schema#',
179
            'title'      => $this->model->get_this_model_name(),
180
            'type'       => 'object',
181
            'properties' => array(
182
                'link' => array(
183
                    'description' => esc_html__(
184
                        'Link to event on WordPress site hosting events.',
185
                        'event_espresso'
186
                    ),
187
                    'type' => 'string',
188
                    'readonly' => true,
189
                ),
190
                '_links' => array(
191
                    'description' => esc_html__(
192
                        'Various links for resources related to the entity.',
193
                        'event_espresso'
194
                    ),
195
                    'type' => 'object',
196
                    'readonly' => true,
197
                    'properties' => array(
198
                        'self' => array(
199
                            'description' => esc_html__(
200
                                'Link to this entities resource.',
201
                                'event_espresso'
202
                            ),
203
                            'type' => 'array',
204
                            'items' => array(
205
                                'type' => 'object',
206
                                'properties' => array(
207
                                    'href' => array(
208
                                        'type' => 'string',
209
                                    ),
210
                                ),
211
                                'additionalProperties' => false
212
                            ),
213
                            'readonly' => true
214
                        ),
215
                        'collection' => array(
216
                            'description' => esc_html__(
217
                                'Link to this entities collection resource.',
218
                                'event_espresso'
219
                            ),
220
                            'type' => 'array',
221
                            'items' => array(
222
                                'type' => 'object',
223
                                'properties' => array(
224
                                    'href' => array(
225
                                        'type' => 'string'
226
                                    ),
227
                                ),
228
                                'additionalProperties' => false
229
                            ),
230
                            'readonly' => true
231
                        ),
232
                    ),
233
                    'additionalProperties' => false,
234
                ),
235
                '_calculated_fields' => $this->fields_calculator->getJsonSchemaForModel($this->model)
236
            ),
237
            'additionalProperties' => false,
238
        );
239
    }
240
241
242
    /**
243
     * Allows one to just use the object as a string to get the json.
244
     * eg.
245
     * $json_schema = new JsonModelSchema(EEM_Event::instance(), new CalculatedModelFields);
246
     * echo $json_schema; //outputs the schema as a json formatted string.
247
     *
248
     * @return bool|false|mixed|string
249
     */
250
    public function __toString()
251
    {
252
        return wp_json_encode($this->getModelSchema());
253
    }
254
}
255