alias() public method

{@inheritDoc}
public alias ( $alias = null )
 /**
  * @param \Cake\Event\Event $event
  * @param \Cake\ORM\Query $query
  * @param \ArrayObject $options
  * @param bool $primary
  * @return void
  */
 public function beforeFind(Event $event, Query $query, ArrayObject $options, $primary)
 {
     if (!$primary && !$this->_config['recursive']) {
         return;
     }
     $field = $this->_config['field'];
     if (!$field) {
         return;
     }
     $query->find('hashed');
     $idField = $this->_primaryKey;
     if ($primary && $field === $idField) {
         $query->traverseExpressions(function ($expression) {
             if (method_exists($expression, 'getField') && ($expression->getField() === $this->_primaryKey || $expression->getField() === $this->_table->alias() . '.' . $this->_primaryKey)) {
                 $expression->setValue($this->decodeHashid($expression->getValue()));
             }
             return $expression;
         });
     }
     if (!$this->_config['recursive']) {
         return;
     }
     foreach ($this->_table->associations() as $association) {
         if ($association->target()->hasBehavior('Hashid') && $association->finder() === 'all') {
             $association->finder('hashed');
         }
     }
 }
Example #2
1
 /**
  * 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);
 }
 public function __construct(Table $table, Entity $entity, $field, array $settings)
 {
     $this->setRoot(TMP . 'ProfferTests');
     $this->setTable($table->alias());
     $this->setField($field);
     $this->setSeed('proffer_test');
     if (isset($settings['thumbnailSizes'])) {
         $this->setPrefixes($settings['thumbnailSizes']);
     }
     $this->setFilename($entity->get($field));
 }
 /**
  * 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);
 }
 /**
  * Do some checks on the table which has been passed to make sure that it has what we need
  *
  * @param string $table The table
  * @return void
  */
 protected function checkTable($table)
 {
     try {
         $this->Table = $this->loadModel($table);
     } catch (Exception $e) {
         $this->out(__('<error>' . $e->getMessage() . '</error>'));
         exit;
     }
     if (get_class($this->Table) === 'AppModel') {
         $this->out(__('<error>The table could not be found, instance of AppModel loaded.</error>'));
         exit;
     }
     if (!$this->Table->hasBehavior('Proffer')) {
         $out = __("<error>The table '" . $this->Table->alias() . "' does not have the Proffer behavior attached.</error>");
         $this->out($out);
         exit;
     }
     $config = $this->Table->behaviors()->Proffer->config();
     foreach ($config as $field => $settings) {
         if (!$this->Table->hasField($field)) {
             $out = __("<error>The table '" . $this->Table->alias() . "' does not have the configured upload field in it's schema.</error>");
             $this->out($out);
             exit;
         }
         if (!$this->Table->hasField($settings['dir'])) {
             $out = __("<error>The table '" . $this->Table->alias() . "' does not have the configured dir field in it's schema.</error>");
             $this->out($out);
             exit;
         }
     }
 }
 /**
  * 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);
     }
 }
Example #7
0
 /**
  * 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];
 }
Example #8
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;
 }
Example #9
0
 /**
  * Replaces existing association links between the source entity and the target
  * with the ones passed. This method does a smart cleanup, links that are already
  * persisted and present in `$targetEntities` will not be deleted, new links will
  * be created for the passed target entities that are not already in the database
  * and the rest will be removed.
  *
  * For example, if an article is linked to tags 'cake' and 'framework' and you pass
  * to this method an array containing the entities for tags 'cake', 'php' and 'awesome',
  * only the link for cake will be kept in database, the link for 'framework' will be
  * deleted and the links for 'php' and 'awesome' will be created.
  *
  * Existing links are not deleted and created again, they are either left untouched
  * or updated so that potential extra information stored in the joint row is not
  * lost. Updating the link row can be done by making sure the corresponding passed
  * target entity contains the joint property with its primary key and any extra
  * information to be stored.
  *
  * On success, the passed `$sourceEntity` will contain `$targetEntities` as  value
  * in the corresponding property for this association.
  *
  * This method assumes that links between both the source entity and each of the
  * target entities are unique. That is, for any given row in the source table there
  * can only be one link in the junction table pointing to any other given row in
  * the target table.
  *
  * Additional options for new links to be saved can be passed in the third argument,
  * check `Table::save()` for information on the accepted options.
  *
  * ### Example:
  *
  * ```
  * $article->tags = [$tag1, $tag2, $tag3, $tag4];
  * $articles->save($article);
  * $tags = [$tag1, $tag3];
  * $articles->association('tags')->replaceLinks($article, $tags);
  * ```
  *
  * `$article->get('tags')` will contain only `[$tag1, $tag3]` at the end
  *
  * @param \Cake\Datasource\EntityInterface $sourceEntity an entity persisted in the source table for
  * this association
  * @param array $targetEntities list of entities from the target table to be linked
  * @param array $options list of options to be passed to the internal `save`/`delete` calls
  * when persisting/updating new links, or deleting existing ones
  * @throws \InvalidArgumentException if non persisted entities are passed or if
  * any of them is lacking a primary key value
  * @return bool success
  */
 public function replaceLinks(EntityInterface $sourceEntity, array $targetEntities, array $options = [])
 {
     $bindingKey = (array) $this->bindingKey();
     $primaryValue = $sourceEntity->extract($bindingKey);
     if (count(array_filter($primaryValue, 'strlen')) !== count($bindingKey)) {
         $message = 'Could not find primary key value for source entity';
         throw new InvalidArgumentException($message);
     }
     return $this->junction()->connection()->transactional(function () use($sourceEntity, $targetEntities, $primaryValue, $options) {
         $foreignKey = (array) $this->foreignKey();
         $hasMany = $this->source()->association($this->_junctionTable->alias());
         $existing = $hasMany->find('all')->where(array_combine($foreignKey, $primaryValue));
         $associationConditions = $this->conditions();
         if ($associationConditions) {
             $existing->contain($this->target()->alias());
             $existing->andWhere($associationConditions);
         }
         $jointEntities = $this->_collectJointEntities($sourceEntity, $targetEntities);
         $inserts = $this->_diffLinks($existing, $jointEntities, $targetEntities, $options);
         if ($inserts && !$this->_saveTarget($sourceEntity, $inserts, $options)) {
             return false;
         }
         $property = $this->property();
         if (count($inserts)) {
             $inserted = array_combine(array_keys($inserts), (array) $sourceEntity->get($property));
             $targetEntities = $inserted + $targetEntities;
         }
         ksort($targetEntities);
         $sourceEntity->set($property, array_values($targetEntities));
         $sourceEntity->dirty($property, false);
         return true;
     });
 }
