protected function _autoSelects($name, array $options = array()) { $model = $this->_binding->model(); $method = Inflector::pluralize($name); $rules = $this->instance->validates; if (method_exists($model, $method)) { $list = $model::$method(); if (!empty($list)) { $options['list'] = $list; return $options; } } if (isset($rules[$name])) { if (is_array($rules[$name][0])) { $rule_list = $rules[$name]; } else { $rule_list = array($rules[$name]); } foreach ($rule_list as $rule) { if ($rule[0] === 'inList' and isset($rule['list'])) { foreach ($rule['list'] as $optval) { $options['list'][$optval] = Inflector::humanize($optval); } } } } return $options; }
public function testIndexScaffold() { $this->_controller->index(); $scaffold = $this->_controller->access('scaffold'); $expected = array('base' => '/radium/configurations', 'controller' => 'Configurations', 'library' => 'radium', 'class' => 'MockConfigurations', 'model' => 'radium\\tests\\mocks\\data\\MockConfigurations', 'slug' => Inflector::underscore('MockConfigurations'), 'singular' => Inflector::singularize('MockConfigurations'), 'plural' => Inflector::pluralize('MockConfigurations'), 'table' => Inflector::tableize('MockConfigurations'), 'human' => Inflector::humanize('MockConfigurations')); $this->assertEqual($expected, $scaffold); }
/** * Prepare `Aco` and `Aro` identifiers to be used for finding Acos and Aros nodes */ protected function _prepareAcl() { $request = $this->request->params; $user = $this->_user; $guest = $this->_guest; $buildAroPath = function ($group = null, $path = array()) use(&$buildAroPath) { $parent = null; $path[] = Inflector::pluralize($group['slug']); if ($group['parent_id']) { $parent = UserGroups::first(array('conditions' => array('parent_id' => $group['parent_id']))); } if ($parent) { return $buildAroPath($parent, $path); } return join('/', $path); }; $prepareAco = function () use($request) { extract($request); $library = isset($library) ? $library . '/' : ''; return $library . 'controllers/' . $controller; }; $prepareAro = function () use($user, $guest, $buildAroPath) { if ($guest) { return 'guests'; } return 'users/' . $buildAroPath($user['user_group']); }; $this->_aco = $prepareAco(); $this->_aro = $prepareAro(); }
/** * Get the class name for the mock. * * @param string $request * @return string */ protected function _class($request) { $type = $request->action; $name = $request->args(); if ($command = $this->_instance($type)) { $request->params['action'] = $name; $name = $command->invokeMethod('_class', array($request)); } return Inflector::pluralize("Mock{$name}"); }
public function run($name = null, $null = null) { $library = Libraries::get($this->library); if (empty($library['prefix'])) { return false; } $model = Inflector::classify($name); $use = "\\{$library['prefix']}models\\{$model}"; $params = array('namespace' => "{$library['prefix']}controllers", 'use' => $use, 'class' => "{$name}Controller", 'model' => $model, 'singular' => Inflector::singularize(Inflector::underscore($name)), 'plural' => Inflector::pluralize(Inflector::underscore($name))); if ($this->_save($this->template, $params)) { $this->out("{$params['class']} created in {$params['namespace']}."); return true; } return false; }
public function relationship($class, $type, $name, array $config = array()) { $field = Inflector::underscore(Inflector::singularize($name)); $key = "{$field}_id"; $primary = $class::meta('key'); if (is_array($primary)) { $key = array_combine($primary, $primary); } elseif ($type === 'hasMany' || $type === 'hasOne') { if ($type === 'hasMany') { $field = Inflector::pluralize($field); } $secondary = Inflector::underscore(Inflector::singularize($class::meta('name'))); $key = array($primary => "{$secondary}_id"); } $from = $class; $fieldName = $field; $config += compact('type', 'name', 'key', 'from', 'fieldName'); return $this->_instance('relationship', $config); }
public static function handlers($handlers = null) { if (!static::$_handlers) { static::$_handlers = array('binding' => function ($request, $options) { $model = $options['binding']; $name = $options['name']; $model = Libraries::locate('models', $model ?: Inflector::pluralize($name)); if (!$model || is_string($model) && !class_exists($model)) { $msg = "Could not find resource-mapped model class for resource `{$name}`."; throw new UnmappedResourceException($msg); } return $model; }, 'isRequired' => function ($request, $options, $result = null) { $name = $options['name']; $required = $options['required']; $model = $options['binding']; $isCountable = $result && $result instanceof Countable; $isValid = $result && !$isCountable || $isCountable && $result->valid(); if ($isValid || !$required) { return $result; } $model = is_object($model) ? get_class($model) : $model; $message = "Resource `{$name}` not found in model `{$model}`."; throw new ResourceNotFoundException($message); }, 'default' => array(function ($request, $options) { $isRequired = Resources::handlers('isRequired'); $query = (array) $options['call'] + array('all'); $call = $query[0]; unset($query[0]); return $isRequired($request, $options, $options['binding']::$call($query)); }, 'create' => function ($request, $options) { return $options['binding']::create($request->data); })); } if (is_array($handlers)) { static::$_handlers = $handlers + static::$_handlers; } if ($handlers && is_string($handlers)) { return isset(static::$_handlers[$handlers]) ? static::$_handlers[$handlers] : null; } return static::$_handlers; }
/** * Returns a list of links to model types' actions (Page types, User types, etc.) * By default, with no options specified, this returns a list of links to create any type of page (except core page). * * @param $model_name String The model name (can be lowercase, the Util class corrects it) * @param $action String The controller action * @param $options Array Various options that get passed to Util::list_types() and the key "link_options" can contain an array of options for the $this->html->link() * @return String HTML list of links * @see minerva\libraries\util\Util::list_types() */ public function link_types($model_name='Page', $action='create', $options=array()) { $options += array('exclude_minerva' => true, 'link_options' => array()); $libraries = Util::list_types($model_name, $options); $output = ''; (count($libraries) > 0) ? $output .= '<ul>':$output .= ''; foreach($libraries as $library) { if(substr($library, 0, 7) == 'minerva') { $model = $library; } else { $model = 'minerva\libraries\\' . $library; } $type = current(explode('\\', $library)); if(strtolower($type) == 'minerva') { $type = null; } $output .= '<li>' . $this->link($model::display_name(), '/' . Inflector::pluralize($model_name) . '/' . $action . '/' . $type, $options['link_options']) . '</li>'; } (count($libraries) > 0) ? $output .= '</ul>':$output .= ''; return $output; }
/** * Return statistics from the test runs. * * @return array */ public function stats() { $results = (array) $this->results['group']; $defaults = array('asserts' => 0, 'passes' => array(), 'fails' => array(), 'exceptions' => array(), 'errors' => array(), 'skips' => array()); $stats = array_reduce($results, function ($stats, $result) use($defaults) { $stats = (array) $stats + $defaults; $result = empty($result[0]) ? array($result) : $result; foreach ($result as $response) { if (empty($response['result'])) { continue; } $result = $response['result']; if (in_array($result, array('fail', 'exception'))) { $response = array_merge(array('class' => 'unknown', 'method' => 'unknown'), $response); $stats['errors'][] = $response; } unset($response['file'], $response['result']); if (in_array($result, array('pass', 'fail'))) { $stats['asserts']++; } if (in_array($result, array('pass', 'fail', 'exception', 'skip'))) { $stats[Inflector::pluralize($result)][] = $response; } } return $stats; }); $stats = (array) $stats + $defaults; $count = array_map(function ($value) { return is_array($value) ? count($value) : $value; }, $stats); $success = $count['passes'] === $count['asserts'] && $count['errors'] === 0; return compact('stats', 'count', 'success'); }
/** * Run through the default set. model, controller, test model, test controller * * @param string $name class name to create * @return boolean */ protected function _default($name) { $commands = array(array('model', Inflector::pluralize($name)), array('controller', Inflector::pluralize($name)), array('test', 'model', Inflector::pluralize($name)), array('test', 'controller', Inflector::pluralize($name))); foreach ($commands as $args) { $command = $this->template = $this->request->params['command'] = array_shift($args); $this->request->params['action'] = array_shift($args); $this->request->params['args'] = $args; if (!$this->_execute($command)) { return false; } } return true; }
/** * Returns absolute paths to files according to configuration. * * @param string $category * @param string $locale * @param string $scope * @return array */ protected function _files($category, $locale, $scope) { $path = $this->_config['path']; $scope = $scope ?: 'default'; if (($pos = strpos($category, 'Template')) !== false) { $category = substr($category, 0, $pos); return array("{$path}/{$category}_{$scope}.pot"); } if ($category == 'message') { $category = Inflector::pluralize($category); } $category = strtoupper($category); return array("{$path}/{$locale}/LC_{$category}/{$scope}.mo", "{$path}/{$locale}/LC_{$category}/{$scope}.po"); }
protected function _readEmbeddedFilter() { // filter for relations self::applyFilter('read', function ($self, $params, $chain) { $results = $chain->next($self, $params, $chain); if (isset($params['options']['with']) && !empty($params['options']['with'])) { $model = is_object($params['query']) ? $params['query']->model() : null; $relations = $model::relations(); foreach ($params['options']['with'] as $k => $name) { if (isset($relations[$name])) { $relation = $relations[$name]->data(); $relationModel = Libraries::locate('models', $relation['to']); if (!empty($relationModel) && !empty($results) && isset($relation['embedded'])) { $embedded_on = $relation['embedded']; $resultsArray = $results->to('array'); foreach ($resultsArray as $k => $result) { $relationalData = Set::extract($result, '/' . str_replace('.', '/', $embedded_on)); if (!empty($embedded_on)) { $keys = explode('.', $embedded_on); $lastKey = array_slice($keys, -1, 1); $lastKey = $lastKey[0]; $data = array(); foreach ($relationalData as $rk => $rv) { if (!empty($rv)) { if (!is_array($rv)) { $data[$rk] = $rv; } else { if (isset($rv[$lastKey]) && !empty($rv[$lastKey])) { $data[$rk] = $rv[$lastKey]; } } } } if (!empty($data)) { // TODO : Add support for conditions, fields, order, page, limit $validFields = array_fill_keys(array('with'), null); $options = array_intersect_key($relation, $validFields); $options['data'] = $data; if ($relation['type'] == 'hasMany') { $type = 'all'; } else { $type = 'first'; } $relationResult = $relationModel::find($type, $options); } else { if ($relation['type'] == 'hasMany') { $relationResult = $self->item($relationModel, array(), array('class' => 'set')); } else { $relationResult = null; } } // if fieldName === true, use the default lithium fieldName. // if fieldName != relationName, then it was manually set, so use it // else, just use the embedded key $relationName = $relation['type'] == 'hasOne' ? Inflector::pluralize($relation['name']) : $relation['name']; if ($relation['fieldName'] === true) { $relation['fieldName'] = lcfirst($relationName); $keys = explode('.', $relation['fieldName']); } else { if ($relation['fieldName'] != lcfirst($relationName)) { $keys = explode('.', $relation['fieldName']); } } $ref = $results[$k]; foreach ($keys as $k => $key) { if (!isset($ref->{$key})) { $ref->{$key} = $self->item(null, array(), array('class' => 'entity')); } if (count($keys) - 1 == $k) { $ref->{$key} = $relationResult; } else { $ref = $ref->{$key}; } } } } } } } } return $results; }); }
} switch ($type) { case 'rte': case 'textarea': $options = array('type' => 'textarea', 'class' => "form-control autogrow {$field}", 'rows' => 3); if (in_array($field, $readonly)) { $options['disabled'] = 'disabled'; $options['class'] .= ' uneditable-textarea'; } if ($type == 'rte') { $options['class'] .= ' rte'; } echo $this->form->field($field, $options); break; case 'select': $method = Inflector::underscore(Inflector::pluralize($field)); $options = array('type' => 'select', 'class' => "form-control {$field}", 'data-switch' => $field, 'list' => $model::$method()); if (isset($schema[$field]['null']) && $schema[$field]['null'] === true) { $options['empty'] = true; } if (in_array($field, $readonly)) { $options['type'] = 'text'; $options['value'] = $model::$method($this->scaffold->object->{$field}); $options['disabled'] = 'disabled'; $options['class'] .= ' uneditable-input'; } echo $this->form->field($field, $options); break; case 'configuration': $options = array('type' => 'select', 'class' => "form-control {$field}", 'data-switch' => 'configuration', 'list' => Configurations::find('list')); if (isset($schema[$field]['null']) && $schema[$field]['null'] === true) {
/** * If no resource parameter definition exists for a method, generate a default mapping. * * @param string $method The class method name to be called, i.e. `'index'`, `'add'`, etc. * @return array Returns an array where the key is the singular or plural name of the `Resource` * class, i.e. `'post'` or `'posts'`, and the value is a sub-array with an * optionally-non-namespaced model name or fully-qualified class name as the first * value, and a `'call'` key, indicating the name of the class method to call. */ protected function _default($method) { $name = lcfirst(static::_name()); $isPlural = $method == 'index'; $call = array(true => 'first', $isPlural => 'all', $method == 'add' => 'create'); $key = $isPlural ? Inflector::pluralize($name) : Inflector::singularize($name); return array($key => array(static::binding(), 'call' => $call[true], 'required' => !$isPlural)); }
/** * Connect a resource to the `Router`. * * @param string $resource The name of the resource * @param array $options */ public static function bind($resource, $options = array()) { $resources = explode('/', $resource); $splitCount = count($resources); $class = static::$_classes['route']; $scope = isset($options['scope']) ? '(/{:scope:' . strtolower($options['scope']) . '})' : ''; if ($splitCount > 1) { $controller = $resources[$splitCount - 1]; $resource = Inflector::underscore($controller); for ($i = $splitCount - 2; $i >= 0; $i--) { $resource = Inflector::underscore($resources[$i]) . '/{:' . Inflector::underscore($resources[$i]) . '_id:[0-9a-f]{24}|[0-9]+}/' . $resource; } } else { $resource = Inflector::pluralize(strtolower(Inflector::slug($resource))); $controller = $resource; $resource = Inflector::underscore($resource); } $types = static::$_types; if (isset($options['types'])) { $types = $options['types'] + $types; } if (isset($options['except'])) { foreach (array_intersect((array) $options['except'], array_keys($types)) as $k) { unset($types[$k]); } } if (isset($options['only'])) { foreach (array_keys($types) as $k) { if (!in_array($k, (array) $options['only'])) { unset($types[$k]); } } } $configs = array(); foreach ($types as $action => $params) { $config = array('template' => $scope . String::insert($params['template'], array('resource' => $resource)), 'params' => $params['params'] + array('controller' => $controller, 'action' => isset($params['action']) ? $params['action'] : $action)); $configs[] = $config; if (@$options['type_support'] != false) { if (isset($params['type_support']) && $params['type_support'] || @$options['type_support']) { $config = array('template' => $scope . String::insert($params['template'] . '(.{:type:\\w+})?', array('resource' => $resource)), 'params' => $params['params'] + array('controller' => $controller, 'action' => isset($params['action']) ? $params['action'] : $action)); $configs[] = $config; } } } return $configs; }
protected function _init() { parent::_init(); $config =& $this->_config; $type = $config['type']; $name = $type == 'hasOne' ? Inflector::pluralize($config['name']) : $config['name']; $config['fieldName'] = $config['fieldName'] ?: lcfirst($name); if (!$config['to']) { $assoc = preg_replace("/\\w+\$/", "", $config['from']) . $name; $config['to'] = Libraries::locate('models', $assoc); } if (!$config['key'] || !is_array($config['key'])) { $config['key'] = $this->_keys($config['key']); } }
public function testAddingUninflectedWords() { $this->assertEqual(Inflector::pluralize('bord'), 'bords'); Inflector::rules('uninflected', 'bord'); $this->assertEqual(Inflector::pluralize('bord'), 'bord'); }
/** * undocumented function * * @return void */ public function stats() { $results = (array) $this->results['group']; return $this->reporter->stats(array_reduce($results, function ($stats, $result) { $stats = (array) $stats + array('asserts' => 0, 'passes' => array(), 'fails' => array(), 'exceptions' => array(), 'errors' => array()); $result = empty($result[0]) ? array($result) : $result; foreach ($result as $response) { if (empty($response['result'])) { continue; } $result = $response['result']; if (in_array($result, array('fail', 'exception'))) { $stats['errors'][] = $response; } unset($response['file'], $response['result']); if (in_array($result, array('pass', 'fail'))) { $stats['asserts']++; } if (in_array($result, array('pass', 'fail', 'exception'))) { $stats[Inflector::pluralize($result)][] = $response; } } return $stats; })); }
protected function _readList($path, $category, $locale) { $plural = Inflector::pluralize($category); $file = "{$path}/main/{$locale}.xml"; $query = "/ldml/localeDisplayNames/{$plural}/{$category}"; $nodes = $this->_parseXml($file, $query); $data = array(); foreach ($nodes as $node) { $data = $this->_merge($data, array('id' => (string) $node['type'], 'translated' => (string) $node)); } return $data; }
/** * counts distinct values regarding a specific field * * @param string $field name of the field to count distinct values against * @param array $options an array of additional options * - `group`: set to $field, overwrite here * - `fields`: what fields to retrieve, useful if you overwrite the reduce code * - `initial`: initial object to aggregate data in, defaults to StdObject * - `reduce`: reduce method to be used within mongodb, must be of type `MongoCode` * @return array an array containing relevant rss data as keys and their corresponding values */ public static function distinctCount($field = 'type', $options = array()) { $defaults = array('group' => $field, 'fields' => array('_id', $field), 'initial' => new \stdClass(), 'reduce' => new \MongoCode("function(doc, prev) { " . "if(typeof(prev[doc.{$field}]) == 'undefined') {" . "prev[doc.{$field}] = 0;" . "}" . "prev[doc.{$field}] += 1;" . "}")); $options += $defaults; $method = Inflector::pluralize($field); $result = method_exists(__CLASS__, $method) ? array_fill_keys(array_keys(static::$method()), 0) : array(); $res = static::find('all', $options); if (!$res) { return $result; } $keys = $res->map(function ($item) use($field) { return $item->{$field}; }); $values = $res->map(function ($item) use($field) { return $item->{$item->{$field}}; }); return array_merge($result, array_combine($keys->data(), $values->data())); }
/** * Creates a relationship binding between this model and another. Overwritten to allow model to model relations seperate of data source relations. * * @see lithium\data\model\Relationship * @param string $type The type of relationship to create. Must be one of `'hasOne'`, * `'hasMany'` or `'belongsTo'`. * @param string $name The name of the relationship. If this is also the name of the model, * the model must be in the same namespace as this model. Otherwise, the * fully-namespaced path to the model class must be specified in `$config`. * @param array $config Any other configuration that should be specified in the relationship. * See the `Relationship` class for more information. * @return object Returns an instance of the `Relationship` class that defines the connection. */ public static function bind($type, $name, array $config = array()) { $defaults = array('default' => false); // li3_embedded catch to make embedding easier if (isset($config['embedded']) && !isset($config['default'])) { if (!empty($config['embedded'])) { $config['default'] = true; } else { $config['default'] = false; } } $config += $defaults; $self = static::_object(); if (!isset($config['to']) && isset($config['class'])) { $config['to'] = $config['class']; } if (!isset($config['to'])) { $config['to'] = $name; } $config['to'] = Libraries::locate('models', $config['to']); $targetModel = $config['to']; //TODO, add general exception option & add mongo exception for non embedded if (!empty($targetModel) && $config['default'] === false) { // continue on if default lithium relationship will not work if (isset($config['fieldName'])) { $fieldName = $config['fieldName']; } else { $fieldName = $name; if ($type == 'hasMany') { $fieldName = Inflector::pluralize($name); } else { $fieldName = Inflector::singularize($name); } $fieldName = Inflector::underscore($fieldName); } $key = "{$fieldName}_id"; $from = get_called_class(); $config += compact('type', 'name', 'key', 'from', 'fieldName'); $connection = static::connection(); $relationship = $connection->invokeMethod('_instance', array('relationship', $config)); if (!empty($relationship)) { $self->_alternateRelations[$name] = $relationship; return null; } } return parent::bind($type, $name, $config); }
/** * Tests the storage mechanism for `$_underscored`, `$_camelized`, * `$_humanized` and `$_pluralized`. * * @return void */ public function testStorageMechanism() { Inflector::reset(); $expected = array('TestField' => 'test_field'); $this->assertFalse($this->getProtectedValue('$_underscored')); $this->assertEqual(Inflector::underscore('TestField'), 'test_field'); $this->assertEqual($expected, $this->getProtectedValue('$_underscored')); $this->assertEqual(Inflector::underscore('TestField'), 'test_field'); $expected = array('test_field' => 'TestField'); $this->assertFalse($this->getProtectedValue('$_camelized')); $this->assertEqual(Inflector::camelize('test_field', true), 'TestField'); $this->assertEqual($expected, $this->getProtectedValue('$_camelized')); $this->assertEqual(Inflector::camelize('test_field', true), 'TestField'); $expected = array('test_field:_' => 'Test Field'); $this->assertFalse($this->getProtectedValue('$_humanized')); $this->assertEqual(Inflector::humanize('test_field'), 'Test Field'); $this->assertEqual($expected, $this->getProtectedValue('$_humanized')); $this->assertEqual(Inflector::humanize('test_field'), 'Test Field'); $expected = array('field' => 'fields'); $this->assertFalse($this->getProtectedValue('$_pluralized')); $this->assertEqual(Inflector::pluralize('field'), 'fields'); $this->assertEqual($expected, $this->getProtectedValue('$_pluralized')); $this->assertEqual(Inflector::pluralize('field'), 'fields'); }
/** * Returns the field name of a relation name (underscore). * * @param string The type of the relation. * @param string The name of the relation. * @return string */ public function relationFieldName($type, $name) { $fieldName = Inflector::underscore($name); if (preg_match('/Many$/', $type)) { $fieldName = Inflector::pluralize($fieldName); } else { $fieldName = Inflector::singularize($fieldName); } return $fieldName; }
/** * Get the model class used in controller methods. * * @param string $request * @return string */ protected function _model($request) { return Inflector::camelize(Inflector::pluralize($request->action)); }
/** * Get the plural variable used for data in controller methods. * * @param string $request * @return string */ protected function _plural($request) { return Inflector::pluralize(Inflector::camelize($request->action, false)); }
/** * Generates different variations of the configured $this->model property name * * If no model is configured (i.e. `null`) - it automatically detects the corresponding * model for this Controller via Inflection and `Libraries::locate()`. * * @see lithium\core\Libraries::locate() * @param string $field defines, what variation of the default you want to have * available are 'class', 'model', 'singular', 'plural' and 'table' and 'human'. * if omitted, returns array containing all of them. * @return array|string **/ protected function _scaffold($field = null) { if (is_null($this->model)) { $this->model = (string) Libraries::locate('models', $this->request->controller); } if (is_null($this->scaffold)) { $class = basename(str_replace('\\', '/', $this->model)); $base = !empty($this->library) ? array('controller' => $this->controller, 'library' => $this->library) : array('controller' => $this->controller); $this->scaffold = array('base' => Router::match($base, $this->request), 'controller' => strtolower($this->controller), 'library' => $this->library, 'class' => $class, 'model' => $this->model, 'slug' => Inflector::underscore($class), 'singular' => Inflector::singularize($class), 'plural' => Inflector::pluralize($class), 'table' => Inflector::tableize($class), 'human' => Inflector::humanize($class)); } if (!is_null($field)) { return isset($this->scaffold[$field]) ? $this->scaffold[$field] : false; } Environment::set(true, array('scaffold' => $this->scaffold)); return $this->scaffold; }