- '/User/id': Similar to the classic {n}.User.id. - '/User[2]/name': Selects the name of the second User. - '/User[id>2]': Selects all Users with an id > 2. - '/User[id>2][<5]': Selects all Users with an id > 2 but < 5. - '/Post/Comment[author_name=John]/../name': Selects the name of all posts that have at least one comment written by John. - '/Posts[name]': Selects all Posts that have a 'name' key. - '/Comment/.[1]': Selects the contents of the first comment. - '/Comment/.[:last]': Selects the last comment. - '/Comment/.[:first]': Selects the first comment. - '/Comment[text=/lithium/i]': Selects the all comments that have a text matching the regex /lithium/i. - '/Comment/@*': Selects all key names of all comments.
Example #1
0
 /**
  * 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'];
     });
 }
Example #2
0
 /**
  * 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;
 }
Example #3
0
 /**
  * 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);
     });
 }
Example #4
0
 /**
  * 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;
     });
 }
Example #5
0
 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;
 }
Example #6
0
 /**
  * Object constructor.
  * Instantiates the Memcached object, adds appropriate servers to the pool,
  * and configures any optional settings passed.
  *
  * @see lithium\storage\Cache::config()
  * @param array $config Configuration parameters for this cache adapter.
  *        These settings are indexed by name and queryable
  *        through `Cache::config('name')`.
  * @return void
  */
 public function __construct(array $config = array())
 {
     $defaults = array('prefix' => '', 'expiry' => '+1 hour', 'servers' => array(array('127.0.0.1', 11211, 100)));
     if (is_null(static::$connection)) {
         static::$connection = new \Memcached();
     }
     $configuration = Set::merge($defaults, $config);
     parent::__construct($configuration);
     static::$connection->addServers($this->_config['servers']);
 }
Example #7
0
 public function testArrayConfiguration()
 {
     $result = Configurations::create(Set::merge($this->_default, array('type' => 'array', 'value' => 'foo=bar')));
     $this->assertEqual(array('foo' => 'bar'), $result->val());
     $this->assertEqual('bar', $result->val('foo'));
     $result = Configurations::create(Set::merge($this->_default, array('type' => 'array', 'value' => "foo.bar=baz\nfoo.baz=bar")));
     $this->assertEqual(array('foo' => array('bar' => 'baz', 'baz' => 'bar')), $result->val());
     $this->assertEqual(array('bar' => 'baz', 'baz' => 'bar'), $result->val('foo'));
     $this->assertEqual('baz', $result->val('foo.bar'));
 }
Example #8
0
 /**
  * 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);
 }
Example #9
0
 /**
  * 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('');
         }
     }
 }
Example #10
0
 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');
 }
Example #11
0
 /**
  * Create `RecaptchaOptions` javascript object if you have additional options configured
  * @param array $options `'key' => 'value'` pairs to be converted to javascript
  * object as `RecaptchaOptions`
  * @see https://developers.google.com/recaptcha/docs/customization
  * @return null|string Return null if you don't have additional options
  * or script with `RecaptchaOptions` object
  */
 protected function _recaptchaOptions(array $options = array())
 {
     $defaults = Libraries::get('li3_recaptcha', 'options');
     if ($defaults) {
         $options = Set::merge($defaults, $options);
     }
     if (empty($options)) {
         return null;
     }
     $script = '<script type="text/javascript">';
     $script .= 'var RecaptchaOptions = ' . json_encode($options) . ';';
     $script .= '</script>';
     return $script;
 }
Example #12
0
 /**
  * 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();
 }
 /**
  * Runs a test group or a specific test file based on the passed
  * parameters.
  *
  * @param string $group If set, this test group is run. If not set, a group test may
  *        also be run by passing the 'group' option to the $options parameter.
  * @param array $options Options array for the test run. Valid options are:
  *        - 'case': The fully namespaced test case to be run.
  *        - 'group': The fully namespaced test group to be run.
  *        - 'filters': An array of filters that the test output should be run through.
  * @return array A compact array of the title, an array of the results, as well
  *         as an additional array of the results after the $options['filters']
  *         have been applied.
  */
 public static function run($group = null, $options = array())
 {
     $defaults = array('title' => $group, 'filters' => array(), 'reporter' => 'text');
     $options += $defaults;
     $items = (array) $group;
     $isCase = preg_match('/Test$/', $group);
     if ($isCase) {
         $items = array(new $group());
     }
     $options['filters'] = Set::normalize($options['filters']);
     $group = static::_group($items);
     $report = static::_report($group, $options);
     $report->run();
     return $report;
 }
