/** * Quotes and prepares fields and values for an SQL UPDATE statement * * @param Model $model * @param array $fields * @param boolean $quoteValues If values should be quoted, or treated as SQL snippets * @param boolean $alias Include the model alias in the field name * @return array Fields and values, quoted and preparted * @access protected */ function _prepareUpdateFields(&$model, $fields, $quoteValues = true, $alias = false) { $quotedAlias = $this->startQuote . $model->alias . $this->endQuote; $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), false); } elseif (!$alias) { $update .= str_replace($quotedAlias . '.', '', str_replace($model->alias . '.', '', $value)); } else { $update .= $value; } $updates[] = $update; } return $updates; }
/** * get the maximum index value in the table. * * @param Model $Model * @param string $scope * @param string $right * @param integer $recursive * @param boolean $created * @return integer */ protected function _getMax($Model, $scope, $right, $recursive = -1, $created = false) { $db = ConnectionManager::getDataSource($Model->useDbConfig); if ($created) { if (is_string($scope)) { $scope .= " AND {$Model->alias}.{$Model->primaryKey} <> "; $scope .= $db->value($Model->id, $Model->getColumnType($Model->primaryKey)); } else { $scope['NOT'][$Model->alias . '.' . $Model->primaryKey] = $Model->id; } } $name = $Model->alias . '.' . $right; list($edge) = array_values($Model->find('first', array('conditions' => $scope, 'fields' => $db->calculate($Model, 'max', array($name, $right)), 'recursive' => $recursive))); return empty($edge[$right]) ? 0 : $edge[$right]; }
/** * 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; }
/** * Returns the column type of a given * * @param Model $model * @param string $field */ function getColumnType(&$model, $field) { return $model->getColumnType($field); }
/** * Extracts a Model.field identifier and an SQL condition operator from a string, formats * and inserts values, and composes them into an SQL snippet. * * @param string $key An SQL key snippet containing a field and optional SQL operator * @param mixed $value The value(s) to be inserted in the string * @param Model $Model Model object initiating the query * @return string */ protected function _parseKey($key, $value, Model $Model = null) { $operatorMatch = '/^(((' . implode(')|(', $this->_sqlOps); $operatorMatch .= ')\\x20?)|<[>=]?(?![^>]+>)\\x20?|[>=!]{1,3}(?!<)\\x20?)/is'; $bound = strpos($key, '?') !== false || is_array($value) && strpos($key, ':') !== false; $key = trim($key); if (strpos($key, ' ') === false) { $operator = '='; } else { list($key, $operator) = explode(' ', $key, 2); if (!preg_match($operatorMatch, trim($operator)) && strpos($operator, ' ') !== false) { $key = $key . ' ' . $operator; $split = strrpos($key, ' '); $operator = substr($key, $split); $key = substr($key, 0, $split); } } $virtual = false; $type = null; if ($Model !== null) { if ($Model->isVirtualField($key)) { $key = $this->_quoteFields($Model->getVirtualField($key)); $virtual = true; } $type = $Model->getColumnType($key); } $null = $value === null || is_array($value) && empty($value); if (strtolower($operator) === 'not') { $data = $this->conditionKeysToString(array($operator => array($key => $value)), true, $Model); return $data[0]; } $value = $this->value($value, $type); if (!$virtual && $key !== '?') { $isKey = strpos($key, '(') !== false || strpos($key, ')') !== false || strpos($key, '|') !== false; $key = $isKey ? $this->_quoteFields($key) : $this->name($key); } if ($bound) { return CakeText::insert($key . ' ' . trim($operator), $value); } if (!preg_match($operatorMatch, trim($operator))) { $operator .= is_array($value) ? ' IN' : ' ='; } $operator = trim($operator); if (is_array($value)) { $value = implode(', ', $value); switch ($operator) { case '=': $operator = 'IN'; break; case '!=': case '<>': $operator = 'NOT IN'; break; } $value = "({$value})"; } elseif ($null || $value === 'NULL') { switch ($operator) { case '=': $operator = 'IS'; break; case '!=': case '<>': $operator = 'IS NOT'; break; } } if ($virtual) { return "({$key}) {$operator} {$value}"; } return "{$key} {$operator} {$value}"; }
/** * Soft deletes a record * * @param Model $Model using this behavior of model * @param int $id record id * @return bool */ public function softdelete(Model $Model, $id = null) { if ($id) { $Model->id = $id; } if (!$Model->id) { return false; } $deleteCol = 'deleted'; if (!$Model->hasField($deleteCol)) { return false; } $db = $Model->getDataSource(); $now = time(); $default = array('formatter' => 'date'); $colType = array_merge($default, $db->columns[$Model->getColumnType($deleteCol)]); $time = $now; if (array_key_exists('format', $colType)) { $time = call_user_func($colType['formatter'], $colType['format']); } if (!empty($Model->whitelist)) { $Model->whitelist[] = $deleteCol; } $Model->set($deleteCol, $time); return $Model->saveField($deleteCol, $time); }
/** * 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; }
/** * Caches the sum of the different ratings for each of them * * For example a rating of 1 will increase the value in the field "rating_1" by 1, * a rating of 2 will increase "rating_2" by one... * * @param Model $Model * @param array Data passed to afterRate() or similar structure * @return boolean True on success */ public function cacheRatingStatistics(Model $Model, $data = array()) { extract($data); if ($result) { if ($type == 'removeRating') { $value = $oldRating['Rating']['value']; } if ($Model->getColumnType($this->_fieldName(round($value, 0)))) { $data = $Model->find('first', array('conditions' => array($Model->alias . '.' . $Model->primaryKey => $foreignKey), 'recursive' => -1)); if (($update == true || $type == 'removeRating') && !empty($oldRating['Rating'])) { $oldId = round($oldRating['Rating']['value']); $data[$Model->alias][$this->_fieldName($oldId)] -= 1; } if ($type == 'saveRating') { $newId = round($value); $data[$Model->alias][$this->_fieldName($newId)] += 1; } return $Model->save($data, array('validate' => $this->settings[$Model->alias]['modelValidate'], 'callbacks' => $this->settings[$Model->alias]['modelCallbacks'])); } } }
/** * Get now() * * @param Model $model Model using this behavior * @param string $field Room data * @return string now() */ private function __now(Model $model, $field) { $db = $model->getDataSource(); $colType = array_merge(array('formatter' => 'date'), $db->columns[$model->getColumnType($field)]); $time = time(); if (array_key_exists('format', $colType)) { $time = call_user_func($colType['formatter'], $colType['format']); } return $time; }
/** * Get time format for the specified column * * @param Model $Model Model instance * @param string $column Column name * @return string Formatted time */ protected function _formatForColumn(&$Model, $column) { $default = array('formatter' => 'date'); $db =& ConnectionManager::getDataSource($Model->useDbConfig); $colType = array_merge($default, $db->columns[$Model->getColumnType($column)]); if (!array_key_exists('format', $colType)) { $time = strtotime('now'); } else { $time = $colType['formatter']($colType['format']); } return $time; }
protected function getDeletedFieldColumnType(Model $model) { if (empty($this->settings[$model->alias]['column_type'])) { $this->settings[$model->alias]['column_type'] = $model->getColumnType($this->getFieldName($model)); } return $this->settings[$model->alias]['column_type']; }
/** * Is Numberic * * @author Everton Yoshitani <*****@*****.**> * @since 1.0 * @param Model $Model * @param string $column * @return boolean */ public function isNumeric(Model $Model, $column = null) { $types = array('biginteger', 'integer'); /** * This is repetitive, but it's worth NOT putting in a function since it's called * so much and function calls are expensive. */ if (!array_key_exists($Model->name, $this->_column_type_cache) || !array_key_exists($column, $this->_column_type_cache[$Model->name])) { $this->_column_type_cache[$Model->name][$column] = $Model->getColumnType($column); } return in_array($this->_column_type_cache[$Model->name][$column], $types); }