Completed
Push — master ( 641b84...acf229 )
by Ben
03:05
created

BranchCollection::flattenRecursive()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 11
ccs 0
cts 0
cp 0
rs 9.4285
cc 2
eloc 5
nc 2
nop 2
crap 6
1
<?php
2
3
namespace Thinktomorrow\Vine\Branch;
4
5
use ArrayAccess;
6
use ArrayIterator;
7
use Countable;
8
use IteratorAggregate;
9
use Thinktomorrow\Vine\VineException;
10
11
class BranchCollection implements ArrayAccess, Countable, IteratorAggregate
12
{
13
    private $branches;
14
15 36
    public function __construct(array $branches = [])
16
    {
17 36
        self::validateBranches($branches);
18
19 36
        $this->branches = $branches;
20 36
    }
21
22 12
    public function hasBranches()
23
    {
24 12
        return ($this->branches && count($this->branches) > 0);
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->branches of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
25
    }
26
27 18
    public function push(Branch $branch)
28
    {
29 18
        $this->branches[] = $branch;
30
31 18
        return $this;
32
    }
33
34 3
    public function __get($key)
35
    {
36 3
        if(isset($this->$key)) return $this->$key;
37
38
        throw VineException::unknownBranchCollectionAttribute($key);
39
    }
40
41 36
    public static function validateBranches($branches)
42
    {
43 36
        foreach($branches as $branch)
44
        {
45 9
            if(!$branch instanceof Branch)
46 6
            {
47 3
                throw VineException::requiredAsBranch($branch);
48
            }
49 24
        }
50 36
    }
51
52 3
    public function offsetSet($offset, $value) {
53 3
        if (is_null($offset)) {
54 3
            $this->branches[] = $value;
55 2
        } else {
56
            $this->branches[$offset] = $value;
57
        }
58 3
    }
59
60 3
    public function offsetExists($offset) {
61 3
        return isset($this->branches[$offset]);
62
    }
63
64
    public function offsetUnset($offset) {
65
        unset($this->branches[$offset]);
66
    }
67
68 21
    public function offsetGet($offset) {
69 21
        return isset($this->branches[$offset]) ? $this->branches[$offset] : null;
70
    }
71
72 21
    public function count()
73
    {
74 21
        return count($this->branches);
75
    }
76
77
    /**
78
     * Iterator for the branches
79
     *
80
     * @return \ArrayIterator
81
     */
82 24
    public function getIterator()
83
    {
84 24
        return new ArrayIterator($this->branches);
85
    }
86
87 3
    public function toArray()
88
    {
89 3
        return BuildArray::fromCollection($this);
90
    }
91
92
    public function flatten()
93
    {
94
        $flatten = [];
95
96
        foreach($this->branches as $branch)
97
        {
98
            $flatten = array_merge($flatten,$this->flattenRecursive($branch,0));
99
        }
100
101
        return new static($flatten);
102
    }
103
104
    protected function flattenRecursive(Branch $branch, $level = 0)
105
    {
106
        $children = $branch->branches;
0 ignored issues
show
Documentation introduced by
The property $branches is declared private in Thinktomorrow\Vine\Branch\Branch. Since you implemented __get(), maybe consider adding a @property or @property-read annotation. This makes it easier for IDEs to provide auto-completion.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
107
108
        // Remove the children reference
109
        $output = [new Branch($branch->key,$branch->value,$branch->label)];
0 ignored issues
show
Documentation introduced by
The property $key is declared private in Thinktomorrow\Vine\Branch\Branch. Since you implemented __get(), maybe consider adding a @property or @property-read annotation. This makes it easier for IDEs to provide auto-completion.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
Documentation introduced by
The property $value is declared private in Thinktomorrow\Vine\Branch\Branch. Since you implemented __get(), maybe consider adding a @property or @property-read annotation. This makes it easier for IDEs to provide auto-completion.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
Documentation introduced by
The property $label is declared private in Thinktomorrow\Vine\Branch\Branch. Since you implemented __get(), maybe consider adding a @property or @property-read annotation. This makes it easier for IDEs to provide auto-completion.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
110
111
        foreach($children as $child) $output = array_merge($output,$this->flattenRecursive($child,$level+1));
112
113
        return $output;
114
    }
115
}
116