DataBag::__clone()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 9
rs 9.6666
cc 3
eloc 5
nc 3
nop 0
1
<?php
2
3
/**
4
 * Copyright (c) 2015-present Ganbaro Digital Ltd
5
 * All rights reserved.
6
 *
7
 * Redistribution and use in source and binary forms, with or without
8
 * modification, are permitted provided that the following conditions
9
 * are met:
10
 *
11
 *   * Redistributions of source code must retain the above copyright
12
 *     notice, this list of conditions and the following disclaimer.
13
 *
14
 *   * Redistributions in binary form must reproduce the above copyright
15
 *     notice, this list of conditions and the following disclaimer in
16
 *     the documentation and/or other materials provided with the
17
 *     distribution.
18
 *
19
 *   * Neither the names of the copyright holders nor the names of his
20
 *     contributors may be used to endorse or promote products derived
21
 *     from this software without specific prior written permission.
22
 *
23
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
26
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
27
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
28
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
29
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
31
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
33
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34
 * POSSIBILITY OF SUCH DAMAGE.
35
 *
36
 * @category  Libraries
37
 * @package   DataContainers/Containers
38
 * @author    Stuart Herbert <[email protected]>
39
 * @copyright 2011-present Mediasift Ltd www.datasift.com
40
 * @copyright 2015-present Ganbaro Digital Ltd www.ganbarodigital.com
41
 * @license   http://www.opensource.org/licenses/bsd-license.php  BSD License
42
 * @link      http://code.ganbarodigital.com/php-data-containers
43
 */
44
45
namespace GanbaroDigital\DataContainers\Containers;
46
47
use ArrayIterator;
48
use IteratorAggregate;
49
use stdClass;
50
use GanbaroDigital\DataContainers\Exceptions\E4xx_NoSuchProperty;
51
use GanbaroDigital\DataContainers\Checks\HasUsingDotNotationPath;
52
use GanbaroDigital\DataContainers\Checks\IsDotNotationPath;
53
use GanbaroDigital\DataContainers\Editors\MergeUsingDotNotationPath;
54
use GanbaroDigital\DataContainers\Editors\RemoveUsingDotNotationPath;
55
use GanbaroDigital\DataContainers\Filters\FilterDotNotationPath;
56
57
/**
58
 * The DataBag is based on the BaseObject that I built for Datasift's
59
 * open-source library 'Stone'.
60
 *
61
 * It's essentially a stdClass-on-steroids.
62
 */
63
class DataBag extends stdClass implements DataContainer
64
{
65
    /**
66
     * magic method, called when there's an attempt to get a property
67
     * that doesn't actually exist
68
     *
69
     * if $propertyName is a dot.notation.support path, we'll attempt to
70
     * retrieve the property from the data bag's children
71
     *
72
     * @param  string $propertyName
73
     *         name of the property being read
74
     * @return mixed
75
     *
76
     * @throws E4xx_NoSuchProperty
77
     */
78
    public function __get($propertyName)
79
    {
80
        // is the user trying to use dot.notation?
81
        if (IsDotNotationPath::checkString($propertyName)) {
82
            return FilterDotNotationPath::fromObject($this, $propertyName);
83
        }
84
85
        // if we get here, then we have no idea what you are trying to get
86
        throw new E4xx_NoSuchProperty($this, $propertyName);
87
    }
88
89
    /**
90
     * magic method, called when there's an attempt to set a property that
91
     * doesn't actually exist
92
     *
93
     * if $propertyName is a dot.notation.support path, we'll attempt to
94
     * set the property using the path
95
     *
96
     * @param string $propertyName
97
     *        name of the property to set
98
     * @param mixed $propertyValue
99
     *        value of the property to set
100
     * @return void
101
     */
102
    public function __set($propertyName, $propertyValue)
103
    {
104
        // is the user trying to use dot.notation?
105
        if (IsDotNotationPath::checkString($propertyName)) {
106
            return MergeUsingDotNotationPath::intoObject($this, $propertyName, $propertyValue, DataBag::class);
107
        }
108
109
        // if we get here, then we simply have a new property to set
110
        //
111
        // I hope that it does not recurse!
112
        $this->$propertyName = $propertyValue;
113
    }
114
115
    /**
116
     * magic method, called when we want to know if a fake property exists
117
     * or not
118
     *
119
     * if $propertyName is a dot.notation.support path, we'll attempt to
120
     * follow it to find the stated property
121
     *
122
     * @param  string $propertyName
123
     *         name of the property to search for
124
     * @return boolean
125
     *         TRUE if the property exists (or is emulated)
126
     *         FALSE otherwise
127
     */
128
    public function __isset($propertyName)
129
    {
130
        // is the user trying to use dot.notation?
131
        if (IsDotNotationPath::checkString($propertyName)) {
132
            return HasUsingDotNotationPath::inObject($this, $propertyName);
133
        }
134
135
        // if we get here, the property does not exist
136
        return false;
137
    }
138
139
    /**
140
     * magic method, called when we want to delete a fake property
141
     *
142
     * @param string $propertyName
143
     *        the property to remove
144
     */
145
    public function __unset($propertyName)
146
    {
147
        RemoveUsingDotNotationPath::from($this, $propertyName);
148
    }
149
150
    /**
151
     * magic method, called after we have been cloned
152
     *
153
     * we go all-in and perform a deep clone
154
     *
155
     * @return void
156
     */
157
    public function __clone()
158
    {
159
        $properties = get_object_vars($this);
160
        foreach ($properties as $propertyName => $propertyValue) {
161
            if (is_object($propertyValue)) {
162
                $this->$propertyName = clone $propertyValue;
163
            }
164
        }
165
    }
166
167
    /**
168
     * support foreach() loops over our data
169
     *
170
     * @return \Traversable
171
     */
172
    public function getIterator()
173
    {
174
        return new ArrayIterator($this);
175
    }
176
}
177