Example #14
0
 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));
     });
 }
Example #15
0
 /**
  * Runs a test group or a specific test file based on the passed
  * parameters.
  *
  * @param string $group If set, this test group is run. If not set, a group test may
  *        also be run by passing the 'group' option to the $options parameter.
  * @param array $options Options array for the test run. Valid options are:
  *        - 'case': The fully namespaced test case to be run.
  *        - 'group': The fully namespaced test group to be run.
  *        - 'filters': An array of filters that the test output should be run through.
  * @return array A compact array of the title, an array of the results, as well
  *         as an additional array of the results after the $options['filters']
  *         have been applied.
  * @filter
  */
 public static function run($group = null, array $options = array())
 {
     $defaults = array('title' => $group, 'filters' => array(), 'reporter' => 'text');
     $options += $defaults;
     $isCase = is_string($group) && preg_match('/Test$/', $group);
     $items = $isCase ? array(new $group()) : (array) $group;
     $options['filters'] = Set::normalize($options['filters']);
     $group = static::_group($items);
     $report = static::_report($group, $options);
     return static::_filter(__FUNCTION__, compact('report'), function ($self, $params, $chain) {
         $environment = Environment::get();
         Environment::set('test');
         $params['report']->run();
         Environment::set($environment);
         return $params['report'];
     });
 }
