/** * Generates a SQL sub-query for replacing in ORDER BY clause. * * @param string $column Name of the column being replaced by this sub-query * @param string|null $bundle Consider attributes only for a specific bundle * @return string SQL sub-query statement */ protected function _subQuery($column, $bundle = null) { $alias = $this->_table->alias(); $pk = $this->_table->primaryKey(); $type = $this->_toolbox->getType($column); $subConditions = ['EavAttribute.table_alias' => $this->_table->table(), 'EavValues.entity_id' => "{$alias}.{$pk}", 'EavAttribute.name' => $column]; if (!empty($bundle)) { $subConditions['EavAttribute.bundle'] = $bundle; } $subQuery = TableRegistry::get('Eav.EavValues')->find()->contain(['EavAttribute'])->select(["EavValues.value_{$type}"])->where($subConditions)->sql(); return str_replace([':c0', ':c1', ':c2', ':c3'], ['"' . $this->_table->table() . '"', "{$alias}.{$pk}", '"' . $column . '"', '"' . $bundle . '"'], $subQuery); }
/** * Load a table, get it's config and then regenerate the thumbnails for that tables upload fields. * * @param string $table The name of the table * @return void */ public function generate($table) { $this->checkTable($table); $config = $this->Table->behaviors()->Proffer->config(); foreach ($config as $field => $settings) { $records = $this->{$this->Table->alias()}->find()->select([$this->Table->primaryKey(), $field, $settings['dir']])->where(["{$field} IS NOT NULL", "{$field} != ''"]); foreach ($records as $item) { if ($this->param('verbose')) { $this->out(__('Processing ' . $this->Table->alias() . ' ' . $item->get($this->Table->primaryKey()))); } if (!empty($this->param('path-class'))) { $class = (string) $this->param('path-class'); $path = new $class($this->Table, $item, $field, $settings); } else { $path = new ProfferPath($this->Table, $item, $field, $settings); } if (!empty($this->param('image-class'))) { $class = (string) $this->param('image_class'); $transform = new $class($this->Table, $path); } else { $transform = new ImageTransform($this->Table, $path); } $transform->processThumbnails($settings); if ($this->param('verbose')) { $this->out(__('Thumbnails regenerated for ' . $path->fullPath())); } else { $this->out(__('Thumbnails regenerated for ' . $this->Table->alias() . ' ' . $item->get($field))); } } } $this->out($this->nl(0)); $this->out(__('<info>Completed</info>')); }
/** * Returns the basepath for the current field/data combination. * If a `path` is specified in settings, then that will be used as * the replacement pattern * * @return string * @throws LogicException if a replacement is not valid for the current dataset */ public function basepath() { $defaultPath = 'webroot{DS}files{DS}{model}{DS}{field}{DS}'; $path = Hash::get($this->settings, 'path', $defaultPath); if (strpos($path, '{primaryKey}') !== false) { if ($this->entity->isNew()) { throw new LogicException('{primaryKey} substitution not allowed for new entities'); } if (is_array($this->table->primaryKey())) { throw new LogicException('{primaryKey} substitution not valid for composite primary keys'); } } $replacements = ['{primaryKey}' => $this->entity->get($this->table->primaryKey()), '{model}' => $this->table->alias(), '{relatedModel}' => $this->entity->model, '{table}' => $this->table->table(), '{field}' => $this->field, '{time}' => time(), '{microtime}' => microtime(), '{DS}' => DIRECTORY_SEPARATOR]; return str_replace(array_keys($replacements), array_values($replacements), $path); }
/** * ResetSlugs method. * * Regenerate all slugs. On large dbs this can take more than 30 seconds - a time * limit is set to allow a minimum 100 updates per second as a preventative measure. * * Note that you should use the Reset behavior if you need additional functionality such * as callbacks or timeouts. * * @param array $params * @return bool Success */ public function resetSlugs($params = []) { if (!$this->_table->hasField($this->_config['field'])) { throw new Exception('Table does not have field ' . $this->_config['field']); } $defaults = ['page' => 1, 'limit' => 100, 'fields' => array_merge([$this->_table->primaryKey()], $this->_config['label']), 'order' => $this->_table->displayField() . ' ASC', 'conditions' => $this->_config['scope'], 'overwrite' => true]; $params = array_merge($defaults, $params); $count = $this->_table->find('all', compact('conditions'))->count(); $max = ini_get('max_execution_time'); if ($max) { set_time_limit(max($max, $count / 100)); } $this->_table->behaviors()->Slugged->config($params, null, false); while ($records = $this->_table->find('all', $params)->toArray()) { foreach ($records as $record) { $record->isNew(true); $options = ['validate' => true, 'fieldList' => array_merge([$this->_table->primaryKey(), $this->_config['field']], $this->_config['label'])]; if (!$this->_table->save($record, $options)) { throw new Exception(print_r($this->_table->errors(), true)); } } $params['page']++; } return true; }
/** * Returns an array with foreignKey value. * * @param \Cake\Datasource\EntityInterface $entity Entity. * @return array */ protected function _extractForeignKey($entity) { $foreignKey = (array) $this->_config['foreignKey']; $primaryKey = (array) $this->_table->primaryKey(); $pkValue = $entity->extract($primaryKey); return array_combine($foreignKey, $pkValue); }
/** * Gets a list of all virtual columns present in given $query's SELECT clause. * * This method will alter the given Query object removing any virtual column * present in its SELECT clause in order to avoid incorrect SQL statements. * Selected virtual columns should be fetched after query is executed using * mapReduce or similar. * * @param \Cake\ORM\Query $query The query object to be scoped * @param string|null $bundle Consider attributes only for a specific bundle * @return array List of virtual columns names */ public function getVirtualColumns(Query $query, $bundle = null) { static $selectedVirtual = []; $cacheKey = md5($query->sql()) . '_' . $bundle; if (isset($selectedVirtual[$cacheKey])) { return $selectedVirtual[$cacheKey]; } $selectClause = (array) $query->clause('select'); if (empty($selectClause)) { $selectedVirtual[$cacheKey] = array_keys($this->_toolbox->attributes($bundle)); return $selectedVirtual[$cacheKey]; } $selectedVirtual[$cacheKey] = []; $virtualColumns = array_keys($this->_toolbox->attributes($bundle)); foreach ($selectClause as $index => $column) { list($table, $column) = pluginSplit($column); if ((empty($table) || $table == $this->_table->alias()) && in_array($column, $virtualColumns)) { $selectedVirtual[$cacheKey][$index] = $column; unset($selectClause[$index]); } } if (empty($selectClause) && !empty($selectedVirtual[$cacheKey])) { $selectClause[] = $this->_table->primaryKey(); } $query->select($selectClause, true); return $selectedVirtual[$cacheKey]; }
/** * Builds a query for loading the passed list of entity objects along with the * associations specified in $contain. * * @param Cake\Collection\CollectionInterface $objects The original entitites * @param array $contain The associations to be loaded * @param Cake\ORM\Table $source The table to use for fetching the top level entities * @return Cake\ORM\Query */ protected function _getQuery($objects, $contain, $source) { $primaryKey = $source->primaryKey(); $method = is_string($primaryKey) ? 'get' : 'extract'; $keys = $objects->map(function ($entity) use($primaryKey, $method) { return $entity->{$method}($primaryKey); }); $query = $source->find()->select((array) $primaryKey)->where(function ($exp, $q) use($primaryKey, $keys, $source) { if (is_array($primaryKey) && count($primaryKey) === 1) { $primaryKey = current($primaryKey); } if (is_string($primaryKey)) { return $exp->in($source->aliasField($primaryKey), $keys->toList()); } $types = array_intersect_key($q->defaultTypes(), array_flip($primaryKey)); $primaryKey = array_map([$source, 'aliasField'], $primaryKey); return new TupleComparison($primaryKey, $keys->toList(), $types, 'IN'); })->contain($contain); foreach ($query->eagerLoader()->attachableAssociations($source) as $loadable) { $config = $loadable->config(); $config['includeFields'] = true; $loadable->config($config); } return $query; }
/** * Merges each of the elements from `$data` into each of the entities in `$entities * 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 such association, a new one will be created. * * Records in `$data` are matched against the entities by using the primary key * column. Entries in `$entities` that cannot be matched to any record in * `$data` will be discarded. Records in `$data` that could not be matched will * be marshalled as a new entity. * * 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 array|\Traversable $entities the entities that will get the * data merged in * @param array $data list of arrays to be merged into the entities * @param array $include The list of associations to be merged * @return array */ public function mergeMany($entities, array $data, array $include = []) { $primary = (array) $this->_table->primaryKey(); $indexed = (new Collection($data))->groupBy($primary[0])->toArray(); $new = isset($indexed[null]) ? [$indexed[null]] : []; unset($indexed[null]); $output = []; foreach ($entities as $entity) { if (!$entity instanceof EntityInterface) { continue; } $key = $entity->get($primary[0]); if ($key === null || !isset($indexed[$key])) { continue; } $output[] = $this->merge($entity, $indexed[$key][0], $include); unset($indexed[$key]); } foreach (array_merge($indexed, $new) as $record) { foreach ($record as $value) { $output[] = $this->one($value, $include); } } return $output; }
/** * Modifies the entity before it is saved so that versioned fields are persisted * in the database too. * * @param \Cake\Event\Event $event The beforeSave event that was fired * @param \Cake\ORM\Entity $entity The entity that is going to be saved * @param \ArrayObject $options the options passed to the save method * @return void */ public function beforeSave(Event $event, Entity $entity, ArrayObject $options) { $table = $this->_config['versionTable']; $newOptions = [$table => ['validate' => false]]; $options['associated'] = $newOptions + $options['associated']; $fields = $this->_fields(); $values = $entity->extract($fields); $model = $this->_table->alias(); $primaryKey = (array) $this->_table->primaryKey(); $primaryKey = current($primaryKey); $foreignKey = $entity->get($primaryKey); $versionField = $this->_config['versionField']; $preexistent = TableRegistry::get($table)->find()->select(['version_id'])->where(compact('foreign_key', 'model'))->order(['id desc'])->limit(1)->hydrate(false)->toArray(); $versionId = Hash::get($preexistent, '0.version_id', 0) + 1; $created = new Time(); foreach ($values as $field => $content) { if ($field == $primaryKey || $field == $versionField) { continue; } $data = ['version_id' => $versionId, 'model' => $model, 'foreign_key' => $foreignKey, 'field' => $field, 'content' => $content, 'created' => $created]; $new[$field] = new Entity($data, ['useSetters' => false, 'markNew' => true]); } $entity->set('__version', $new); if (!empty($versionField) && in_array($versionField, $fields)) { $entity->set($this->_config['versionField'], $versionId); } }
/** * Helper method used to generated multiple translated field entities * out of the data found in the `_translations` property in the passed * entity. The result will be put into its `_i18n` property * * @param \Cake\Datasource\EntityInterface $entity Entity * @return void */ protected function _bundleTranslatedFields($entity) { $translations = (array) $entity->get('_translations'); if (empty($translations) && !$entity->dirty('_translations')) { return; } $fields = $this->_config['fields']; $primaryKey = (array) $this->_table->primaryKey(); $key = $entity->get(current($primaryKey)); $find = []; foreach ($translations as $lang => $translation) { foreach ($fields as $field) { if (!$translation->dirty($field)) { continue; } $find[] = ['locale' => $lang, 'field' => $field, 'foreign_key' => $key]; $contents[] = new Entity(['content' => $translation->get($field)], ['useSetters' => false]); } } if (empty($find)) { return; } $results = $this->_findExistingTranslations($find); foreach ($find as $i => $translation) { if (!empty($results[$i])) { $contents[$i]->set('id', $results[$i], ['setter' => false]); $contents[$i]->isNew(false); } else { $translation['model'] = $this->_config['referenceName']; $contents[$i]->set($translation, ['setter' => false, 'guard' => false]); $contents[$i]->isNew(true); } } $entity->set('_i18n', $contents); }
/** * beforeFind callback * * inject where condition if context is 'tenant' * * @param \Cake\Event\Event $event The afterSave event that was fired. * @param \Cake\ORM\Query $query The query. * @return void */ public function beforeFind(Event $event, Query $query, $options) { // if context is tenant, add conditions to query if (MTApp::getContext() == 'tenant') { // check if find option has "skipTenant", recursive error fix if (!isset($options['skipTenantCheck']) || $options['skipTenantCheck'] !== true) { // secure the configured tenant table by adding a primary key condition if ($this->_table->alias() === MTApp::config('model')['className']) { $query->where([$this->_table->alias() . '.' . $this->_table->primaryKey() => MTApp::tenant()->id]); } else { $query->where([$this->_table->alias() . '.' . $this->config('foreign_key_field') => MTApp::tenant()->id]); } } } else { throw new DataScopeViolationException('Tenant Scoped accessed globally'); } return $query; }
/** * Calculates entity's primary key. * * If PK is composed of multiple columns they will be merged with `:` symbol. * For example, consider `Users` table with composed PK <nick, email>, then for * certain User entity this method could return: * * john-locke:john@the-island.com * * @param \Cake\Datasource\EntityInterface $entity The entity * @return string */ public function getEntityId(EntityInterface $entity) { $pk = []; $keys = $this->_table->primaryKey(); $keys = !is_array($keys) ? [$keys] : $keys; foreach ($keys as $key) { $pk[] = $entity->get($key); } return implode(':', $pk); }
/** * Attaches comments to each entity on find operation. * * @param \Cake\Event\Event $event The event that was triggered * @param \Cake\ORM\Query $query The query object * @param array $options Additional options as an array * @param bool $primary Whether is find is a primary query or not * @return void */ public function beforeFind(Event $event, $query, $options, $primary) { if ($this->_enabled && $query->count() > 0) { $pk = $this->_table->primaryKey(); $tableAlias = Inflector::underscore($this->_table->alias()); $query->contain(['Comments' => function ($query) { return $query->find('threaded')->contain(['Users'])->order($this->config('order')); }]); if ($this->config('count') || isset($options['comments_count']) && $options['comments_count'] === true) { $query->formatResults(function ($results) use($pk, $tableAlias) { return $results->map(function ($entity) use($pk, $tableAlias) { $entityId = $entity->{$pk}; $count = TableRegistry::get('Comment.Comments')->find()->where(['entity_id' => $entityId, 'table_alias' => $tableAlias])->count(); $entity->set('comments_count', $count); return $entity; }); }); } } }
/** * Gets or constructs an user entity with a given id. * * @paramx mixed array|int|string $userId * @return \Cake\Datasource\EntityInterface */ protected function _getUserEntity($userId) { if (is_a($userId, 'Cake\\Datasource\\EntityInterface')) { return $userId; } if (is_string($userId) || is_integer($userId)) { return $this->UserTable->newEntity([$this->UserTable->primaryKey() => $userId]); } if (is_array($userId)) { return $this->UserTable->newEntity($userId); } }
/** * Gets table's PK as an array. * * @return array */ protected function _tablePrimaryKey() { $alias = $this->_table->alias(); $pk = $this->_table->primaryKey(); if (!is_array($pk)) { $pk = [$pk]; } $pk = array_map(function ($key) use($alias) { return "{$alias}.{$key}"; }, $pk); return $pk; }
/** * Find or create new draft database entry and return entity ID * * @param \Cake\ORM\Table $table Table instance * @param array|null $conditions Find conditions * * @return int $id Draft Id */ public function getDraftId(Table $table, $conditions = []) { $conditions = array_merge($this->config[$table->alias()]['conditions'], $conditions); $result = $table->find()->select(['id' => $table->primaryKey()])->andWhere($conditions)->first(); if ($result) { return $result->id; } else { $entity = $table->newEntity($conditions, ['validate' => false]); $entity = $table->save($entity); return $entity->id; } }
public function increment(Table $table, $counter, $identifier) { list($alias, $field) = $this->_counterSplit($counter); $key = $table->primaryKey(); if ($table->alias() !== $alias) { $key = $table->{$alias}->bindingKey(); $table = TableRegistry::get($alias); } $expression = new QueryExpression("{$field} = {$field} + " . $this->_offset); $conditions = [$key => $identifier] + $this->_conditions; return $table->updateAll($expression, $conditions); }
/** * Merges each of the elements from `$data` into each of the entities in `$entities` * and recursively does the same for each 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. * * Records in `$data` are matched against the entities using the primary key * column. Entries in `$entities` that cannot be matched to any record in * `$data` will be discarded. Records in `$data` that could not be matched will * be marshalled as a new entity. * * 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: * * - 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. * - 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. * - accessibleFields: A list of fields to allow or deny in entity accessible fields. * * @param array|\Traversable $entities the entities that will get the * data merged in * @param array $data list of arrays to be merged into the entities * @param array $options List of options. * @return array */ public function mergeMany($entities, array $data, array $options = []) { $primary = (array) $this->_table->primaryKey(); $indexed = (new Collection($data))->groupBy(function ($el) use($primary) { $keys = []; foreach ($primary as $key) { $keys[] = isset($el[$key]) ? $el[$key] : ''; } return implode(';', $keys); })->map(function ($element, $key) { return $key === '' ? $element : $element[0]; })->toArray(); $new = isset($indexed[null]) ? $indexed[null] : []; unset($indexed[null]); $output = []; foreach ($entities as $entity) { if (!$entity instanceof EntityInterface) { continue; } $key = implode(';', $entity->extract($primary)); if ($key === null || !isset($indexed[$key])) { continue; } $output[] = $this->merge($entity, $indexed[$key], $options); unset($indexed[$key]); } $maybeExistentQuery = (new Collection($indexed))->map(function ($data, $key) { return explode(';', $key); })->filter(function ($keys) use($primary) { return count(array_filter($keys, 'strlen')) === count($primary); })->reduce(function ($query, $keys) use($primary) { $fields = array_map([$this->_table, 'aliasField'], $primary); return $query->orWhere($query->newExpr()->and_(array_combine($fields, $keys))); }, $this->_table->find()); if (!empty($indexed) && count($maybeExistentQuery->clause('where'))) { foreach ($maybeExistentQuery as $entity) { $key = implode(';', $entity->extract($primary)); if (isset($indexed[$key])) { $output[] = $this->merge($entity, $indexed[$key], $options); unset($indexed[$key]); } } } foreach ((new Collection($indexed))->append($new) as $value) { if (!is_array($value)) { continue; } $output[] = $this->one($value, $options); } return $output; }
/** * Ensures that the provided entity contains non-empty values for the left and * right fields * * @param \Cake\ORM\Entity $entity The entity to ensure fields for * @return void */ protected function _ensureFields($entity) { $config = $this->config(); $fields = [$config['left'], $config['right']]; $values = array_filter($entity->extract($fields)); if (count($values) === count($fields)) { return; } $fresh = $this->_table->get($entity->get($this->_table->primaryKey()), $fields); $entity->set($fresh->extract($fields), ['guard' => false]); foreach ($fields as $field) { $entity->dirty($field, false); } }
/** * Deletes an user record * * @param mixed $userId * @param array $options * @return boolean */ public function deleteUser($userId = null, $options = []) { if (is_string($userId) || is_integer($userId)) { $entity = $this->UserTable->newEntity([$this->UserTable->primaryKey() => $userId]); } if (is_array($userId)) { $entity = $this->UserTable->newEntity($userId); } if ($this->UserTable->delete($entity)) { $this->handleFlashAndRedirect('success', $options); return true; } else { $this->handleFlashAndRedirect('error', $options); return false; } }
public function increment(Table $table, $counter, $identifier) { list($alias, $field) = $this->_counterSplit($counter); $key = $table->primaryKey(); if ($table->alias() !== $alias) { $key = $table->{$alias}->bindingKey(); $table = TableRegistry::get($alias); } if (!$this->_cache->read($counter)) { $options = ['fields' => [$field]]; $this->_cache->write($counter, $table->get($identifier, $options)->{$field}); } $count = $this->_cache->increment($counter, $this->_offset); if (!($count % $this->_threshold)) { return; } $table->updateAll([$field => $count], [$key => $identifier]); }
/** * Get the primary key field from the model or parameters * * @param \Cake\ORM\Table $model The model to introspect. * @return array The columns in the primary key */ public function getPrimaryKey($model) { if (!empty($this->params['primary-key'])) { $fields = explode(',', $this->params['primary-key']); return array_values(array_filter(array_map('trim', $fields))); } return (array) $model->primaryKey(); }
/** * Helper method to find the primary key for a record. * * @param Cake\ORM\Table $Table An instantiated Table object. * @param Cake\ORM\ntity $entity The record being saved into the DB. * @return string The numeric or UUID value of the record's primary key, or 'unknown' on failure. */ protected function findKey(Table $Table, Entity $entity) { if (!empty($entity->{$Table->primaryKey()})) { $key = $entity->{$Table->primaryKey()}; } else { $key = 'unknown'; } return $key; }
/** * Retrieve and return associated record Entity, by primary key value. * If the record has been trashed - query will return NULL. * * @param \Cake\ORM\Table $table Table instance * @param string $value Primary key value * @return object */ protected function _getAssociatedRecord(Table $table, $value) { $options = ['conditions' => [$table->primaryKey() => $value], 'limit' => 1]; // try to fetch with trashed if finder method exists, otherwise fallback to find all try { $query = $table->find('withTrashed', $options); } catch (BadMethodCallException $e) { $query = $table->find('all', $options); } return $query->first(); }
/** * Method called on the destruction of a database session. * * @param int $id ID that uniquely identifies session in database * @return bool True for successful delete, false otherwise. */ public function destroy($id) { return (bool) $this->_table->delete(new Entity([$this->_table->primaryKey() => $id], ['markNew' => false])); }
/** * Deletes/sets null the related objects according to the dependency between source and targets and foreign key nullability * Skips deleting records present in $remainingEntities * * @param array $properties array of foreignKey properties * @param EntityInterface $entity the entity which should have its associated entities unassigned * @param Table $target The associated table * @param array $remainingEntities Entities that should not be deleted * @return void */ protected function _unlinkAssociated(array $properties, EntityInterface $entity, Table $target, array $remainingEntities = []) { $primaryKey = (array) $target->primaryKey(); $mustBeDependent = !$this->_foreignKeyAcceptsNull($target, $properties) || $this->dependent(); $exclusions = new Collection($remainingEntities); $exclusions = $exclusions->map(function ($ent) use($primaryKey) { return $ent->extract($primaryKey); })->filter(function ($v) { return !in_array(null, array_values($v), true); })->toArray(); if (count($exclusions) > 0) { $conditions = ['NOT' => ['OR' => $exclusions], $properties]; if ($mustBeDependent) { if ($this->_cascadeCallbacks) { $query = $this->find('all')->where($conditions); foreach ($query as $assoc) { $target->delete($assoc); } } else { $target->deleteAll($conditions); } } else { $updateFields = array_fill_keys(array_keys($properties), null); $target->updateAll($updateFields, $conditions); } } }
/** * Deletes/sets null the related objects according to the dependency between source and targets and foreign key nullability * Skips deleting records present in $remainingEntities * * @param array $properties array of foreignKey properties * @param \Cake\Datasource\EntityInterface $entity the entity which should have its associated entities unassigned * @param \Cake\ORM\Table $target The associated table * @param array $remainingEntities Entities that should not be deleted * @param array $options list of options accepted by `Table::delete()` * @return bool success */ protected function _unlinkAssociated(array $properties, EntityInterface $entity, Table $target, array $remainingEntities = [], array $options = []) { $primaryKey = (array) $target->primaryKey(); $exclusions = new Collection($remainingEntities); $exclusions = $exclusions->map(function ($ent) use($primaryKey) { return $ent->extract($primaryKey); })->filter(function ($v) { return !in_array(null, array_values($v), true); })->toArray(); $conditions = $properties; if (count($exclusions) > 0) { $conditions = ['NOT' => ['OR' => $exclusions], $properties]; } return $this->_unlink(array_keys($properties), $target, $conditions, $options); }
/** * Tests the bindingKey() method when the association source is not the * owning side * * @return void */ public function testBindingDefaultNoOwningSide() { $target = new Table(); $target->primaryKey(['foo', 'site_id']); $this->association->target($target); $this->association->expects($this->once())->method('isOwningSide')->will($this->returnValue(false)); $result = $this->association->bindingKey(); $this->assertEquals(['foo', 'site_id'], $result); }
/** * Tests primaryKey method * * @return void */ public function testPrimaryKey() { $table = new Table(['table' => 'users', 'schema' => ['id' => ['type' => 'integer'], '_constraints' => ['primary' => ['type' => 'primary', 'columns' => ['id']]]]]); $this->assertEquals('id', $table->primaryKey()); $table->primaryKey('thingID'); $this->assertEquals('thingID', $table->primaryKey()); $table->primaryKey(['thingID', 'user_id']); $this->assertEquals(['thingID', 'user_id'], $table->primaryKey()); }
/** * Processes the records. * * @param \Cake\ORM\Table $table * @param int $chunkCount * @param int $chunkSize * @return void */ protected function _process(Table $table, $chunkCount, $chunkSize) { $query = $table->find(); if ($table->hasFinder('purifier')) { $query->find('purifier'); } $fields = explode(',', $this->param('fields')); $fields[] = $table->primaryKey(); $results = $query->select($fields)->offset($chunkCount)->limit($chunkSize)->orderDesc($table->aliasField($table->primaryKey()))->all(); if (empty($results)) { return; } foreach ($results as $result) { try { $table->save($result); $chunkCount++; } catch (\Exception $e) { $this->error($e->getMessage()); } } }