Example #10
0
 /**
  * Correctly nests results keys including those coming from associations
  *
  * @param mixed $row Array containing columns and values or false if there is no results
  * @return array Results
  */
 protected function _groupResult($row)
 {
     $defaultAlias = $this->_defaultTable->alias();
     $results = $presentAliases = [];
     foreach ($row as $key => $value) {
         $table = $defaultAlias;
         $field = $key;
         if (isset($this->_associationMap[$key])) {
             $results[$key] = $value;
             continue;
         }
         if (empty($this->_map[$key])) {
             $parts = explode('__', $key);
             if (count($parts) > 1) {
                 $this->_map[$key] = $parts;
             }
         }
         if (!empty($this->_map[$key])) {
             list($table, $field) = $this->_map[$key];
         }
         $presentAliases[$table] = true;
         $results[$table][$field] = $value;
     }
     unset($presentAliases[$defaultAlias]);
     $results[$defaultAlias] = $this->_castValues($this->_defaultTable, $results[$defaultAlias]);
     $options = ['useSetters' => false, 'markClean' => true, 'markNew' => false, 'guard' => false];
     foreach (array_reverse($this->_associationMap) as $assoc) {
         $alias = $assoc['nestKey'];
         $instance = $assoc['instance'];
         if (!isset($results[$alias])) {
             $results = $instance->defaultRowValue($results, $assoc['canBeJoined']);
             continue;
         }
         $target = $instance->target();
         $options['source'] = $target->alias();
         unset($presentAliases[$alias]);
         if ($assoc['canBeJoined']) {
             $results[$alias] = $this->_castValues($target, $results[$alias]);
         }
         if ($this->_hydrate && $assoc['canBeJoined']) {
             $entity = new $assoc['entityClass']($results[$alias], $options);
             $entity->clean();
             $results[$alias] = $entity;
         }
         $results = $instance->transformRow($results, $alias, $assoc['canBeJoined']);
     }
     foreach ($presentAliases as $alias => $present) {
         if (!isset($results[$alias])) {
             continue;
         }
         $results[$defaultAlias][$alias] = $results[$alias];
     }
     $options['source'] = $defaultAlias;
     $results = $results[$defaultAlias];
     if ($this->_hydrate && !$results instanceof Entity) {
         $results = new $this->_entityClass($results, $options);
     }
     return $results;
 }
 /**
  * Returns default version association name.
  *
  * @param string $field Field name.
  * @return string
  */
 protected function _associationName($field = null)
 {
     $alias = Inflector::singularize($this->_table->alias());
     if ($field) {
         $field = Inflector::camelize($field);
     }
     return $alias . $field . 'Version';
 }
 /**
  * Get comments for the given entity.
  *
  * Allows you to get all comments even when this behavior was disabled
  * using `unbindComments()`.
  *
  * ### Usage:
  *
  *     // in your controller, gets comments for post which id equals 2
  *     $postComments = $this->Posts->find('comments', ['for' => 2]);
  *
  * @param \Cake\ORM\Query $query The query object
  * @param array $options Additional options as an array
  * @return \Cake\Datasource\ResultSetDecorator Comments collection
  * @throws \InvalidArgumentException When the 'for' key is not passed in $options
  */
 public function findComments(Query $query, $options)
 {
     $tableAlias = Inflector::underscore($this->_table->alias());
     if (empty($options['for'])) {
         throw new \InvalidArgumentException("The 'for' key is required for find('children')");
     }
     $comments = $this->_table->Comments->find('threaded')->where(['table_alias' => $tableAlias, 'entity_id' => $options['for']])->order($this->config('order'))->all();
     return $comments;
 }
