AbstractManyRelation   A
last analyzed

Complexity

Total Complexity 20

Size/Duplication

Total Lines 219
Duplicated Lines 0 %

Coupling/Cohesion

Dependencies 3

Importance

Changes 8
Bugs 2 Features 1
Metric Value
wmc 20
c 8
b 2
f 1
cbo 3
dl 0
loc 219
rs 10

12 Methods

Rating   Name   Duplication   Size   Complexity  
A offsetExists() 0 7 1
A offsetGet() 0 7 2
A offsetSet() 0 6 1
A offsetUnset() 0 11 2
A count() 0 6 1
A setReference() 0 6 1
A setOrderBy() 0 6 1
A getReference() 0 4 1
A getOrderBy() 0 4 1
A add() 0 20 3
A addAll() 0 8 2
B toArray() 0 22 4
1
<?php
2
/**
3
 * Fwk
4
 *
5
 * Copyright (c) 2011-2014, Julien Ballestracci <[email protected]>.
6
 * All rights reserved.
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 *
11
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
12
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
13
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
14
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
15
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
16
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
17
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
18
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
19
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
20
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
21
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
22
 * POSSIBILITY OF SUCH DAMAGE.
23
 *
24
 * PHP Version 5.3
25
 *
26
 * @category   Database
27
 * @package    Fwk
28
 * @subpackage Db
29
 * @author     Julien Ballestracci <[email protected]>
30
 * @copyright  2011-2014 Julien Ballestracci <[email protected]>
31
 * @license    http://www.opensource.org/licenses/bsd-license.php  BSD License
32
 * @link       http://www.nitronet.org/fwk
33
 */
34
namespace Fwk\Db\Relations;
35
36
use Fwk\Db\Registry\Registry;
37
use Fwk\Db\RelationInterface;
38
use Fwk\Db\Registry\RegistryState;
39
use Fwk\Db\Accessor;
40
41
/**
42
 * Abstract utility class for *Many Relations
43
 *
44
 * @category Relations
45
 * @package  Fwk\Db
46
 * @author   Julien Ballestracci <[email protected]>
47
 * @license  http://www.opensource.org/licenses/bsd-license.php  BSD License
48
 * @link     http://www.nitronet.org/fwk
49
 */
50
abstract class AbstractManyRelation extends AbstractRelation implements
51
    \ArrayAccess, \Countable
