If an \Cake\Database\Schema\Table is passed, it will be used for this table
instead of the default one.
If an array is passed, a new \Cake\Database\Schema\Table will be constructed
out of it and used as the schema for this table.
public function testDeteccaoAutomatica() { $this->Noticias->addBehavior("CakePtbr.AjusteData"); $noticia = $this->__preparaNoticia(); $this->assertEquals("datetime", $this->Noticias->schema()->columnType("publicado_em")); $this->assertEquals("2015-03-22", $noticia->get("autorizado_em")); $this->assertEquals("2015-03-25 16:42:05", $noticia->get("publicado_em")); }
/** * Merges `$data` into `$entity` and recursively does the same for each one of * the association names passed in `$include`. When merging associations, if an * entity is not present in the parent entity for a given association, a new one * will be created. * * When merging HasMany or BelongsToMany associations, all the entities in the * `$data` array will appear, those that can be matched by primary key will get * the data merged, but those that cannot, will be discarded. * * @param \Cake\Datasource\EntityInterface $entity the entity that will get the * data merged in * @param array $data key value list of fields to be merged into the entity * @param array $include The list of associations to be merged * @return \Cake\Datasource\EntityInterface */ public function merge(EntityInterface $entity, array $data, array $include = []) { $propertyMap = $this->_buildPropertyMap($include); $tableName = $this->_table->alias(); if (isset($data[$tableName])) { $data = $data[$tableName]; } $schema = $this->_table->schema(); $properties = []; foreach ($data as $key => $value) { $columnType = $schema->columnType($key); $original = $entity->get($key); if (isset($propertyMap[$key])) { $assoc = $propertyMap[$key]['association']; $nested = $propertyMap[$key]['nested']; $value = $this->_mergeAssociation($original, $assoc, $value, $nested); } elseif ($columnType) { $converter = Type::build($columnType); $value = $converter->marshal($value); if ($original == $value) { continue; } } $properties[$key] = $value; } $entity->set($properties); return $entity; }
/** * Move a node under the same parent node or under a new node. * New position of the node can be specified * * @param int $id ID of the node to move * @param int $parent_id ID of the (new) parent node * @param int $position New position of the node. Position is zero based. * @return boolean */ public function moveNode($id, $parent_id, $position = null) { $primaryKey = $this->_table->schema()->primaryKey(); $primaryKey = count($primaryKey) == 1 ? $primaryKey[0] : $primaryKey; $parent_id_fieldname = $this->config('model_parent_id_fieldname'); $sort_fieldname = $this->config('model_sort_fieldname'); $connection = $this->_table->connection(); $connection->begin(); $result = true; /* * Get moved node */ $node = $this->_table->get($id); /* * Get current nodes positions of (new) siblings */ $current_children = $this->_table->query()->where([$parent_id_fieldname => $parent_id])->order([$sort_fieldname => 'asc']); $new_sort_children = []; foreach ($current_children as $current_position => $current_child) { if ($current_child->{$primaryKey} != $id) { $new_sort_children[] = $current_child; } } /* * Default position is after all siblings */ $position = isset($position) ? $position : $current_children->count(); $position = $position >= 0 ? $position : 0; $position = $position <= count($new_sort_children) ? $position : count($new_sort_children); /* * Insert moved node at position */ array_splice($new_sort_children, $position, 0, array($node)); /* * If node has a new parent -> save it */ if ($node->{$parent_id_fieldname} != $parent_id) { $query = $this->_table->query()->update()->set([$parent_id_fieldname => $parent_id])->where([$primaryKey => $id]); if (!$query->execute()) { $result = false; } } /* * Update positions */ foreach ($new_sort_children as $index => $new_sort_child) { $query = $this->_table->query()->update()->set([$sort_fieldname => $index * 10])->where([$primaryKey => $new_sort_child->{$primaryKey}]); if (!$query->execute()) { $result = false; } } /***********/ if ($result) { $connection->commit(); } else { $connection->rollback(); } return $result; }
/** * Checks that the given instance's slug do not collide with table's real column * names. * * If collision occurs, an error message will be registered on the given entity. * * @param \Field\Model\Entity\FieldInstance $instance Instance to validate * @return void */ protected function _validateSlug($instance) { $slug = $instance->get('eav_attribute')->get('name'); $columns = $this->_table->schema()->columns(); if (in_array($slug, $columns)) { $instance->get('eav_attribute')->errors('name', __d('field', 'The name "{0}" cannot be used as it collides with table column names.', $slug)); } }
/** * Merges `$data` into `$entity` and recursively does the same for each one of * the association names passed in `$options`. When merging associations, if an * entity is not present in the parent entity for a given association, a new one * will be created. * * When merging HasMany or BelongsToMany associations, all the entities in the * `$data` array will appear, those that can be matched by primary key will get * the data merged, but those that cannot, will be discarded. `ids` option can be used * to determine whether the association must use the `_ids` format. * * ### Options: * * * associated: Associations listed here will be marshalled as well. * * validate: Whether or not to validate data before hydrating the entities. Can * also be set to a string to use a specific validator. Defaults to true/default. * * fieldList: A whitelist of fields to be assigned to the entity. If not present * the accessible fields list in the entity will be used. * * accessibleFields: A list of fields to allow or deny in entity accessible fields. * * The above options can be used in each nested `associated` array. In addition to the above * options you can also use the `onlyIds` option for HasMany and BelongsToMany associations. * When true this option restricts the request data to only be read from `_ids`. * * ``` * $result = $marshaller->merge($entity, $data, [ * 'associated' => ['Tags' => ['onlyIds' => true]] * ]); * ``` * * @param \Cake\Datasource\EntityInterface $entity the entity that will get the * data merged in * @param array $data key value list of fields to be merged into the entity * @param array $options List of options. * @return \Cake\Datasource\EntityInterface */ public function merge(EntityInterface $entity, array $data, array $options = []) { list($data, $options) = $this->_prepareDataAndOptions($data, $options); $propertyMap = $this->_buildPropertyMap($options); $isNew = $entity->isNew(); $keys = []; if (!$isNew) { $keys = $entity->extract((array) $this->_table->primaryKey()); } if (isset($options['accessibleFields'])) { foreach ((array) $options['accessibleFields'] as $key => $value) { $entity->accessible($key, $value); } } $errors = $this->_validate($data + $keys, $options, $isNew); $schema = $this->_table->schema(); $properties = $marshalledAssocs = []; foreach ($data as $key => $value) { if (!empty($errors[$key])) { continue; } $columnType = $schema->columnType($key); $original = $entity->get($key); if (isset($propertyMap[$key])) { $assoc = $propertyMap[$key]['association']; $value = $this->_mergeAssociation($original, $assoc, $value, $propertyMap[$key]); $marshalledAssocs[$key] = true; } elseif ($columnType) { $converter = Type::build($columnType); $value = $converter->marshal($value); $isObject = is_object($value); if (!$isObject && $original === $value || $isObject && $original == $value) { continue; } } $properties[$key] = $value; } if (!isset($options['fieldList'])) { $entity->set($properties); $entity->errors($errors); foreach (array_keys($marshalledAssocs) as $field) { if ($properties[$field] instanceof EntityInterface) { $entity->dirty($field, $properties[$field]->dirty()); } } return $entity; } foreach ((array) $options['fieldList'] as $field) { if (array_key_exists($field, $properties)) { $entity->set($field, $properties[$field]); if ($properties[$field] instanceof EntityInterface && isset($marshalledAssocs[$field])) { $entity->dirty($field, $properties[$field]->dirty()); } } } $entity->errors($errors); return $entity; }
/** * Merges `$data` into `$entity` and recursively does the same for each one of * the association names passed in `$options`. When merging associations, if an * entity is not present in the parent entity for a given association, a new one * will be created. * * When merging HasMany or BelongsToMany associations, all the entities in the * `$data` array will appear, those that can be matched by primary key will get * the data merged, but those that cannot, will be discarded. `ids` option can be used * to determine whether the association must use the `_ids` format. * * ### Options: * * - associated: Associations listed here will be marshalled as well. * - validate: Whether or not to validate data before hydrating the entities. Can * also be set to a string to use a specific validator. Defaults to true/default. * - fieldList: A whitelist of fields to be assigned to the entity. If not present * the accessible fields list in the entity will be used. * - accessibleFields: A list of fields to allow or deny in entity accessible fields. * * The above options can be used in each nested `associated` array. In addition to the above * options you can also use the `onlyIds` option for HasMany and BelongsToMany associations. * When true this option restricts the request data to only be read from `_ids`. * * ``` * $result = $marshaller->merge($entity, $data, [ * 'associated' => ['Tags' => ['onlyIds' => true]] * ]); * ``` * * @param \Cake\Datasource\EntityInterface $entity the entity that will get the * data merged in * @param array $data key value list of fields to be merged into the entity * @param array $options List of options. * @return \Cake\Datasource\EntityInterface */ public function merge(EntityInterface $entity, array $data, array $options = []) { list($data, $options) = $this->_prepareDataAndOptions($data, $options); $isNew = $entity->isNew(); $keys = []; if (!$isNew) { $keys = $entity->extract((array) $this->_table->primaryKey()); } if (isset($options['accessibleFields'])) { foreach ((array) $options['accessibleFields'] as $key => $value) { $entity->accessible($key, $value); } } $errors = $this->_validate($data + $keys, $options, $isNew); $schema = $this->_table->schema(); $options['isMerge'] = true; $propertyMap = $this->_buildPropertyMap($data, $options); $properties = $marshalledAssocs = []; foreach ($data as $key => $value) { if (!empty($errors[$key])) { if ($entity instanceof InvalidPropertyInterface) { $entity->invalid($key, $value); } continue; } $original = $entity->get($key); if (isset($propertyMap[$key])) { $value = $propertyMap[$key]($value, $entity); // Don't dirty scalar values and objects that didn't // change. Arrays will always be marked as dirty because // the original/updated list could contain references to the // same objects, even though those objects may have changed internally. if (is_scalar($value) && $original === $value || $value === null && $original === $value || is_object($value) && !$value instanceof EntityInterface && $original == $value) { continue; } } $properties[$key] = $value; } $entity->errors($errors); if (!isset($options['fieldList'])) { $entity->set($properties); foreach ($properties as $field => $value) { if ($value instanceof EntityInterface) { $entity->dirty($field, $value->dirty()); } } return $entity; } foreach ((array) $options['fieldList'] as $field) { if (array_key_exists($field, $properties)) { $entity->set($field, $properties[$field]); if ($properties[$field] instanceof EntityInterface) { $entity->dirty($field, $properties[$field]->dirty()); } } } return $entity; }
/** * Returns an array of fields to be versioned. * * @return array */ protected function _fields() { $schema = $this->_table->schema(); $fields = $schema->columns(); if ($this->_config['fields'] !== null) { $fields = array_intersect($fields, (array) $this->_config['fields']); } return $fields; }
/** * Initial Tree * * - One * -- One-SubA * - Two * -- Two-SubA * --- Two-SubA-1 * ---- Two-SubA-1-1 * - Three * - Four * -- Four-SubA * * @return void */ public function setUp() { parent::setUp(); $this->Tree = new TreeHelper(new View(null)); $this->Table = TableRegistry::get('AfterTrees'); $this->Table->addBehavior('Tree'); //$this->Table->truncate(); $connection = ConnectionManager::get('test'); $sql = $this->Table->schema()->truncateSql($connection); foreach ($sql as $snippet) { $connection->execute($snippet); } //$this->Table->deleteAll(array()); $data = [['name' => 'One'], ['name' => 'Two'], ['name' => 'Three'], ['name' => 'Four'], ['name' => 'One-SubA', 'parent_id' => 1], ['name' => 'Two-SubA', 'parent_id' => 2], ['name' => 'Four-SubA', 'parent_id' => 4], ['name' => 'Two-SubA-1', 'parent_id' => 6], ['name' => 'Two-SubA-1-1', 'parent_id' => 8]]; foreach ($data as $row) { $row = new Entity($row); $this->Table->save($row); } }
/** * {@inheritDoc} * * Look for virtual columns in query's WHERE clause. * * @param \Cake\ORM\Query $query The query to scope * @param string|null $bundle Consider attributes only for a specific bundle * @return \Cake\ORM\Query The modified query object */ public function scope(Query $query, $bundle = null) { $orderClause = $query->clause('order'); if (!$orderClause) { return $query; } $class = new \ReflectionClass($orderClause); $property = $class->getProperty('_conditions'); $property->setAccessible(true); $conditions = $property->getValue($orderClause); foreach ($conditions as $column => $direction) { if (empty($column) || in_array($column, (array) $this->_table->schema()->columns()) || !in_array($column, $this->_toolbox->getAttributeNames())) { continue; } $conditions['(' . $this->_subQuery($column, $bundle) . ')'] = $direction; unset($conditions[$column]); } $property->setValue($orderClause, $conditions); return $query; }
/** * testBeforeFind * * @return void * @access public */ public function testBeforeFind() { $condicoes = ['nome' => '1.000,00', 'valor' => '1.500,03']; $consulta = $this->Produtos->find('all')->where($condicoes); $consulta->all(); $condicoesTratadas = []; $todosCampos = []; /** * @var Query $consulta */ $consulta->clause("where")->traverse(function ($comparison) use(&$condicoesTratadas, &$todosCampos) { /** * @var Comparison $comparison */ if (isset($comparison)) { if ($this->Produtos->schema()->columnType($comparison->getField()) === "float") { $condicoesTratadas[$comparison->getField()] = $comparison->getValue(); } $todosCampos[$comparison->getField()] = $comparison->getValue(); } }); $this->assertEquals("1.000,00", $todosCampos["nome"]); $this->assertEquals("1500.03", $condicoesTratadas["valor"]); }
/** * @param \ArrayObject $data * @param \Cake\ORM\Table $table * @return \ArrayObject */ protected function _process($data, Table $table) { $associations = []; /* @var \Cake\ORM\Association $association */ foreach ($table->associations() as $association) { $associations[$association->property()] = $association->name(); } foreach ($data as $key => $value) { if (array_key_exists($key, $associations)) { $data[$key] = $this->_process($data[$key], $table->association($associations[$key])->target()); continue; } $nullable = Hash::get((array) $table->schema()->column($key), 'null'); if ($nullable !== true) { continue; } if ($value !== '') { continue; } $default = Hash::get((array) $table->schema()->column($key), 'default'); $data[$key] = $default; } return $data; }
/** * Constructor * * Merges config with the default and store in the config property * * @param \Cake\ORM\Table $table The table this behavior is attached to. * @param array $config The config for this behavior. */ public function __construct(Table $table, array $config = []) { $columns = $table->schema()->columns(); foreach (['deleted', 'trashed'] as $name) { if (in_array($name, $columns, true)) { $this->_defaultConfig['field'] = $name; break; } } if (empty($this->_defaultConfig['field']) && ($field = Configure::read('Muffin/Trash.field'))) { $this->_defaultConfig['field'] = $field; } parent::__construct($table, $config); if (!empty($config['events'])) { $this->config('events', $config['events'], false); } }
/** * Constructor hook method. * * Implement this method to avoid having to overwrite * the constructor and call parent. * * @param array $config The configuration array this behavior is using. * @return void */ public function initialize(array $config) { if ($this->_config['length'] === null) { $length = $this->_table->schema()->column($this->_config['field'])['length']; $this->_config['length'] = $length ?: 0; } $label = $this->_config['label'] = (array) $this->_config['label']; if ($this->_table->behaviors()->has('Translate')) { $this->_config['length'] = false; } if ($this->_config['length']) { foreach ($label as $field) { $alias = $this->_table->alias(); if (strpos($field, '.')) { list($alias, $field) = explode('.', $field); if (!$this->_table->{$alias}->hasField($field)) { throw new Exception('(SluggedBehavior::setup) model ' . $this->_table->{$alias}->name . ' is missing the field ' . $field . ' (specified in the setup for model ' . $this->_table->name . ') '); } } elseif (!$this->_table->hasField($field) && !method_exists($this->_table->entityClass(), '_get' . Inflector::classify($field))) { throw new Exception('(SluggedBehavior::setup) model ' . $this->_table->name . ' is missing the field ' . $field . ' specified in the setup.'); } } } }
/** * Merges `$data` into `$entity` and recursively does the same for each one of * the association names passed in `$options`. When merging associations, if an * entity is not present in the parent entity for a given association, a new one * will be created. * * When merging HasMany or BelongsToMany associations, all the entities in the * `$data` array will appear, those that can be matched by primary key will get * the data merged, but those that cannot, will be discarded. * * ### Options: * * * associated: Associations listed here will be marshalled as well. * * fieldList: A whitelist of fields to be assigned to the entity. If not present * the accessible fields list in the entity will be used. * * @param \Cake\Datasource\EntityInterface $entity the entity that will get the * data merged in * @param array $data key value list of fields to be merged into the entity * @param array $options List of options. * @return \Cake\Datasource\EntityInterface */ public function merge(EntityInterface $entity, array $data, array $options = []) { $propertyMap = $this->_buildPropertyMap($options); $tableName = $this->_table->alias(); if (isset($data[$tableName])) { $data = $data[$tableName]; } $schema = $this->_table->schema(); $properties = []; foreach ($data as $key => $value) { $columnType = $schema->columnType($key); $original = $entity->get($key); if (isset($propertyMap[$key])) { $assoc = $propertyMap[$key]['association']; $value = $this->_mergeAssociation($original, $assoc, $value, $propertyMap[$key]); } elseif ($columnType) { $converter = Type::build($columnType); $value = $converter->marshal($value); $isObject = is_object($value); if (!$isObject && $original === $value || $isObject && $original == $value) { continue; } } $properties[$key] = $value; } if (!isset($options['fieldList'])) { $entity->set($properties); return $entity; } foreach ((array) $options['fieldList'] as $field) { if (isset($properties[$field])) { $entity->set($field, $properties[$field]); } } return $entity; }
/** * Analyzes the given unary expression and alters it according. * * @param \Cake\Database\Expression\UnaryExpression $expression Unary expression * @param string $bundle Consider attributes only for a specific bundle * @param \Cake\ORM\Query $query The query instance this expression comes from * @return \Cake\Database\Expression\UnaryExpression Scoped expression (or not) */ protected function _inspectUnaryExpression(UnaryExpression $expression, $bundle, Query $query) { $class = new \ReflectionClass($expression); $property = $class->getProperty('_value'); $property->setAccessible(true); $value = $property->getValue($expression); if ($value instanceof IdentifierExpression) { $field = $value->getIdentifier(); $column = is_string($field) ? $this->_toolbox->columnName($field) : ''; if (empty($column) || in_array($column, (array) $this->_table->schema()->columns()) || !in_array($column, $this->_toolbox->getAttributeNames($bundle)) || !$this->_toolbox->isSearchable($column)) { // nothing to alter return $expression; } $pk = $this->_tablePrimaryKey(); $driverClass = $this->_driverClass($query); switch ($driverClass) { case 'sqlite': $concat = implode(' || ', $pk); $field = "({$concat} || '')"; break; case 'mysql': case 'postgres': case 'sqlserver': default: $concat = implode(', ', $pk); $field = "CONCAT({$concat}, '')"; break; } $attr = $this->_toolbox->attributes($bundle)[$column]; $type = $this->_toolbox->getType($column); $subQuery = TableRegistry::get('Eav.EavValues')->find()->select("EavValues.value_{$type}")->where(['EavValues.entity_id' => $field, 'EavValues.eav_attribute_id' => $attr['id']])->sql(); $subQuery = str_replace([':c0', ':c1'], [$field, $attr['id']], $subQuery); $property->setValue($expression, "({$subQuery})"); } return $expression; }
/** * Hints this object to associate the correct types when casting conditions * for the database. This is done by extracting the field types from the schema * associated to the passed table object. This prevents the user from repeating * himself when specifying conditions. * * This method returns the same query object for chaining. * * @param \Cake\ORM\Table $table The table to pull types from * @return $this */ public function addDefaultTypes(Table $table) { $alias = $table->alias(); $schema = $table->schema(); $fields = []; foreach ($schema->columns() as $f) { $fields[$f] = $fields[$alias . '.' . $f] = $schema->columnType($f); } $this->typeMap()->addDefaults($fields); return $this; }
/** * Helper method that clears all records from the provided Table instance. * * The default file is `config/seed.php`. When the `--dev` flag is * present, the default file changes to `config/seed_dev.php`. If * the `--file` option is present, it overrides everything else and * its value is used explicitly. * * @param Cake\ORM\Table $Table The Table instance to TRUNCATE. * @return bool True on success truncation, false on failure. */ protected function truncateTable($Table) { $truncateSql = $Table->schema()->truncateSql($Table->connection())[0]; $success = $Table->connection()->query($truncateSql); if ($success) { $this->verbose("<success>{$Table->alias()}: Existing DB records truncated.</success>"); } else { $this->quiet("<warning>{$Table->alias()}: Can not truncate existing records.</warning>"); } return $success; }
/** * Get behaviors * * @param \Cake\ORM\Table $model The model to generate behaviors for. * @return array Behaviors */ public function getBehaviors($model) { $behaviors = []; $schema = $model->schema(); $fields = $schema->columns(); if (empty($fields)) { return []; } if (in_array('created', $fields) || in_array('modified', $fields)) { $behaviors['Timestamp'] = []; } if (in_array('lft', $fields) && $schema->columnType('lft') === 'integer' && in_array('rght', $fields) && $schema->columnType('rght') === 'integer' && in_array('parent_id', $fields)) { $behaviors['Tree'] = []; } $counterCache = $this->getCounterCache($model); if (!empty($counterCache)) { $behaviors['CounterCache'] = $counterCache; } return $behaviors; }
/** * Casts all values from a row brought from a table to the correct * PHP type. * * @param Table $table The table object * @param array $values The values to cast * @return array */ protected function _castValues($table, $values) { $alias = $table->alias(); $driver = $this->_query->connection()->driver(); if (empty($this->types[$alias])) { $schema = $table->schema(); foreach ($schema->columns() as $col) { $this->types[$alias][$col] = Type::build($schema->columnType($col)); } } foreach ($values as $field => $value) { if (!isset($this->types[$alias][$field])) { continue; } $values[$field] = $this->types[$alias][$field]->toPHP($value, $driver); } return $values; }
/** * Get the fields from a model. * * Uses the fields and no-fields options. * * @param \Cake\ORM\Table $model The model to introspect. * @return array The columns to make accessible */ public function getFields($model) { if (!empty($this->params['no-fields'])) { return []; } if (!empty($this->params['fields'])) { $fields = explode(',', $this->params['fields']); return array_values(array_filter(array_map('trim', $fields))); } $schema = $model->schema(); $columns = $schema->columns(); $primary = $this->getPrimaryKey($model); $exclude = array_merge($primary, ['created', 'modified', 'updated']); /* $associations = $model->associations(); foreach ($associations->keys() as $assocName) { $columns[] = $associations->get($assocName)->property(); } */ return array_values(array_diff($columns, $exclude)); }
/** * Checks the nullable flag of the foreign key * * @param Table $table the table containing the foreign key * @param array $properties the list of fields that compose the foreign key * @return bool */ protected function _foreignKeyAcceptsNull(Table $table, array $properties) { return !in_array(false, array_map(function ($prop) use($table) { return $table->schema()->isNullable($prop); }, array_keys($properties))); }
/** * Hints this object to associate the correct types when casting conditions * for the database. This is done by extracting the field types from the schema * associated to the passed table object. This prevents the user from repeating * himself when specifying conditions. * * This method returns the same query object for chaining. * * @param \Cake\ORM\Table $table The table to pull types from * @return $this */ public function addDefaultTypes(Table $table) { $alias = $table->alias(); $map = $table->schema()->typeMap(); $fields = []; foreach ($map as $f => $type) { $fields[$f] = $fields[$alias . '.' . $f] = $type; } $this->typeMap()->addDefaults($fields); return $this; }
/** * Check whether or not the entity fields are nullable and null. * * @param \Cake\Datasource\EntityInterface $entity The entity to check. * @param \Cake\ORM\Table $source The table to use schema from. * @return bool */ protected function _fieldsAreNull($entity, $source) { $nulls = 0; $schema = $source->schema(); foreach ($this->_fields as $field) { if ($schema->column($field) && $schema->isNullable($field) && $entity->get($field) === null) { $nulls++; } } return $nulls === count($this->_fields); }
/** * Sets the property name that should be filled with data from the target table * in the source table record. * If no arguments are passed, the currently configured type is returned. * * @param string|null $name The name of the association property. Use null to read the current value. * @return string */ public function property($name = null) { if ($name !== null) { $this->_propertyName = $name; } if ($name === null && !$this->_propertyName) { $this->_propertyName = $this->_propertyName(); if (in_array($this->_propertyName, $this->_sourceTable->schema()->columns())) { $msg = 'Association property name "%s" clashes with field of same name of table "%s".' . ' You should explicitly specify the "propertyName" option.'; trigger_error(sprintf($msg, $this->_propertyName, $this->_sourceTable->table()), E_USER_WARNING); } } return $this->_propertyName; }
/** * Get behaviors * * @param \Cake\ORM\Table $model * @return array Behaviors */ public function getBehaviors($model) { $behaviors = []; $schema = $model->schema(); $fields = $schema->columns(); if (empty($fields)) { return []; } if (in_array('created', $fields) || in_array('modified', $fields)) { $behaviors['Timestamp'] = []; } if (in_array('lft', $fields) && $schema->columnType('lft') === 'integer' && in_array('rght', $fields) && $schema->columnType('rght') === 'integer' && in_array('parent_id', $fields)) { $behaviors['Tree'] = []; } $counterCache = []; foreach ($fields as $field) { if (strpos($field, '_count') === false) { continue; } list($name) = explode('_count', $field); $assoc = $this->_modelName($name); $counterCache[] = "'{$assoc}' => ['{$field}']"; } if (!empty($counterCache)) { $behaviors['CounterCache'] = $counterCache; } return $behaviors; }
/** * Returns the Type classes for each of the passed fields belonging to the * table. * * @param \Cake\ORM\Table $table The table from which to get the schema * @param array $fields The fields whitelist to use for fields in the schema. * @return array */ protected function _getTypes($table, $fields) { $types = []; $schema = $table->schema(); $map = array_keys(Type::map() + ['string' => 1, 'text' => 1, 'boolean' => 1]); $typeMap = array_combine($map, array_map(['Cake\\Database\\Type', 'build'], $map)); foreach (['string', 'text'] as $t) { if (get_class($typeMap[$t]) === 'Cake\\Database\\Type') { unset($typeMap[$t]); } } foreach (array_intersect($fields, $schema->columns()) as $col) { $typeName = $schema->columnType($col); if (isset($typeMap[$typeName])) { $types[$col] = $typeMap[$typeName]; } } return $types; }
/** * Tests schema method * * @return void */ public function testSchema() { $schema = $this->connection->schemaCollection()->describe('users'); $table = new Table(['table' => 'users', 'connection' => $this->connection]); $this->assertEquals($schema, $table->schema()); $table = new Table(['table' => 'stuff']); $table->schema($schema); $this->assertSame($schema, $table->schema()); $table = new Table(['table' => 'another']); $schema = ['id' => ['type' => 'integer']]; $table->schema($schema); $this->assertEquals(new \Cake\Database\Schema\Table('another', $schema), $table->schema()); }