|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
namespace ORM\Entity; |
|
4
|
|
|
|
|
5
|
|
|
use ORM\Entity; |
|
6
|
|
|
use ORM\EntityFetcher; |
|
7
|
|
|
use ORM\Exception; |
|
8
|
|
|
use ORM\Exception\IncompletePrimaryKey; |
|
9
|
|
|
use ORM\Exception\InvalidConfiguration; |
|
10
|
|
|
use ORM\Exception\InvalidRelation; |
|
11
|
|
|
use ORM\Exception\NoEntityManager; |
|
12
|
|
|
use ORM\Exception\UndefinedRelation; |
|
13
|
|
|
use ORM\Relation; |
|
14
|
|
|
|
|
15
|
|
|
trait Relations |
|
16
|
|
|
{ |
|
17
|
|
|
/** Relation definitions |
|
18
|
|
|
* @var array */ |
|
19
|
|
|
protected static $relations = []; |
|
20
|
|
|
|
|
21
|
|
|
/** The entity manager from which this entity got created |
|
22
|
|
|
* @var EM */ |
|
23
|
|
|
protected $entityManager; |
|
24
|
|
|
|
|
25
|
|
|
/** Related objects for getRelated |
|
26
|
|
|
* @var array */ |
|
27
|
|
|
protected $relatedObjects = []; |
|
28
|
|
|
|
|
29
|
|
|
/** |
|
30
|
|
|
* Get the definition for $relation |
|
31
|
|
|
* |
|
32
|
|
|
* It normalize the short definition form and create a Relation object from it. |
|
33
|
|
|
* |
|
34
|
|
|
* @param string $relation |
|
35
|
|
|
* @return Relation |
|
36
|
|
|
* @throws InvalidConfiguration |
|
37
|
|
|
* @throws UndefinedRelation |
|
38
|
|
|
*/ |
|
39
|
83 |
|
public static function getRelation($relation) |
|
40
|
|
|
{ |
|
41
|
83 |
|
if (!isset(static::$relations[$relation])) { |
|
42
|
3 |
|
throw new UndefinedRelation('Relation ' . $relation . ' is not defined'); |
|
43
|
|
|
} |
|
44
|
|
|
|
|
45
|
82 |
|
$relDef = &static::$relations[$relation]; |
|
46
|
|
|
|
|
47
|
82 |
|
if (!$relDef instanceof Relation) { |
|
48
|
14 |
|
$relDef = Relation::createRelation($relation, $relDef); |
|
49
|
|
|
} |
|
50
|
|
|
|
|
51
|
81 |
|
return $relDef; |
|
52
|
|
|
} |
|
53
|
|
|
|
|
54
|
|
|
/** |
|
55
|
|
|
* Get related objects |
|
56
|
|
|
* |
|
57
|
|
|
* The difference between getRelated and fetch is that getRelated stores the fetched entities. To refresh set |
|
58
|
|
|
* $refresh to true. |
|
59
|
|
|
* |
|
60
|
|
|
* @param string $relation |
|
61
|
|
|
* @param bool $refresh |
|
62
|
|
|
* @return mixed |
|
63
|
|
|
* @throws Exception\NoConnection |
|
64
|
|
|
* @throws Exception\NoEntity |
|
65
|
|
|
* @throws IncompletePrimaryKey |
|
66
|
|
|
* @throws InvalidConfiguration |
|
67
|
|
|
* @throws NoEntityManager |
|
68
|
|
|
* @throws UndefinedRelation |
|
69
|
|
|
*/ |
|
70
|
11 |
|
public function getRelated($relation, $refresh = false) |
|
71
|
|
|
{ |
|
72
|
11 |
|
if ($refresh || !isset($this->relatedObjects[$relation])) { |
|
73
|
9 |
|
$this->relatedObjects[$relation] = $this->fetch($relation, true); |
|
74
|
|
|
} |
|
75
|
|
|
|
|
76
|
11 |
|
return $this->relatedObjects[$relation]; |
|
77
|
|
|
} |
|
78
|
|
|
|
|
79
|
|
|
/** |
|
80
|
|
|
* Set $relation to $entity |
|
81
|
|
|
* |
|
82
|
|
|
* This method is only for the owner of a relation. |
|
83
|
|
|
* |
|
84
|
|
|
* @param string $relation |
|
85
|
|
|
* @param Entity $entity |
|
86
|
|
|
* @throws IncompletePrimaryKey |
|
87
|
|
|
* @throws InvalidRelation |
|
88
|
|
|
*/ |
|
89
|
7 |
|
public function setRelated($relation, Entity $entity = null) |
|
90
|
|
|
{ |
|
91
|
7 |
|
$this::getRelation($relation)->setRelated($this, $entity); |
|
92
|
|
|
|
|
93
|
4 |
|
$this->relatedObjects[$relation] = $entity; |
|
94
|
4 |
|
} |
|
95
|
|
|
|
|
96
|
|
|
/** |
|
97
|
|
|
* Add relations for $relation to $entities |
|
98
|
|
|
* |
|
99
|
|
|
* This method is only for many-to-many relations. |
|
100
|
|
|
* |
|
101
|
|
|
* This method does not take care about already existing relations and will fail hard. |
|
102
|
|
|
* |
|
103
|
|
|
* @param string $relation |
|
104
|
|
|
* @param Entity[] $entities |
|
105
|
|
|
* @throws NoEntityManager |
|
106
|
|
|
*/ |
|
107
|
8 |
|
public function addRelated($relation, array $entities) |
|
108
|
|
|
{ |
|
109
|
|
|
// @codeCoverageIgnoreStart |
|
110
|
|
|
if (func_num_args() === 3 && func_get_arg(2) instanceof EM) { |
|
|
|
|
|
|
111
|
|
|
trigger_error( |
|
112
|
|
|
'Passing EntityManager to addRelated is deprecated. Use ->setEntityManager() to overwrite', |
|
113
|
|
|
E_USER_DEPRECATED |
|
114
|
|
|
); |
|
115
|
|
|
} |
|
116
|
|
|
// @codeCoverageIgnoreEnd |
|
117
|
|
|
|
|
118
|
8 |
|
$this::getRelation($relation)->addRelated($this, $entities, $this->entityManager); |
|
119
|
4 |
|
} |
|
120
|
|
|
|
|
121
|
|
|
/** |
|
122
|
|
|
* Delete relations for $relation to $entities |
|
123
|
|
|
* |
|
124
|
|
|
* This method is only for many-to-many relations. |
|
125
|
|
|
* |
|
126
|
|
|
* @param string $relation |
|
127
|
|
|
* @param Entity[] $entities |
|
128
|
|
|
* @throws NoEntityManager |
|
129
|
|
|
*/ |
|
130
|
8 |
|
public function deleteRelated($relation, $entities) |
|
131
|
|
|
{ |
|
132
|
|
|
// @codeCoverageIgnoreStart |
|
133
|
|
|
if (func_num_args() === 3 && func_get_arg(2) instanceof EM) { |
|
|
|
|
|
|
134
|
|
|
trigger_error( |
|
135
|
|
|
'Passing EntityManager to deleteRelated is deprecated. Use ->setEntityManager() to overwrite', |
|
136
|
|
|
E_USER_DEPRECATED |
|
137
|
|
|
); |
|
138
|
|
|
} |
|
139
|
|
|
// @codeCoverageIgnoreEnd |
|
140
|
|
|
|
|
141
|
8 |
|
$this::getRelation($relation)->deleteRelated($this, $entities, $this->entityManager); |
|
142
|
4 |
|
} |
|
143
|
|
|
|
|
144
|
|
|
/** |
|
145
|
|
|
* Fetches related objects |
|
146
|
|
|
* |
|
147
|
|
|
* For relations with cardinality many it returns an EntityFetcher. Otherwise it returns the entity. |
|
148
|
|
|
* |
|
149
|
|
|
* It will throw an error for non owner when the key is incomplete. |
|
150
|
|
|
* |
|
151
|
|
|
* @param string $relation The relation to fetch |
|
152
|
|
|
* @param bool $getAll |
|
153
|
|
|
* @return Entity|Entity[]|EntityFetcher |
|
154
|
|
|
* @throws NoEntityManager |
|
155
|
|
|
*/ |
|
156
|
20 |
|
public function fetch($relation, $getAll = false) |
|
157
|
|
|
{ |
|
158
|
|
|
// @codeCoverageIgnoreStart |
|
159
|
|
|
if ($getAll instanceof EM || func_num_args() === 3 && $getAll === null) { |
|
|
|
|
|
|
160
|
|
|
$getAll = func_num_args() === 3 ? func_get_arg(2) : false; |
|
161
|
|
|
trigger_error( |
|
162
|
|
|
'Passing EntityManager to fetch is deprecated. Use ->setEntityManager() to overwrite', |
|
163
|
|
|
E_USER_DEPRECATED |
|
164
|
|
|
); |
|
165
|
|
|
} |
|
166
|
|
|
// @codeCoverageIgnoreEnd |
|
167
|
|
|
|
|
168
|
20 |
|
$relation = $this::getRelation($relation); |
|
169
|
|
|
|
|
170
|
20 |
|
if ($getAll) { |
|
171
|
4 |
|
return $relation->fetchAll($this, $this->entityManager); |
|
172
|
|
|
} else { |
|
173
|
16 |
|
return $relation->fetch($this, $this->entityManager); |
|
174
|
|
|
} |
|
175
|
|
|
} |
|
176
|
|
|
} |
|
177
|
|
|
|
This error could be the result of:
1. Missing dependencies
PHP Analyzer uses your
composer.jsonfile (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects thecomposer.jsonto be in the root folder of your repository.Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the
requireorrequire-devsection?2. Missing use statement
PHP does not complain about undefined classes in
ìnstanceofchecks. For example, the following PHP code will work perfectly fine:If you have not tested against this specific condition, such errors might go unnoticed.