52
{
53
    /**
54
     * Name of the column to be used as the index for this relation's entities
55
     *
56
     * @var string
57
     */
58
    protected $reference;
59
60
    /**
61
     * Name of the column to use for sorting this relation's entities
62
     *
63
     * @var array
64
     */
65
    protected $orderBy;
66
67
    /**
68
     * Test if an entity is present in this relation.
69
     * Triggers a fetch if the relation is FETCH_LAZY
70
     *
71
     * @param string|integer $offset The index key
72
     *
73
     * @return boolean
74
     */
75
    public function offsetExists($offset)
76
    {
77
        $this->fetch();
78
        $array = $this->toArray();
79
80
        return array_key_exists($offset, $array);
81
    }
82
83
    /**
84
     * Returns the entity at the given index (reference) if any, or null.
85
     * Triggers a fetch if the relation is FETCH_LAZY
86
     *
87
     * @param string|integer $offset The index key
88
     *
89
     * @return object|null
90
     */
91
    public function offsetGet($offset)
92
    {
93
        $this->fetch();
94
        $array  = $this->toArray();
95
96
        return (array_key_exists($offset, $array) ? $array[$offset] : null);
97
    }
98
99
    /**
100
     * Adds an entity to this relation at the given index
101
     *
102
     * @param string|integer $offset The index key
103
     * @param object         $value  The entity
104
     *
105
     * @return RelationInterface|void
106
     */
107
    public function offsetSet($offset, $value)
108
    {
109
        $this->fetch();
110
111
        return $this->add($value);
112
    }
113
114
    /**
115
     * Removes an entity at the given index
116
     * Triggers a fetch if the relation is FETCH_LAZY
117
     *
118
     * @param string|integer $offset The index key
119
     *
120
     * @return void
121
     */
122
    public function offsetUnset($offset)
123
    {
124
        $this->fetch();
125
126
        $obj    = $this->offsetGet($offset);
127
        if (null === $obj) {
128
            return;
129
        }
130
131
        parent::remove($obj);
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (remove() instead of offsetUnset()). Are you sure this is correct? If so, you might want to change this to $this->remove().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
132
    }
133
134
    /**
135
     * Count entities in this relation.
136
     * Triggers a fetch if the relation is FETCH_LAZY
137
     *
138
     * @return int
139
     */
140
    public function count()
141
    {
142
        $this->fetch();
143
144
        return $this->getRegistry()->count();
145
    }
146
147
     /**
148
     * Defines the column to use as index for this relation's entities
149
     *
150
     * @param string $column The column's name
151
      *
152
     * @return RelationInterface
0 ignored issues
show
Documentation introduced by
Should the return type not be AbstractManyRelation?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
153
     */
154
    public function setReference($column)
155
    {
156
        $this->reference = $column;
157
158
        return $this;
159
    }
160
161
    /**
162
     * Defines the column to use to sort entities in this relation
163
     *
164
     * @param string $column    The column's name
165
     * @param string $direction The direction (asc or desc)
0 ignored issues
show
Documentation introduced by
Should the type for parameter $direction not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
166
     *
167
     * @return RelationInterface
0 ignored issues
show
Documentation introduced by
Should the return type not be AbstractManyRelation?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
168
     */
169
    public function setOrderBy($column, $direction = null)
170
    {
171
        $this->orderBy = array('column' => $column, 'direction' => $direction);
172
173
        return $this;
174
    }
175
176
    /**
177
     * Returns the column used as reference (index)
178
     *
179
     * @return string
180
     */
181
    public function getReference()
182
    {
183
        return $this->reference;
184
    }
185
186
    /**
187
     * Returns the orderBy for this relation
188
     *
189
     * @return array
190
     */
191
    public function getOrderBy()
192
    {
193
        return $this->orderBy;
194
    }
195
196
    /**
197
     * Adds an entity to the collection
198
     *
199
     * @param object $object      The entity
200
     * @param array  $identifiers List of identifiers (PK) for this entity
201
     *
202
     * @return void
203
     */
204
    public function add($object, array $identifiers = array())
205
    {
206
        if ($this->has($object)) {
207
            return;
208
        }
209
210
        $data = array('reference' => null);
211
        if (!empty($this->reference)) {
212
            $access             = new Accessor($object);
213
            $reference          = $access->get($this->reference);
214
            $data['reference']  = $reference;
215
        }
216
217
        $this->getRegistry()->store(
218
            $object,
219
            $identifiers,
220
            RegistryState::REGISTERED,
221
            $data
222
        );
223
    }
224
225
    /**
226
     * Adds a set of objects to this relation
227
     *
228
     * @param array $objects List of entities
229
     *
230
     * @return RelationInterface
0 ignored issues
show
Documentation introduced by
Should the return type not be AbstractManyRelation?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
231
     */
232
    public function addAll(array $objects)
233
    {
234
        foreach ($objects as $object) {
235
            $this->add($object);
236
        }
237
238
        return $this;
239
    }
240
241
    /**
242
     * Returns an array of all entities in this relation
243
     *
244
     * @return array
245
     */
246
    public function toArray()
247
    {
248
        $this->fetch();
249
250
        $final = array();
251
        $list = $this->getRegistry()->getStore();
252
        foreach ($list as $entry) {
253
            if ($entry->getAction() == Registry::ACTION_DELETE) {
254
                continue;
255
            }
256
257
            if (empty($this->reference)) {
258
                $final[] = $entry->getObject();
259
                continue;
260
            }
261
262
            $ref    = $entry->data('reference', null);
263
            $final[$ref]  = $entry->getObject();
264
        }
265
266
        return $final;
267
    }
268
}