Collapses a multi-dimensional array into a single dimension, using a delimited array path
for each array element's key, i.e. array(array('Foo' => array('Bar' => 'Far'))) becomes
array('0.Foo.Bar' => 'Far').
public static function find(array $options = array()) { $defaults = array('collect' => true); $options += $defaults; $data = array(); $libs = Libraries::get(null, 'path'); $recursive = true; foreach ($libs as $lib => $path) { $result = array(); $path .= '/views/widgets'; $files = StaticContents::available(compact('path', 'recursive')); if (!$files) { continue; } $temp = array_keys(Set::flatten($files, array('separator' => '/'))); foreach ($temp as $key => $value) { if (strpos($value, 'admin.') !== false) { continue; } if (strpos($value, 'inc.') !== false) { continue; } $result[$key] = str_replace('.html.php', '', $value); } $data[$lib] = $result; } return $data; }
/** * returns rendered content * * @param string $content input content * @param string $data field to retrieve from configuration * @param array $options an array with additional options * @return string content as given * @filter */ public function get($content, $data = null, array $options = array()) { $defaults = array('default' => null, 'flat' => false); $options += $defaults; $params = compact('content', 'data', 'options'); return $this->_filter(__METHOD__, $params, function ($self, $params) { extract($params); try { $config = IniFormat::parse($content); } catch (IniFormatException $e) { return $options['default']; } catch (Exception $e) { return $options['default']; } if (empty($data)) { return $options['flat'] ? Set::flatten($config) : $config; } if (is_scalar($data) && isset($config[$data])) { return $config[$data]; } $data = '/' . str_replace('.', '/', (string) $data) . '/.'; $result = current(Set::extract((array) $config, $data)); if (!empty($result)) { return $result; } return $options['default']; }); }
/** * returns rendered content * * @param string $content input content * @param string $data field to retrieve from configuration * @param array $options an array with additional options * @return string content as given * @filter */ public function get($content, $data = null, array $options = array()) { $defaults = array('default' => array(), 'flat' => false); $options += $defaults; $params = compact('content', 'data', 'options'); return $this->_filter(__METHOD__, $params, function ($self, $params) { extract($params); try { $config = NeonFormatter::decode($content); } catch (NeonException $e) { return $options['default']; } catch (Exception $e) { return $options['default']; } if (!empty($data) && is_scalar($data)) { if (array_key_exists($data, (array) $config)) { return $config[$data]; } } if ($data) { $data = '/' . str_replace('.', '/', $data) . '/.'; $result = current(Set::extract((array) $config, $data)); return !empty($result) ? $result : null; } return $options['flat'] ? Set::flatten($config) : $config; }); }
/** * Parses an associative array into an array, containing one * array for each row, that has 'key' and 'value' filled * as expected. That makes rendering of arbitrary meta-data * much simpler, e.g. if you do not know, what data you are * about to retrieve. * * @param array $data an associative array containing mixed data * @return array an numerical indexed array with arrays for each * item in $data, having 'key' and 'value' set accordingly */ public function data(array $data = array(), array $options = array()) { $defaults = array('flatten' => true); $options += $defaults; if ($options['flatten']) { $data = Set::flatten($this->_extract($data)); } return array_map(function ($key, $value) { return compact('key', 'value'); }, array_keys($data), $data); }
public function connections() { $data = Connections::get(); $connections = new Collection(compact('data')); if (true || $this->request->is('json')) { $connections->each(function ($name) { $config = Connections::get($name, array('config' => true)); unset($config['object']); return array_merge(compact('name'), Set::flatten($config)); }); } return compact('connections'); }
public static function parse($conditions, $data, array $options = array()) { $params = compact('conditions', 'data', 'options'); return static::_filter(__METHOD__, $params, function ($self, $params) { extract($params); $defaults = array(); $options += $defaults; $check = String::insert($conditions, Set::flatten($data)); if (strpbrk($check, '&|')) { return eval("return (boolean)({$check});"); } // TODO: take care, that spaces are around operator return $self::invokeMethod('compare', explode(" ", $check, 3)); }); }
/** * Renders `$data` into an easier to understand, or flat, array. * * @param array $data Data to traverse. * @return array */ protected function _toString($data) { foreach ($data as $key => $val) { switch (true) { case is_object($val) && !$val instanceof Closure: try { $data[$key] = (string) $val; } catch (Exception $e) { $data[$key] = ''; } break; case is_array($val): $data = array_merge($data, Set::flatten($val)); break; } } return $data; }
/** * Checks a set of values against a specified rules list. This method may be used to validate * any arbitrary array of data against a set of validation rules. * * @param array $values An array of key/value pairs, where the values are to be checked. * @param array $rules An array of rules to check the values in `$values` against. Each key in * `$rules` should match a key contained in `$values`, and each value should be a * validation rule in one of the allowable formats. For example, if you are * validating a data set containing a `'credit_card'` key, possible values for * `$rules` would be as follows: * - `array('credit_card' => 'You must include a credit card number')`: This is the * simplest form of validation rule, in which the value is simply a message to * display if the rule fails. Using this format, all other validation settings * inherit from the defaults, including the validation rule itself, which only * checks to see that the corresponding key in `$values` is present and contains * a value that is not empty. _Please note when globalizing validation messages:_ * When specifying messages, it may be preferable to use a code string (i.e. * `'ERR_NO_TITLE'`) instead of the full text of the validation error. These code * strings may then be translated by the appropriate tools in the templating * layer. * - `array('credit_card' => array('creditCard', 'message' => 'Invalid CC #'))`: * In the second format, the validation rule (in this case `creditCard`) and * associated configuration are specified as an array, where the rule to use is * the first value in the array (no key), and additional settings are specified * as other keys in the array. Please see the list below for more information on * allowed keys. * - The final format allows you to apply multiple validation rules to a single * value, and it is specified as follows: * * `array('credit_card' => array( * array('notEmpty', 'message' => 'You must include credit card number'), * array('creditCard', 'message' => 'Your credit card number must be valid') * ));` * @param array $options Validator-specific options. * * Each rule defined as an array can contain any of the following settings (in addition to the * first value, which represents the rule to be used): * - `'message'` _string_: The error message to be returned if the validation rule fails. See * the note above regarding globalization of error messages. * - `'required`' _boolean_: Represents whether the value is required to be present in * `$values`. If `'required'` is set to `false`, the validation rule will be skipped if the * corresponding key is not present. Defaults to `true`. * - `'skipEmpty'` _boolean_: Similar to `'required'`, this setting (if `true`) will cause the * validation rule to be skipped if the corresponding value is empty (an empty string or * `null`). Defaults to `false`. * - `'format'` _string_: If the validation rule has multiple format definitions (see the * `add()` or `__init()` methods), the name of the format to be used can be specified here. * Additionally, two special values can be used: either `'any'`, which means that all formats * will be checked and the rule will pass if any format passes, or `'all'`, which requires * all formats to pass in order for the rule check to succeed. * @return array Returns an array containing all validation failures for data in `$values`, * where each key matches a key in `$values`, and each value is an array of that * element's validation errors. * @filter */ public static function check(array $values, array $rules, array $options = array()) { $defaults = array('notEmpty', 'message' => null, 'required' => true, 'skipEmpty' => false, 'format' => 'any', 'on' => null, 'last' => false); $options += $defaults; $params = compact('values', 'rules', 'options'); return static::_filter(__FUNCTION__, $params, function ($self, $params) { $values = $params['values']; $rules = $params['rules']; $options = $params['options']; $errors = array(); $events = (array) (isset($options['events']) ? $options['events'] : null); $values = Set::flatten($values); foreach ($rules as $field => $rules) { $rules = is_string($rules) ? array('message' => $rules) : $rules; $rules = is_array(current($rules)) ? $rules : array($rules); $errors[$field] = array(); $options['field'] = $field; foreach ($rules as $key => $rule) { $rule += $options + compact('values'); list($name) = $rule; if ($events && $rule['on'] && !array_intersect($events, (array) $rule['on'])) { continue; } if (!array_key_exists($field, $values)) { if ($rule['required']) { $errors[$field][] = $rule['message'] ?: $key; } if ($rule['last']) { break; } continue; } if (empty($values[$field]) && $rule['skipEmpty']) { continue; } if (!$self::rule($name, $values[$field], $rule['format'], $rule + $options)) { $errors[$field][] = $rule['message'] ?: $key; if ($rule['last']) { break; } } } } return array_filter($errors); }); }
/** * Delete value from the cookie * * @param string $key The key to be deleted * @param array $options Options array * @return boolean True on successful delete, false otherwise */ public function delete($key, $options = array()) { $config = $options + $this->_config; return function ($self, $params, $chain) use(&$config) { extract($params); $key = is_array($key) ? Set::flatten($key) : array($key); foreach ($key as $name) { $name = explode('.', $name); $name = $config['name'] ? array_merge(array($config['name']), $name) : $name; if (count($name) == 1) { $name = current($name); } else { $name = array_shift($name) . '[' . join('][', $name) . ']'; } setcookie($name, "", time() - 1, $config['path'], $config['domain'], $config['secure'], $config['httponly']); } }; }
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); }
/** * generates a parsed message, depending on given $type * * @param string $type what type is this event * @param string $data additional data to be tracked for that event * @return string|boolean parsed string of message, or false in case of error */ public static function message($type, $data = array()) { if (!array_key_exists($type, Activity::$_events)) { return false; } return String::insert(Activity::$_events[$type], Set::flatten($data)); }
<?php use lithium\net\http\Router; $url = Router::match(array('library' => 'radium', 'controller' => 'assets', 'action' => 'show', 'id' => $this->scaffold->object->id()), $this->request(), array('absolute' => true)); ?> <div class="plaintext"><pre><?php echo $url; ?> </pre></div> <audio controls><source src="<?php echo $url; ?> " type="<?php echo $this->scaffold->object['mime']; ?> "></audio> <hr /> <?php unset($this->scaffold->object['file']); echo $this->scaffold->render('data', array('data' => \lithium\util\Set::flatten($this->scaffold->object->data())));
/** * Clears all cookies. * * @param array $options Options array. Not used fro this adapter method. * @return boolean True on successful clear, false otherwise. */ public function clear(array $options = array()) { $options += array('destroySession' => true); $config = $this->_config; $cookieClass = get_called_class(); return function ($self, $params) use(&$config, $options, $cookieClass) { if ($options['destroySession'] && session_id()) { session_destroy(); } if (!isset($_COOKIE[$config['name']])) { return true; } $cookies = array_keys(Set::flatten($_COOKIE[$config['name']])); foreach ($cookies as $name) { $name = $cookieClass::keyFormat($name, $config); $result = setcookie($name, "", 1, $config['path'], $config['domain'], $config['secure'], $config['httponly']); if (!$result) { throw new RuntimeException("There was an error clearing {$cookie} cookie."); } } unset($_COOKIE[$config['name']]); return true; }; }
/** * Validates form data using an embedded form signature string. The form signature string * must be embedded in `security.signature` alongside the other data to check against. * * Note: Will ignore any other data inside `security.*`. * * @param array|object $data The form data as an array or an * object with the data inside the `data` property. * @return boolean `true` if the form data is valid, `false` if not. */ public static function check($data) { if (is_object($data) && isset($data->data)) { $data = $data->data; } if (!isset($data['security']['signature'])) { throw new Exception('Unable to check form signature. Cannot find signature in data.'); } $signature = $data['security']['signature']; unset($data['security']); $parsed = static::_parse($signature); $data = Set::flatten($data); if (array_intersect_assoc($data, $parsed['locked']) != $parsed['locked']) { return false; } $fields = array_diff(array_keys($data), array_keys($parsed['locked']), $parsed['excluded']); return $signature === static::_compile($fields, $parsed['locked'], $parsed['excluded']); }
public static function check($data) { if (is_object($data) && isset($data->data)) { $data = $data->data; } if (!isset($data['security']['signature'])) { return false; } $signature = $data['security']['signature']; unset($data['security']); $data = Set::flatten($data); $fields = array_keys($data); list($locked, $excluded, $hash) = explode('::', $signature, 3); $locked = unserialize(urldecode($locked)); $excluded = unserialize(urldecode($excluded)); $fields = array_diff($fields, $excluded); if (array_intersect_assoc($data, $locked) != $locked) { return false; } return $signature === static::key(compact('fields', 'locked', 'excluded')); }
/** * Get the geocode latitude/longitude points from given address. * Look in the cache first, otherwise get from web service (i.e. Google or Yahoo!). * * @param object $entity A `Record` or `Document` object containing the address data to be * geocoded. */ public static function geocode($entity) { if (!isset(static::$_configurations[$class = $entity->model()])) { return null; } $config = static::$_configurations[$class]; $geocoder = static::$_classes['geocoder']; $data = Set::flatten($entity->data()); $address = trim(String::insert($config['format'], $data)); return $address ? $geocoder::find($config['service'], $address) : null; }
/** * returns a properly processed item as rss-item * * @param object $entity instance of current Record * @param array $fields an array of additional fields to generate * @param array $options an array of additional options * - `merge`: set to false, to process only given fields * @return array an array containing relevant rss data as keys and their corresponding values */ public function rssItem($entity, $fields = array(), array $options = array()) { $defaults = array('merge' => true); $options += $defaults; static::$_rss['pubDate'] = function ($object) { return date('D, d M Y g:i:s O', $object->created->sec); }; $fields = $options['merge'] ? array_merge(static::$_rss, $fields) : $fields; $item = array(); foreach ($fields as $field => $source) { switch (true) { case is_callable($source): $item[$field] = $source($entity); break; case stristr($source, '{:'): $replace = array_merge(Environment::get('scaffold'), Set::flatten($entity->data()), array('host' => $_SERVER['HTTP_HOST'])); $item[$field] = String::insert($source, $replace); break; case isset($entity->{$source}): $item[$field] = $entity->{$source}; break; } } return $item; }
foreach ($fields as $field) { fputcsv($out, array($field, isset($object[$field]) ? $object[$field] : '')); } } if ($scaffold && isset($data['objects'])) { $objects = $data['objects'] ?: array(); $name = String::insert('{:slug}.csv', $scaffold); fputcsv($out, array_values($fields)); foreach ($data['objects'] as $row) { fputcsv($out, Set::flatten($row)); } } if (!$scaffold && $data) { $name = 'temp.csv'; foreach ($data as $row) { fputcsv($out, Set::flatten($row)); } } fclose($out); header(sprintf('Content-Disposition: attachment; filename="%s"', $name)); return ob_get_clean(); })); // Libraries::add('Handlebars', array( // // "prefix" => "Handlebars_", // // "includePath" => LITHIUM_LIBRARY_PATH, // or LITHIUM_APP_PATH . '/libraries' // // "bootstrap" => "Loader/Autoloader.php", // // "loader" => array("Handlebars", "register"), // // "transform" => function($class) { return str_replace("_", "/", $class) . ".php"; } // )); require RADIUM_PATH . '/libraries/Handlebars/Autoloader.php'; Autoloader::register();
<?php echo $this->html->link('Home', '/'); ?> </li> <li> <?php echo $this->html->link('radium', '/radium'); ?> </li> <li class="active"> <?php echo $this->title('Request'); ?> </li> </ol> <div class="header"> <div class="col-md-12"> <h3 class="header-title"><?php echo $this->title(); ?> </h3> </div> </div> <div class="main-content"> <?php echo $this->Handlebars->render('scaffold/data', array('data' => \lithium\util\Set::flatten($request))); ?> </div>