123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148 |
- <?php
- /**
- * CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
- * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
- *
- * Licensed under The MIT License
- * For full copyright and license information, please see the LICENSE.txt
- * Redistributions of files must retain the above copyright notice.
- *
- * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
- * @link https://cakephp.org CakePHP(tm) Project
- * @since 3.0.0
- * @license https://opensource.org/licenses/mit-license.php MIT License
- */
- namespace Cake\Collection;
- use Traversable;
- /**
- * Provides utility protected methods for extracting a property or column
- * from an array or object.
- */
- trait ExtractTrait
- {
- /**
- * Returns a callable that can be used to extract a property or column from
- * an array or object based on a dot separated path.
- *
- * @param string|callable $callback A dot separated path of column to follow
- * so that the final one can be returned or a callable that will take care
- * of doing that.
- * @return callable
- */
- protected function _propertyExtractor($callback)
- {
- if (!is_string($callback)) {
- return $callback;
- }
- $path = explode('.', $callback);
- if (strpos($callback, '{*}') !== false) {
- return function ($element) use ($path) {
- return $this->_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 array $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 array $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 callable
- */
- 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;
- };
- }
- }
|