Takes a CamelCased version of a word and turns it into an under_scored one.
public static underscore ( string $word ) : string | ||
$word | string | CamelCased version of a word (i.e. `'RedBike'`). |
return | string | Under_scored version of the workd (i.e. `'red_bike'`). |
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); }
/** * Override the save method to handle view specific params. * * @param array $params * @return mixed */ protected function _save(array $params = array()) { $params['path'] = Inflector::underscore($this->request->action); $params['file'] = $this->request->args(0); $contents = $this->_template(); $result = String::insert($contents, $params); if (!empty($this->_library['path'])) { $path = $this->_library['path'] . "/views/{$params['path']}/{$params['file']}"; $file = str_replace('//', '/', "{$path}.php"); $directory = dirname($file); if (!is_dir($directory)) { if (!mkdir($directory, 0755, true)) { return false; } } $directory = str_replace($this->_library['path'] . '/', '', $directory); if (file_exists($file)) { $prompt = "{$file} already exists. Overwrite?"; $choices = array('y', 'n'); if ($this->in($prompt, compact('choices')) !== 'y') { return "{$params['file']} skipped."; } } if (is_int(file_put_contents($file, $result))) { return "{$params['file']}.php created in {$directory}."; } } return false; }
public function relationship($class, $type, $name, array $options = array()) { $keys = Inflector::underscore($type == 'belongsTo' ? $name : $class::meta('name')) . '_id'; $options += compact('name', 'type', 'keys'); $options['from'] = $class; $relationship = $this->_classes['relationship']; return new $relationship($options); }
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); }
/** * Override the save method to handle view specific params. * * @param array $params */ protected function _save(array $params = array()) { $params['path'] = Inflector::underscore($this->request->action); $params['file'] = $this->request->args(0); $contents = $this->_template(); $result = String::insert($contents, $params); if (!empty($this->_library['path'])) { $path = $this->_library['path'] . "/views/{$params['path']}/{$params['file']}"; $file = str_replace('//', '/', "{$path}.php"); $directory = dirname($file); if (!is_dir($directory)) { if (!mkdir($directory, 0755, true)) { return false; } } $directory = str_replace($this->_library['path'] . '/', '', $directory); if (file_put_contents($file, "<?php\n\n{$result}\n\n?>")) { return "{$params['file']}.php created in {$directory}."; } } return false; }
public function testLazyMetadataInit() { MockPost::config(array('schema' => new Schema(array('fields' => array('id' => array('type' => 'integer'), 'name' => array('type' => 'string'), 'label' => array('type' => 'string')))))); $this->assertIdentical('mock_posts', MockPost::meta('source')); $this->assertIdentical('name', MockPost::meta('title')); $this->assertEmpty(MockPost::meta('unexisting')); $config = array('schema' => new Schema(array('fields' => array('id' => array('type' => 'integer'), 'name' => array('type' => 'string'), 'label' => array('type' => 'string')))), 'initializers' => array('source' => function ($self) { return Inflector::tableize($self::meta('name')); }, 'name' => function ($self) { return Inflector::singularize('CoolPosts'); }, 'title' => function ($self) { static $i = 1; return 'label' . $i++; })); MockPost::reset(); MockPost::config($config); $this->assertIdentical('cool_posts', MockPost::meta('source')); $this->assertIdentical('label1', MockPost::meta('title')); $this->assertNotIdentical('label2', MockPost::meta('title')); $this->assertIdentical('label1', MockPost::meta('title')); $meta = MockPost::meta(); $this->assertIdentical('label1', $meta['title']); $this->assertIdentical('CoolPost', MockPost::meta('name')); MockPost::reset(); unset($config['initializers']['title']); $config['initializers']['source'] = function ($self) { return Inflector::underscore($self::meta('name')); }; MockPost::config($config); $this->assertIdentical('cool_post', MockPost::meta('source')); $this->assertIdentical('name', MockPost::meta('title')); $this->assertIdentical('CoolPost', MockPost::meta('name')); MockPost::reset(); MockPost::config($config); $expected = array('class' => 'lithium\\tests\\mocks\\data\\MockPost', 'connection' => false, 'key' => 'id', 'name' => 'CoolPost', 'title' => 'name', 'source' => 'cool_post'); $this->assertEqual($expected, MockPost::meta()); }
/** * Allows the use of syntactic-sugar like `Mailer::deliverTestWithLocal()` * instead of `Mailer::deliver('test', array('delivery' => 'local'))`. * * @see li3_mailer\action\Mailer::deliver() * @link http://php.net/manual/en/language.oop5.overloading.php PHP * Manual: Overloading * @throws BadMethodCallException On unhandled call, will * throw an exception. * @param string $method Method name caught by `__callStatic()`. * @param array $params Arguments given to the above `$method` call. * @return mixed Results of dispatched `Mailer::deliver()` call. */ public static function __callStatic($method, $params) { $pattern = '/^deliver(?P<message>\\w+)With(?P<delivery>\\w+)$/'; $found = preg_match($pattern, $method, $args); if (!$found) { preg_match('/^deliver(?P<message>\\w+)$/', $method, $args); } if (!$args) { $class = get_called_class(); $class = substr($class, strrpos($class, "\\") + 1); $error = "Method `{$method}` not defined or handled " . "in class `{$class}`."; throw new BadMethodCallException($error); } $message = Inflector::underscore($args['message']); if (isset($params[0]) && is_array($params[0])) { $params = $params[0]; } if (isset($args['delivery'])) { $params['delivery'] = Inflector::underscore($args['delivery']); } return static::deliver($message, $params); }
public static function export(array $resources, array $options = array()) { $defaults = array('prefix' => null); $options += $defaults; $classes = static::$_classes; $remap = array(); $names = array(); foreach ($resources as $resource => $config) { if (is_int($resource)) { $resource = $config; $config = array(); } $config += array('class' => Libraries::locate('resources', $resource), 'path' => str_replace('_', '-', Inflector::underscore($resource)), 'key' => 'id:(?:[0-9a-f]{24})|(?:\\d+)'); $config += static::_instance($config['class'])->config(); $first = substr($config['path'], 0, 1); $remap[$resource] = $config; $name = "[{$first}" . ucfirst($first) . "]" . substr($config['path'], 1); static::$_exports[$resource] = $config; static::$_bindings += array($config['binding'] => $resource); $template = join('/', array($options['prefix'], "{:controller:{$name}}", "{:action:[^0-9]+}", "{:{$config['key']}}")); $classes['router']::connect($template, array('action' => null)); } }
public function __call($method, $args) { $params = empty($args) ? array() : $args[0]; $method = Inflector::underscore($method); return $this->_context->view()->render(array('element' => "{$method}_partial"), $params); }
/** * parseMatch Matches the current request parameters against a set of given parameters. * Can match against a shorthand string (Controller::action) or a full array. If a parameter * is provided then it must have an equivilent in the Request objects parmeters in order * to validate. * Is also acceptable to match a parameter without a specific value. * * @param mixed $match A set of parameters to validate the request against. * @param mixed $params The Lithium `Request` object, or an array with at least * 'request', and 'params' * @access public * @return boolean True if a match is found. */ public static function parseMatch($match, $params) { if (empty($match)) { return false; } if (is_array($match)) { $_params = $params; if (!static::_parseClosures($match, $params['request'], $_params)) { return false; } } elseif (is_callable($match)) { return (bool) $match($params['request'], $params); } $matchParams = array(); foreach ((array) $match as $key => $param) { if (is_string($param)) { if (preg_match('/^([A-Za-z0-9_\\*\\\\]+)::([A-Za-z0-9_\\*]+)$/', $param, $regexMatches)) { $matchParams += array('controller' => $regexMatches[1], 'action' => $regexMatches[2]); continue; } } $matchParams[$key] = $param; } foreach ($matchParams as $type => $value) { if ($value === '*') { continue; } if ($type === 'controller') { $value = Inflector::underscore($value); } $exists_in_request = array_key_exists($type, $params['params']); if (!$exists_in_request || $value !== Inflector::underscore($params['params'][$type])) { return false; } } return true; }
} 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) {
/** * 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; }
/** * Helper function for taking a path string and parsing it into a controller and action array. * * @param string $path Path string to parse. * @param boolean $context * @return array */ protected static function _parseString($path, $context) { if (!preg_match('/^[A-Za-z0-9_]+::[A-Za-z0-9_]+$/', $path)) { $base = $context ? $context->env('base') : ''; $path = trim($path, '/'); return $context !== false ? "{$base}/{$path}" : null; } list($controller, $action) = explode('::', $path, 2); $controller = Inflector::underscore($controller); return compact('controller', 'action'); }
/** * Allows the use of syntactic-sugar like `Model::all()` instead of `Model::find('all')`. * * @see lithium\data\Model::find() * @see lithium\data\Model::$_meta * @link http://php.net/manual/en/language.oop5.overloading.php PHP Manual: Overloading * * @throws BadMethodCallException On unhandled call, will throw an exception. * @param string $method Method name caught by `__callStatic()`. * @param array $params Arguments given to the above `$method` call. * @return mixed Results of dispatched `Model::find()` call. */ public static function __callStatic($method, $params) { $self = static::_object(); $isFinder = isset($self->_finders[$method]); if ($isFinder && count($params) === 2 && is_array($params[1])) { $params = array($params[1] + array($method => $params[0])); } if ($method == 'all' || $isFinder) { if ($params && !is_array($params[0])) { $params[0] = array('conditions' => static::key($params[0])); } return $self::find($method, $params ? $params[0] : array()); } preg_match('/^findBy(?P<field>\\w+)$|^find(?P<type>\\w+)By(?P<fields>\\w+)$/', $method, $args); if (!$args) { $message = "Method `%s` not defined or handled in class `%s`."; throw new BadMethodCallException(sprintf($message, $method, get_class($self))); } $field = Inflector::underscore($args['field'] ? $args['field'] : $args['fields']); $type = isset($args['type']) ? $args['type'] : 'first'; $type[0] = strtolower($type[0]); $conditions = array($field => array_shift($params)); $params = isset($params[0]) && count($params) == 1 ? $params[0] : $params; return $self::find($type, compact('conditions') + $params); }
/** * 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); }
/** * Uses results (typically coming from a controller action) to generate content and headers for * a Response object. * * @param array $options An array of options, as follows: * - `'data'`: An associative array of variables to be assigned to the template. These * are merged on top of any variables set in `Controller::set()`. * - `'head'`: If true, only renders the headers of the response, not the body. Defaults * to `false`. * - `'template'`: The name of a template, which usually matches the name of the action. * By default, this template is looked for in the views directory of the current * controller, i.e. given a `PostsController` object, if template is set to `'view'`, * the template path would be `views/posts/view.html.php`. Defaults to the name of the * action being rendered. * @return void */ public function render(array $options = array()) { $media = $this->_classes['media']; $class = get_class($this); $name = preg_replace('/Controller$/', '', substr($class, strrpos($class, '\\') + 1)); $defaults = array('status' => null, 'location' => false, 'data' => null, 'head' => false); $options += $defaults + array('controller' => Inflector::underscore($name)); if ($options['data']) { $this->set($options['data']); unset($options['data']); } $options = $options + $this->_render; $type = key($options); $types = array_flip($media::types()); if (isset($types[$type])) { $options['type'] = $type; $this->set(current($options)); unset($options[$type]); } $this->_render['hasRendered'] = true; $this->response->type($options['type']); $this->response->status($options['status']); $this->response->headers('Location', $options['location']); if ($options['head']) { return; } $data = $this->_render['data']; $data = isset($data[0]) && count($data) == 1 ? $data[0] : $data; $media::render($this->response, $data, $options + array('request' => $this->request)); }
/** * 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'); }
/** * 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; }
protected function _init() { parent::_init(); $self = $this; $url = $this->_url(); $transitions = $this->_statusTransitions; $this->_responders += array('exception' => function ($request, array $resources, array $options) { if (!$options['data'] instanceof Exception) { return $options; } $result = array('status' => $options['status'] ?: $options['data']->getCode(), 'data' => array('type' => basename(str_replace('\\', '/', get_class($options['data']))), 'message' => $options['data']->getMessage())); return $result + $options; }, 'status' => function ($request, array $resources, array $options) use($transitions) { if ($options['status'] && is_int($options['status'])) { return $options; } $method = $options['method']; $events = isset($transitions[$method]) ? $transitions[$method] : $transitions[0]; foreach ($events as $transition) { foreach ($options['state'] as $i => $state) { $state = (array) $state + $options; if (array_intersect_assoc($transition[$i], $state) != $transition[$i]) { continue 2; } } return array('status' => $transition[2]) + $options; } return $options; }, 'browser' => function ($request, array $resources, array $options) use($self) { if (!$options['requiresView']) { return $options; } $key = lcfirst($options['controller']); $id = is_object($options['data']) ? spl_object_hash($options['data']) : null; foreach ($resources as $name => $value) { if (is_object($value) && spl_object_hash($value) == $id) { $key = $name; break; } } $options += array('template' => $options['method'], 'layout' => 'default'); $options['status'] = $options['status'] ?: 200; $options['controller'] = Inflector::underscore($options['controller']); $options['data'] = array($key => $options['data']); if (isset($options['viewData']) && is_callable($options['viewData'])) { $options['data'] += $options['viewData'](); } if (isset($options['view']) && is_array($options['view'])) { $options['data'] = $options['view'] + $options['data']; unset($options['view']); } return $options; }, 'next' => function ($request, array $resources, array $options) use($url) { if (!$options['next'] || $options['location'] || !$options['requiresView']) { return $options; } $location = $url($request, $options['next']); return compact('location') + array('status' => 302) + $options; }, 'location' => function ($request, array $resources, array $options) use($url) { $validStatus = in_array($options['status'], array(201, 301, 302, 303)); if (!$options['location'] || $options['next'] || !$validStatus) { return $options; } return array('location' => $url($request, $options['location'])) + $options; }, 'error' => function ($request, array $resources, array $options) { $failed = $options['success'] === false || $options['status'] === 422; $isObj = is_object($options['data']) && method_exists($options['data'], 'errors'); if ($isObj && $failed) { $options = array('data' => $options['data']->errors()) + $options; } return $options; }); }
/** * Get the properties for the class * * @param string $class * @param array $options * @return array */ protected function _properties($class, $options = array()) { $defaults = array('name' => null); $options += $defaults; $properties = Inspector::properties($class); $results = array(); foreach ($properties as &$property) { $comment = Docblock::comment($property['docComment']); $description = trim($comment['description']); $type = isset($comment['tags']['var']) ? strtok($comment['tags']['var'], ' ') : null; $name = str_replace('_', '-', Inflector::underscore($property['name'])); $usage = $type == 'boolean' ? "-{$name}" : "--{$name}=" . strtoupper($name); $results[$name] = compact('name', 'description', 'type', 'usage'); if ($name == $options['name']) { return array($name => $results[$name]); } } return $results; }
/** * Matches the current request parameters against a set of given parameters. Can match * against a shorthand string (Controller::action) or a full array. If a parameter * is provided then it must have an equivalent in the Request objects parmeters in order * to validate. * Is also acceptable to match a parameter without a specific value. * * @param mixed $match A set of parameters to validate the request against. * @param mixed $request A lithium Request object. * @access public * @return boolean True if a match is found. */ protected function _match($match, $request) { if (empty($match)) { return false; } if (is_array($match)) { if (!$this->_run($match, $request)) { return false; } } $params = array(); foreach ((array) $match as $key => $param) { if (is_string($param)) { if (preg_match('/^[A-Za-z0-9_\*]+::[A-Za-z0-9_\*]+$/', $param, $regexMatches)) { list($controller, $action) = explode('::', reset($regexMatches)); $params += compact('controller', 'action'); continue; } } $params[$key] = $param; } foreach ($params as $type => $value) { if ($value === '*') { continue; } if ($type === 'controller') { $value = Inflector::underscore($value); } if (!array_key_exists($type, $request->params) || $value !== $request->params[$type]) { return false; } } return true; }
/** * Defines or modifies the default settings of a relationship between two models. * * @param string $class * @param string $type * @param string $name * @param array $config * @return array Returns an array containing the configuration for a model relationship. */ public function relationship($class, $type, $name, array $config = array()) { $singularName = $type == 'hasMany' ? Inflector::singularize($name) : $name; $keys = $type == 'belongsTo' ? $class::meta('name') : $singularName; $keys = Inflector::underscore($keys) . '_id'; $from = $class; return $this->_instance('relationship', $config + compact('type', 'name', 'keys', 'from')); }
/** * 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; }
/** * Used to get or set an array of named formatter closures, which are used to format route * parameters when generating URLs. For example, for controller/action parameters to be dashed * instead of underscored or camelBacked, you could do the following: * * {{{ * use lithium\util\Inflector; * * Router::formatters(array( * 'controller' => function($value) { return Inflector::slug($value); }, * 'action' => function($value) { return Inflector::slug($value); } * )); * }}} * * _Note_: Because formatters are copied to `Route` objects on an individual basis, make sure * you append custom formatters _before_ connecting new routes. * * @param array $formatters An array of named formatter closures to append to (or overwrite) the * existing list. * @return array Returns the formatters array. */ public static function formatters(array $formatters = array()) { if (!static::$_formatters) { static::$_formatters = array('args' => function ($value) { return is_array($value) ? join('/', $value) : $value; }, 'controller' => function ($value) { return Inflector::underscore($value); }); } if ($formatters) { static::$_formatters = array_filter($formatters + static::$_formatters); } return static::$_formatters; }
/** * Tests that non-prefixed (poorly named or structured) libraries can still be added. * * @return void */ public function testAddNonPrefixedLibrary() { $tmpDir = realpath(Libraries::get(true, 'resources') . '/tmp'); $this->skipIf(!is_writable($tmpDir), "Can't write to resources directory."); $fakeDir = $tmpDir . '/fake'; $fake = "<?php class Fake {} ?>"; $fakeFilename = $fakeDir . '/fake.php'; mkdir($fakeDir, 0777, true); file_put_contents($fakeFilename, $fake); Libraries::add('bad', array('prefix' => false, 'path' => $fakeDir, 'transform' => function ($class, $config) { return ''; })); Libraries::add('fake', array('path' => $fakeDir, 'includePath' => true, 'prefix' => false, 'transform' => function ($class, $config) { return $config['path'] . '/' . Inflector::underscore($class) . '.php'; })); $this->assertFalse(class_exists('Fake', false)); $this->assertTrue(class_exists('Fake')); unlink($fakeFilename); rmdir($fakeDir); Libraries::remove('fake'); }
if ($report->title) { ?> <h2><span>test results for </span><?php echo $report->title; ?> </h2> <?php } ?> <span class="filters"> <?php echo join('', array_map(function ($class) use($request) { $url = "?filters[]={$class}"; $name = join('', array_slice(explode("\\", $class), -1)); $key = Inflector::underscore($name); $isActive = isset($request->query['filters']) && array_search($class, $request->query['filters']) !== false; $active = $isActive ? 'active' : null; return "<a class=\"{$key} {$active}\" href=\"{$url}\">{$name}</a>"; }, $filters)); ?> </span> <?php echo $report->render("stats"); foreach ($report->filters() as $filter => $options) { $data = $report->results['filters'][$filter]; echo $report->render($options['name'], compact('data', 'base')); } ?> </div> </article>
/** * Iterates through relationship types to construct relation map. * * @return void * @todo See if this can be rewritten to be lazy. */ protected static function _relations() { $relations = array(); $self = static::_instance(); foreach ($self->_relationTypes as $type => $keys) { foreach (Set::normalize($self->{$type}) as $name => $options) { $key = Inflector::underscore($type == 'belongsTo' ? $name : $self->_meta['name']); $defaults = array('type' => $type, 'class' => $name, 'fields' => true, 'key' => $key . '_id'); $relations[$name] = (array) $options + $defaults; } } return $relations; }
/** * Uses results (typically coming from a controller action) to generate content and headers for * a `Response` object. * * @see lithium\action\Controller::$_render * @param array $options An array of options, as follows: * - `'data'`: An associative array of variables to be assigned to the template. These * are merged on top of any variables set in `Controller::set()`. * - `'head'`: If true, only renders the headers of the response, not the body. Defaults * to `false`. * - `'template'`: The name of a template, which usually matches the name of the action. * By default, this template is looked for in the views directory of the current * controller, i.e. given a `PostsController` object, if template is set to `'view'`, * the template path would be `views/posts/view.html.php`. Defaults to the name of the * action being rendered. * * The options specified here are merged with the values in the `Controller::$_render` * property. You may refer to it for other options accepted by this method. * @return object Returns the `Response` object associated with this `Controller` instance. */ public function render(array $options = array()) { $media = $this->_classes['media']; $class = get_class($this); $name = preg_replace('/Controller$/', '', substr($class, strrpos($class, '\\') + 1)); $key = key($options); if (isset($options['data'])) { $this->set($options['data']); unset($options['data']); } $defaults = array('status' => null, 'location' => false, 'data' => null, 'head' => false, 'controller' => Inflector::underscore($name), 'library' => Libraries::get($class)); $options += $this->_render + $defaults; if ($key && $media::type($key)) { $options['type'] = $key; $this->set($options[$key]); unset($options[$key]); } $this->_render['hasRendered'] = true; $this->response->type($options['type']); $this->response->status($options['status']); $this->response->headers('Location', $options['location']); if ($options['head']) { return; } $response = $media::render($this->response, $this->_render['data'], $options + array('request' => $this->request)); return $this->response = $response ?: $this->response; }
/** * Extract an archive into a path. If one param exists, the app.phar.gz template will be used. * If both parameters exist, then the first will be the template archive and the second will be * the name of the extracted archive * * - `li3 library extract myapp` : uses command/create/template/app.phar.gz * - `li3 library extract another_archive myapp` : uses * command/create/template/another_archive.phar.gz * - `li3 library extract plugin li3_plugin` : uses command/create/template/plugin.phar.gz * - `li3 library extract /full/path/to/a.phar.gz myapp` : paths that begin with a '/' * can extract from archives outside of the default command/create/template/ * location * * @param string $name if only param, command/create/template/app.phar.gz extracted to $name * otherwise, the template name or full path to extract `from` phar.gz. * @param string $result if exists $name is extracted to $result * @return boolean */ public function extract($name = 'new', $result = null) { $from = 'app'; $to = $name; if ($result) { $from = $name; $to = $result; } $to = $this->_toPath($to); if ($from[0] !== '/') { $from = Libraries::locate('command.create.template', $from, array('filter' => false, 'type' => 'file', 'suffix' => '.phar.gz')); if (!$from || is_array($from)) { return false; } } if (file_exists($from)) { try { $archive = new Phar($from); } catch (Exception $e) { $this->error($e->getMessage()); return false; } if ($archive->extractTo($to)) { $this->out(basename($to) . " created in " . dirname($to) . " from {$from}"); if (empty($this->namespace)) { $this->namespace = Inflector::underscore(basename($to)); } $replacements = $this->_findReplacements($to); return $this->_replaceAfterExtract($to, compact('namespace', 'replacements')); } } $this->error("Could not extract {$to} from {$from}"); return false; }