public function testHasChild() { $data = DataSources::getOrderData(); $engine = DataSources::getEngine(); $results = $engine->extract($data, '/order/items/1'); $this->assertEquals(1, count($results)); $result =& $results[0]; $pointer = new Envalo_APath_Pointer($result, 'some_part', '/orders/items/1', null); $this->assertTrue($pointer->hasChild('sku')); }
/** * @param $data array * @param $nodes Envalo_APath_Node[] * @param $pointer Envalo_APath_Pointer|null * @param $create_path boolean * @return Envalo_APath_Pointer[]|null */ protected function _walk(&$data, &$nodes, $create_path = false, &$pointer = null) { $result = array(); $current_pointer = null; $current_path = ''; $value = null; //ROOT POINTER if ($pointer == null) { $ptr =& $data; $current_pointer = new Envalo_APath_Pointer($ptr, null, $current_path, null); } else { if ($pointer instanceof Envalo_APath_Pointer) { $current_pointer =& $pointer; } } $use_current = null; /* $nodes is an array of Envalo_APath_Node objects. Each node object * represents one step in the path we are traversing. * A node can contain zero or more filters, which are sub-paths off of * the current node used to validate or invalidate the node. A node may also * have zero or one condition checks. These compare the value of the node to * some static field. */ /* @var $node Envalo_APath_Node */ foreach ($nodes as $index => $node) { $part = $node->getPart(); $use_current = false; if ($part == '..') { $new_nodes = array_slice($nodes, $index + 1); $parent_pointer = $current_pointer->getParent(); if (!$parent_pointer) { //Either we are at the root node or something has gone wrong. return null; } $parent_ptr =& $parent_pointer->_pointer; return $this->_walk($parent_ptr, $new_nodes, $create_path, $parent_pointer); } else { if ($part == '.') { $use_current = true; } else { if ($part == '#') { $sub_nodes = array_slice($nodes, $index + 1); $sub_ptr =& $current_pointer->_pointer; $sub_path = $current_pointer->getPath() . '/' . $part; $sub_results = array(); foreach ($sub_ptr as $sub_index => &$sub_array) { if (is_int($sub_index)) { $sub_pointer = new Envalo_APath_Pointer($sub_array, $sub_index, $sub_path, $current_pointer); $sub_result = $this->_walk($sub_array, $sub_nodes, $create_path, $sub_pointer); if ($sub_result) { $sub_results = array_merge($sub_results, $sub_result); } } } return $sub_results; } else { if ($part == '*') { $sub_nodes = array_slice($nodes, $index + 1); $sub_ptr =& $current_pointer->_pointer; $sub_path = $current_pointer->getPath() . '/' . $part; $sub_results = array(); foreach ($sub_ptr as $sub_index => &$sub_array) { $sub_pointer = new Envalo_APath_Pointer($sub_array, $sub_index, $sub_path, $current_pointer); $sub_result = $this->_walk($sub_array, $sub_nodes, $create_path, $sub_pointer); if ($sub_result) { $sub_results = array_merge($sub_results, $sub_result); } } return $sub_results; } else { if (!$current_pointer->hasChild($part) && !$create_path) { //Return... return null; } } } } } if (!$use_current) { $ptr =& $current_pointer->_pointer; if (!is_array($ptr)) { // IF we are trying to walk into an array but we aren't using an array, bad things could happen. return null; } if (!isset($ptr[$part]) && $create_path) { $ptr[$part] = array(); } $ptr =& $ptr[$part]; $new_path = $current_pointer->getPath() . '/' . $part; $current_pointer = new Envalo_APath_Pointer($ptr, $part, $new_path, $current_pointer); } if ($node->getCondition()) { $condition = $node->getCondition(); if (!$condition->process($current_pointer->_pointer)) { return null; } } if (is_array($node->getFilters()) && count($node->getFilters())) { foreach ($node->getFilters() as $filter) { $filter_ptr =& $current_pointer->_pointer; $filter_pointer = new Envalo_APath_Pointer($filter_ptr, $current_pointer->getPart(), $current_pointer->getPath(), $current_pointer->getParent()); if (is_null($this->_walk($filter_pointer->_pointer, $filter, $create_path, $filter_pointer))) { return null; } } } } $result[] = $current_pointer; return $result; }