Example #13
0
 /**
  * Returns the ids found for each of the condition arrays passed for the translations
  * table. Each records is indexed by the corresponding position to the conditions array
  *
  * @param array $ruleSet an array of arary of conditions to be used for finding each
  * @return array
  */
 protected function _findExistingTranslations($ruleSet)
 {
     $association = $this->_table->association($this->_translationTable->alias());
     $query = $association->find()->select(['id', 'num' => 0])->where(current($ruleSet))->hydrate(false)->bufferResults(false);
     unset($ruleSet[0]);
     foreach ($ruleSet as $i => $conditions) {
         $q = $association->find()->select(['id', 'num' => $i])->where($conditions);
         $query->unionAll($q);
     }
     return $query->combine('num', 'id')->toArray();
 }
Example #14
0
 /**
  * beforeDelete callback
  *
  * Prevent delete if the context is not global
  *
  * @param \Cake\Event\Event $event The beforeDelete event that was fired.
  * @param \Cake\ORM\Entity $entity The entity that was saved.
  * @return void
  */
 public function beforeDelete(Event $event, Entity $entity, $options)
 {
     if (MTApp::getContext() == 'tenant') {
         $field = $this->config('foreign_key_field');
         //paranoid check of ownership
         if ($entity->{$field} != MTApp::tenant()->id) {
             //current tenant is NOT owner
             throw new DataScopeViolationException('Tenant->id:' . MTApp::tenant()->id . ' does not own ' . $this->_table->alias() . '->id:' . $entity->id);
         }
     }
     return true;
 }
Example #15
0
 /**
  * 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;
 }
 /**
  * Validation rules.
  *
  * @param \Cake\Event\Event $event The event instance.
  * @return void
  * @throws \Cake\Network\Exception\ForbiddenException When
  *  - $_manageTable is not defined.
  *  - trait is used in non-controller classes.
  *  - the controller is not a backend controller.
  */
 public function beforeFilter(Event $event)
 {
     $requestParams = $event->subject()->request->params;
     if (empty($this->_manageTable) || !($this->_table = TableRegistry::get($this->_manageTable))) {
         throw new ForbiddenException(__d('field', 'FieldUIControllerTrait: The property $_manageTable was not found or is empty.'));
     } elseif (!$this instanceof Controller) {
         throw new ForbiddenException(__d('field', 'FieldUIControllerTrait: This trait must be used on instances of Cake\\Controller\\Controller.'));
     } elseif (!isset($requestParams['prefix']) || strtolower($requestParams['prefix']) !== 'admin') {
         throw new ForbiddenException(__d('field', 'FieldUIControllerTrait: This trait must be used on backend-controllers only.'));
     }
     $this->_tableAlias = Inflector::underscore($this->_table->alias());
 }
 /**
  * Returns data and options prepared to validate and marshall.
  *
  * @param array $data The data to prepare.
  * @param array $options The options passed to this marshaller.
  * @return array An array containing prepared data and options.
  */
 protected function _prepareDataAndOptions($data, $options)
 {
     $options += ['validate' => true];
     $tableName = $this->_table->alias();
     if (isset($data[$tableName])) {
         $data = $data[$tableName];
     }
     $data = new \ArrayObject($data);
     $options = new \ArrayObject($options);
     $this->_table->dispatchEvent('Model.beforeMarshal', compact('data', 'options'));
     return [(array) $data, (array) $options];
 }
