_extract($element, $path); }; } return function ($element) use ($path) { return $this->_simpleExtract($element, $path); }; } /** * Returns a column from $data that can be extracted * by iterating over the column names contained in $path. * It will return arrays for elements in represented with `{*}` * * @param array|\ArrayAccess $data Data. * @param string[] $path Path to extract from. * @return mixed */ protected function _extract($data, $path) { $value = null; $collectionTransform = false; foreach ($path as $i => $column) { if ($column === '{*}') { $collectionTransform = true; continue; } if ( $collectionTransform && !($data instanceof Traversable || is_array($data)) ) { return null; } if ($collectionTransform) { $rest = implode('.', array_slice($path, $i)); return (new Collection($data))->extract($rest); } if (!isset($data[$column])) { return null; } $value = $data[$column]; $data = $value; } return $value; } /** * Returns a column from $data that can be extracted * by iterating over the column names contained in $path * * @param array|\ArrayAccess $data Data. * @param string[] $path Path to extract from. * @return mixed */ protected function _simpleExtract($data, $path) { $value = null; foreach ($path as $column) { if (!isset($data[$column])) { return null; } $value = $data[$column]; $data = $value; } return $value; } /** * Returns a callable that receives a value and will return whether or not * it matches certain condition. * * @param array $conditions A key-value list of conditions to match where the * key is the property path to get from the current item and the value is the * value to be compared the item with. * @return \Closure */ protected function _createMatcherFilter(array $conditions) { $matchers = []; foreach ($conditions as $property => $value) { $extractor = $this->_propertyExtractor($property); $matchers[] = function ($v) use ($extractor, $value) { return $extractor($v) == $value; }; } return function ($value) use ($matchers) { foreach ($matchers as $match) { if (!$match($value)) { return false; } } return true; }; } }