Example #16
0
 /**
  * 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;
 }
Example #17
0
 public function loadMetadataForClass($className, ClassMetadataInfo $metadata)
 {
     if (!$metadata->reflClass instanceof SchemaReflection) {
         $metadata->reflClass = new SchemaReflection(get_class($metadata));
     }
     $metadata->primaryTable['name'] = $className::meta('source');
     $primaryKey = $className::meta('key');
     $bindings = static::bindings($className);
     $relations = array();
     if (!empty($bindings)) {
         foreach ($bindings as $type => $set) {
             foreach ($set as $key => $relation) {
                 $mapping = array('fetch' => \Doctrine\ORM\Mapping\AssociationMapping::FETCH_EAGER, 'fieldName' => $relation['fieldName'], 'sourceEntity' => $className, 'targetEntity' => $relation['class'], 'mappedBy' => null, 'cascade' => !empty($relation['dependent']) ? array('remove') : array(), 'optional' => $type != 'belongsTo');
                 if (in_array($type, array('hasOne', 'hasMany'))) {
                     $inverse = $type == 'belongsTo';
                     $mapping['joinColumns'][] = array('fieldName' => !$inverse ? $relation['key'] : $relation['fieldName'], 'name' => !$inverse ? $relation['fieldName'] : $relation['key'], 'referencedColumnName' => $relation['class']::meta('key'));
                 }
                 if (in_array($type, array('belongsTo', 'hasOne', 'hasMany'))) {
                     $mapping['mappedBy'] = static::_fieldName($mapping);
                 }
                 $relations[$type][$key] = $mapping;
             }
         }
     }
     $schema = (array) $className::schema();
     $metadata->reflClass->setRelations($relations);
     $metadata->reflClass->setSchema($schema);
     $belongsToFields = !empty($bindings['belongsTo']) ? Set::combine(array_values($bindings['belongsTo']), '/key', '/fieldName') : array();
     foreach ($schema as $field => $column) {
         $mapping = array_merge(array('id' => $field == $primaryKey, 'fieldName' => !empty($belongsToFields[$field]) ? $belongsToFields[$field] : $field, 'columnName' => $field), (array) $column);
         $metadata->mapField($mapping);
         if ($mapping['id']) {
             $metadata->setIdGeneratorType(\Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_AUTO);
         }
     }
     foreach ($relations as $type => $set) {
         foreach ($set as $key => $mapping) {
             $metadata->{static::$_bindingMapping[$type]}($mapping);
             $mapping = $metadata->associationMappings[$mapping['fieldName']];
         }
     }
 }
Example #18
0
 public function run($id = null)
 {
     $id = !is_null($id) ? $id : $this->request->id;
     $model = $this->scaffold['model'];
     $object = $model::first($id);
     if (!$object) {
         $url = array('action' => 'index');
         return $this->redirect($url);
     }
     list($temp, $options) = Set::slice($this->request->data, array('validate', 'strict'));
     switch ($this->request->data['mode']) {
         case 'keep':
             $options['overwrite'] = false;
             break;
         case 'remove':
             $options['prune'] = true;
             break;
     }
     $result = $object->run($options);
     $url = array('action' => 'view', 'args' => array((string) $object->{$model::key()}));
     return $this->redirect($url);
 }
Example #19
0
 /**
  * Pulls request data from superglobals.
  *
  * @return void
  */
 protected function _init()
 {
     parent::_init();
     $mobile = array('iPhone', 'MIDP', 'AvantGo', 'BlackBerry', 'J2ME', 'Opera Mini', 'DoCoMo', 'NetFront', 'Nokia', 'PalmOS', 'PalmSource', 'portalmmm', 'Plucker', 'ReqwirelessWeb', 'iPod', 'SonyEricsson', 'Symbian', 'UP\\.Browser', 'Windows CE', 'Xiino', 'Android');
     if (!empty($this->_config['detectors']['mobile'][1])) {
         $mobile = array_merge($mobile, (array) $this->_config['detectors']['mobile'][1]);
     }
     $this->_detectors['mobile'][1] = $mobile;
     $this->_env += (array) $_SERVER + (array) $_ENV + array('REQUEST_METHOD' => 'GET');
     $envs = array('isapi' => 'IIS', 'cgi' => 'CGI', 'cgi-fcgi' => 'CGI');
     $this->_env['PLATFORM'] = isset($envs[PHP_SAPI]) ? $envs[PHP_SAPI] : null;
     $this->_base = isset($this->_base) ? $this->_base : $this->_base();
     $this->url = '/';
     if (isset($this->_config['url'])) {
         $this->url = rtrim($this->_config['url'], '/');
     } elseif (!empty($_GET['url'])) {
         $this->url = rtrim($_GET['url'], '/');
         unset($_GET['url']);
     }
     if (!empty($this->_config['query'])) {
         $this->query = $this->_config['query'];
     }
     if (isset($_GET)) {
         $this->query += $_GET;
     }
     if (!empty($this->_config['data'])) {
         $this->data = $this->_config['data'];
     } elseif (isset($_POST)) {
         $this->data += $_POST;
     }
     if (isset($this->data['_method'])) {
         $this->_env['HTTP_X_HTTP_METHOD_OVERRIDE'] = strtoupper($this->data['_method']);
         unset($this->data['_method']);
     }
     if (!empty($this->_env['HTTP_X_HTTP_METHOD_OVERRIDE'])) {
         $this->_env['REQUEST_METHOD'] = $this->_env['HTTP_X_HTTP_METHOD_OVERRIDE'];
     }
     $method = strtoupper($this->_env['REQUEST_METHOD']);
     if (($method == 'POST' || $method == 'PUT') && !$this->data) {
         if (($type = $this->type()) && $type !== 'html') {
             $this->_stream = $this->_stream ?: fopen('php://input', 'r');
             $media = $this->_classes['media'];
             $this->data = (array) $media::decode($type, stream_get_contents($this->_stream));
             fclose($this->_stream);
         }
     }
     if (isset($_FILES) && $_FILES) {
         $result = array();
         $normalize = function ($key, $value) use($result, &$normalize) {
             foreach ($value as $param => $content) {
                 foreach ($content as $num => $val) {
                     if (is_numeric($num)) {
                         $result[$key][$num][$param] = $val;
                         continue;
                     }
                     if (is_array($val)) {
                         foreach ($val as $next => $one) {
                             $result[$key][$num][$next][$param] = $one;
                         }
                         continue;
                     }
                     $result[$key][$num][$param] = $val;
                 }
             }
             return $result;
         };
         foreach ($_FILES as $key => $value) {
             if (isset($value['name'])) {
                 if (is_string($value['name'])) {
                     $result[$key] = $value;
                     continue;
                 }
                 if (is_array($value['name'])) {
                     $result += $normalize($key, $value);
                 }
             }
         }
         $this->data = Set::merge((array) $this->data, $result);
     }
 }
Example #20
0
 protected static function _prepareMatchParams($parameters)
 {
     foreach (Set::normalize($parameters) as $token => $scope) {
         if (strpos($token, 'T_') !== 0) {
             unset($parameters[$token]);
             foreach (array('before', 'after') as $key) {
                 if (!isset($scope[$key])) {
                     continue;
                 }
                 $items = array();
                 foreach ((array) $scope[$key] as $item) {
                     $items[] = strpos($item, 'T_') !== 0 ? static::token($item) : $item;
                 }
                 $scope[$key] = $items;
             }
             $parameters[static::token($token)] = $scope;
         }
     }
     return $parameters;
 }
