/** * Triggered when we're passed an error from the `WhistleComponent` * * @param array $error * @return void */ public function error($error) { $error['level'] = $this->_translateError($error['level']); $data = array(); if ($this->_model->name == 'RefereeLog') { if (!empty($error['args'])) { $error['args'] = serialize($error['args']); } if (!empty($error['trace'])) { $error['trace'] = serialize($error['trace']); } if (!empty($error['request_parameters'])) { $error['request_parameters'] = serialize($error['request_parameters']); } $data = $error; } else { $schema = array_keys($this->_model->schema()); $mapping = $this->_config['mapping']; foreach ($error as $key => $value) { if (!empty($mapping[$key])) { if (is_array($mapping[$key])) { $column = array_pop(array_intersect($mapping[$key], $schema)); } else { $column = in_array($mapping[$key], $schema) ? $mapping[$key] : null; } if (!empty($column)) { $data[$column] = $value; } } } } $this->_model->save($data); }
/** * Initiate behavior for the model using specified settings. * Available settings: * * @param object $Model Model using the behaviour * @param array $config Settings to override for model. * @return void */ public function setup(Model $Model, $config = array()) { if (!isset($this->settings[$Model->alias])) { $this->settings[$Model->alias] = $this->_defaultConfig; } $this->settings[$Model->alias] = $config + $this->settings[$Model->alias]; if (empty($this->settings[$Model->alias]['fields'])) { $schema = $Model->schema(); $fields = array(); foreach ($schema as $field => $v) { if (!in_array($v['type'], array('string', 'text'))) { continue; } if (!empty($v['key'])) { continue; } if (isset($v['length']) && $v['length'] === 1) { // TODO: also skip UUID (lenght 36)? continue; } $fields[] = $field; } $this->settings[$Model->alias]['fields'] = $fields; } if ($this->settings[$Model->alias]['mergeQuotes'] === true) { $this->settings[$Model->alias]['mergeQuotes'] = '"'; } }
public function setup(Model $model, $config = array()) { $this->config = Hash::merge(self::$defaultConfig, (array) $config); if (!$model->schema($this->config['field'])) { throw new BadFunctionCallException(__d('optimistic_lock', 'Model %s doesn\'t have field %s.', $model->alias, $this->config['field'])); } }
/** * Adjust configs like: $Model->Behaviors-attach('Tools.DecimalInput', array('fields'=>array('xyz'))) * leave fields empty to auto-detect all float inputs * * @return void */ public function setup(Model $Model, $config = array()) { $this->settings[$Model->alias] = $this->_defaultConfig; if (!empty($config['strict'])) { $this->settings[$Model->alias]['transform']['.'] = '#'; } if ($this->settings[$Model->alias]['localeconv'] || !empty($config['localeconv'])) { // use locale settings $conv = localeconv(); $loc = array('decimals' => $conv['decimal_point'], 'thousands' => $conv['thousands_sep']); } elseif ($configure = Configure::read('Localization')) { // Use configure settings $loc = (array) $configure; } if (!empty($loc)) { $this->settings[$Model->alias]['transform'] = array($loc['thousands'] => $this->settings[$Model->alias]['transform']['.'], $loc['decimals'] => $this->settings[$Model->alias]['transform'][',']); } $this->settings[$Model->alias] = $config + $this->settings[$Model->alias]; $numberFields = array(); $schema = $Model->schema(); foreach ($schema as $key => $values) { if (isset($values['type']) && !in_array($key, $this->settings[$Model->alias]['fields']) && in_array($values['type'], $this->settings[$Model->alias]['observedTypes'])) { array_push($numberFields, $key); } } $this->settings[$Model->alias]['fields'] = array_merge($this->settings[$Model->alias]['fields'], $numberFields); }
/** * MetaBehavior::setup() * * @param Model $model is being run * @param array $config for model * @return boolean setup status */ public function setup(Model $model, $config = array()) { // Loading Meta model to set find and save on the target table $this->Meta = ClassRegistry::init("MetaBehavior.Meta"); // Storing current schema to compare with $this->data in beforeSave callback $this->schema = array_keys($model->schema()); return true; }
/** * Informa se o registro existe e esta ativo (não deletado). * Caso modelo não tenha o campo relacionado ao SoftDelete, apenas * retorna um Model::exists para o registro. * * @param Model $Model * @param int $id ID do registro * @return bool */ public function active($Model, $id) { $schema = $Model->schema(); if (!isset($schema[$this->settings[$Model->alias]['field']])) { return $Model->exists($id); } return (bool) $Model->find('count', array('conditions' => array($Model->alias . '.' . $Model->primaryKey => $id, $Model->alias . '.' . $this->settings[$Model->alias]['field'] => false), 'recursive' => -1, 'callbacks' => false)); }
/** * Setup the model * * @param object Model $Model * @param array $settings * * @return boolean */ public function setup(Model $Model, $settings = array()) { if (isset($settings['with'])) { $base = array('schema' => $Model->schema()); $settings = array_merge($settings, $base); return $this->settings[$Model->alias] = $settings; } }
/** * Setup * * @param Model $model * @param array $config * @return void * @access public */ public function setup(Model $model, $config = array()) { $this->floatFields[$model->alias] = array(); foreach ($model->schema() as $field => $spec) { if ($spec['type'] == 'float') { $this->floatFields[$model->alias][] = $field; } } }
/** * Removes the DESCRIBE stuff from the SQL log */ function schema($field = false) { $db =& ConnectionManager::getDataSource($this->useDbConfig); $fullDebug = $db->fullDebug; $db->fullDebug = false; $return = parent::schema($field); $db->fullDebug = $fullDebug; return $return; }
/** * Join the tables passed in based off the Schema. * * @return void * @author Justin Palmer **/ public function join($args) { $args = func_get_args(); foreach ($args as $key) { if (!$this->model->schema()->relationships->isKey($key)) { throw new NoSchemaRelationshipDefinedException($this->model->table_name(), $key); } $this->relationships[] = $this->model->schema()->relationships->get($key); } return $this->model; }
/** * function beforeSave * * Looks for nullable fields in the schema and replaces empty string values for those fields * with NULL values. This is helpful as hell when foreign key values are nullable lest you * get lots of key constraint errors. * * @param model The model object to be saved. * @return boolean Success */ function beforeSave(Model $model, $options = array()) { $schema = $model->schema(); foreach ($schema as $field => $metadata) { if (isset($model->data[$model->alias][$field]) && !empty($metadata['null'])) { if ($model->data[$model->alias][$field] === '') { $model->data[$model->alias][$field] = null; } } } return true; }
public function beforeSave(Model $model, $options = array()) { $schema = $model->schema(); $data = current($model->data); if (isset($schema['default']) && isset($data['default'])) { // because they are still in their own tables.. // $conditionId = $model->getConditionId(); $default = $data['default']; if ($default == 1) { $model->updateAll(array($model->alias . '.default' => 0)); } } return true; }
/** * Setup enum behavior with the specified configuration settings. * * @example $actsAs = array( * 'CakePHP-Enum-Behavior.Enum' => array( * 'exemple_field' => array(1 => 'value_1', 'key' => 'value_2') * ) * ); * @param object $Model Model using this behavior * @param array $config Configuration settings for $Model */ public function setup(Model $Model, $config = array()) { $this->settings[$Model->name] = $config; $schema = $Model->schema(); foreach ($config as $field => $values) { $baseRule = array('rule' => array('inList', array_map(function ($v) { return (string) $v; }, array_keys($values)), false), 'message' => __('Please choose one of the following values : %s', join(', ', $this->__translate($values))), 'allowEmpty' => in_array(null, $values) || in_array('', $values), 'required' => false); if (isset($schema[$field]) && isset($schema[$field]['null']) && !$schema[$field]['null']) { $Model->validate[$field]['allowedValuesCreate'] = array_merge($baseRule, array('required' => true, 'on' => 'create')); $Model->validate[$field]['allowedValuesUpdate'] = array_merge($baseRule, array('on' => 'update')); } else { $Model->validate[$field]['allowedValues'] = $baseRule; } } }
/** * Initialize the fixture. * */ public function init() { if (isset($this->import) && (is_string($this->import) || is_array($this->import))) { $import = array_merge(array('connection' => 'default', 'records' => false), is_array($this->import) ? $this->import : array('model' => $this->import)); if (isset($import['model']) && App::import('Model', $import['model'])) { App::import('Model', $import['model']); list(, $modelClass) = pluginSplit($import['model']); $model = new $modelClass(null, null, $import['connection']); $db = $model->getDataSource(); if (empty($model->tablePrefix)) { $model->tablePrefix = $db->config['prefix']; } $this->fields = $model->schema(true); $this->fields[$model->primaryKey]['key'] = 'primary'; $this->table = $db->fullTableName($model, false); ClassRegistry::config(array('ds' => 'test')); ClassRegistry::flush(); } elseif (isset($import['table'])) { $model = new Model(null, $import['table'], $import['connection']); $db = ConnectionManager::getDataSource($import['connection']); $db->cacheSources = false; $model->useDbConfig = $import['connection']; $model->name = Inflector::camelize(Inflector::singularize($import['table'])); $model->table = $import['table']; $model->tablePrefix = $db->config['prefix']; $this->fields = $model->schema(true); ClassRegistry::flush(); } if (!empty($db->config['prefix']) && strpos($this->table, $db->config['prefix']) === 0) { $this->table = str_replace($db->config['prefix'], '', $this->table); } if (isset($import['records']) && $import['records'] !== false && isset($model) && isset($db)) { $this->records = array(); $query = array('fields' => $db->fields($model, null, array_keys($this->fields)), 'table' => $db->fullTableName($model), 'alias' => $model->alias, 'conditions' => array(), 'order' => null, 'limit' => null, 'group' => null); $records = $db->fetchAll($db->buildStatement($query, $model), false, $model->alias); if ($records !== false && !empty($records)) { $this->records = Set::extract($records, '{n}.' . $model->alias); } } } if (!isset($this->table)) { $this->table = Inflector::underscore(Inflector::pluralize($this->name)); } if (!isset($this->primaryKey) && isset($this->fields['id'])) { $this->primaryKey = 'id'; } }
public function setup(Model $Model, $settings = array()) { $this->settings[$Model->alias] = $settings + static::$defaultSettings + array('defaults' => function () use($Model) { static $defaultFields = null; if (is_null($defaultFields)) { $schema = $Model->schema(); $defaultFields = array(); if ($schema) { foreach ($schema as $field => $options) { $defaultFields[$field] = isset($options['default']) ? $options['default'] : null; } $defaultFields += array($Model->primaryKey => null); } } return $defaultFields; }); }
/** * Automatically detect primary key data type for `_validateId()` * * Binary or string with length of 36 chars will be detected as UUID * If the primary key is a number, integer validation will be used * * If no reliable detection can be made, no validation will be made * * @return string */ protected function _detectPrimaryKeyFieldType() { if (empty($this->_model) || empty($this->_modelName)) { $this->_setModelProperties(); } $fInfo = $this->_model->schema($this->_model->primaryKey); if (empty($fInfo)) { return false; } if ($fInfo['length'] == 36 && ($fInfo['type'] === 'string' || $fInfo['type'] === 'binary')) { return 'uuid'; } if ($fInfo['type'] === 'integer') { return 'integer'; } return false; }
/** * generateValidationRules * * @param Model $Model * @param array * @return void */ public function generateValidationRules(Model $Model) { $schema = $Model->schema(); foreach ($schema as $field => $meta) { if ($field === $Model->primaryKey) { continue; } if ($meta['null'] === false) { $Model->validate[$field]['notEmpty'] = array('rule' => 'notEmpty', 'empty' => false, 'message' => __('This field can not be empty.')); } if ($meta['type'] === 'boolean') { $Model->validate[$field]['boolean'] = array('rule' => 'boolean', 'empty' => false, 'message' => __('This field can not be empty.')); } if ($meta['type'] === 'string') { $Model->validate[$field]['length'] = array('rule' => array('length', $meta['length']), 'empty' => false, 'message' => __('This field can not be longer than %d.', $meta['length'])); } } }
/** * Get mapping for the given type * * @param string $type Can be 'app' or a plugin name * @param bool $cache Whether to return the cached value or not * @return mixed False in case of no file found or empty mapping, array with mapping */ public function getMapping($type, $cache = true) { if ($type !== 'app') { $type = Inflector::camelize($type); } if ($cache && !empty($this->_mapping[$type])) { return $this->_mapping[$type]; } $mapping = $this->_enumerateMigrations($type); if (empty($mapping)) { return false; } $migrated = $this->Version->find('all', array('conditions' => array('OR' => array(array($this->Version->alias . '.type' => Inflector::underscore($type)), array($this->Version->alias . '.type' => $type))), 'recursive' => -1)); // For BC, 002 was not applied yet. $bc = $this->Version->schema('class') === null; if ($bc) { $migrated = Hash::combine($migrated, '{n}.' . $this->Version->alias . '.version', '{n}.' . $this->Version->alias . '.created'); } else { $migrated = Hash::combine($migrated, '{n}.' . $this->Version->alias . '.class', '{n}.' . $this->Version->alias . '.created'); } $bcMapping = array(); if ($type === 'Migrations') { $bcMapping = array('InitMigrations' => 'M4af6e0f0a1284147a0b100ca58157726', 'ConvertVersionToClassNames' => 'M4ec50d1f7a284842b1b770fdcbdd56cb'); } ksort($mapping); foreach ($mapping as $version => $migration) { list($name, $class) = each($migration); $mapping[$version] = array('version' => $version, 'name' => $name, 'class' => $class, 'type' => $type, 'migrated' => null); if ($bc) { if (isset($migrated[$version])) { $mapping[$version]['migrated'] = $migrated[$version]; } } else { if (isset($migrated[$class])) { $mapping[$version]['migrated'] = $migrated[$class]; } elseif (isset($bcMapping[$class]) && !empty($migrated[$bcMapping[$class]])) { $mapping[$version]['migrated'] = $migrated[$bcMapping[$class]]; } } } $this->_mapping[$type] = $mapping; return $mapping; }
/** * getTables * * * @params * @return */ function getTables() { $db =& ConnectionManager::getDataSource($this->useDbConfig); $usePrefix = empty($db->config['prefix']) ? '' : $db->config['prefix']; if ($usePrefix) { $tables = array(); foreach ($db->listSources() as $table) { if (!strncmp($table, $usePrefix, strlen($usePrefix))) { $tables[] = substr($table, strlen($usePrefix)); } } } else { $tables = $db->listSources(); } $schema = array(); foreach ($tables as $key => $value) { $tempModel = new Model(array('table' => $value, 'ds' => $this->useDbConfig)); $fields = $tempModel->schema(); $schema[$value]['fields'] = $fields; } return $schema; }
/** * Setup method * * Use the model's label field as the default field on which to base the slug, the label can be made up of multiple * fields by specifying an array of fields * * @param Model $Model * @param array $config * @return void */ public function setup(Model $Model, $config = []) { $defaults = ['notices' => Configure::read('debug'), 'label' => [$Model->displayField]]; $defaults += $this->_defaultConfig; foreach ($defaults['replace'] as $key => $value) { $defaults['replace'][$key] = __d('tools', $value); } $config += (array) Configure::read('Slugged'); $config += $defaults; if ($config['length'] === null) { $schema = $Model->schema($config['slugField']); $length = !empty($schema['length']) ? $schema['length'] : 0; $config['length'] = $length; } $this->settings[$Model->alias] = $config; extract($this->settings[$Model->alias]); $label = $this->settings[$Model->alias]['label'] = (array) $label; if ($Model->Behaviors->loaded('Translate')) { $notices = false; } if ($notices) { foreach ($label as $field) { $alias = $Model->alias; if (strpos($field, '.')) { list($alias, $field) = explode('.', $field); if (!$Model->{$alias}->hasField($field)) { trigger_error('(SluggedBehavior::setup) model ' . $Model->{$alias}->name . ' is missing the field ' . $field . ' (specified in the setup for model ' . $Model->name . ') ', E_USER_WARNING); $Model->Behaviors->disable($this->name); } } elseif (!$Model->hasField($field)) { trigger_error('(SluggedBehavior::setup) model ' . $Model->name . ' is missing the field ' . $field . ' specified in the setup.', E_USER_WARNING); $Model->Behaviors->disable($this->name); } } } }
/** * Finds all possible keys to use on custom associations. * * @return array array of tables and possible keys */ protected function _generatePossibleKeys() { $possible = array(); foreach ($this->_tables as $otherTable) { $tempOtherModel = new Model(array('table' => $otherTable, 'ds' => $this->connection)); $modelFieldsTemp = $tempOtherModel->schema(true); foreach ($modelFieldsTemp as $fieldName => $field) { if ($field['type'] == 'integer' || $field['type'] == 'string') { $possible[$otherTable][] = $fieldName; } } } return $possible; }
/** * Handles interactive baking * * @access private */ function __interactive() { $this->hr(); $this->out(sprintf("Bake Model\nPath: %s", $this->path)); $this->hr(); $this->interactive = true; $primaryKey = 'id'; $validate = $associations = array(); if (empty($this->connection)) { $this->connection = $this->DbConfig->getConfig(); } $currentModelName = $this->getName(); $useTable = $this->getTable($currentModelName); $db =& ConnectionManager::getDataSource($this->connection); $fullTableName = $db->fullTableName($useTable); if (in_array($useTable, $this->_tables)) { $tempModel = new Model(array('name' => $currentModelName, 'table' => $useTable, 'ds' => $this->connection)); $fields = $tempModel->schema(true); if (!array_key_exists('id', $fields)) { $primaryKey = $this->findPrimaryKey($fields); } } else { $this->err(sprintf(__('Table %s does not exist, cannot bake a model without a table.', true), $useTable)); $this->_stop(); return false; } $displayField = $tempModel->hasField(array('name', 'title')); if (!$displayField) { $displayField = $this->findDisplayField($tempModel->schema()); } $prompt = __("Would you like to supply validation criteria \nfor the fields in your model?", true); $wannaDoValidation = $this->in($prompt, array('y', 'n'), 'y'); if (array_search($useTable, $this->_tables) !== false && strtolower($wannaDoValidation) == 'y') { $validate = $this->doValidation($tempModel); } $prompt = __("Would you like to define model associations\n(hasMany, hasOne, belongsTo, etc.)?", true); $wannaDoAssoc = $this->in($prompt, array('y', 'n'), 'y'); if (strtolower($wannaDoAssoc) == 'y') { $associations = $this->doAssociations($tempModel); } $this->out(); $this->hr(); $this->out(__('The following Model will be created:', true)); $this->hr(); $this->out("Name: " . $currentModelName); if ($this->connection !== 'default') { $this->out(sprintf(__("DB Config: %s", true), $this->connection)); } if ($fullTableName !== Inflector::tableize($currentModelName)) { $this->out(sprintf(__("DB Table: %s", true), $fullTableName)); } if ($primaryKey != 'id') { $this->out(sprintf(__("Primary Key: %s", true), $primaryKey)); } if (!empty($validate)) { $this->out(sprintf(__("Validation: %s", true), print_r($validate, true))); } if (!empty($associations)) { $this->out(__("Associations:", true)); $assocKeys = array('belongsTo', 'hasOne', 'hasMany', 'hasAndBelongsToMany'); foreach ($assocKeys as $assocKey) { $this->_printAssociation($currentModelName, $assocKey, $associations); } } $this->hr(); $looksGood = $this->in(__('Look okay?', true), array('y', 'n'), 'y'); if (strtolower($looksGood) == 'y') { $vars = compact('associations', 'validate', 'primaryKey', 'useTable', 'displayField'); $vars['useDbConfig'] = $this->connection; if ($this->bake($currentModelName, $vars)) { if ($this->_checkUnitTest()) { $this->bakeFixture($currentModelName, $useTable); $this->bakeTest($currentModelName, $useTable, $associations); } } } else { return false; } }
/** * Generates the fields list of an SQL query. * * @param Model $model * @param string $alias Alias tablename * @param mixed $fields * @param boolean $quote If false, returns fields array unquoted * @return array * @access public */ function fields(&$model, $alias = null, $fields = array(), $quote = true) { if (empty($alias)) { $alias = $model->alias; } $cacheKey = array($model->useDbConfig, $model->table, array_keys($model->schema()), $model->name, $model->getVirtualField(), $alias, $fields, $quote); $cacheKey = crc32(serialize($cacheKey)); if ($return = $this->cacheMethod(__FUNCTION__, $cacheKey)) { return $return; } $allFields = empty($fields); if ($allFields) { $fields = array_keys($model->schema()); } elseif (!is_array($fields)) { $fields = String::tokenize($fields); } $fields = array_values(array_filter($fields)); $allFields = $allFields || in_array('*', $fields) || in_array($model->alias . '.*', $fields); $virtual = array(); $virtualFields = $model->getVirtualField(); if (!empty($virtualFields)) { $virtualKeys = array_keys($virtualFields); foreach ($virtualKeys as $field) { $virtualKeys[] = $model->alias . '.' . $field; } $virtual = $allFields ? $virtualKeys : array_intersect($virtualKeys, $fields); foreach ($virtual as $i => $field) { if (strpos($field, '.') !== false) { $virtual[$i] = str_replace($model->alias . '.', '', $field); } $fields = array_diff($fields, array($field)); } $fields = array_values($fields); } if (!$quote) { if (!empty($virtual)) { $fields = array_merge($fields, $this->_constructVirtualFields($model, $alias, $virtual)); } return $fields; } $count = count($fields); if ($count >= 1 && !in_array($fields[0], array('*', 'COUNT(*)'))) { for ($i = 0; $i < $count; $i++) { if (is_string($fields[$i]) && in_array($fields[$i], $virtual)) { unset($fields[$i]); continue; } if (is_object($fields[$i]) && isset($fields[$i]->type) && $fields[$i]->type === 'expression') { $fields[$i] = $fields[$i]->value; } elseif (preg_match('/^\\(.*\\)\\s' . $this->alias . '.*/i', $fields[$i])) { continue; } elseif (!preg_match('/^.+\\(.*\\)/', $fields[$i])) { $prepend = ''; if (strpos($fields[$i], 'DISTINCT') !== false) { $prepend = 'DISTINCT '; $fields[$i] = trim(str_replace('DISTINCT', '', $fields[$i])); } $dot = strpos($fields[$i], '.'); if ($dot === false) { $prefix = !(strpos($fields[$i], ' ') !== false || strpos($fields[$i], '(') !== false); $fields[$i] = $this->name(($prefix ? $alias . '.' : '') . $fields[$i]); } else { $value = array(); $comma = strpos($fields[$i], ','); if ($comma === false) { $build = explode('.', $fields[$i]); if (!Set::numeric($build)) { $fields[$i] = $this->name(implode('.', $build)); } } } $fields[$i] = $prepend . $fields[$i]; } elseif (preg_match('/\\(([\\.\\w]+)\\)/', $fields[$i], $field)) { if (isset($field[1])) { if (strpos($field[1], '.') === false) { $field[1] = $this->name($alias . '.' . $field[1]); } else { $field[0] = explode('.', $field[1]); if (!Set::numeric($field[0])) { $field[0] = implode('.', array_map(array(&$this, 'name'), $field[0])); $fields[$i] = preg_replace('/\\(' . $field[1] . '\\)/', '(' . $field[0] . ')', $fields[$i], 1); } } } } } } if (!empty($virtual)) { $fields = array_merge($fields, $this->_constructVirtualFields($model, $alias, $virtual)); } return $this->cacheMethod(__FUNCTION__, $cacheKey, array_unique($fields)); }
/** * Interact with the user to get a custom SQL condition and use that to extract data * to build a fixture. * * @param string $modelName name of the model to take records from. * @param string $useTable Name of table to use. * @return array Array of records. */ protected function _getRecordsFromTable($modelName, $useTable = null) { $modelObject = new Model(array('name' => $modelName, 'table' => $useTable, 'ds' => $this->connection)); if ($this->interactive) { $condition = null; $prompt = __d('cake_console', "Please provide a SQL fragment to use as conditions\nExample: WHERE 1=1"); while (!$condition) { $condition = $this->in($prompt, null, 'WHERE 1=1'); } $recordsFound = $modelObject->find('count', array('conditions' => $condition, 'recursive' => -1)); $prompt = __d('cake_console', "How many records do you want to import?"); $recordCount = $this->in($prompt, null, $recordsFound < 10 ? $recordsFound : 10); } else { $condition = 'WHERE 1=1'; $recordCount = isset($this->params['count']) ? $this->params['count'] : 10; } $records = $modelObject->find('all', array('conditions' => $condition, 'recursive' => -1, 'limit' => $recordCount)); $schema = $modelObject->schema(true); $out = array(); foreach ($records as $record) { $row = array(); foreach ($record[$modelObject->alias] as $field => $value) { if ($schema[$field]['type'] === 'boolean') { $value = (int) (bool) $value; } $row[$field] = $value; } $out[] = $row; } return $out; }
/** * TranslateBehavior::beforeFind * callback * * @param Model $Model modelo que actua como este Behavior. * @param array $query * @return array Modified query * @access public */ function beforeFind(&$Model, $query) { /* * @TODO checar por que trae todos los modelos relacionados aun cuando no se le indica ningun contain * y solo cuando se hace desde un controller que no es el propio al modelo */ #pr($this->settings); if ($this->__notAllow($Model)) { return $query; } $this->Model = $Model; $this->alias = $Model->alias; $this->query[$this->alias] = $query; $this->contains[$this->alias] = array(); $this->traducibles[$this->alias] = array(); if (empty($this->locale)) { $this->locale = array(Configure::read("I18n.Locale")); } $locale = $this->locale; $db =& ConnectionManager::getDataSource($Model->useDbConfig); $tablePrefix = $this->I18n->tablePrefix; !empty($this->query[$this->alias]['contain']) ? $this->query[$this->alias]['contain'] = am($this->query[$this->alias]['contain'], $this->__getContainableParams()) : ($this->query[$this->alias]['contain'] = $this->__getContainableParams()); # se pasan los joins a una variable auxiliar para poner hasta al final estos joins if (is_string($this->query[$this->alias]['joins'])) { $joins = array($this->query[$this->alias]['joins']); } elseif (is_array($this->query[$this->alias]['joins'])) { $joins = $this->query[$this->alias]['joins']; $this->query[$this->alias]['joins'] = array(); } #esto se hace cuando se usa el paginate, ya que este primero hace un count de los elementos #pr($this->query); if (is_string($this->query[$this->alias]['fields']) && 'COUNT(*) AS ' . $db->name('count') == $this->query[$this->alias]['fields']) { $this->query[$this->alias]['fields'] = 'COUNT(DISTINCT(' . $db->name($Model->alias . '.' . $Model->primaryKey) . ')) ' . $db->alias . 'count'; if (is_string($this->query[$this->alias]['joins'])) { $this->query[$this->alias]['joins'] = array($this->query[$this->alias]['joins']); } $this->query[$this->alias]['joins'][] = array('type' => 'LEFT', 'alias' => $this->I18n->alias, 'table' => $db->name($tablePrefix . $this->I18n->useTable), 'conditions' => array($Model->alias . '.' . $Model->primaryKey => $db->identifier($this->I18n->alias . '.foreign_key'), $this->I18n->alias . '.model' => $Model->name, $this->I18n->alias . '.locale' => $locale)); #pr($this->query); #se ponen los joins que venian originalmente en $query['joins'] al final del arreglo if (!empty($joins)) { foreach ($joins as $join) { $this->query[$this->alias]['joins'][] = $join; } } if (!empty($this->query[$this->alias]['contain'])) { $this->__changeContain($this->query[$this->alias]['contain'], $this->contains[$this->alias], $this->Model); } if (!empty($this->contains[$this->alias])) { $this->__containsToJoins($this->contains[$this->alias]); } $this->__changeFields(); if (!empty($this->query[$this->alias]['conditions'])) { $this->__changeConditions($this->query[$this->alias]['conditions']); } if (!empty($this->query[$this->alias]['order'])) { $this->query[$this->alias]['order'] = $this->__changeOrder($this->query[$this->alias]['order']); } //Debug::dump($this->query,'fin count'); return $this->query[$this->alias]; } #pr($this->query['fields']); #si no se especifica ningun campo se traen todos los campos del modelo if (empty($this->query[$this->alias]['fields'])) { $traducibles = array(); if ($this->isTranslate($this->Model)) { $traducibles = $this->Model->Behaviors->Translate->settings[$this->Model->alias]; } #pr($traducibles); foreach (am(array_keys($this->Model->schema()), $traducibles) as $tableField) { $this->query[$this->alias]['fields'][] = sprintf("%s.%s", $this->Model->alias, $tableField); } #$this->query['fields'][]=$Model->alias.".*"; } #pr($this->query['fields']); #se ponen los joins que venian originalmente en $query['joins'] al final del arreglo if (!empty($joins)) { foreach ($joins as $join) { $this->query[$this->alias]['joins'][] = $join; } } if (!empty($this->query[$this->alias]['contain'])) { $this->__changeContain($this->query[$this->alias]['contain'], $this->contains[$this->alias], $this->Model); } if (!empty($this->contains[$this->alias])) { $this->__containsToJoins($this->contains[$this->alias]); } //Debug::dump($this->query['fields']); #Se quitan los campos traducibles para los modelos afectados $this->__changeFields(); #debug($this->traducibles); #Esto es parte del translate behavior y no se para que es if (is_array($this->query[$this->alias]['fields'])) { $this->query[$this->alias]['fields'] = array_merge($this->query[$this->alias]['fields']); } if (!empty($this->query[$this->alias]['conditions'])) { $this->__changeConditions($this->query[$this->alias]['conditions']); } if (!empty($this->query[$this->alias]['order'])) { $this->query[$this->alias]['order'] = $this->__changeOrder($this->query[$this->alias]['order']); } #pr($this->query); #pr($this->contains); return $this->query[$this->alias]; }
/** * Handles interactive baking * * @access private */ function __interactive() { $this->hr(); $this->out(sprintf("Bake Model\nPath: %s", $this->path)); $this->hr(); $this->interactive = true; $useTable = null; $primaryKey = 'id'; $validate = array(); $associations = array('belongsTo' => array(), 'hasOne' => array(), 'hasMany' => array(), 'hasAndBelongsToMany' => array()); $useDbConfig = 'default'; $configs = get_class_vars('DATABASE_CONFIG'); if (!is_array($configs)) { return $this->DbConfig->execute(); } $connections = array_keys($configs); if (count($connections) > 1) { $useDbConfig = $this->in(__('Use Database Config', true) . ':', $connections, 'default'); } $currentModelName = $this->getName($useDbConfig); $db =& ConnectionManager::getDataSource($useDbConfig); $useTable = Inflector::tableize($currentModelName); $fullTableName = $db->fullTableName($useTable, false); $tableIsGood = false; if (array_search($useTable, $this->__tables) === false) { $this->out(''); $this->out(sprintf(__("Given your model named '%s', Cake would expect a database table named %s", true), $currentModelName, $fullTableName)); $tableIsGood = $this->in(__('Do you want to use this table?', true), array('y', 'n'), 'y'); } if (low($tableIsGood) == 'n' || low($tableIsGood) == 'no') { $useTable = $this->in(__('What is the name of the table (enter "null" to use NO table)?', true)); } while ($tableIsGood == false && low($useTable) != 'null') { if (is_array($this->__tables) && !in_array($useTable, $this->__tables)) { $fullTableName = $db->fullTableName($useTable, false); $this->out($fullTableName . ' does not exist.'); $useTable = $this->in(__('What is the name of the table (enter "null" to use NO table)?', true)); $tableIsGood = false; } else { $tableIsGood = true; } } $wannaDoValidation = $this->in(__('Would you like to supply validation criteria for the fields in your model?', true), array('y', 'n'), 'y'); if (in_array($useTable, $this->__tables)) { App::import('Model'); $tempModel = new Model(array('name' => $currentModelName, 'table' => $useTable, 'ds' => $useDbConfig)); $fields = $tempModel->schema(); if (!array_key_exists('id', $fields)) { foreach ($fields as $name => $field) { if (isset($field['key']) && $field['key'] == 'primary') { break; } } $primaryKey = $this->in(__('What is the primaryKey?', true), null, $name); } } if (array_search($useTable, $this->__tables) !== false && (low($wannaDoValidation) == 'y' || low($wannaDoValidation) == 'yes')) { $validate = $this->doValidation($tempModel); } $wannaDoAssoc = $this->in(__('Would you like to define model associations (hasMany, hasOne, belongsTo, etc.)?', true), array('y', 'n'), 'y'); if (low($wannaDoAssoc) == 'y' || low($wannaDoAssoc) == 'yes') { $associations = $this->doAssociations($tempModel); } $this->out(''); $this->hr(); $this->out(__('The following Model will be created:', true)); $this->hr(); $this->out("Name: " . $currentModelName); if ($useDbConfig !== 'default') { $this->out("DB Config: " . $useDbConfig); } if ($fullTableName !== Inflector::tableize($currentModelName)) { $this->out("DB Table: " . $fullTableName); } if ($primaryKey != 'id') { $this->out("Primary Key: " . $primaryKey); } if (!empty($validate)) { $this->out("Validation: " . print_r($validate, true)); } if (!empty($associations)) { $this->out("Associations:"); if (!empty($associations['belongsTo'])) { for ($i = 0; $i < count($associations['belongsTo']); $i++) { $this->out("\t\t\t{$currentModelName} belongsTo {$associations['belongsTo'][$i]['alias']}"); } } if (!empty($associations['hasOne'])) { for ($i = 0; $i < count($associations['hasOne']); $i++) { $this->out("\t\t\t{$currentModelName} hasOne\t{$associations['hasOne'][$i]['alias']}"); } } if (!empty($associations['hasMany'])) { for ($i = 0; $i < count($associations['hasMany']); $i++) { $this->out("\t\t\t{$currentModelName} hasMany\t{$associations['hasMany'][$i]['alias']}"); } } if (!empty($associations['hasAndBelongsToMany'])) { for ($i = 0; $i < count($associations['hasAndBelongsToMany']); $i++) { $this->out("\t\t\t{$currentModelName} hasAndBelongsToMany {$associations['hasAndBelongsToMany'][$i]['alias']}"); } } } $this->hr(); $looksGood = $this->in(__('Look okay?', true), array('y', 'n'), 'y'); if (low($looksGood) == 'y' || low($looksGood) == 'yes') { if ($this->bake($currentModelName, $associations, $validate, $primaryKey, $useTable, $useDbConfig)) { if ($this->_checkUnitTest()) { $this->bakeTest($currentModelName, $useTable, $associations); } } } else { return false; } }
/** * Quotes and prepares fields and values for an SQL UPDATE statement * * @param Model $Model The model to prepare fields for. * @param array $fields The fields to update. * @param bool $quoteValues If values should be quoted, or treated as SQL snippets * @param bool $alias Include the model alias in the field name * @return array Fields and values, quoted and prepared */ protected function _prepareUpdateFields(Model $Model, $fields, $quoteValues = true, $alias = false) { $quotedAlias = $this->startQuote . $Model->alias . $this->endQuote; $schema = $Model->schema(); $updates = array(); foreach ($fields as $field => $value) { if ($alias && strpos($field, '.') === false) { $quoted = $Model->escapeField($field); } elseif (!$alias && strpos($field, '.') !== false) { $quoted = $this->name(str_replace($quotedAlias . '.', '', str_replace($Model->alias . '.', '', $field))); } else { $quoted = $this->name($field); } if ($value === null) { $updates[] = $quoted . ' = NULL'; continue; } $update = $quoted . ' = '; if ($quoteValues) { $update .= $this->value($value, $Model->getColumnType($field), isset($schema[$field]) ? $schema[$field]['null'] : true); } elseif ($Model->getColumnType($field) === 'boolean' && (is_int($value) || is_bool($value))) { $update .= $this->boolean($value, true); } elseif (!$alias) { $update .= str_replace($quotedAlias . '.', '', str_replace($Model->alias . '.', '', $value)); } else { $update .= $value; } $updates[] = $update; } return $updates; }
/** * Return the Model schema. * * @param Model|string $model * @return array */ public function describe($model) { return $model->schema(); }
function schema() { $schema = array("id" => "", "name" => "", "email" => "", "password" => ""); return parent::schema($schema); }
/** * Generates the fields list of an SQL query. * * @param Model $model * @param string $alias Alias tablename * @param mixed $fields * @param boolean $quote If false, returns fields array unquoted * @return array */ public function fields(&$model, $alias = null, $fields = array(), $quote = true) { if (empty($alias)) { $alias = $model->alias; } if (empty($fields)) { $fields = array_keys($model->schema()); } elseif (!is_array($fields)) { $fields = String::tokenize($fields); } $fields = array_values(array_filter($fields)); if (!$quote) { return $fields; } $count = count($fields); if ($count >= 1 && !in_array($fields[0], array('*', 'COUNT(*)'))) { for ($i = 0; $i < $count; $i++) { if (preg_match('/^\\(.*\\)\\s' . $this->alias . '.*/i', $fields[$i])) { continue; } elseif (!preg_match('/^.+\\(.*\\)/', $fields[$i])) { $prepend = ''; if (strpos($fields[$i], 'DISTINCT') !== false) { $prepend = 'DISTINCT '; $fields[$i] = trim(str_replace('DISTINCT', '', $fields[$i])); } $dot = strpos($fields[$i], '.'); if ($dot === false) { $prefix = !(strpos($fields[$i], ' ') !== false || strpos($fields[$i], '(') !== false); $fields[$i] = $this->name(($prefix ? $alias . '.' : '') . $fields[$i]); } else { $value = array(); $comma = strpos($fields[$i], ','); if ($comma === false) { $build = explode('.', $fields[$i]); if (!Set::numeric($build)) { $fields[$i] = $this->name($build[0] . '.' . $build[1]); } $comma = String::tokenize($fields[$i]); foreach ($comma as $string) { if (preg_match('/^[0-9]+\\.[0-9]+$/', $string)) { $value[] = $string; } else { $build = explode('.', $string); $value[] = $this->name(trim($build[0]) . '.' . trim($build[1])); } } $fields[$i] = implode(', ', $value); } } $fields[$i] = $prepend . $fields[$i]; } elseif (preg_match('/\\(([\\.\\w]+)\\)/', $fields[$i], $field)) { if (isset($field[1])) { if (strpos($field[1], '.') === false) { $field[1] = $this->name($alias . '.' . $field[1]); } else { $field[0] = explode('.', $field[1]); if (!Set::numeric($field[0])) { $field[0] = implode('.', array_map(array($this, 'name'), $field[0])); $fields[$i] = preg_replace('/\\(' . $field[1] . '\\)/', '(' . $field[0] . ')', $fields[$i], 1); } } } } } } return array_unique($fields); }