/** * Returns filtered associations for controllers models. HasMany association are filtered if * already existing in BelongsToMany * * @param Table $model The model to build associations for. * @return array associations */ public function filterAssociations(Table $model) { $belongsToManyJunctionsAliases = $this->belongsToManyJunctionAliases($model); $keys = ['BelongsTo', 'HasOne', 'HasMany', 'BelongsToMany']; $associations = []; foreach ($keys as $type) { foreach ($model->associations()->type($type) as $assoc) { $target = $assoc->target(); $assocName = $assoc->name(); $alias = $target->alias(); //filter existing HasMany if ($type === 'HasMany' && in_array($alias, $belongsToManyJunctionsAliases)) { continue; } $targetClass = get_class($target); list(, $className) = namespaceSplit($targetClass); $navLink = true; $modelClass = get_class($model); if ($modelClass !== 'Cake\\ORM\\Table' && $targetClass === $modelClass) { $navLink = false; } $className = preg_replace('/(.*)Table$/', '\\1', $className); if ($className === '') { $className = $alias; } try { $associations[$type][$assocName] = ['property' => $assoc->property(), 'variable' => Inflector::variable($assocName), 'primaryKey' => (array) $target->primaryKey(), 'displayField' => $target->displayField(), 'foreignKey' => $assoc->foreignKey(), 'alias' => $alias, 'controller' => $className, 'fields' => $target->schema()->columns(), 'navLink' => $navLink]; } catch (Exception $e) { // Do nothing it could be a bogus association name. } } } return $associations; }
/** * Get the element name for the panel. * * @return string */ public function elementName() { list($ns, $name) = namespaceSplit(get_class($this)); if ($this->plugin) { return $this->plugin . '.' . Inflector::underscore($name); } return Inflector::underscore($name); }
/** * Gets the repository for this entity * * @param EntityInterface $entity * @return Table */ protected function _repository($entity) { $source = $entity->source(); if ($source === null) { list(, $class) = namespaceSplit(get_class($entity)); $source = Inflector::pluralize($class); } return TableRegistry::get($source); }
/** * Returns the database method name or sets a new one * * @param string|null $method the new method name * @return string */ public function method($method = null) { if ($method !== null) { $this->_method = $method; } if ($this->_method === null) { $method = namespaceSplit(get_class($this)); $method = substr(end($method), 0, -6); $this->_method = Inflector::underscore($method); } return $this->_method; }
public function __construct(MacroRegistry $macroRegistry, array $config = [], $name = null) { if ($this->name === null && $name === null) { list(, $name) = namespaceSplit(get_class($this)); $name = substr($name, 0, -5); } if ($name !== null) { $this->name = $name; } $this->config($config); $this->modelFactory('Table', ['Cake\\ORM\\TableRegistry', 'get']); $modelClass = ($this->plugin ? $this->plugin . '.' : '') . $this->name; $this->_setModelClass($modelClass); }
/** * Renders the response for the exception. * * @return Response The response to be sent. */ public function render($exception) { $exception = $exception instanceof PHP7ErrorException ? $exception->getError() : $exception; list(, $baseClass) = namespaceSplit(get_class($exception)); if (substr($baseClass, -9) === 'Exception') { $baseClass = substr($baseClass, 0, -9); } $action = (new Text($baseClass))->camelBackize() ?: 'error500'; $class = Core::className('Error', 'Controller', 'Controller'); $controller = new $class(); if (!in_array($action, get_class_methods($controller))) { $action = "processError"; } return $controller->callAction($action, ["exception" => $exception, "request" => Router::getInstance()->request()]); }
/** * Get an array of associations matching a specific type. * * @param string $class The type of associations you want. For example 'BelongsTo' * @return array An array of Association objects. */ public function type($class) { $out = array_filter($this->_items, function ($assoc) use($class) { list($ns, $name) = namespaceSplit(get_class($assoc)); return $class === $name; }); return array_values($out); }
/** * Prepare some additional data from the context. * * If the table option was provided to the constructor and it * was a string, ORM\TableRegistry will be used to get the correct table instance. * * If an object is provided as the table option, it will be used as is. * * If no table option is provided, the table name will be derived based on * naming conventions. This inference will work with a number of common objects * like arrays, Collection objects and ResultSets. * * @return void * @throws \RuntimeException When a table object cannot be located/inferred. */ protected function _prepare() { $table = $this->_context['table']; $entity = $this->_context['entity']; if (empty($table)) { if (is_array($entity) || $entity instanceof Traversable) { $entity = (new Collection($entity))->first(); } $isEntity = $entity instanceof Entity; if ($isEntity) { $table = $entity->source(); } if (!$table && $isEntity && get_class($entity) !== 'Cake\\ORM\\Entity') { list($ns, $entityClass) = namespaceSplit(get_class($entity)); $table = Inflector::pluralize($entityClass); } } if (is_string($table)) { $table = TableRegistry::get($table); } if (!is_object($table)) { throw new \RuntimeException('Unable to find table class for current entity'); } $this->_isCollection = is_array($entity) || $entity instanceof Traversable; $alias = $this->_rootName = $table->alias(); $this->_tables[$alias] = $table; }
/** * Constructor. * * Sets a number of properties based on conventions if they are empty. To override the * conventions CakePHP uses you can define properties in your class declaration. * * @param \Cake\Network\Request|null $request Request object for this controller. Can be null for testing, * but expect that features that use the request parameters will not work. * @param \Cake\Network\Response|null $response Response object for this controller. * @param string|null $name Override the name useful in testing when using mocks. * @param \Cake\Event\EventManager|null $eventManager The event manager. Defaults to a new instance. */ public function __construct(Request $request = null, Response $response = null, $name = null, $eventManager = null) { if ($this->name === null && $name === null) { list(, $name) = namespaceSplit(get_class($this)); $name = substr($name, 0, -10); } if ($name !== null) { $this->name = $name; } if (!$this->viewPath) { $viewPath = $this->name; if (isset($request->params['prefix'])) { $prefixes = array_map('Cake\\Utility\\Inflector::camelize', explode('/', $request->params['prefix'])); $viewPath = implode(DS, $prefixes) . DS . $viewPath; } $this->viewPath = $viewPath; } if (!$request instanceof Request) { $request = new Request(); } $this->setRequest($request); if (!$response instanceof Response) { $response = new Response(); } $this->response = $response; if ($eventManager) { $this->eventManager($eventManager); } $this->modelFactory('Table', ['Cake\\ORM\\TableRegistry', 'get']); $modelClass = ($this->plugin ? $this->plugin . '.' : '') . $this->name; $this->_setModelClass($modelClass); $this->initialize(); $this->_mergeControllerVars(); $this->_loadComponents(); $this->eventManager()->on($this); }
/** * Append matching tasks in $path to the $tasks array. * * @param array $tasks The task list to modify and return. * @param string $path The base path to look in. * @param string $namespace The base namespace. * @param string|null $prefix The prefix to append. * @return array Updated tasks. */ protected function _findTasks($tasks, $path, $namespace, $prefix = null) { $path .= 'Shell/Task'; if (!is_dir($path)) { return $tasks; } $candidates = $this->_findClassFiles($path, $namespace); $classes = $this->_findTaskClasses($candidates); foreach ($classes as $class) { list(, $name) = namespaceSplit($class); $name = substr($name, 0, -4); $fullName = ($prefix ? $prefix . '.' : '') . $name; $tasks[$name] = $fullName; } return $tasks; }
/** * Get method name * * @param Exception $exception Exception instance. * @return string */ protected function _method(Exception $exception) { $exception = $this->_unwrap($exception); list(, $baseClass) = namespaceSplit(get_class($exception)); if (substr($baseClass, -9) === 'Exception') { $baseClass = substr($baseClass, 0, -9); } $method = Inflector::variable($baseClass) ?: 'error500'; return $this->method = $method; }
/** * Get method name * * @param \Exception $exception Exception instance. * @return string */ protected function _method(\Exception $exception) { list(, $baseClass) = namespaceSplit(get_class($exception)); $baseClass = substr($baseClass, 0, -9); $method = Inflector::variable($baseClass) ?: 'error500'; return $this->method = $method; }
/** * Returns the type name name or sets a new one * * @param string $name the new type name * @return string */ public function name($name = null) { if ($name !== null) { $this->_name = $name; } if ($this->_name === null) { $name = namespaceSplit(get_class($this)); $name = substr(end($name), 0, -4); if (empty($name)) { $name = '*'; } $this->_name = Inflector::underscore($name); } return $this->_name; }
/** * Extract the id from the theme class name. * * @return string */ protected function _extractId() { list(, $className) = namespaceSplit(get_class($this)); $id = explode('Theme', $className)[0]; if (!$className || !$id) { user_error(__d('wasabi_cms', 'The theme class {0} has an invalid name. The name has to end with "Theme".', $className)); } return $id; }
/** * Return current table in camelCase form. * It adds plugin name as a prefix. * * @return string Table Name along with its prefix if found. */ protected function _currentTable() { list($namespace, $alias) = namespaceSplit(get_class($this)); $alias = substr($alias, 0, -5); list($plugin) = explode('\\', $namespace); if ($plugin === 'App') { return Inflector::camelize($alias); } return Inflector::camelize($plugin . '.' . $alias); }
/** * Tests that the `driver` option supports the short classname/plugin syntax. * * @return void */ public function testDriverOptionClassNameSupport() { $connection = new Connection(['driver' => 'TestDriver']); $this->assertInstanceOf('\\TestApp\\Database\\Driver\\TestDriver', $connection->driver()); $connection = new Connection(['driver' => 'TestPlugin.TestDriver']); $this->assertInstanceOf('\\TestPlugin\\Database\\Driver\\TestDriver', $connection->driver()); list(, $name) = namespaceSplit(get_class($this->connection->driver())); $connection = new Connection(['driver' => $name]); $this->assertInstanceOf(get_class($this->connection->driver()), $connection->driver()); }
/** * Returns an array of information of this field. Valid options are: * * - `type` (string): Type of data this field stores, possible values are: * datetime, decimal, int, text, varchar. * * - `name` (string): Human readable name of this field. ex. `Selectbox` * Defaults to class name. * * - `description` (string): Something about what this field does or allows * to do. Defaults to class name. * * - `hidden` (bool): If set to false users can not use this field via * Field UI. Defaults to true, users can use it via Field UI. * * - `maxInstances` (int): Maximum number instances of this field a table * can have. Set to 0 to indicates no limits. Defaults to 0. * * - `searchable` (bool): Whether this field can be searched using WHERE * clauses. * * @return array */ public function info() { list(, $handlerName) = namespaceSplit(get_class($this)); return ['type' => 'varchar', 'name' => (string) $handlerName, 'description' => (string) $handlerName, 'hidden' => false, 'maxInstances' => 0, 'searchable' => true]; }
/** * Returns associations for controllers models. * * @param Table $model The model to build associations for. * @return array associations */ protected function _associations(Table $model) { $keys = ['BelongsTo', 'HasOne', 'HasMany', 'BelongsToMany']; $associations = []; foreach ($keys as $type) { foreach ($model->associations()->type($type) as $assoc) { $target = $assoc->target(); $assocName = $assoc->name(); $alias = $target->alias(); $targetClass = get_class($target); list(, $className) = namespaceSplit($targetClass); $modelClass = get_class($model); if ($modelClass !== 'Cake\\ORM\\Table' && $targetClass === $modelClass) { continue; } $className = preg_replace('/(.*)Table$/', '\\1', $className); if ($className === '') { $className = $alias; } $associations[$type][$assocName] = ['property' => $assoc->property(), 'variable' => Inflector::variable($assocName), 'primaryKey' => (array) $target->primaryKey(), 'displayField' => $target->displayField(), 'foreignKey' => $assoc->foreignKey(), 'alias' => $alias, 'controller' => $className, 'fields' => $target->schema()->columns()]; } } return $associations; }
/** * Magic __toString() method to get the CacheEngine's name * * @return string Returns the CacheEngine's name */ public function __toString() { if (!empty($this->_engine)) { list($ns, $class) = namespaceSplit(get_class($this->_engine)); return str_replace('Engine', '', $class); } return $this->_config['className']; }
/** * test namespaceSplit * * @return void */ public function testNamespaceSplit() { $result = namespaceSplit('Something'); $this->assertEquals(['', 'Something'], $result); $result = namespaceSplit('\\Something'); $this->assertEquals(['', 'Something'], $result); $result = namespaceSplit('Cake\\Something'); $this->assertEquals(['Cake', 'Something'], $result); $result = namespaceSplit('Cake\\Test\\Something'); $this->assertEquals(['Cake\\Test', 'Something'], $result); }
/** * Generate a constructor code snippet for the type and class name * * @param string $type The Type of object you are generating tests for eg. controller * @param string $fullClassName The full classname of the class the test is being generated for. * @return array Constructor snippets for the thing you are building. */ public function generateConstructor($type, $fullClassName) { list(, $className) = namespaceSplit($fullClassName); $type = strtolower($type); $pre = $construct = $post = ''; if ($type === 'table') { $className = str_replace('Table', '', $className); $pre = "\$config = TableRegistry::exists('{$className}') ? [] : ['className' => '{$fullClassName}'];"; $construct = "TableRegistry::get('{$className}', \$config);"; } if ($type === 'behavior' || $type === 'entity' || $type === 'form') { $construct = "new {$className}();"; } if ($type === 'helper') { $pre = "\$view = new View();"; $construct = "new {$className}(\$view);"; } if ($type === 'component') { $pre = "\$registry = new ComponentRegistry();"; $construct = "new {$className}(\$registry);"; } if ($type === 'shell') { $pre = "\$this->io = \$this->getMock('Cake\\Console\\ConsoleIo');"; $construct = "new {$className}(\$this->io);"; } if ($type === 'cell') { $pre = "\$this->request = \$this->getMock('Cake\\Network\\Request');\n"; $pre .= " \$this->response = \$this->getMock('Cake\\Network\\Response');"; $construct = "new {$className}(\$this->request, \$this->response);"; } return [$pre, $construct, $post]; }
/** * Returns the endpoint name or sets a new one * * @param string|null $endpoint the new endpoint name * @return string */ public function endpoint($endpoint = null) { if ($endpoint !== null) { $this->_endpoint = $endpoint; } if ($this->_endpoint === null) { $endpoint = namespaceSplit(get_class($this)); $endpoint = substr(end($endpoint), 0, -8); // In case someone constructs the Endpoint class directly if (empty($endpoint)) { $endpoint = $this->alias(); } $this->_endpoint = Inflector::underscore($endpoint); } return $this->_endpoint; }
/** * Constructor. * * Sets a number of properties based on conventions if they are empty. To override the * conventions CakePHP uses you can define properties in your class declaration. * * @param \Cake\Network\Request|null $request Request object for this controller. Can be null for testing, * but expect that features that use the request parameters will not work. * @param \Cake\Network\Response|null $response Response object for this controller. * @param string|null $name Override the name useful in testing when using mocks. * @param \Cake\Event\EventManager|null $eventManager The event manager. Defaults to a new instance. * @param \Cake\Controller\ComponentRegistry|null $components The component registry. Defaults to a new instance. */ public function __construct(Request $request = null, Response $response = null, $name = null, $eventManager = null, $components = null) { if ($name !== null) { $this->name = $name; } if ($this->name === null && isset($request->params['controller'])) { $this->name = $request->params['controller']; } if ($this->name === null) { list(, $name) = namespaceSplit(get_class($this)); $this->name = substr($name, 0, -10); } $this->setRequest($request !== null ? $request : new Request()); $this->response = $response !== null ? $response : new Response(); if ($eventManager !== null) { $this->eventManager($eventManager); } $this->modelFactory('Table', [$this->tableLocator(), 'get']); $modelClass = ($this->plugin ? $this->plugin . '.' : '') . $this->name; $this->_setModelClass($modelClass); if ($components !== null) { $this->components($components); } $this->initialize(); $this->_mergeControllerVars(); $this->_loadComponents(); $this->eventManager()->on($this); }
/** * Gets the name of the class driver used by the given $query to access the DB. * * @param \Cake\ORM\Query $query The query to inspect * @return string Lowercased drive name. e.g. `mysql` */ protected function _driverClass(Query $query) { $conn = $query->connection(null); list(, $driverClass) = namespaceSplit(strtolower(get_class($conn->driver()))); return $driverClass; }
/** * {@inheritDoc} */ public function alias($alias = null) { if ($alias !== null) { $this->_alias = $alias; } if ($this->_alias === null) { $alias = namespaceSplit(get_class($this)); $alias = substr(end($alias), 0, -5) ?: $this->_table; $this->_alias = $alias; } return $this->_alias; }
/** * Get an array of associations matching a specific type. * * @param string|array $class The type of associations you want. * For example 'BelongsTo' or array like ['BelongsTo', 'HasOne'] * @return array An array of Association objects. */ public function type($class) { $class = array_map('strtolower', (array) $class); $out = array_filter($this->_items, function ($assoc) use($class) { list(, $name) = namespaceSplit(get_class($assoc)); return in_array(strtolower($name), $class, true); }); return array_values($out); }
/** * Initialize the fixture. * * @return void * @throws \Cake\ORM\Exception\MissingTableClassException When importing from a table that does not exist. */ public function init() { if ($this->table === null) { list(, $class) = namespaceSplit(get_class($this)); preg_match('/^(.*)Fixture$/', $class, $matches); $table = $class; if (isset($matches[1])) { $table = $matches[1]; } $this->table = Inflector::tableize($table); } if (empty($this->import) && !empty($this->fields)) { $this->_schemaFromFields(); } if (!empty($this->import)) { $this->_schemaFromImport(); } }
/** * Determine the reference name to use for a given table * * The reference name is usually derived from the class name of the table object * (PostsTable -> Posts), however for autotable instances it is derived from * the database table the object points at - or as a last resort, the alias * of the autotable instance. * * @param \Cake\ORM\Table $table The table class to get a reference name for. * @return string */ protected function _referenceName(Table $table) { $name = namespaceSplit(get_class($table)); $name = substr(end($name), 0, -5); if (empty($name)) { $name = $table->table() ?: $table->alias(); $name = Inflector::camelize($name); } return $name; }
/** * Constructs this Shell instance. * * @param \Cake\Console\ConsoleIo $io An io instance. * @link http://book.cakephp.org/3.0/en/console-and-shells.html#Shell */ public function __construct(ConsoleIo $io = null) { if (!$this->name) { list(, $class) = namespaceSplit(get_class($this)); $this->name = str_replace(['Shell', 'Task'], '', $class); } $this->_io = $io ?: new ConsoleIo(); $locator = $this->tableLocator() ?: 'Cake\\ORM\\TableRegistry'; $this->modelFactory('Table', [$locator, 'get']); $this->Tasks = new TaskRegistry($this); $this->_mergeVars(['tasks'], ['associative' => ['tasks']]); $this->_io->setLoggers(true); if (isset($this->modelClass)) { $this->loadModel(); } }
/** * Returns the table name using the fixture class * * @return string */ protected function _tableFromClass() { list(, $class) = namespaceSplit(get_class($this)); preg_match('/^(.*)Fixture$/', $class, $matches); $table = $class; if (isset($matches[1])) { $table = $matches[1]; } return Inflector::tableize($table); }