schema() public method

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 schema ( array | Cake\Database\Schema\Table | null $schema = null ) : Cake\Database\Schema\Table
$schema array | Cake\Database\Schema\Table | null New schema to be used for this table
return Cake\Database\Schema\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"));
 }
Example #2
0
 /**
  * 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));
     }
 }
Example #5
0
 /**
  * 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;
 }
Example #6
0
 /**
  * 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;
 }
Example #8
0
 /**
  * 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);
     }
 }
Example #9
0
 /**
  * {@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;
 }
Example #12
0
 /**
  * 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.');
             }
         }
     }
 }
Example #14
0
 /**
  * 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;
 }
Example #15
0
 /**
  * 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;
 }
Example #18
0
 /**
  * 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;
 }
Example #19
0
 /**
  * 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;
 }
Example #20
0
 /**
  * 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));
 }
Example #21
0
 /**
  * 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)));
 }
Example #22
0
 /**
  * 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;
 }
Example #23
0
 /**
  * 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);
 }
Example #24
0
 /**
  * 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;
 }
Example #25
0
 /**
  * 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;
 }
Example #27
0
 /**
  * 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());
 }