Completed
Push — 1.0 ( de14e4...537877 )
by Bernhard
57:08 queued 17:45
created

ResourceCollectionIterator   A

Complexity

Total Complexity 15

Size/Duplication

Total Lines 172
Duplicated Lines 1.74 %

Coupling/Cohesion

Components 1
Dependencies 1

Test Coverage

Coverage 97.06%

Importance

Changes 2
Bugs 1 Features 0
Metric Value
wmc 15
c 2
b 1
f 0
lcom 1
cbo 1
dl 3
loc 172
ccs 33
cts 34
cp 0.9706
rs 10

9 Methods

Rating   Name   Duplication   Size   Complexity  
A current() 0 12 3
A next() 0 4 1
A key() 0 12 3
A valid() 0 4 1
A rewind() 0 4 1
A hasChildren() 0 4 1
A getChildren() 0 4 1
A getCurrentResource() 0 4 1
A __construct() 3 13 3

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
3
/*
4
 * This file is part of the puli/repository package.
5
 *
6
 * (c) Bernhard Schussek <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Puli\Repository\Resource\Iterator;
13
14
use Puli\Repository\Api\Resource\PuliResource;
15
use Puli\Repository\Api\ResourceCollection;
16
17
/**
18
 * A recursive iterator for resource collections.
19
 *
20
 * Use the iterator if you want to iterate a resource collection. You can
21
 * configure what the iterator should return as keys and values:
22
 *
23
 * ```php
24
 * $iterator = new ResourceCollectionIterator(
25
 *     $collection,
26
 *     ResourceCollectionIterator::KEY_AS_PATH | ResourceCollectionIterator::CURRENT_AS_RESOURCE
27
 * );
28
 *
29
 * foreach ($iterator as $path => $resource) {
30
 *     // ...
31
 * }
32
 * ```
33
 *
34
 * If you want to iterate the collection recursively, wrap it in a
35
 * {@link RecursiveResourceIteratorIterator}:
36
 *
37
 * ```php
38
 * $iterator = new RecursiveResourceIteratorIterator(
39
 *     new ResourceCollectionIterator(
40
 *         $collection,
41
 *         ResourceCollectionIterator::KEY_AS_PATH | ResourceCollectionIterator::CURRENT_AS_RESOURCE
42
 *     ),
43
 *     RecursiveResourceIteratorIterator::SELF_FIRST
44
 * );
45
 *
46
 * foreach ($iterator as $path => $resource) {
47
 *     // ...
48
 * }
49
 * ```
50
 *
51
 * @since  1.0
52
 *
53
 * @author Bernhard Schussek <[email protected]>
54
 */
