1: <?php namespace Knot\Dict;
2:
3: use Knot\Exceptions\WrongArrayPathException;
4:
5: trait PathOperationsTrait {
6:
7: /**
8: * For parsing array path.
9: */
10: public static $ARRAY_PATH_DELIMITER = ".";
11:
12: protected $data = [ ];
13:
14: protected $path = '';
15:
16:
17: abstract public function childParent();
18:
19:
20: /**
21: * @param null $add
22: *
23: * @return null|string
24: */
25: public function path($add = null)
26: {
27: return $add ? $this->path != null ? $this->path . self::$ARRAY_PATH_DELIMITER . $add : $add : $this->path;
28: }
29:
30:
31: /**
32: * @param $path
33: *
34: * @return array
35: */
36: public static function pathParser($path)
37: {
38: return explode(self::$ARRAY_PATH_DELIMITER, $path);
39: }
40:
41:
42: /**
43: * @param array $path
44: *
45: * @return string
46: */
47: public static function pathCombiner(array $path)
48: {
49: return implode(self::$ARRAY_PATH_DELIMITER, $path);
50: }
51:
52:
53: /**
54: * @param $path
55: *
56: * @return bool
57: */
58: public function isPath($path)
59: {
60: try
61: {
62: $this->get($path);
63:
64: return true;
65: }
66: catch (WrongArrayPathException $e)
67: {
68: return false;
69: }
70: }
71:
72:
73: /**
74: * @param $path
75: *
76: * @return array|ChildDict|Mixed
77: * @throws WrongArrayPathException
78: */
79: public function get($path)
80: {
81: $arguments = func_get_args();
82:
83: if ( isset( $arguments[1] ) )
84: {
85: $default_return = $arguments[1];
86: }
87:
88: $target_data =& $this->data;
89:
90: foreach (static::pathParser($path) as $way)
91: {
92:
93: if ( ! isset( $target_data[$way] ) )
94: {
95:
96: if ( isset( $default_return ) )
97: {
98: $r = $this->set($path, $default_return);
99:
100: return $r;
101: }
102:
103: throw new WrongArrayPathException($path);
104: }
105:
106: $target_data = &$target_data[$way];
107: }
108:
109: if ( is_array($target_data) )
110: {
111: return new ChildDict($target_data, $this->childParent(), $path);
112: }
113:
114: return $target_data;
115: }
116:
117:
118: /**
119: * For Get path without parsing default return to data.
120: *
121: * @param $path
122: *
123: * @return Mixed
124: * @throws WrongArrayPathException
125: */
126: public function getOnly($path)
127: {
128: $arguments = func_get_args();
129:
130: if ( isset( $arguments[1] ) )
131: {
132: $default_return = $arguments[1];
133: }
134:
135: try
136: {
137: return $this->get($path);
138: }
139: catch (WrongArrayPathException $e)
140: {
141: if ( isset( $default_return ) )
142: {
143: return $default_return;
144: }
145:
146: throw $e;
147: }
148: }
149:
150:
151: /**
152: * @param $rawPath
153: * @param $value
154: *
155: * @return Mixed|\Knot\Dict\ChildDict
156: */
157: public function set($rawPath, $value)
158: {
159: $target_data =& $this->data;
160:
161: foreach (static::pathParser($rawPath) as $path)
162: {
163: // If there is no way to go or this is not an array!
164: if ( ! isset( $target_data[$path] ) || ! is_array($target_data[$path]) )
165: {
166: $target_data[$path] = [ ];
167: }
168:
169: $target_data =& $target_data[$path];
170: }
171:
172: $target_data = $value;
173:
174: if ( is_array($target_data) )
175: {
176: return new ChildDict($target_data, $this->childParent(), $this->path());
177: }
178:
179: return $value;
180: }
181:
182:
183: /**
184: * @param $rawPath
185: *
186: * @return $this
187: */
188: public function del($rawPath)
189: {
190: $target_data =& $this->data;
191:
192: $paths = static::pathParser($rawPath);
193:
194: $target_key = array_pop($paths);
195:
196: foreach ($paths as $path)
197: {
198: // If there is no way to go or this is not an array!
199: if ( ! isset( $target_data[$path] ) || ! is_array($target_data[$path]) )
200: {
201: return $this;
202: }
203:
204: $target_data =& $target_data[$path];
205: }
206:
207: if ( isset( $target_data[$target_key] ) )
208: {
209: unset( $target_data[$target_key] );
210: }
211:
212: return $this;
213: }
214: }