Example #18
0
 /**
  * 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;
     }
 }
 /**
  * Constructor
  *
  * @param \Cake\ORM\Table $table Table instance
  * @param array $config Configuration
  */
 public function __construct(Table $table, array $config = [])
 {
     $tableAlias = $table->alias();
     list($plugin) = pluginSplit($table->registryAlias(), true);
     if (isset($config['referenceName'])) {
         $tableReferenceName = $config['referenceName'];
     } else {
         $tableReferenceName = $this->_referenceName($table);
     }
     $config += ['mainTableAlias' => $tableAlias, 'translationTable' => $plugin . $tableReferenceName . 'Translations', 'hasOneAlias' => $tableAlias . 'Translation'];
     parent::__construct($table, $config);
 }
Example #20
0
 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);
 }
 /**
  * Construct the class and setup the defaults
  *
  * @param Table $table Instance of the table
  * @param Entity $entity Instance of the entity data
  * @param string $field The name of the upload field
  * @param array $settings Array of settings for the upload field
  */
 public function __construct(Table $table, Entity $entity, $field, array $settings)
 {
     if (isset($settings['root'])) {
         $this->setRoot($settings['root']);
     } else {
         $this->setRoot(WWW_ROOT . 'files');
     }
     $this->setTable($table->alias());
     $this->setField($field);
     $this->setSeed($this->generateSeed($entity->get($settings['dir'])));
     if (isset($settings['thumbnailSizes'])) {
         $this->setPrefixes($settings['thumbnailSizes']);
     }
     $this->setFilename($entity->get($field));
 }
Example #22
0
 /**
  * Implementation of the beforeSave event, handles uploading / saving and overwriting of image records.
  *
  * @param Event $event Event object.
  * @param Entity $entity Entity object.
  * @param \ArrayObject $options Options array.
  * @return void
  */
 public function beforeSave(Event $event, Entity $entity, \ArrayObject $options)
 {
     $fields = $this->config('fields');
     $alias = $this->_table->alias();
     $options['associated'] = [$this->_imagesTable->alias() => ['validate' => false]] + $options['associated'];
     $entities = [];
     foreach ($fields as $fieldName => $fieldType) {
         $uploadedImages = [];
         $field = $entity->get($fieldName);
         $field = $fieldType == 'one' ? [$field] : $field;
         foreach ($field as $image) {
             $result = array();
             if (!empty($image['tmp_name'])) {
                 $result = $this->_upload($image['name'], $image['tmp_name'], false);
             } elseif (is_string($image)) {
                 $result = $this->_upload($image, $image, true);
             }
             if (!empty($result)) {
                 $uploadedImages[] = $result + ['model' => $alias, 'field' => $fieldName];
             }
         }
         if (!empty($uploadedImages)) {
             if (!$entity->isNew() && $fieldType == 'one') {
                 $preexisting = $this->_imagesTable->find()->where(['model' => $alias, 'field' => $fieldName, 'foreign_key' => $entity->id])->bufferResults(false);
                 foreach ($preexisting as $index => $image) {
                     $this->_imagesTable->delete($image);
                 }
             }
             foreach ($uploadedImages as $image) {
                 $entities[] = $this->_imagesTable->newEntity($image);
             }
         }
         $entity->dirty($fieldName, true);
     }
     $entity->set('_images', $entities);
 }
Example #23
0
 /**
  * beforeDelete callback
  *
  * Prevent delete if the record is global
  * Prevent delete if the record belongs to another tenant
  *
  * @param \Cake\Event\Event $event The beforeDelete event that was fired.
  * @param \Cake\ORM\Entity $entity The entity that was saved.
  * @return void
  */
 public function beforeDelete(Event $event, Entity $entity, $options)
 {
     if (MTApp::getContext() == 'tenant') {
         $field = $this->config('foreign_key_field');
         //tenant cannot delete global records if he is not the onwer of the global tenant
         if ($entity->{$field} == $this->config('global_value') && MTapp::tenant()->id != $this->config('global_value')) {
             return false;
         }
         //paranoid check of ownership
         if ($entity->{$field} != MTApp::tenant()->id) {
             //current tenant is NOT owner
             throw new DataScopeViolationException('Tenant->id:' . MTApp::tenant()->id . ' does not own ' . $this->_table->alias() . '->id:' . $entity->id);
         }
     }
     return true;
 }
 /**
  * Sets or instantiates the user model class.
  *
  * @param mixed $table
  * @throws \RuntimeException
  * @return void
  */
 public function setUserTable($table = null)
 {
     if ($table === null) {
         $this->UserTable = $this->_controller->{$this->_controller->modelClass};
     } else {
         if (is_object($table)) {
             if (!is_a($table, '\\Cake\\ORM\\Table')) {
                 throw new \RuntimeException('Passed object is not of type \\Cake\\ORM\\Table!');
             }
             $this->UserTable = $table->alias();
         }
         if (is_string($table)) {
             $this->UserTable = TableRegistry::get($table);
         }
     }
     $this->_controller->set('userTable', $this->UserTable->alias());
 }
