Completed
Push — master ( fff5f3...fc4fc8 )
by Thomas
02:20
created

Relations::getRelation()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 3

Importance

Changes 0
Metric Value
dl 0
loc 14
ccs 7
cts 7
cp 1
rs 9.7998
c 0
b 0
f 0
cc 3
nc 3
nop 1
crap 3
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) {
0 ignored issues
show
Bug introduced by
The class ORM\Entity\EM does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to 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 require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
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) {
0 ignored issues
show
Bug introduced by
The class ORM\Entity\EM does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to 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 require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
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) {
0 ignored issues
show
Bug introduced by
The class ORM\Entity\EM does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to 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 require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
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