Passed
Push — 4-cactus ( 9097d8...cd593b )
by Stefano
03:42
created

BEdita/Core/src/Model/Entity/ObjectEntity.php (1 issue)

Labels
Severity
1
<?php
2
/**
3
 * BEdita, API-first content management framework
4
 * Copyright 2018 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 BEdita\Core\Model\Entity;
15
16
use BEdita\Core\Utility\JsonApiSerializable;
17
use Cake\Datasource\Exception\InvalidPrimaryKeyException;
18
use Cake\Datasource\Exception\RecordNotFoundException;
19
use Cake\ORM\Entity;
20
use Cake\ORM\Table;
21
use Cake\ORM\TableRegistry;
22
use Cake\Routing\Router;
23
24
/**
25
 * Object Entity.
26
 *
27
 * @property int $id
28
 * @property int $object_type_id
29
 * @property bool $deleted
30
 * @property string $type
31
 * @property string $status
32
 * @property string $uname
33
 * @property bool $locked
34
 * @property \Cake\I18n\Time|\Cake\I18n\FrozenTime $created
35
 * @property \Cake\I18n\Time|\Cake\I18n\FrozenTime $modified
36
 * @property \Cake\I18n\Time|\Cake\I18n\FrozenTime $published
37
 * @property string $title
38
 * @property string $description
39
 * @property string $body
40
 * @property array $custom_props
41
 * @property array $extra
42
 * @property string $lang
43
 * @property int $created_by
44
 * @property int $modified_by
45
 * @property \Cake\I18n\Time|\Cake\I18n\FrozenTime $publish_start
46
 * @property \Cake\I18n\Time|\Cake\I18n\FrozenTime $publish_end
47
 *
48
 * @property \BEdita\Core\Model\Entity\ObjectType $object_type
49
 * @property \BEdita\Core\Model\Entity\User $created_by_user
50
 * @property \BEdita\Core\Model\Entity\User $modified_by_user
51
 * @property \BEdita\Core\Model\Entity\DateRange[] $date_ranges
52
 * @property \BEdita\Core\Model\Entity\Folder[] $parents
53
 * @property \BEdita\Core\Model\Entity\Tree[] $tree_nodes
54
 * @property \BEdita\Core\Model\Entity\Translation[] $translations
55
 * @since 4.0.0
56
 */