Example #25
0
 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]);
 }
Example #26
0
 /**
  * Constructor
  *
  * @param \Cake\ORM\Query $query Query from where results come
  * @param \Cake\Database\StatementInterface $statement The statement to fetch from
  */
 public function __construct($query, $statement)
 {
     $repository = $query->repository();
     $this->_statement = $statement;
     $this->_driver = $query->connection()->driver();
     $this->_defaultTable = $query->repository();
     $this->_calculateAssociationMap($query);
     $this->_hydrate = $query->hydrate();
     $this->_entityClass = $repository->entityClass();
     $this->_useBuffering = $query->bufferResults();
     $this->_defaultAlias = $this->_defaultTable->alias();
     $this->_calculateColumnMap($query);
     $this->_calculateTypeMap();
     if ($this->_useBuffering) {
         $count = $this->count();
         $this->_results = new SplFixedArray($count);
     }
 }
 /**
  * Generate a mock of the ProfferPath class with various set returns to ensure that the path is always consistent
  *
  * @param Table $table Instance of the table
  * @param Entity $entity Instance of the entity
  * @return \PHPUnit_Framework_MockObject_MockObject
  */
 private function getProfferPathMock(Table $table, Entity $entity)
 {
     $path = $this->getMockBuilder('Proffer\\Lib\\ProfferPath')->setConstructorArgs([$table, $entity, 'photo', $this->config['photo']])->setMethods(['fullPath', 'getFolder'])->getMock();
     $path->expects($this->any())->method('fullPath')->with($this->logicalOr($this->equalTo(null), $this->equalTo('square'), $this->equalTo('portrait')))->will($this->returnCallback(function ($param) use($table, $entity) {
         $filename = '';
         if ($param !== null) {
             $filename = $param . '_';
         }
         $entityFieldData = $entity->get('photo');
         if (is_array($entityFieldData)) {
             $filename .= $entityFieldData['name'];
         } else {
             $filename .= $entityFieldData;
         }
         return TMP . 'ProfferTests' . DS . $table->alias() . DS . 'photo' . DS . 'proffer_test' . DS . $filename;
     }));
     $path->expects($this->any())->method('getFolder')->willReturn(TMP . 'ProfferTests' . DS . $table->alias() . DS . 'photo' . DS . 'proffer_test' . DS);
     return $path;
 }
Example #28
0
 public function findPath(Query $query, array $options)
 {
     if (empty($options['for'])) {
         throw new \InvalidArgumentException("The 'for' key is required for find('path')");
     }
     $for = $options['for'];
     $ancestor_table = $this->getAncestorTable($this->_table);
     $model_alias = $this->_table->alias();
     $ancestor_table->belongsTo($model_alias, ['className' => $model_alias, 'foreignKey' => 'ancestor_id', 'propertyName' => 'linked_node']);
     $query = $ancestor_table->find();
     $query->contain([$model_alias]);
     $query->order(['level' => 'asc']);
     $query->where(['node_id' => $for]);
     $nodes = [];
     foreach ($query as $ancestor_entity) {
         $nodes[] = $ancestor_entity->linked_node;
     }
     $nodes_collections = new \Cake\Collection\Collection($nodes);
     return $nodes_collections;
 }
Example #29
0
 /**
  * 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\ORM\Entity $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);
     $alias = $this->_table->alias();
     foreach ($find as $i => $translation) {
         if (!empty($results[$i])) {
             $contents[$i]->set('id', $results[$i], ['setter' => false]);
             $contents[$i]->isNew(false);
         } else {
             $translation['model'] = $alias;
             $contents[$i]->set($translation, ['setter' => false, 'guard' => false]);
             $contents[$i]->isNew(true);
         }
     }
     $entity->set('_i18n', $contents);
 }
Example #30
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;
 }