1: <?php
2: namespace Pharborist\Types;
3:
4: use Pharborist\ParentNode;
5: use Pharborist\ParenTrait;
6: use Pharborist\Token;
7: use Pharborist\ExpressionNode;
8: use Pharborist\Filter;
9: use Pharborist\CommaListNode;
10: use Pharborist\NodeCollection;
11: use Pharborist\Parser;
12:
13: 14: 15:
16: class ArrayNode extends ParentNode implements ExpressionNode {
17: use ParenTrait;
18:
19: 20: 21:
22: protected $elements;
23:
24: 25: 26:
27: public function getElementList() {
28: return $this->elements;
29: }
30:
31: 32: 33:
34: public function getElements() {
35: return $this->elements->getItems();
36: }
37:
38: 39: 40: 41: 42:
43: public function isMultidimensional() {
44: foreach ($this->elements->getItems() as $element) {
45: if ($element instanceof ArrayPairNode) {
46: if ($element->getValue() instanceof ArrayNode) {
47: return TRUE;
48: }
49: }
50: elseif ($element instanceof ArrayNode) {
51: return TRUE;
52: }
53: }
54: return FALSE;
55: }
56:
57: 58: 59: 60: 61: 62: 63: 64: 65:
66: public function toValue() {
67: $ret = array();
68: foreach ($this->elements->getItems() as $element) {
69: if ($element instanceof ArrayNode) {
70: $ref[] = $element->toValue();
71: }
72: elseif ($element instanceof ArrayPairNode) {
73: $key = $element->getKey();
74: $value = $element->getValue();
75: $value_convertable = $value instanceof ScalarNode || $value instanceof ArrayNode;
76: if (!($key instanceof ScalarNode && $value_convertable)) {
77: throw new \BadMethodCallException('Can only convert scalar arrays.');
78: }
79: $ret[$key->toValue()] = $value->toValue();
80: }
81: elseif ($element instanceof ScalarNode || $element instanceof ArrayNode) {
82:
83: $ret[] = $element->toValue();
84: }
85: else {
86: throw new \BadMethodCallException('Can only convert scalar arrays.');
87: }
88: }
89: return $ret;
90: }
91:
92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106:
107: public function hasKey($key, $recursive = TRUE) {
108: if (!($key instanceof ExpressionNode) && !is_scalar($key)) {
109: throw new \InvalidArgumentException();
110: }
111:
112: $keys = $this->getKeys($recursive);
113: if (is_scalar($key)) {
114: return $keys
115: ->filter(Filter::isInstanceOf('\Pharborist\Types\ScalarNode'))
116: ->is(function(ScalarNode $node) use ($key) {
117: return $node->toValue() === $key;
118: });
119: }
120: else {
121: return $keys
122: ->is(function(ExpressionNode $expr) use ($key) {
123: return $expr->getText() === $key->getText();
124: });
125: }
126: }
127:
128: 129: 130: 131: 132: 133: 134: 135:
136: public function getKeys($recursive = TRUE) {
137: $keys = new NodeCollection();
138: $index = 0;
139: foreach ($this->elements->getItems() as $element) {
140: if ($element instanceof ArrayPairNode) {
141: $keys->add($element->getKey());
142: $value = $element->getValue();
143: }
144: else {
145: $keys->add(Token::integer($index++));
146: $value = $element;
147: }
148:
149: if ($recursive && $value instanceof ArrayNode) {
150: $keys->add($value->getKeys($recursive));
151: }
152: }
153: return $keys;
154: }
155:
156: 157: 158: 159: 160: 161: 162: 163:
164: public function getValues($recursive = TRUE) {
165: $values = new NodeCollection();
166: foreach ($this->elements->getItems() as $element) {
167: if ($element instanceof ArrayPairNode) {
168: $value = $element->getValue();
169: if ($recursive && $value instanceof ArrayNode) {
170: $values->add($value->getValues($recursive));
171: }
172: else {
173: $values->add($value);
174: }
175: }
176: else {
177: $values->add($element);
178: }
179: }
180: return $values;
181: }
182:
183: 184: 185: 186: 187: 188:
189: public static function create($elements) {
190:
191: $node = Parser::parseExpression('[]');
192:
193: foreach ($elements as $element) {
194: $node->getElementList()->appendItem($element);
195: }
196: return $node;
197: }
198: }
199: