Completed
Push — 4-cactus ( 59c50f...21a27c )
by Alberto
02:40
created

Core/src/Model/Behavior/RelationsBehavior.php (1 issue)

Labels
Severity
1
<?php
2
/**
3
 * BEdita, API-first content management framework
4
 * Copyright 2017 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\Behavior;
15
16
use BEdita\Core\ORM\Association\RelatedTo;
17
use Cake\Datasource\Exception\RecordNotFoundException;
18
use Cake\ORM\Behavior;
19
use Cake\ORM\TableRegistry;
20
use League\JsonReference\Dereferencer;
0 ignored issues
show
The type League\JsonReference\Dereferencer was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
21
22
/**
23
 * Relations behavior
24
 */
25
class RelationsBehavior extends Behavior
26
{
27
28
    /**
29
     * {@inheritDoc}
30
     */
31
    protected $_defaultConfig = [
32
        'implementedMethods' => [
33
            'setupRelations' => 'setupRelations',
34
            'getRelations' => 'getRelations',
35
        ],
36
    ];
37
38
    /**
39
     * {@inheritDoc}
40
     */
41
    public function initialize(array $config)
42
    {
43
        parent::initialize($config);
44
45
        $table = $this->getTable();
46
        if (!$table->hasBehavior('ObjectType')) {
47
            $table->addBehavior('BEdita/Core.ObjectType');
48
        }
49
50
        $this->setupRelations();
51
    }
52
53
    /**
54
     * Getter for object type.
55
     *
56
     * @param array $args Method arguments.
57
     * @return \BEdita\Core\Model\Entity\ObjectType
58
     */
59
    protected function objectType(...$args)
60
    {
61
        return $this->getTable()->behaviors()->call('objectType', $args);
62
    }
63
64
    /**
65
     * Creates a new RelatedTo association between this table and a target
66
     * table. A "belongs to many" association is a M-N relationship.
67
     *
68
     * Target table can be inferred by its name, which is provided in the
69
     * first argument, or you can either pass the class name to be instantiated or
70
     * an instance of it directly.
71
     *
72
     * The options array accept the same keys as {@see \Cake\ORM\Table::belongsToMany()}.
73
     *
74
     * This method will return the association object that was built.
75
     *
76
     * @param string $associated The alias for the target table. This is used to
77
     *      uniquely identify the association.
78
     * @param array $options List of options to configure the association definition.
79
     * @return \Cake\ORM\Association
80
     */
81
    protected function relatedTo($associated, array $options = [])
82
    {
83
        $options += ['sourceTable' => $this->getTable()];
84
        $association = new RelatedTo($associated, $options);
85
86
        return $this->getTable()->associations()->add($association->getName(), $association);
87
    }
88
89
    /**
90
     * Set up relations for the current table.
91
     *
92
     * @param string|int|null $objectType Object type name or ID.
93
     * @return void
94
     */
95
    public function setupRelations($objectType = null)
96
    {
97
        if ($objectType === null) {
98
            $objectType = $this->getTable()->getAlias();
99
        }
100
101
        try {
102
            $objectType = $this->objectType($objectType);
103
        } catch (RecordNotFoundException $e) {
104
            return;
105
        }
106
107
        // Add relations to the left side.
108
        foreach ($objectType->getRelations('left') as $relation) {
109
            if ($this->getTable()->association($relation->alias) !== null) {
110
                continue;
111
            }
112
113
            $className = 'BEdita/Core.Objects';
114
            if (count($relation->right_object_types) === 1) {
115
                $className = $relation->right_object_types[0]->table;
116
            }
117
118
            $through = TableRegistry::get(
119
                $relation->alias . 'ObjectRelations',
120
                ['className' => 'ObjectRelations']
121
            );
122
            $through->getValidator()->setProvider(
123
                'jsonSchema',
124
                Dereferencer::draft4()->dereference(json_decode(json_encode($relation->params)))
125
            );
126
127
            $this->relatedTo($relation->alias, [
128
                'className' => $className,
129
                'through' => $through->getRegistryAlias(),
130
                'foreignKey' => 'left_id',
131
                'targetForeignKey' => 'right_id',
132
                'conditions' => [
133
                    $through->aliasField('relation_id') => $relation->id,
134
                    sprintf('%s.deleted', $relation->alias) => false,
135
                ],
136
                'sort' => [
137
                    $through->aliasField('priority') => 'asc',
138
                ],
139
            ]);
140
        }
141
142
        // Add relations to the right side.
143
        foreach ($objectType->getRelations('right') as $relation) {
144
            if ($this->getTable()->association($relation->inverse_alias) !== null) {
145
                continue;
146
            }
147
148
            $className = 'BEdita/Core.Objects';
149
            if (count($relation->left_object_types) === 1) {
150
                $className = $relation->left_object_types[0]->table;
151
            }
152
153
            $through = TableRegistry::get(
154
                $relation->inverse_alias . 'ObjectRelations',
155
                ['className' => 'ObjectRelations']
156
            );
157
            $through->getValidator()->setProvider(
158
                'jsonSchema',
159
                Dereferencer::draft4()->dereference(json_decode(json_encode($relation->params)))
160
            );
161
162
            $this->relatedTo($relation->inverse_alias, [
163
                'className' => $className,
164
                'through' => $through->getRegistryAlias(),
165
                'foreignKey' => 'right_id',
166
                'targetForeignKey' => 'left_id',
167
                'conditions' => [
168
                    $through->aliasField('relation_id') => $relation->id,
169
                    sprintf('%s.deleted', $relation->inverse_alias) => false,
170
                ],
171
                'sort' => [
172
                    $through->aliasField('inv_priority') => 'asc',
173
                ],
174
            ]);
175
        }
176
    }
177
178
    /**
179
     * Get a list of all available relations indexed by their name with regards of side.
180
     *
181
     * @return \BEdita\Core\Model\Entity\Relation[]
182
     * @deprecated Use `ObjectType::getRelations()` instead.
183
     */
184
    public function getRelations()
185
    {
186
        return $this->objectType()->getRelations();
187
    }
188
}
189