55
class ResourceCollectionIterator implements RecursiveResourceIterator
56
{
57
    /**
58
     * Return {@link PuliResource} instances as values.
59
     */
60
    const CURRENT_AS_RESOURCE = 1;
61
62
    /**
63
     * Return the paths of the resources as values.
64
     */
65
    const CURRENT_AS_PATH = 2;
66
67
    /**
68
     * Return the names of the resources as values.
69
     */
70
    const CURRENT_AS_NAME = 4;
71
72
    /**
73
     * Return the paths of the resources as keys.
74
     */
75
    const KEY_AS_PATH = 64;
76
77
    /**
78
     * Return the collection keys as keys.
79
     *
80
     * Attention: Don't use this mode when iterating recursively, as PHP's
81
     * {@link RecursiveIteratorIterator} skips inner nodes then.
82
     */
83
    const KEY_AS_CURSOR = 128;
84
85
    /**
86
     * @var PuliResource[]
87
     */
88
    protected $resources;
89
90
    /**
91
     * @var int
92
     */
93
    protected $mode;
94
95
    /**
96
     * Creates a new iterator.
97
     *
98
     * The following constants can be used to configure the values returned by
99
     * the iterator:
100
     *
101
     *  * {@link CURRENT_AS_RESOURCE}: The {@link PuliResource} objects are
102
     *                                 returned as values;
103
     *  * {@link CURRENT_AS_PATH}: The resource paths are returned as values;
104
     *  * {@link CURRENT_AS_NAME}: The resource names are returned as values.
105
     *
106
     * The following constants can be used to configure the keys returned by
107
     * the iterator:
108
     *
109
     *  * {@link KEY_AS_CURSOR}: The collection keys are returned as keys;
110
     *  * {@link KEY_AS_PATH}: The resource paths are returned as keys.
111
     *
112
     * By default, the mode `KEY_AS_PATH | CURRENT_AS_RESOURCE` is used.
113
     *
114
     * @param ResourceCollection $resources The resources to iterate.
115
     * @param int|null           $mode      A bitwise combination of the mode
116
     *                                      constants.
117
     */
118 653
    public function __construct(ResourceCollection $resources, $mode = null)
119
    {
120 653 View Code Duplication
        if (!($mode & (self::CURRENT_AS_PATH | self::CURRENT_AS_RESOURCE | self::CURRENT_AS_NAME))) {
121 642
            $mode |= self::CURRENT_AS_RESOURCE;
122
        }
123
124 653
        if (!($mode & (self::KEY_AS_PATH | self::KEY_AS_CURSOR))) {
125 7
            $mode |= self::KEY_AS_PATH;
126
        }
127
128 653
        $this->resources = $resources->toArray();
129 653
        $this->mode = $mode;
130 653
    }
131
132
    /**
133
     * Returns the current value of the iterator.
134
     *
135
     * @return PuliResource|string The current value as configured in
136
     *                             {@link __construct}.
137
     */
138 377
    public function current()
139
    {
140 377
        if ($this->mode & self::CURRENT_AS_RESOURCE) {
141 367
            return current($this->resources);
142
        }
143
144 10
        if ($this->mode & self::CURRENT_AS_PATH) {
145 2
            return current($this->resources)->getPath();
146
        }
147
148 8
        return current($this->resources)->getName();
149
    }
150
151
    /**
152
     * Advances the iterator to the next position.
153
     */
154 377
    public function next()
155
    {
156 377
        next($this->resources);
157 377
    }
158
159
    /**
160
     * Returns the current key of the iterator.
161
     *
162
     * @return int|string|null The current key as configured in
163
     *                         {@link __construct} or `null` if the cursor
164
     *                         is behind the last element.
165
     */
166 130
    public function key()
167
    {
168 130
        if (null === ($key = key($this->resources))) {
169
            return null;
170
        }
171
172 130
        if ($this->mode & self::KEY_AS_PATH) {
173 10
            return $this->resources[$key]->getPath();
174
        }
175
176 120
        return $key;
177
    }
178
179
    /**
180
     * Returns whether the iterator points to a valid key.
181
     *
182
     * @return bool Whether the iterator position is valid.
183
     */
184 652
    public function valid()
185
    {
186 652
        return null !== key($this->resources);
187
    }
188
189
    /**
190
     * Rewinds the iterator to the first entry.
191
     */
192 651
    public function rewind()
193
    {
194 651
        reset($this->resources);
195 651
    }
196
197
    /**
198
     * Returns whether the iterator can be applied recursively over the
199
     * current element.
200
     *
201
     * @return bool Whether the current element can be iterated recursively.
202
     */
203 9
    public function hasChildren()
204
    {
205 9
        return current($this->resources)->hasChildren();
206
    }
207
208
    /**
209
     * Returns the iterator for the children of the current element.
210
     *
211
     * @return static Returns an instance of this class for the children of
212
     *                the current element.
213
     */
214 9
    public function getChildren()
215
    {
216 9
        return new static(current($this->resources)->listChildren(), $this->mode);
217
    }
218
219
    /**
220
     * {@inheritdoc}
221
     */
222 5
    public function getCurrentResource()
223
    {
224 5
        return current($this->resources);
225
    }
226
}
227