public function __construct(array $record, array $options = null) { if (isset($options['model'])) { $this->_Model = $options['model']; } else { if (!empty($this->_modelName)) { $modelName = $this->_modelName; } else { $className = get_class($this); $prefix = ActiveRecordBehavior::$defaultSettings['prefix']; if (substr($className, 0, strlen($prefix)) == $prefix) { $modelName = substr($className, strlen($prefix)); } else { $modelName = $className; } } $this->_modelName = $modelName; App::import('Model', $modelName); $this->_Model = ClassRegistry::init($modelName); } if (isset($record[$this->_Model->alias])) { $this->_Record = $record[$this->_Model->alias]; } else { $this->_Record = $record; } if (empty($options['norefresh'])) { $oldRecord = $this->_Record; $this->refresh(); $this->_Record = $oldRecord + $this->_Record; } $defaultFields = $this->_Model->activeRecordBehaviorSettings('defaults'); $this->_Record += $defaultFields(); $this->_directDelete = $this->_Model->activeRecordBehaviorSettings('directDelete'); if (isset($options['directDelete'])) { $this->_directDelete = $options['directDelete']; } $create = true; if (isset($options['create'])) { $create = $options['create']; } if ($create) { ActiveRecordManager::create($this); $this->_created = true; $this->_changed = true; } foreach ($this->_Model->associations() as $associationType) { foreach ($this->_Model->{$associationType} as $associationName => $associationDefinition) { $association = new ActiveRecordAssociation($associationName, $this, $associationType, $associationDefinition, $record, $create); $this->_associations[$associationName] = $association; unset($this->_Record[$associationName]); } } foreach ($this->_Record as $key => $value) { $this->_originalRecord[$key] = $value; } App::uses(get_class($this) . 'Immutable', 'Model/' . $this->_Model->activeRecordBehaviorSettings('subfolder')); }
/** * Replaces `{$__cakeID__$}` and `{$__cakeForeignKey__$}` placeholders in query data. * * @param string $query Query string needing replacements done. * @param array $data Array of data with values that will be inserted in placeholders. * @param string $association Name of association model being replaced * @param array $assocData * @param Model $model Instance of the model to replace $__cakeID__$ * @param Model $linkModel Instance of model to replace $__cakeForeignKey__$ * @param array $stack * @return string String of query data with placeholders replaced. */ public function insertQueryData($query, $data, $association, $assocData, Model $model, Model $linkModel, $stack) { $keys = array('{$__cakeID__$}', '{$__cakeForeignKey__$}'); foreach ($keys as $key) { $val = null; $type = null; if (strpos($query, $key) !== false) { switch ($key) { case '{$__cakeID__$}': if (isset($data[$model->alias]) || isset($data[$association])) { if (isset($data[$model->alias][$model->primaryKey])) { $val = $data[$model->alias][$model->primaryKey]; } elseif (isset($data[$association][$model->primaryKey])) { $val = $data[$association][$model->primaryKey]; } } else { $found = false; foreach (array_reverse($stack) as $assoc) { if (isset($data[$assoc]) && isset($data[$assoc][$model->primaryKey])) { $val = $data[$assoc][$model->primaryKey]; $found = true; break; } } if (!$found) { $val = ''; } } $type = $model->getColumnType($model->primaryKey); break; case '{$__cakeForeignKey__$}': foreach ($model->associations() as $name) { foreach ($model->{$name} as $assocName => $assoc) { if ($assocName === $association) { if (isset($assoc['foreignKey'])) { $foreignKey = $assoc['foreignKey']; $assocModel = $model->{$assocName}; $type = $assocModel->getColumnType($assocModel->primaryKey); if (isset($data[$model->alias][$foreignKey])) { $val = $data[$model->alias][$foreignKey]; } elseif (isset($data[$association][$foreignKey])) { $val = $data[$association][$foreignKey]; } else { $found = false; foreach (array_reverse($stack) as $assoc) { if (isset($data[$assoc]) && isset($data[$assoc][$foreignKey])) { $val = $data[$assoc][$foreignKey]; $found = true; break; } } if (!$found) { $val = ''; } } } break 3; } } } break; } if (empty($val) && $val !== '0') { return false; } $query = str_replace($key, $this->value($val, $type), $query); } } return $query; }
/** * buildRelatedModels method * * @param Model $model * @return void */ protected function _buildRelatedModels(Model $model) { foreach ($model->associations() as $type) { foreach ($model->{$type} as $assoc => $assocData) { if (is_string($assocData)) { $className = $assocData; } elseif (isset($assocData['className'])) { $className = $assocData['className']; } $model->{$className} = new $className(); $model->{$className}->schema(); } } }
/** * Replaces `{$__cakeID__$}` and `{$__cakeForeignKey__$}` placeholders in query data. * * @param string $query Query string needing replacements done. * @param array $data Array of data with values that will be inserted in placeholders. * @param string $association Name of association model being replaced. * @param Model $Model Model instance. * @param array $stack The context stack. * @return mixed String of query data with placeholders replaced, or false on failure. */ public function insertQueryData($query, $data, $association, Model $Model, $stack) { $keys = array('{$__cakeID__$}', '{$__cakeForeignKey__$}'); $modelAlias = $Model->alias; foreach ($keys as $key) { if (strpos($query, $key) === false) { continue; } $insertKey = $InsertModel = null; switch ($key) { case '{$__cakeID__$}': $InsertModel = $Model; $insertKey = $Model->primaryKey; break; case '{$__cakeForeignKey__$}': foreach ($Model->associations() as $type) { foreach ($Model->{$type} as $assoc => $assocData) { if ($assoc !== $association) { continue; } if (isset($assocData['foreignKey'])) { $InsertModel = $Model->{$assoc}; $insertKey = $assocData['foreignKey']; } break 3; } } break; } $val = $dataType = null; if (!empty($insertKey) && !empty($InsertModel)) { if (isset($data[$modelAlias][$insertKey])) { $val = $data[$modelAlias][$insertKey]; } elseif (isset($data[$association][$insertKey])) { $val = $data[$association][$insertKey]; } else { $found = false; foreach (array_reverse($stack) as $assocData) { if (is_string($assocData) && isset($data[$assocData]) && isset($data[$assocData][$insertKey])) { $val = $data[$assocData][$insertKey]; $found = true; break; } } if (!$found) { $val = ''; } } $dataType = $InsertModel->getColumnType($InsertModel->primaryKey); } if (empty($val) && $val !== '0') { return false; } $query = str_replace($key, $this->value($val, $dataType), $query); } return $query; }
/** * Process a model recursively and pull out all the * model names converting them to fixture names. * * @param Model $subject A Model class to scan for associations and pull fixtures off of. * @return void */ protected function _processModel($subject) { $this->_addFixture($subject->alias()); foreach ($subject->associations()->keys() as $alias) { $assoc = $subject->association($alias); $target = $assoc->target(); $name = $target->alias(); $subjectClass = get_class($subject); if ($subjectClass !== 'Cake\\ORM\\Table' && $subjectClass === get_class($target)) { continue; } if (!isset($this->_fixtures[$name])) { $this->_processModel($target); } if ($assoc->type() === Association::MANY_TO_MANY) { $junction = $assoc->junction(); if (!isset($this->_fixtures[$junction->alias()])) { $this->_processModel($junction); } } } }
/** * Return model alias + all model aliases from model association * (if model have associations with itself) * * @param Model $Model * @return array */ protected function _getAliases(Model $Model) { $aliases = array_merge(array($Model->alias), $this->config[$Model->alias]['aliases']); foreach ($Model->associations() as $associationType) { foreach ($Model->{$associationType} as $associationKey => $association) { if ($association['className'] === $Model->name) { $aliases[] = $associationKey; } } } return $aliases; }
/** * Process a model recursively and pull out all the * model names converting them to fixture names. * * @param Model $subject A Model class to scan for associations and pull fixtures off of. * @return void */ protected function _processModel($subject) { $this->_addFixture($subject->alias()); foreach ($subject->associations()->keys() as $alias) { $assoc = $subject->association($alias); $name = $assoc->target()->alias(); if (!isset($this->_fixtures[$name])) { $this->_processModel($assoc->target()); } if ($assoc->type() === Association::MANY_TO_MANY) { $junction = $assoc->junction(); if (!isset($this->_fixtures[$junction->alias()])) { $this->_processModel($junction); } } } }