Accepts a one-dimensional array where the keys are separated by a delimiter.
public static expand ( array $data, array $options = [] ) : array | ||
$data | array | The one-dimensional array to expand. |
$options | array | The options used when expanding the array: - `'separator'` _string_: The delimiter to use when separating keys. Defaults to `'.'`. |
리턴 | array | Returns a multi-dimensional array expanded from a one dimensional dot-separated array. |
/** * Magic method to make Controller callable. * * @see lithium\action\Dispatcher::_callable() * @param \lithium\action\Request $request * @param array $dispatchParams Array of params after being parsed by router. * @param array $options Some basic options for this controller. * @return string * @filter */ public function __invoke($request, $dispatchParams, array $options = array()) { $dispatchParamsDefaults = array('args' => array()); $dispatchParams += $dispatchParamsDefaults; $defaults = array('format' => 'html', 'timeout' => 0); $options += (array) $request->query + $defaults; $params = compact('request', 'dispatchParams', 'options'); return $this->_filter(__METHOD__, $params, function ($self, $params) { $request = $params['request']; $options = $params['options']; $params = $params['dispatchParams']; set_time_limit((int) $options['timeout']); $group = join('\\', (array) $params['args']); if ($group === "all") { $group = Group::all(); $options['title'] = 'All Tests'; } $self->invokeMethod('_saveCtrlContext'); $report = Dispatcher::run($group, $options); $self->invokeMethod('_restoreCtrlContext'); $filters = Libraries::locate('test.filter'); $menu = Libraries::locate('tests', null, array('filter' => '/cases|integration|functional/', 'exclude' => '/mocks/')); sort($menu); $menu = Set::expand(array_combine($menu, $menu), array('separator' => "\\")); $result = compact('request', 'report', 'filters', 'menu'); return $report->render('layout', $result); }); }
/** * parses an ini-style string into an array * * when entering data into ini-style input fields, make sure, that you comply with the following * rules (read up on http://php.net/parse_ini_string): * * There are reserved words which must not be used as keys for ini files. These include: * * `null`, `yes`, `no`, `true`, `false`, `on`, `off` and `none` * * Values `null`, `no` and `false` results in "", `yes` and `true` results in "1". * Characters ?{}|&~![()^" must not be used anywhere in the key and have a special meaning * in the value. So better not use them. * * @see http://php.net/parse_ini_string * @see lithium\util\Set::expand() * @param string|array $data the string to be parsed, or an array thereof * @param array $options an array of options currently supported are * - `default` : what to return, if nothing is found, defaults to an empty array * - `process_sections` : to enable process_sections, defaults to true * - `scanner_mode` : set scanner_mode to something different than INI_SCANNER_NORMAL * @return array an associative, eventually multidimensional array or the `default` option. */ public static function parse($data = null, array $options = array()) { $defaults = array('default' => array(), 'scanner_mode' => INI_SCANNER_NORMAL, 'process_sections' => true); $options += $defaults; if (empty($data)) { return $options['default']; } if (is_array($data)) { foreach ($data as $key => $value) { $data[$key] = static::parse($value, $options); } return $data; } $raw = parse_ini_string(static::filter($data), $options['process_sections'], $options['scanner_mode']); if (empty($raw)) { return $options['default']; } try { $result = Set::expand($raw); } catch (Exception $e) { $error = $e->getMessage(); $e = new IniFormatException(sprintf('IniFormat Error: %s', $error)); $e->setData(compact('data', 'raw', 'options')); throw $e; } return $result; }
/** * Initializes the record set and uses the database connection to get the column list contained * in the query that created this object. * * @see lithium\data\collection\RecordSet::$_columns * @return void * @todo The part that uses _handle->schema() should be rewritten so that the column list * is coming from the query object. */ protected function _init() { parent::_init(); if ($this->_result) { $this->_columns = $this->_columnMap(); if ($this->_query) { $columns = array_filter(array_keys($this->_columns)); $this->_dependencies = Set::expand(Set::normalize($columns)); $this->_keyIndex = $this->_keyIndex(''); } } }
/** * Initializes the record set and uses the database connection to get the column list contained * in the query that created this object. * * @see lithium\data\collection\RecordSet::$_columns * @return void * @todo The part that uses _handle->schema() should be rewritten so that the column list * is coming from the query object. */ protected function _init() { parent::_init(); if (!$this->_result) { return; } $this->_columns = $this->_columnMap(); if (!$this->_query) { return; } $this->_keyIndex = $this->_keyIndex(); $this->_dependencies = Set::expand(Set::normalize(array_filter(array_keys($this->_columns)))); $this->_relationships = $this->_query->relationships(); }
/** * 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(), array $options = array()) { return static::_filter(__FUNCTION__, compact('data', 'options'), function ($self, $params) { $data = Set::merge(Set::expand($self::schema()->defaults()), $params['data']); return $self::connection()->item($self, $data, $params['options']); }); }
public function testFlattenTwoLevels() { $data = array( array( 'Post' => array('id' => '1', 'author_id' => '1', 'title' => 'First Post'), 'Author' => array('id' => '1', 'user' => 'nate', 'password' => 'foo') ), array( 'Post' => array( 'id' => '2', 'author_id' => '3', 'title' => 'Second Post', 'body' => 'Second Post Body' ), 'Author' => array('id' => '3', 'user' => 'joel', 'password' => null) ) ); $expected = array( '0.Post.id' => '1', '0.Post.author_id' => '1', '0.Post.title' => 'First Post', '0.Author.id' => '1', '0.Author.user' => 'nate', '0.Author.password' => 'foo', '1.Post.id' => '2', '1.Post.author_id' => '3', '1.Post.title' => 'Second Post', '1.Post.body' => 'Second Post Body', '1.Author.id' => '3', '1.Author.user' => 'joel', '1.Author.password' => null ); $result = Set::flatten($data); $this->assertEqual($expected, $result); $result = Set::expand($result); $this->assertEqual($data, $result); $result = Set::flatten($data[0], array('separator' => '/')); $expected = array( 'Post/id' => '1', 'Post/author_id' => '1', 'Post/title' => 'First Post', 'Author/id' => '1', 'Author/user' => 'nate', 'Author/password' => 'foo' ); $this->assertEqual($expected, $result); $result = Set::expand($expected, array('separator' => '/')); $this->assertEqual($data[0], $result); }
/** * 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(), array $options = array()) { $self = static::_object(); $params = compact('data', 'options'); return static::_filter(__FUNCTION__, $params, function ($self, $params) { $data = $params['data']; $options = $params['options']; $defaults = array(); foreach ((array) $self::schema() as $field => $config) { if (isset($config['default'])) { $defaults[$field] = $config['default']; } } $data = Set::merge(Set::expand($defaults), $data); return $self::connection()->item($self, $data, $options); }); }
/** * 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(), array $options = array()) { $defaults = array('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 = array('model' => $self, 'data' => $data) + $params['options']; return $self::invokeMethod('_instance', array($class, $options)); }); }
public function testExpand() { $data = array('Gallery.Image' => null, 'Gallery.Image.Tag' => null, 'Gallery.Image.Tag.Author' => null); $expected = array('Gallery' => array('Image' => array('Tag' => array('Author' => null)))); $this->assertEqual($expected, Set::expand($data)); $data = array('Gallery.Image.Tag' => null, 'Gallery.Image' => null, 'Gallery.Image.Tag.Author' => null); $expected = array('Gallery' => array('Image' => array('Tag' => array('Author' => null)))); $this->assertEqual($expected, Set::expand($data)); $data = array('Gallery.Image.Tag.Author' => null, 'Gallery.Image.Tag' => null, 'Gallery.Image' => null); $expected = array('Gallery' => array('Image' => array('Tag' => array('Author' => null)))); $this->assertEqual($expected, Set::expand($data)); }
/** * 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 = array()) { $defaults = array('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', array($query)))) { return false; } $sql = $self->renderCommand($data['type'], $data); } $result = $self->invokeMethod('_execute', array($sql)); if ($return === 'resource') { return $result; } if ($return === 'item') { return $model::create(array(), compact('query', 'result') + array('class' => 'set', 'defaults' => false)); } $columns = $args['schema'] ?: $self->schema($query, $result); if (!is_array(reset($columns))) { $columns = array('' => $columns); } $i = 0; $records = array(); foreach ($result as $data) { $offset = 0; $records[$i] = array(); foreach ($columns as $path => $cols) { $len = count($cols); $values = array_combine($cols, array_slice($data, $offset, $len)); $path ? $records[$i][$path] = $values : ($records[$i] += $values); $offset += $len; } $i++; } return Set::expand($records); }); }
protected function _export($data, $exporter) { if ($data instanceof Countable) { $result = array(); foreach ($data as $key => $val) { $result[] = $this->_export($val, $exporter); } return $result; } if (!is_object($data)) { return $data; } $result = $exporter($data); if (!is_array($result) || !$result) { return $data; } $fields = is_object($data) && method_exists($data, 'schema') ? $data->schema() : null; foreach ($result as $key => $val) { if (!is_int($key)) { continue; } if (isset($fields[$val]) || $fields === null) { unset($result[$key]); $result[$val] = $data->{$val}; } } return Set::expand($result); }