/** * @param $filter * @param $value * @param $element * @param string $path * @return array|mixed */ protected function _recursiveFilter($filter, $value, $element, $path = '') { if (is_array($value)) { $cleanValues = array(); $parent = $path; foreach ($value as $k => $v) { $path = $parent !== '' ? $parent . '.' . $k : $k; $cleanValues[$k] = $this->_recursiveFilter($filter, $v, $element, $path); } return $cleanValues; } else { if ($element === '__ALL__' || $element === $path || Set::matches($element, Set::expand(array($path => '')))) { return call_user_func($filter, $value); } else { return $value; } } }
/** * Tests Set::expand * * @return void */ public function testExpand() { $data = array('My', 'Array', 'To', 'Flatten'); $flat = Set::flatten($data); $result = Set::expand($flat); $this->assertEquals($data, $result); }
/** * Reads records from a database using a `lithium\data\model\Query` object or raw SQL string. * * @param string|object $query `lithium\data\model\Query` object or SQL string. * @param array $options If `$query` is a raw string, contains the values that will be escaped * and quoted. Other options: * - `'return'` _string_: switch return between `'array'`, `'item'`, or * `'resource'` _string_: Defaults to `'item'`. * * @return mixed Determined by `$options['return']`. * @filter */ public function read($query, array $options = []) { $defaults = ['return' => is_string($query) ? 'array' : 'item', 'schema' => null, 'quotes' => $this->_quotes]; $options += $defaults; return $this->_filter(__METHOD__, compact('query', 'options'), function ($self, $params) { $query = $params['query']; $args = $params['options']; $return = $args['return']; unset($args['return']); $model = is_object($query) ? $query->model() : null; if (is_string($query)) { $sql = String::insert($query, $self->value($args)); } else { if (!($data = $self->invokeMethod('_queryExport', [$query]))) { return false; } $sql = $self->renderCommand($data['type'], $data); } $result = $self->invokeMethod('_execute', [$sql]); switch ($return) { case 'resource': return $result; case 'array': $columns = $args['schema'] ?: $self->schema($query, $result); if (!is_array(reset($columns))) { $columns = ['' => $columns]; } $i = 0; $records = []; foreach ($result as $data) { $offset = 0; $records[$i] = []; foreach ($columns as $path => $cols) { $len = count($cols); $values = array_combine($cols, array_slice($data, $offset, $len)); if ($path) { $records[$i][$path] = $values; } else { $records[$i] += $values; } $offset += $len; } $i++; } return Set::expand($records); case 'item': return $model::create([], compact('query', 'result') + ['class' => 'set', 'defaults' => false]); } }); }
/** * Instantiates a new record or document object, initialized with any data passed in. For * example: * * {{{ * $post = Posts::create(array('title' => 'New post')); * echo $post->title; // echoes 'New post' * $success = $post->save(); * }}} * * Note that while this method creates a new object, there is no effect on the database until * the `save()` method is called. * * In addition, this method can be used to simulate loading a pre-existing object from the * database, without actually querying the database: * * {{{ * $post = Posts::create(array('id' => $id, 'moreData' => 'foo'), array('exists' => true)); * $post->title = 'New title'; * $success = $post->save(); * }}} * * This will create an update query against the object with an ID matching `$id`. Also note that * only the `title` field will be updated. * * @param array $data Any data that this object should be populated with initially. * @param array $options Options to be passed to item. * * @return object Returns a new, _un-saved_ record or document object. In addition to the values * passed to `$data`, the object will also contain any values assigned to the * `'default'` key of each field defined in `$_schema`. * @filter */ public static function create(array $data = [], array $options = []) { $defaults = ['defaults' => true, 'class' => 'entity']; $options += $defaults; return static::_filter(__FUNCTION__, compact('data', 'options'), function ($self, $params) { $class = $params['options']['class']; unset($params['options']['class']); if ($class === 'entity' && $params['options']['defaults']) { $data = Set::merge(Set::expand($self::schema()->defaults()), $params['data']); } else { $data = $params['data']; } $options = ['model' => $self, 'data' => $data] + $params['options']; return $self::invokeMethod('_instance', [$class, $options]); }); }