Example #21
0
	/**
	 * Adds an Access rule. This works much like the Validator class.
	 * All rules should be anonymous functions and will be passed
	 * $user, $request, and $options which will contain the entire
	 * rule array which contains its own name plus other data that
	 * could be used to determine access.
	 *
	 * @param string $name The rule name.
	 * @param function $rule The closure for the rule, which has to return true or false.
	 */
	public function add($name, $rule = null) {
		$this->_rules = Set::merge($this->_rules, is_array($name) ? $name : array($name => $rule));
	}
Example #22
0
 /**
  * Checks a single-use hash key against the session token that generated it, using
  * a cryptographically-secure verification method. Accepts either the request key as a string,
  * or a `Request` object with a `$data` property containing a `['security']['token']` key.
  *
  * For example, the following two controller code samples are equivalent:
  *
  * {{{
  * $key = $this->request->data['security']['token'];
  *
  * if (!RequestToken::check($key)) {
  * 	// Handle invalid request...
  * }
  * }}}
  *
  * {{{
  * if (!RequestToken::check($this->request)) {
  * 	// Handle invalid request...
  * }
  * }}}
  *
  * @param mixed $key Either the actual key as a string, or a `Request` object containing the
  *              key.
  * @param array $options The options to use when matching the key to the token:
  *              - `'sessionKey'` _string_: The key used when reading the token from the session.
  * @return boolean Returns `true` if the hash key is a cryptographic match to the stored
  *         session token. Returns `false` on failure, which indicates a forged request attempt.
  */
 public static function check($key, array $options = array())
 {
     $defaults = array('sessionKey' => 'security.token');
     $options += $defaults;
     $session = static::$_classes['session'];
     if (is_object($key) && isset($key->data)) {
         $result = Set::extract($key->data, '/security/token');
         $key = $result ? $result[0] : null;
     }
     return Password::check($session::read($options['sessionKey']), (string) $key);
 }
Example #23
0
 /**
  * Delete value from the session
  *
  * @param string $key The key to be deleted
  * @param array $options Options array. Not used for this adapter method.
  * @return closure Function returning boolean `true` if the key no longer exists
  *         in the session, `false` otherwise
  */
 public static function delete($key, array $options = array())
 {
     if (!static::isStarted() && !static::_start()) {
         throw new RuntimeException("Could not start session.");
     }
     $class = __CLASS__;
     return function ($self, $params) use($class) {
         $key = $params['key'];
         $class::overwrite($_SESSION, Set::remove($_SESSION, $key));
         return !Set::check($_SESSION, $key);
     };
 }
Example #24
0
 /**
  * Iterates through relationship types to construct relation map.
  *
  * @return void
  * @todo See if this can be rewritten to be lazy.
  */
 protected static function _relationsToLoad()
 {
     try {
         if (!static::connection()) {
             return;
         }
     } catch (ConfigExcepton $e) {
         return;
     }
     $self = static::_object();
     foreach ($self->_relationTypes as $type) {
         $self->{$type} = Set::normalize($self->{$type});
         foreach ($self->{$type} as $name => $config) {
             $self->_relationsToLoad[$name] = $type;
         }
     }
 }
Example #25
0
 /**
  * Allows you to configure a default set of options which are included on a per-method basis,
  * and configure method template overrides.
  *
  * To force all `<label />` elements to have a default `class` attribute value of `"foo"`,
  * simply do the following:
  *
  * {{{
  * $this->form->config(array('label' => array('class' => 'foo')));
  * }}}
  *
  * @param array $config An associative array where the keys are `Form` method names, and the
  *              values are arrays of configuration options to be included in the `$options`
  *              parameter of each method specified.
  * @return array Returns an array containing the currently set per-method configurations, and
  *         an array of the currently set template overrides (in the `'templates'` array key).
  * @see lithium\template\helper\Form::$_templateMap
  */
 public function config($config = array())
 {
     if (empty($config)) {
         return array('templates' => $this->_templateMap) + array_intersect_key($this->_config, array('base' => '', 'text' => '', 'textarea' => ''));
     }
     if (isset($config['templates'])) {
         $this->_templateMap = $config['templates'] + $this->_templateMap;
         unset($config['templates']);
     }
     return ($this->_config = Set::merge($this->_config, $config)) + array('templates' => $this->_templateMap);
 }
Example #26
0
	public function testMixedKeyNormalization() {
		$input = array('"string"' => array('before' => '=>'), 1 => array('before' => '=>'));
		$result = Set::normalize($input);
		$this->assertEqual($input, $result);

		$input = 'Foo,Bar,Baz';
		$result = Set::normalize($input);
		$this->assertEqual(array('Foo' => null, 'Bar' => null, 'Baz' => null), $result);

		$input = array('baz' => 'foo', 'bar');
		$result = Set::normalize($input, false);
		$this->assertEqual(array('baz' => 'foo', 'bar' => null), $result);
	}
