/** * 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); }
/** * Tests the table method * * @return void */ public function testTableMethod() { $table = new Table(['table' => 'users']); $this->assertEquals('users', $table->table()); $table = new UsersTable(); $this->assertEquals('users', $table->table()); $table = $this->getMockBuilder('\\Cake\\ORM\\Table')->setMethods(['find'])->setMockClassName('SpecialThingsTable')->getMock(); $this->assertEquals('special_things', $table->table()); $table = new Table(['alias' => 'LoveBoats']); $this->assertEquals('love_boats', $table->table()); $table->table('other'); $this->assertEquals('other', $table->table()); }
/** * 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); }
/** * Creates the associations between the bound table and every field passed to * this method. * * Additionally it creates a `i18n` HasMany association that will be * used for fetching all translations for each record in the bound table * * @param array $fields list of fields to create associations for * @param string $table the table name to use for storing each field translation * @param string $model the model field value * @param string $strategy the strategy used in the _i18n association * * @return void */ public function setupFieldAssociations($fields, $table, $model, $strategy) { $targetAlias = $this->_translationTable->alias(); $alias = $this->_table->alias(); $filter = $this->_config['onlyTranslated']; $tableLocator = $this->tableLocator(); foreach ($fields as $field) { $name = $alias . '_' . $field . '_translation'; if (!$tableLocator->exists($name)) { $fieldTable = $tableLocator->get($name, ['className' => $table, 'alias' => $name, 'table' => $this->_translationTable->table()]); } else { $fieldTable = $tableLocator->get($name); } $conditions = [$name . '.model' => $model, $name . '.field' => $field]; if (!$this->_config['allowEmptyTranslations']) { $conditions[$name . '.content !='] = ''; } $this->_table->hasOne($name, ['targetTable' => $fieldTable, 'foreignKey' => 'foreign_key', 'joinType' => $filter ? 'INNER' : 'LEFT', 'conditions' => $conditions, 'propertyName' => $field . '_translation']); } $conditions = ["{$targetAlias}.model" => $model]; if (!$this->_config['allowEmptyTranslations']) { $conditions["{$targetAlias}.content !="] = ''; } $this->_table->hasMany($targetAlias, ['className' => $table, 'foreignKey' => 'foreign_key', 'strategy' => $strategy, 'conditions' => $conditions, 'propertyName' => '_i18n', 'dependent' => true]); }
/** * Store to FileStorage table. * * @param object $docEntity Document entity * @param string $field of the association * @param array $fileData File data * @param array $options for extra setup * @return object|bool Fresh created entity or false on unsuccesful attempts. */ protected function _storeFileStorage($docEntity, $field, $fileData, $options = []) { $fieldsDefinitions = []; $fieldOption = []; $assocName = CsvMigrationsUtils::createAssociationName('Burzum/FileStorage.FileStorage', $field); $fileStorEnt = $this->_table->{$assocName}->newEntity($fileData); if (method_exists($this->_table, 'getFieldsDefinitions') && is_callable([$this->_table, 'getFieldsDefinitions'])) { $fieldsDefinitions = $this->_table->getFieldsDefinitions(); } if (!empty($fieldsDefinitions)) { foreach ($fieldsDefinitions as $tableField => $definition) { if ($tableField == $field) { $fieldOption = $definition; break; } } } if (!empty($options['ajax'])) { //AJAX upload doesn't know anything about the entity //it relates to, as it's not saved yet $patchData = ['model' => $this->_table->table(), 'model_field' => $field]; } else { $patchData = [$this->_fileStorageForeignKey => $docEntity->get('id'), 'model' => $this->_table->table(), 'model_field' => $field]; } $fileStorEnt = $this->_table->{$assocName}->patchEntity($fileStorEnt, $patchData); if ($this->_table->{$assocName}->save($fileStorEnt)) { if (!empty($fieldOption) && $fieldOption['type'] == 'images') { $this->createThumbnails($fileStorEnt); } return $fileStorEnt; } return false; }
/** * Gets the field(s) from the args and checks if they're present in the table. * * @param \Cake\ORM\Table $table Table object. * @return array Set of of fields explode()'ed from the args */ protected function _getFields(Table $table) { $fields = explode(',', $this->args[1]); foreach ($fields as $field) { if (!$table->hasField($field)) { $this->abort(sprintf('Table `%s` is missing the field `%s`.', $table->table(), $field)); } } return $fields; }
/** * Gets all attributes added to this table. * * @param string|null $bundle Get attributes within given bundle, or all of them * regardless of the bundle if not provided * @return array List of attributes indexed by name (virtual column name) */ public function attributes($bundle = null) { $key = empty($bundle) ? '@all' : $bundle; if (isset($this->_attributes[$key])) { return $this->_attributes[$key]; } $this->_attributes[$key] = []; $conditions = ['EavAttributes.table_alias' => $this->_table->table()]; if (!empty($bundle)) { $conditions['EavAttributes.bundle'] = $bundle; } $cacheKey = $this->_table->table() . '_' . $key; $attrs = TableRegistry::get('Eav.EavAttributes')->find()->cache($cacheKey, 'eav_table_attrs')->where($conditions)->all()->toArray(); foreach ($attrs as $attr) { $this->_attributes[$key][$attr->get('name')] = $attr; } return $this->attributes($bundle); }
/** * Creates the associations between the bound table and every field passed to * this method. * * Additionally it creates a `i18n` HasMany association that will be * used for fetching all translations for each record in the bound table * * @param array $fields list of fields to create associations for * @param string $table the table name to use for storing each field translation * @param array $fieldConditions conditions for finding fields * @param string $strategy the strategy used in the _i18n association * * @return void */ public function setupFieldAssociations($fields, $table, $fieldConditions, $strategy) { $targetAlias = $this->_translationTable->alias(); $alias = $this->_table->alias(); $filter = $this->_config['onlyTranslated']; foreach ($fields as $field) { $name = $alias . '_' . $field . '_translation'; $conditions = [$name . '.model' => $fieldConditions['model'], $name . '.field' => $field]; foreach ($fieldConditions as $fieldName => $fieldValue) { $conditions[$name . '.' . $fieldName] = $fieldValue; } if (!TableRegistry::exists($name)) { $fieldTable = TableRegistry::get($name, ['className' => $table, 'alias' => $name, 'table' => $this->_translationTable->table()]); } else { $fieldTable = TableRegistry::get($name); } $this->_table->hasOne($name, ['targetTable' => $fieldTable, 'foreignKey' => 'foreign_key', 'joinType' => $filter ? 'INNER' : 'LEFT', 'conditions' => $conditions, 'propertyName' => $field . '_translation']); } $this->_table->hasMany($targetAlias, ['className' => $table, 'foreignKey' => 'foreign_key', 'strategy' => $strategy, 'conditions' => ["{$targetAlias}.model" => $fieldConditions['model']], 'propertyName' => '_i18n', 'dependent' => true]); }
/** * 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; }
/** * Method that retrieves many to one associated records * @param \Cake\ORM\Table $table Table object * @param \Cake\ORM\Association $association Association object * @return array associated records */ protected function _manyToOneAssociatedRecords(\Cake\ORM\Table $table, \Cake\ORM\Association $association) { $tableName = $table->table(); $primaryKey = $table->primaryKey(); $assocTableName = $association->table(); $assocPrimaryKey = $association->primaryKey(); $assocForeignKey = $association->foreignKey(); $recordId = $this->request->params['pass'][0]; $displayField = $association->displayField(); $connection = ConnectionManager::get('default'); $records = $connection->execute('SELECT ' . $assocTableName . '.' . $displayField . ' FROM ' . $tableName . ' LEFT JOIN ' . $assocTableName . ' ON ' . $tableName . '.' . $assocForeignKey . ' = ' . $assocTableName . '.' . $assocPrimaryKey . ' WHERE ' . $tableName . '.' . $primaryKey . ' = :id LIMIT 1', ['id' => $recordId])->fetchAll('assoc'); // store associated table records $result = $records[0][$displayField]; return $result; }
/** * Builds the path under which the data gets stored in the storage adapter. * * @param Table $table * @param EntityInterface $entity * @return string */ public function buildPath($table, $entity) { $path = ''; if ($this->_config['tableFolder']) { $path .= $table->table() . DS; } if ($this->_config['randomPath'] === true) { $path .= StorageUtils::randomPath($entity[$table->primaryKey()]); } if ($this->_config['uuidFolder'] === true) { $path .= $this->stripDashes($entity[$table->primaryKey()]) . DS; } return $path; }
/** * {@inheritDoc} */ public function __construct(Table $table, array $config = []) { $config['pk'] = $table->primaryKey(); $config['tableAlias'] = (string) Inflector::underscore($table->table()); $table->hasOne('Search.SearchDatasets', ['foreignKey' => 'entity_id', 'conditions' => ['SearchDatasets.table_alias' => $config['tableAlias']], 'dependent' => true]); parent::__construct($table, $config); }