57
class ObjectEntity extends Entity implements JsonApiSerializable
58
{
59
    use JsonApiTrait {
60
        listAssociations as protected jsonApiListAssociations;
61
        getMeta as protected jsonApiGetMeta;
62
    }
63
64
    /**
65
     * @inheritDoc
66
     */
67
    protected $_accessible = [
68
        '*' => true,
69
        'id' => false,
70
        'object_type_id' => false,
71
        'object_type' => false,
72
        'type' => false,
73
        'deleted' => false,
74
        'locked' => false,
75
        'created' => false,
76
        'modified' => false,
77
        'published' => false,
78
        'created_by' => false,
79
        'modified_by' => false,
80
    ];
81
82
    /**
83
     * @inheritDoc
84
     */
85
    protected $_virtual = [
86
        'type',
87
    ];
88
89
    /**
90
     * @inheritDoc
91
     */
92
    protected $_hidden = [
93
        'created_by_user',
94
        'modified_by_user',
95
        'object_type_id',
96
        'object_type',
97
        'deleted',
98
        'custom_props',
99
        'tree_nodes',
100
    ];
101
102
    /**
103
     * See if a property has been set in an entity.
104
     * Could be set in `_properties` array or a virtual one.
105
     * Options to exclude hidden properties and to include virtual properties.
106
     *
107
     * @param string $property Property name
108
     * @param bool $hidden Include hidden (default true)
109
     * @param bool $virtual Include virtual (default false)
110
     * @return bool
111
     */
112
    public function hasProperty(string $property, bool $hidden = true, bool $virtual = false)
113
    {
114
        if ($hidden && !$virtual) {
115
            return array_key_exists($property, $this->_properties);
116
        }
117
118
        $properties = array_keys($this->_properties);
119
        if (!$hidden) {
120
            $properties = array_diff($properties, $this->_hidden);
121
        }
122
        if ($virtual) {
123
            $properties = array_merge($properties, $this->_virtual);
124
        }
125
126
        return in_array($property, $properties);
127
    }
128
129
    /**
130
     * @inheritDoc
131
     */
132
    public function getTable()
133
    {
134
        return TableRegistry::getTableLocator()->get($this->type ?: $this->getSource());
135
    }
136
137
    /**
138
     * @inheritDoc
139
     */
140
    protected function getType()
141
    {
142
        return $this->type;
143
    }
144
145
    /**
146
     * @inheritDoc
147
     */
148
    protected function getMeta()
149
    {
150
        return array_diff_key($this->jsonApiGetMeta(), array_flip(['type']));
151
    }
152
153
    /**
154
     * @inheritDoc
155
     */
156
    protected function getLinks()
157
    {
158
        $options = [
159
            '_name' => 'api:objects:resource',
160
            'object_type' => $this->type,
161
            'id' => $this->id,
162
        ];
163
        if ($this->deleted) {
164
            $options = [
165
                '_name' => 'api:trash:resource',
166
                'id' => $this->id,
167
            ];
168
        }
169
170
        return [
171
            'self' => Router::url($options, true),
172
        ];
173
    }
174
175
    /**
176
     * @inheritDoc
177
     */
178
    protected static function listAssociations(Table $Table, array $hidden = [])
179
    {
180
        $associations = static::jsonApiListAssociations($Table, $hidden);
181
        $associations = array_diff($associations, ['date_ranges', 'categories', 'tags']);
182
183
        return $associations;
184
    }
185
186
    /**
187
     * @inheritDoc
188
     */
189
    protected function getRelationships()
190
    {
191
        $relationships = $included = [];
192
        if ($this->deleted) {
193
            return [$relationships, $included];
194
        }
195
196
        $entity = $this;
197
        $table = $this->getTable();
198
        if ($table->getRegistryAlias() !== $this->getSource()) {
199
            $entity = $table->newEntity([]);
200
        }
201
202
        $associations = $entity::listAssociations($table, $entity->getHidden());
0 ignored issues
show
The method listAssociations() does not exist on Cake\Datasource\EntityInterface. It seems like you code against a sub-type of said class. However, the method does not exist in Cake\ORM\Entity or BEdita\Core\Model\Entity\AuthProvider or BEdita\Core\Model\Entity\UserToken or BEdita\Core\Model\Entity\ObjectRelation or BEdita\Core\Model\Entity\ObjectPermission or BEdita\Core\Model\Entity\RolesUser or BEdita\Core\Model\Entity\ObjectProperty or DebugKit\Model\Entity\Request or BEdita\Core\Model\Entity\DateRange or DebugKit\Model\Entity\Panel or BEdita\Core\Model\Entity\RelationType or BEdita\Core\Model\Entity\Tree or BEdita\Core\Model\Entity\ExternalAuth. Are you sure you never get one of those? ( Ignorable by Annotation )

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

202
        /** @scrutinizer ignore-call */ 
203
        $associations = $entity::listAssociations($table, $entity->getHidden());
Loading history...
203
        foreach ($associations as $relationship) {
204
            $self = Router::url(
205
                [
206
                    '_name' => 'api:objects:relationships',
207
                    'object_type' => $this->type,
208
                    'relationship' => $relationship,
209
                    'id' => $this->getId(),
210
                ],
211
                true
212
            );
213
            $related = Router::url(
214
                [
215
                    '_name' => 'api:objects:related',
216
                    'object_type' => $this->type,
217
                    'relationship' => $relationship,
218
                    'related_id' => $this->getId(),
219
                ],
220
                true
221
            );
222
223
            if ($this->has($relationship)) {
224
                $entities = $this->get($relationship);
225
                $data = $this->getIncluded($entities);
226
                if (!is_array($entities)) {
227
                    $entities = [$entities];
228
                }
229
                $included = array_merge($included, $entities);
230
            }
231
232
            $relationships[$relationship] = [
233
                'links' => compact('related', 'self'),
234
            ];
235
            if (isset($data)) {
236
                $relationships[$relationship] += compact('data');
237
                unset($data);
238
            }
239
            $count = $this->getRelationshipCount($relationship);
240
            if ($count !== null) {
241
                $relationships[$relationship] += [
242
                    'meta' => compact('count'),
243
                ];
244
            }
245
        }
246
247
        return [$relationships, $included];
248
    }
249
250
    /**
251
     * @inheritDoc
252
     */
253
    public function getVisible(): array
254
    {
255
        $visible = parent::getVisible();
256
        $this->loadObjectType();
257
        if (!$this->object_type) {
258
            return $visible;
259
        }
260
261
        $hidden = !empty($this->object_type->hidden) ? $this->object_type->hidden : [];
262
263
        return array_diff($visible, $hidden);
264
    }
265
266
    /**
267
     * Load `object_type`, read from object_types table if not set.
268
     *
269
     * @return void
270
     */
271
    protected function loadObjectType()
272
    {
273
        if (!$this->object_type) {
274
            try {
275
                $typeId = $this->object_type_id ?: $this->getSource();
276
                $this->object_type = TableRegistry::getTableLocator()->get('ObjectTypes')->get($typeId);
277
            } catch (RecordNotFoundException $e) {
278
            } catch (InvalidPrimaryKeyException $e) {
279
            }
280
        }
281
    }
282
283
    /**
284
     * Getter for `type` virtual property.
285
     *
286
     * @return string
287
     */
288
    protected function _getType()
289
    {
290
        $this->loadObjectType();
291
        if (!$this->object_type) {
292
            return null;
293
        }
294
295
        return $this->object_type->name;
296
    }
297
298
    /**
299
     * Setter for `type` virtual property.
300
     *
301
     * @param string $type Object type name.
302
     * @return string
303
     */
304
    protected function _setType($type)
305
    {
306
        try {
307
            $this->object_type = TableRegistry::getTableLocator()->get('ObjectTypes')->get($type);
308
            $this->object_type_id = $this->object_type->id;
309
            $this->setDirty('object_type_id', true);
310
        } catch (RecordNotFoundException $e) {
311
            return null;
312
        }
313
314
        return $type;
315
    }
316
}
317