Example #27
0
 /**
  * Handles appending nested objects to document changesets.
  *
  * @param array $changes The full set of changes to be made to the database.
  * @param string $key The key of the field to append, which may be a dot-separated path if the
  *               value is or is contained within a nested object.
  * @param mixed $value The value to append to the changeset. Can be a scalar value, array, a
  *              nested object, or part of a nested object.
  * @param string $change The type of change, as to whether update/remove or rename etc.
  * @return array Returns the value of `$changes`, with any new changed values appended.
  */
 protected static function _append($changes, $key, $value, $change)
 {
     $options = array('finalize' => false);
     if (!is_object($value) || !method_exists($value, 'export')) {
         $changes[$change][$key] = $change == 'update' ? $value : true;
         return $changes;
     }
     if ($value->exists()) {
         if ($change == 'update') {
             $export = $value->export();
             $export['key'] = $key;
             return Set::merge($changes, static::_update($export));
         }
         $children = static::_update($value->export());
         if (!empty($children)) {
             return Set::merge($changes, $children);
         }
         $changes[$change][$key] = true;
         return $changes;
     }
     $changes['update'][$key] = static::_create($value->export(), $options);
     return $changes;
 }
Example #28
0
 /**
  * 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']);
         }
     };
 }
Example #29
0
 /**
  * Adds to or replaces built-in validation rules specified in `Validator::$_rules`.  Any new
  * validation rules created are automatically callable as validation methods.
  *
  * For example:
  * {{{
  * Validator::add('zeroToNine', '/^[0-9]$/');
  * $isValid = Validator::isZeroToNine("5"); // true
  * $isValid = Validator::isZeroToNine("20"); // false
  * }}}
  *
  * Alternatively, the first parameter may be an array of rules expressed as key/value pairs,
  * as in the following:
  * {{{
  * Validator::add(array(
  * 	'zeroToNine' => '/^[0-9]$/',
  * 	'tenToNineteen' => '/^1[0-9]$/',
  * ));
  * }}}
  *
  * In addition to regular expressions, validation rules can also be defined as full anonymous
  * functions:
  * {{{
  * use app\models\Account;
  *
  * Validator::add('accountActive', function($value) {
  * 	$value = is_int($value) ? Account::find($value) : $value;
  * 	return (boolean) $value->is_active;
  * });
  *
  * $testAccount = Account::create(array('is_active' => false));
  * Validator::isAccountActive($testAccount); // returns false
  * }}}
  *
  * These functions can take up to 3 parameters:
  * 	- `$value` _mixed_: This is the actual value to be validated (as in the above example).
  * 	- `$format` _string_: Often, validation rules come in multiple "formats", for example:
  * 	  postal codes, which vary by country or region. Defining multiple formats allows you to
  * 	  retian flexibility in how you validate data. In cases where a user's country of origin
  * 	  is known, the appropriate validation rule may be selected. In cases where it is not
  * 	  known, the value of `$format` may be `'any'`, which should pass if any format matches.
  * 	  In cases where validation rule formats are not mutually exclusive, the value may be
  * 	  `'all'`, in which case all must match.
  * 	- `$options` _array_: This parameter allows a validation rule to implement custom
  * 	  options.
  *
  * @see lithium\util\Validator::$_rules
  * @param mixed $name The name of the validation rule (string), or an array of key/value pairs
  *              of names and rules.
  * @param string $rule If $name is a string, this should be a string regular expression, or a
  *               closure that returns a boolean indicating success. Should be left blank if
  *               `$name` is an array.
  * @param array $options The default options for validating this rule. An option which applies
  *              to all regular expression rules is `'contains'` which, if set to true, allows
  *              validated values to simply _contain_ a match to a rule, rather than exactly
  *              matching it in whole.
  * @return void
  */
 public static function add($name, $rule = null, array $options = array())
 {
     if (!is_array($name)) {
         $name = array($name => $rule);
     }
     static::$_rules = Set::merge(static::$_rules, $name);
     if (!empty($options)) {
         $options = array_combine(array_keys($name), array_fill(0, count($name), $options));
         static::$_options = Set::merge(static::$_options, $options);
     }
 }
Example #30
0
 public function testNodeWithNonStrictMode()
 {
     Fixtures::save('db');
     extract($this->_models);
     $result = Set::extract(Aco::node('root/printers/refill/unexisting', false), '/id');
     $expected = ['9', '6', '1'];
     $this->assertEqual($expected, $result);
 }