Passed
Push — master ( c8547b...1d562b )
by Michiel
22:08
created

AbstractSelectorContainer::appendSelector()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 2.0625

Importance

Changes 0
Metric Value
cc 2
eloc 3
nc 2
nop 1
dl 0
loc 6
ccs 3
cts 4
cp 0.75
crap 2.0625
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
4
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
5
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
6
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
7
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
8
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
9
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
10
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
11
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
13
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14
 *
15
 * This software consists of voluntary contributions made by many individuals
16
 * and is licensed under the LGPL. For more information please see
17
 * <http://phing.info>.
18
 */
19
20
/**
21
 * This is the base class for selectors that can contain other selectors.
22
 *
23
 * @author  Siad Ardroumli <[email protected]>
24
 * @package phing.types.selectors
25
 */
26
abstract class AbstractSelectorContainer extends DataType implements SelectorContainer
27
{
28
    use SelectorAware;
29
30
    /**
31
     * Performs the check for circular references and returns the
32
     * referenced FileSet.
33
     *
34
     * @param Project $p
35
     *
36
     * @throws BuildException
37
     *
38
     * @return FileSet
39
     */
40
    public function getRef(Project $p)
0 ignored issues
show
Unused Code introduced by
The parameter $p is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

40
    public function getRef(/** @scrutinizer ignore-unused */ Project $p)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
41
    {
42
        $dataTypeName = StringHelper::substring(__CLASS__, strrpos(__CLASS__, '\\') + 1);
43
        return $this->getCheckedRef(__CLASS__, $dataTypeName);
44
    }
45
46
    /**
47
     * Indicates whether there are any selectors here.
48
     *
49
     * @return boolean Whether any selectors are in this container
50
     */
51
    public function hasSelectors()
52
    {
53
        if ($this->isReference() && $this->getProject() !== null) {
54
            return $this->getRef($this->getProject())->hasSelectors();
55
        }
56
57
        return !empty($this->selectorsList);
58
    }
59
60
    /**
61
     * Convert the Selectors within this container to a string. This will
62
     * just be a helper class for the subclasses that put their own name
63
     * around the contents listed here.
64
     *
65
     * @return string comma separated list of Selectors contained in this one
66
     */
67
    public function __toString()
68
    {
69
        return implode(', ', $this->selectorElements());
70
    }
71
72
    /**
73
     * <p>
74
     * This validates each contained selector
75
     * provided that the selector implements the validate interface.
76
     * </p>
77
     * <p>Ordinarily, this will validate all the elements of a selector
78
     * container even if the isSelected() method of some elements is
79
     * never called. This has two effects:</p>
80
     * <ul>
81
     * <li>Validation will often occur twice.
82
     * <li>Since it is not required that selectors derive from
83
     * BaseSelector, there could be selectors in the container whose
84
     * error conditions are not detected if their isSelected() call
85
     * is never made.
86
     * </ul>
87
     */
88 6
    public function validate()
89
    {
90 6
        if ($this->isReference()) {
91
            $dataTypeName = StringHelper::substring(__CLASS__, strrpos(__CLASS__, '\\') + 1);
92
            $this->getCheckedRef(__CLASS__, $dataTypeName)->validate();
93
        }
94 6
        $selectorElements = $this->selectorElements();
95 6
        $this->dieOnCircularReference($selectorElements, $this->getProject());
96 6
        foreach ($selectorElements as $o) {
97 6
            if ($o instanceof BaseSelector) {
98 2
                $o->validate();
99
            }
100
        }
101 6
    }
102
103
    /**
104
     * Gives the count of the number of selectors in this container
105
     *
106
     * @throws Exception
107
     * @return int The number of selectors in this container
108
     */
109 6
    public function count()
110
    {
111 6
        if ($this->isReference() && $this->getProject() !== null) {
112
            try {
113
                return $this->getRef($this->getProject())->count();
114
            } catch (Exception $e) {
115
                throw $e;
116
            }
117
        }
118
119 6
        return count($this->selectorsList);
120
    }
121
122
    /**
123
     * Returns the set of selectors as an array.
124
     *
125
     * @param  Project $p
126
     * @throws BuildException
127
     * @return array of selectors in this container
128
     */
129 6
    public function getSelectors(Project $p)
130
    {
131 6
        if ($this->isReference()) {
132
            return $this->getRef($p)->getSelectors($p);
133
        }
134
135
// *copy* selectors
136 6
        $result = [];
137 6
        for ($i = 0, $size = count($this->selectorsList); $i < $size; $i++) {
138 6
            $result[] = clone $this->selectorsList[$i];
139
        }
140
141 6
        return $result;
142
    }
143
144
    /**
145
     * Returns an array for accessing the set of selectors.
146
     *
147
     * @return array The array of selectors
148
     */
149 6
    public function selectorElements()
150
    {
151 6
        if ($this->isReference() && $this->getProject() !== null) {
152
            return $this->getRef($this->getProject())->selectorElements();
153
        }
154
155 6
        return $this->selectorsList;
156
    }
157
158
    /**
159
     * Add a new selector into this container.
160
     *
161
     * @param FileSelector $selector new selector to add
162
     *
163
     * @throws BuildException
164
     *
165
     * @return void
166
     */
167 6
    public function appendSelector(FileSelector $selector)
168
    {
169 6
        if ($this->isReference()) {
170
            throw $this->noChildrenAllowed();
171
        }
172 6
        $this->selectorsList[] = $selector;
173 6
    }
174
175 6
    public function dieOnCircularReference(&$stk, Project $p = null)
176
    {
177 6
        if ($this->checked) {
178 6
            return;
179
        }
180
181
        if ($this->isReference()) {
182
            parent::dieOnCircularReference($stk, $p);
183
        } else {
184
            foreach ($this->selectorsList as $fileSelector) {
185
                if ($fileSelector instanceof DataType) {
186
                    self::pushAndInvokeCircularReferenceCheck($fileSelector, $stk, $p);
0 ignored issues
show
Bug introduced by
It seems like $p can also be of type null; however, parameter $p of DataType::pushAndInvokeCircularReferenceCheck() does only seem to accept Project, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

186
                    self::pushAndInvokeCircularReferenceCheck($fileSelector, $stk, /** @scrutinizer ignore-type */ $p);
Loading history...
187
                }
188
            }
189
            $this->checked = true;
190
        }
191
    }
192
}
193