mirror of
https://github.com/kamilwylegala/cakephp2-php8.git
synced 2025-01-19 02:56:15 +00:00
Merge branch '2.1' of github.com:cakephp/cakephp into 2.1
This commit is contained in:
commit
1a741b853b
26 changed files with 382 additions and 180 deletions
|
@ -17,4 +17,5 @@
|
|||
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
|
||||
*/
|
||||
$versionFile = file(CAKE . 'VERSION.txt');
|
||||
return $config['Cake.version'] = trim(array_pop($versionFile));
|
||||
$config['Cake.version'] = trim(array_pop($versionFile));
|
||||
return $config;
|
||||
|
|
|
@ -432,7 +432,7 @@ class AuthComponent extends Component {
|
|||
*/
|
||||
public function allow($action = null) {
|
||||
$args = func_get_args();
|
||||
if (empty($args)) {
|
||||
if (empty($args) || $action === null) {
|
||||
$this->allowedActions = $this->_methods;
|
||||
} else {
|
||||
if (isset($args[0]) && is_array($args[0])) {
|
||||
|
@ -458,7 +458,7 @@ class AuthComponent extends Component {
|
|||
*/
|
||||
public function deny($action = null) {
|
||||
$args = func_get_args();
|
||||
if (empty($args)) {
|
||||
if (empty($args) || $action === null) {
|
||||
$this->allowedActions = array();
|
||||
} else {
|
||||
if (isset($args[0]) && is_array($args[0])) {
|
||||
|
|
|
@ -333,7 +333,7 @@ class PaginatorComponent extends Component {
|
|||
$options['order'] = array($options['sort'] => $direction);
|
||||
}
|
||||
|
||||
if (!empty($whitelist)) {
|
||||
if (!empty($whitelist) && isset($options['order']) && is_array($options['order'])) {
|
||||
$field = key($options['order']);
|
||||
if (!in_array($field, $whitelist)) {
|
||||
$options['order'] = null;
|
||||
|
|
|
@ -312,7 +312,7 @@ class Configure {
|
|||
$keys = array_keys($values);
|
||||
foreach ($keys as $key) {
|
||||
if (($c = self::read($key)) && is_array($values[$key]) && is_array($c)) {
|
||||
$values[$key] = array_merge_recursive($c, $values[$key]);
|
||||
$values[$key] = Set::merge($c, $values[$key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,6 +45,13 @@ class I18n {
|
|||
*/
|
||||
public $l10n = null;
|
||||
|
||||
/**
|
||||
* Default domain of translation
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public static $defaultDomain = 'default';
|
||||
|
||||
/**
|
||||
* Current domain of translation
|
||||
*
|
||||
|
@ -82,8 +89,7 @@ class I18n {
|
|||
protected $_noLocale = false;
|
||||
|
||||
/**
|
||||
* Set to true when I18N::_bindTextDomain() is called for the first time.
|
||||
* If a translation file is found it is set to false again
|
||||
* Translation categories
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
|
@ -122,9 +128,11 @@ class I18n {
|
|||
* @param string $domain Domain The domain of the translation. Domains are often used by plugin translations
|
||||
* @param string $category Category The integer value of the category to use.
|
||||
* @param integer $count Count Count is used with $plural to choose the correct plural form.
|
||||
* @param string $language Language to translate string to.
|
||||
* If null it checks for language in session followed by Config.language configuration variable.
|
||||
* @return string translated string.
|
||||
*/
|
||||
public static function translate($singular, $plural = null, $domain = null, $category = 6, $count = null) {
|
||||
public static function translate($singular, $plural = null, $domain = null, $category = 6, $count = null, $language = null) {
|
||||
$_this = I18n::getInstance();
|
||||
|
||||
if (strpos($singular, "\r\n") !== false) {
|
||||
|
@ -137,10 +145,13 @@ class I18n {
|
|||
if (is_numeric($category)) {
|
||||
$_this->category = $_this->_categories[$category];
|
||||
}
|
||||
$language = Configure::read('Config.language');
|
||||
|
||||
if (!empty($_SESSION['Config']['language'])) {
|
||||
$language = $_SESSION['Config']['language'];
|
||||
if (empty($language)) {
|
||||
if (!empty($_SESSION['Config']['language'])) {
|
||||
$language = $_SESSION['Config']['language'];
|
||||
} else {
|
||||
$language = Configure::read('Config.language');
|
||||
}
|
||||
}
|
||||
|
||||
if (($_this->_lang && $_this->_lang !== $language) || !$_this->_lang) {
|
||||
|
@ -149,7 +160,7 @@ class I18n {
|
|||
}
|
||||
|
||||
if (is_null($domain)) {
|
||||
$domain = 'default';
|
||||
$domain = self::$defaultDomain;
|
||||
}
|
||||
|
||||
$_this->domain = $domain . '_' . $_this->l10n->lang;
|
||||
|
@ -304,41 +315,51 @@ class I18n {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
foreach ($searchPaths as $directory) {
|
||||
|
||||
foreach ($this->l10n->languagePath as $lang) {
|
||||
$file = $directory . $lang . DS . $this->category . DS . $domain;
|
||||
$localeDef = $directory . $lang . DS . $this->category;
|
||||
if (is_file($localeDef)) {
|
||||
$definitions = self::loadLocaleDefinition($localeDef);
|
||||
if ($definitions !== false) {
|
||||
$this->_domains[$domain][$this->_lang][$this->category] = self::loadLocaleDefinition($localeDef);
|
||||
$this->_noLocale = false;
|
||||
return $domain;
|
||||
}
|
||||
}
|
||||
|
||||
if ($core) {
|
||||
$app = $directory . $lang . DS . $this->category . DS . 'core';
|
||||
$translations = false;
|
||||
|
||||
if (file_exists($fn = "$app.mo")) {
|
||||
$this->_loadMo($fn, $domain);
|
||||
$this->_noLocale = false;
|
||||
if (is_file($app . '.mo')) {
|
||||
$translations = self::loadMo($app . '.mo');
|
||||
}
|
||||
if ($translations === false && is_file($app . '.po')) {
|
||||
$translations = self::loadPo($app . '.po');
|
||||
}
|
||||
|
||||
if ($translations !== false) {
|
||||
$this->_domains[$domain][$this->_lang][$this->category] = $translations;
|
||||
$merge[$domain][$this->_lang][$this->category] = $this->_domains[$domain][$this->_lang][$this->category];
|
||||
$core = null;
|
||||
} elseif (file_exists($fn = "$app.po") && ($f = fopen($fn, "r"))) {
|
||||
$this->_loadPo($f, $domain);
|
||||
$this->_noLocale = false;
|
||||
$merge[$domain][$this->_lang][$this->category] = $this->_domains[$domain][$this->_lang][$this->category];
|
||||
$core = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (file_exists($fn = "$file.mo")) {
|
||||
$this->_loadMo($fn, $domain);
|
||||
$file = $directory . $lang . DS . $this->category . DS . $domain;
|
||||
$translations = false;
|
||||
|
||||
if (is_file($file . '.mo')) {
|
||||
$translations = self::loadMo($file . '.mo');
|
||||
}
|
||||
if ($translations === false && is_file($file . '.po')) {
|
||||
$translations = self::loadPo($file . '.po');
|
||||
}
|
||||
|
||||
if ($translations !== false) {
|
||||
$this->_domains[$domain][$this->_lang][$this->category] = $translations;
|
||||
$this->_noLocale = false;
|
||||
break 2;
|
||||
} elseif (file_exists($fn = "$file.po") && ($f = fopen($fn, "r"))) {
|
||||
$this->_loadPo($f, $domain);
|
||||
$this->_noLocale = false;
|
||||
break 2;
|
||||
} elseif (is_file($localeDef) && ($f = fopen($localeDef, "r"))) {
|
||||
$this->_loadLocaleDefinition($f, $domain);
|
||||
$this->_noLocale = false;
|
||||
return $domain;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -368,20 +389,21 @@ class I18n {
|
|||
unset($this->_domains[$domain][$this->_lang][$this->category][null]);
|
||||
}
|
||||
}
|
||||
|
||||
return $domain;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the binary .mo file for translation and sets the values for this translation in the var I18n::_domains
|
||||
* Loads the binary .mo file and returns array of translations
|
||||
*
|
||||
* @param string $file Binary .mo file to load
|
||||
* @param string $domain Domain where to load file in
|
||||
* @return void
|
||||
* @param string $filename Binary .mo file to load
|
||||
* @return mixed Array of translations on success or false on failure
|
||||
*/
|
||||
protected function _loadMo($file, $domain) {
|
||||
$data = file_get_contents($file);
|
||||
public static function loadMo($filename) {
|
||||
$translations = false;
|
||||
|
||||
if ($data) {
|
||||
if ($data = file_get_contents($filename)) {
|
||||
$translations = array();
|
||||
$header = substr($data, 0, 20);
|
||||
$header = unpack("L1magic/L1version/L1count/L1o_msg/L1o_trn", $header);
|
||||
extract($header);
|
||||
|
@ -401,24 +423,29 @@ class I18n {
|
|||
if (strpos($msgstr, "\000")) {
|
||||
$msgstr = explode("\000", $msgstr);
|
||||
}
|
||||
$this->_domains[$domain][$this->_lang][$this->category][$msgid] = $msgstr;
|
||||
$translations[$msgid] = $msgstr;
|
||||
|
||||
if (isset($msgid_plural)) {
|
||||
$this->_domains[$domain][$this->_lang][$this->category][$msgid_plural] =& $this->_domains[$domain][$this->_lang][$this->category][$msgid];
|
||||
$translations[$msgid_plural] =& $translations[$msgid];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $translations;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the text .po file for translation and sets the values for this translation in the var I18n::_domains
|
||||
* Loads the text .po file and returns array of translations
|
||||
*
|
||||
* @param resource $file Text .po file to load
|
||||
* @param string $domain Domain to load file in
|
||||
* @return array Binded domain elements
|
||||
* @param string $filename Text .po file to load
|
||||
* @return mixed Array of translations on success or false on failure
|
||||
*/
|
||||
protected function _loadPo($file, $domain) {
|
||||
public static function loadPo($filename) {
|
||||
if (!$file = fopen($filename, "r")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$type = 0;
|
||||
$translations = array();
|
||||
$translationKey = "";
|
||||
|
@ -477,22 +504,28 @@ class I18n {
|
|||
}
|
||||
} while (!feof($file));
|
||||
fclose($file);
|
||||
|
||||
$merge[""] = $header;
|
||||
return $this->_domains[$domain][$this->_lang][$this->category] = array_merge($merge, $translations);
|
||||
return array_merge($merge, $translations);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a locale definition file following the POSIX standard
|
||||
*
|
||||
* @param resource $file file handler
|
||||
* @param string $domain Domain where locale definitions will be stored
|
||||
* @return void
|
||||
* @param string $filename Locale definition filename
|
||||
* @return mixed Array of definitions on success or false on failure
|
||||
*/
|
||||
protected function _loadLocaleDefinition($file, $domain = null) {
|
||||
public static function loadLocaleDefinition($filename) {
|
||||
if (!$file = fopen($filename, "r")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$definitions = array();
|
||||
$comment = '#';
|
||||
$escape = '\\';
|
||||
$currentToken = false;
|
||||
$value = '';
|
||||
$_this = I18n::getInstance();
|
||||
while ($line = fgets($file)) {
|
||||
$line = trim($line);
|
||||
if (empty($line) || $line[0] === $comment) {
|
||||
|
@ -527,19 +560,21 @@ class I18n {
|
|||
$replacements = array_map('crc32', $mustEscape);
|
||||
$value = str_replace($mustEscape, $replacements, $value);
|
||||
$value = explode(';', $value);
|
||||
$this->__escape = $escape;
|
||||
$_this->__escape = $escape;
|
||||
foreach ($value as $i => $val) {
|
||||
$val = trim($val, '"');
|
||||
$val = preg_replace_callback('/(?:<)?(.[^>]*)(?:>)?/', array(&$this, '_parseLiteralValue'), $val);
|
||||
$val = preg_replace_callback('/(?:<)?(.[^>]*)(?:>)?/', array(&$_this, '_parseLiteralValue'), $val);
|
||||
$val = str_replace($replacements, $mustEscape, $val);
|
||||
$value[$i] = $val;
|
||||
}
|
||||
if (count($value) == 1) {
|
||||
$this->_domains[$domain][$this->_lang][$this->category][$currentToken] = array_pop($value);
|
||||
$definitions[$currentToken] = array_pop($value);
|
||||
} else {
|
||||
$this->_domains[$domain][$this->_lang][$this->category][$currentToken] = $value;
|
||||
$definitions[$currentToken] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
return $definitions;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -34,6 +34,20 @@ class TranslateBehavior extends ModelBehavior {
|
|||
*/
|
||||
public $runtime = array();
|
||||
|
||||
/**
|
||||
* Stores the joinTable object for generating joins.
|
||||
*
|
||||
* @var object
|
||||
*/
|
||||
var $_joinTable;
|
||||
|
||||
/**
|
||||
* Stores the runtime model for generating joins.
|
||||
*
|
||||
* @var Model
|
||||
*/
|
||||
var $_runtimeModel;
|
||||
|
||||
/**
|
||||
* Callback
|
||||
*
|
||||
|
@ -94,6 +108,7 @@ class TranslateBehavior extends ModelBehavior {
|
|||
}
|
||||
$db = $model->getDataSource();
|
||||
$RuntimeModel = $this->translateModel($model);
|
||||
|
||||
if (!empty($RuntimeModel->tablePrefix)) {
|
||||
$tablePrefix = $RuntimeModel->tablePrefix;
|
||||
} else {
|
||||
|
@ -104,8 +119,11 @@ class TranslateBehavior extends ModelBehavior {
|
|||
$joinTable->table = $RuntimeModel->table;
|
||||
$joinTable->schemaName = $RuntimeModel->getDataSource()->getSchemaName();
|
||||
|
||||
$this->_joinTable = $joinTable;
|
||||
$this->_runtimeModel = $RuntimeModel;
|
||||
|
||||
if (is_string($query['fields']) && 'COUNT(*) AS ' . $db->name('count') == $query['fields']) {
|
||||
$query['fields'] = 'COUNT(DISTINCT(' . $db->name($model->alias . '.' . $model->primaryKey) . ')) ' . $db->alias . 'count';
|
||||
$query['fields'] = 'COUNT(DISTINCT('.$db->name($model->alias . '.' . $model->primaryKey) . ')) ' . $db->alias . 'count';
|
||||
$query['joins'][] = array(
|
||||
'type' => 'INNER',
|
||||
'alias' => $RuntimeModel->alias,
|
||||
|
@ -116,6 +134,11 @@ class TranslateBehavior extends ModelBehavior {
|
|||
$RuntimeModel->alias.'.locale' => $locale
|
||||
)
|
||||
);
|
||||
$conditionFields = $this->_checkConditions($model, $query);
|
||||
foreach ($conditionFields as $field) {
|
||||
$query = $this->_addJoin($model, $query, $field, $field, $locale);
|
||||
}
|
||||
unset($this->_joinTable, $this->_runtimeModel);
|
||||
return $query;
|
||||
}
|
||||
|
||||
|
@ -145,45 +168,93 @@ class TranslateBehavior extends ModelBehavior {
|
|||
unset($query['fields'][$key]);
|
||||
}
|
||||
}
|
||||
|
||||
if (is_array($locale)) {
|
||||
foreach ($locale as $_locale) {
|
||||
$model->virtualFields['i18n_' . $field . '_' . $_locale] = 'I18n__' . $field . '__' . $_locale . '.content';
|
||||
if (!empty($query['fields'])) {
|
||||
$query['fields'][] = 'i18n_' . $field . '_' . $_locale;
|
||||
}
|
||||
$query['joins'][] = array(
|
||||
'type' => 'LEFT',
|
||||
'alias' => 'I18n__' . $field . '__' . $_locale,
|
||||
'table' => $joinTable,
|
||||
'conditions' => array(
|
||||
$model->alias . '.' . $model->primaryKey => $db->identifier("I18n__{$field}__{$_locale}.foreign_key"),
|
||||
'I18n__' . $field . '__' . $_locale . '.model' => $model->name,
|
||||
'I18n__' . $field . '__' . $_locale . '.' . $RuntimeModel->displayField => $aliasField,
|
||||
'I18n__' . $field . '__' . $_locale . '.locale' => $_locale
|
||||
)
|
||||
);
|
||||
}
|
||||
} else {
|
||||
$model->virtualFields['i18n_' . $field] = 'I18n__' . $field . '.content';
|
||||
if (!empty($query['fields'])) {
|
||||
$query['fields'][] = 'i18n_' . $field;
|
||||
}
|
||||
$query['joins'][] = array(
|
||||
'type' => 'INNER',
|
||||
'alias' => 'I18n__' . $field,
|
||||
'table' => $joinTable,
|
||||
'conditions' => array(
|
||||
$model->alias . '.' . $model->primaryKey => $db->identifier("I18n__{$field}.foreign_key"),
|
||||
'I18n__' . $field . '.model' => $model->name,
|
||||
'I18n__' . $field . '.' . $RuntimeModel->displayField => $aliasField,
|
||||
'I18n__' . $field . '.locale' => $locale
|
||||
)
|
||||
);
|
||||
}
|
||||
$query = $this->_addJoin($model, $query, $field, $aliasField, $locale);
|
||||
}
|
||||
}
|
||||
$this->runtime[$model->alias]['beforeFind'] = $addFields;
|
||||
unset($this->_joinTable, $this->_runtimeModel);
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check a query's conditions for translated fields.
|
||||
* Return an array of translated fields found in the conditions.
|
||||
*
|
||||
* @param Model $model The model being read.
|
||||
* @param array $query The query array.
|
||||
* @return array The list of translated fields that are in the conditions.
|
||||
*/
|
||||
protected function _checkConditions(Model $model, $query) {
|
||||
$conditionFields = array();
|
||||
if (empty($query['conditions']) || (!empty($query['conditions']) && !is_array($query['conditions'])) ) {
|
||||
return $conditionFields;
|
||||
}
|
||||
foreach ($query['conditions'] as $col => $val) {
|
||||
foreach ($this->settings[$model->alias] as $field => $assoc) {
|
||||
if (is_numeric($field)) {
|
||||
$field = $assoc;
|
||||
}
|
||||
if (strpos($col, $field) !== false) {
|
||||
$conditionFields[] = $field;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $conditionFields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a join for translated fields and possibly a field.
|
||||
*
|
||||
* @param Model $model The model being worked on.
|
||||
* @param object $joinTable The jointable object.
|
||||
* @param array $query The query array to append a join to.
|
||||
* @param string $field The field name being joined.
|
||||
* @param string $aliasField The aliased field name being joined.
|
||||
* @param mixed $locale The locale(s) having joins added.
|
||||
* @param boolean $addField Whether or not to add a field.
|
||||
* @return array The modfied query
|
||||
*/
|
||||
protected function _addJoin(Model $model, $query, $field, $aliasField, $locale, $addField = false) {
|
||||
$db = ConnectionManager::getDataSource($model->useDbConfig);
|
||||
|
||||
$RuntimeModel = $this->_runtimeModel;
|
||||
$joinTable = $this->_joinTable;
|
||||
|
||||
if (is_array($locale)) {
|
||||
foreach ($locale as $_locale) {
|
||||
$model->virtualFields['i18n_' . $field . '_' . $_locale] = 'I18n__' . $field . '__' . $_locale . '.content';
|
||||
if (!empty($query['fields']) && is_array($query['fields'])) {
|
||||
$query['fields'][] = 'i18n_'.$field.'_'.$_locale;
|
||||
}
|
||||
$query['joins'][] = array(
|
||||
'type' => 'LEFT',
|
||||
'alias' => 'I18n__'.$field.'__'.$_locale,
|
||||
'table' => $joinTable,
|
||||
'conditions' => array(
|
||||
$model->alias . '.' . $model->primaryKey => $db->identifier("I18n__{$field}__{$_locale}.foreign_key"),
|
||||
'I18n__'.$field.'__'.$_locale.'.model' => $model->name,
|
||||
'I18n__'.$field.'__'.$_locale.'.'.$RuntimeModel->displayField => $aliasField,
|
||||
'I18n__'.$field.'__'.$_locale.'.locale' => $_locale
|
||||
)
|
||||
);
|
||||
}
|
||||
} else {
|
||||
$model->virtualFields['i18n_' . $field] = 'I18n__' . $field . '.content';
|
||||
if (!empty($query['fields']) && is_array($query['fields'])) {
|
||||
$query['fields'][] = 'i18n_'.$field;
|
||||
}
|
||||
$query['joins'][] = array(
|
||||
'type' => 'INNER',
|
||||
'alias' => 'I18n__'.$field,
|
||||
'table' => $joinTable,
|
||||
'conditions' => array(
|
||||
$model->alias . '.' . $model->primaryKey => $db->identifier("I18n__{$field}.foreign_key"),
|
||||
'I18n__'.$field.'.model' => $model->name,
|
||||
'I18n__'.$field.'.'.$RuntimeModel->displayField => $aliasField,
|
||||
'I18n__'.$field.'.locale' => $locale
|
||||
)
|
||||
);
|
||||
}
|
||||
return $query;
|
||||
}
|
||||
|
||||
|
|
|
@ -107,6 +107,9 @@ class BehaviorCollection extends ObjectCollection implements CakeEventListener {
|
|||
$alias = $behavior;
|
||||
$behavior = $config['className'];
|
||||
}
|
||||
$configDisabled = isset($config['enabled']) && $config['enabled'] === false;
|
||||
unset($config['enabled'], $config['className']);
|
||||
|
||||
list($plugin, $name) = pluginSplit($behavior, true);
|
||||
if (!isset($alias)) {
|
||||
$alias = $name;
|
||||
|
@ -166,8 +169,7 @@ class BehaviorCollection extends ObjectCollection implements CakeEventListener {
|
|||
}
|
||||
}
|
||||
|
||||
$enable = isset($config['enabled']) ? $config['enabled'] : true;
|
||||
if ($enable) {
|
||||
if (!in_array($alias, $this->_enabled) && !$configDisabled) {
|
||||
$this->enable($alias);
|
||||
} else {
|
||||
$this->disable($alias);
|
||||
|
|
|
@ -182,7 +182,7 @@ class Sqlserver extends DboSource {
|
|||
} else {
|
||||
$tables = array();
|
||||
|
||||
while ($line = $result->fetch()) {
|
||||
while ($line = $result->fetch(PDO::FETCH_NUM)) {
|
||||
$tables[] = $line[0];
|
||||
}
|
||||
|
||||
|
@ -222,7 +222,7 @@ class Sqlserver extends DboSource {
|
|||
throw new CakeException(__d('cake_dev', 'Could not describe table for %s', $table));
|
||||
}
|
||||
|
||||
foreach ($cols as $column) {
|
||||
while ($column = $cols->fetch(PDO::FETCH_OBJ)) {
|
||||
$field = $column->Field;
|
||||
$fields[$field] = array(
|
||||
'type' => $this->column($column),
|
||||
|
@ -645,14 +645,7 @@ class Sqlserver extends DboSource {
|
|||
$this->_execute('SET IDENTITY_INSERT ' . $this->fullTableName($table) . ' ON');
|
||||
}
|
||||
|
||||
$table = $this->fullTableName($table);
|
||||
$fields = implode(', ', array_map(array(&$this, 'name'), $fields));
|
||||
$this->begin();
|
||||
foreach ($values as $value) {
|
||||
$holder = implode(', ', array_map(array(&$this, 'value'), $value));
|
||||
$this->_execute("INSERT INTO {$table} ({$fields}) VALUES ({$holder})");
|
||||
}
|
||||
$this->commit();
|
||||
parent::insertMulti($table, $fields, $values);
|
||||
|
||||
if ($hasPrimaryKey) {
|
||||
$this->_execute('SET IDENTITY_INSERT ' . $this->fullTableName($table) . ' OFF');
|
||||
|
@ -717,9 +710,6 @@ class Sqlserver extends DboSource {
|
|||
* @return string
|
||||
*/
|
||||
protected function _getPrimaryKey($model) {
|
||||
if (!is_object($model)) {
|
||||
$model = new Model(false, $model);
|
||||
}
|
||||
$schema = $this->describe($model);
|
||||
foreach ($schema as $field => $props) {
|
||||
if (isset($props['key']) && $props['key'] == 'primary') {
|
||||
|
|
|
@ -2815,16 +2815,17 @@ class Model extends Object implements CakeEventListener {
|
|||
$return = $idMap = array();
|
||||
$ids = Set::extract($results, '{n}.' . $this->alias . '.' . $this->primaryKey);
|
||||
|
||||
if (isset($results[0][$this->alias]) && !array_key_exists('parent_id', $results[0][$this->alias])) {
|
||||
trigger_error(
|
||||
__d('cake_dev', 'You cannot use find("threaded") on models without a "parent_id" field.'),
|
||||
E_USER_WARNING
|
||||
);
|
||||
return $return;
|
||||
}
|
||||
|
||||
foreach ($results as $result) {
|
||||
$result['children'] = array();
|
||||
$id = $result[$this->alias][$this->primaryKey];
|
||||
if (!isset($result[$this->alias]['parent_id'])) {
|
||||
trigger_error(
|
||||
__d('cake_dev', 'You cannot use find("threaded") on models without a "parent_id" field.'),
|
||||
E_USER_WARNING
|
||||
);
|
||||
return $return;
|
||||
}
|
||||
$parentId = $result[$this->alias]['parent_id'];
|
||||
if (isset($idMap[$id]['children'])) {
|
||||
$idMap[$id] = array_merge($result, (array)$idMap[$id]);
|
||||
|
|
|
@ -654,6 +654,18 @@ class AuthComponentTest extends CakeTestCase {
|
|||
|
||||
$this->Controller->request['action'] = 'login';
|
||||
$this->assertFalse($this->Controller->Auth->startup($this->Controller));
|
||||
|
||||
$this->Controller->Auth->deny();
|
||||
$this->Controller->Auth->allow(null);
|
||||
|
||||
$this->Controller->request['action'] = 'camelCase';
|
||||
$this->assertTrue($this->Controller->Auth->startup($this->Controller));
|
||||
|
||||
$this->Controller->Auth->allow();
|
||||
$this->Controller->Auth->deny(null);
|
||||
|
||||
$this->Controller->request['action'] = 'camelCase';
|
||||
$this->assertFalse($this->Controller->Auth->startup($this->Controller));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -776,6 +776,26 @@ class PaginatorComponentTest extends CakeTestCase {
|
|||
$this->assertEquals($expected, $result['order']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that no sort doesn't trigger an error.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testValidateSortNoSort() {
|
||||
$model = $this->getMock('Model');
|
||||
$model->alias = 'model';
|
||||
$model->expects($this->any())->method('hasField')->will($this->returnValue(true));
|
||||
|
||||
$options = array('direction' => 'asc');
|
||||
$result = $this->Paginator->validateSort($model, $options, array('title', 'id'));
|
||||
$this->assertFalse(isset($result['order']));
|
||||
|
||||
$options = array('order' => 'invalid desc');
|
||||
$result = $this->Paginator->validateSort($model, $options, array('title', 'id'));
|
||||
|
||||
$this->assertEquals($options['order'], $result['order']);
|
||||
}
|
||||
|
||||
/**
|
||||
* test that maxLimit is respected
|
||||
*
|
||||
|
|
|
@ -224,6 +224,8 @@ class ConfigureTest extends CakeTestCase {
|
|||
$this->assertEquals('value2', Configure::read('Read'));
|
||||
$this->assertEquals('buried2', Configure::read('Deep.Second.SecondDeepest'));
|
||||
$this->assertEquals('buried', Configure::read('Deep.Deeper.Deepest'));
|
||||
$this->assertEquals('Overwrite', Configure::read('TestAcl.classname'));
|
||||
$this->assertEquals('one', Configure::read('TestAcl.custom'));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -50,10 +50,14 @@ class I18nTest extends CakeTestCase {
|
|||
CakePlugin::unload();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* testTranslationCaching method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testTranslationCaching() {
|
||||
Configure::write('Config.language', 'cache_test_po');
|
||||
$i18n = i18n::getInstance();
|
||||
$i18n = I18n::getInstance();
|
||||
|
||||
// reset internally stored entries
|
||||
I18n::clear();
|
||||
|
@ -93,7 +97,6 @@ class I18nTest extends CakeTestCase {
|
|||
$this->assertEquals('FOO', I18n::translate('dom1.foo', false, 'dom1'));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* testDefaultStrings method
|
||||
*
|
||||
|
@ -2588,6 +2591,11 @@ class I18nTest extends CakeTestCase {
|
|||
$this->assertEquals('Po (translated)', $singular);
|
||||
}
|
||||
|
||||
/**
|
||||
* testTimeDefinition method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testTimeDefinition() {
|
||||
Configure::write('Config.language', 'po');
|
||||
$result = __c('d_fmt', 5);
|
||||
|
@ -2603,6 +2611,11 @@ class I18nTest extends CakeTestCase {
|
|||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* testTimeDefinitionJapanese method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testTimeDefinitionJapanese() {
|
||||
Configure::write('Config.language', 'ja_jp');
|
||||
$result = __c('d_fmt', 5);
|
||||
|
@ -2620,12 +2633,29 @@ class I18nTest extends CakeTestCase {
|
|||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* testTranslateLanguageParam method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testTranslateLanguageParam() {
|
||||
Configure::write('Config.language', 'rule_0_po');
|
||||
|
||||
$result = I18n::translate('Plural Rule 1', null, null, 6);
|
||||
$expected = 'Plural Rule 0 (translated)';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = I18n::translate('Plural Rule 1', null, null, 6, null, 'rule_1_po');
|
||||
$expected = 'Plural Rule 1 (translated)';
|
||||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Singular method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function __domainCategorySingular($domain = 'test_plugin', $category = 3) {
|
||||
private function __domainCategorySingular($domain = 'test_plugin', $category = 3) {
|
||||
$singular = __dc($domain, 'Plural Rule 1', $category);
|
||||
return $singular;
|
||||
}
|
||||
|
@ -2635,7 +2665,7 @@ class I18nTest extends CakeTestCase {
|
|||
*
|
||||
* @return void
|
||||
*/
|
||||
function __domainCategoryPlural($domain = 'test_plugin', $category = 3) {
|
||||
private function __domainCategoryPlural($domain = 'test_plugin', $category = 3) {
|
||||
$plurals = array();
|
||||
for ($number = 0; $number <= 25; $number++) {
|
||||
$plurals[] = sprintf(__dcn($domain, '%d = 1', '%d = 0 or > 1', (float)$number, $category), (float)$number);
|
||||
|
@ -2648,7 +2678,7 @@ class I18nTest extends CakeTestCase {
|
|||
*
|
||||
* @return void
|
||||
*/
|
||||
function __domainSingular($domain = 'test_plugin') {
|
||||
private function __domainSingular($domain = 'test_plugin') {
|
||||
$singular = __d($domain, 'Plural Rule 1');
|
||||
return $singular;
|
||||
}
|
||||
|
@ -2658,7 +2688,7 @@ class I18nTest extends CakeTestCase {
|
|||
*
|
||||
* @return void
|
||||
*/
|
||||
function __domainPlural($domain = 'test_plugin') {
|
||||
private function __domainPlural($domain = 'test_plugin') {
|
||||
$plurals = array();
|
||||
for ($number = 0; $number <= 25; $number++) {
|
||||
$plurals[] = sprintf(__dn($domain, '%d = 1', '%d = 0 or > 1', (float)$number), (float)$number );
|
||||
|
@ -2671,7 +2701,7 @@ class I18nTest extends CakeTestCase {
|
|||
*
|
||||
* @return void
|
||||
*/
|
||||
function __category($category = 3) {
|
||||
private function __category($category = 3) {
|
||||
$singular = __c('Plural Rule 1', $category);
|
||||
return $singular;
|
||||
}
|
||||
|
@ -2681,7 +2711,7 @@ class I18nTest extends CakeTestCase {
|
|||
*
|
||||
* @return void
|
||||
*/
|
||||
function __singular() {
|
||||
private function __singular() {
|
||||
$singular = __('Plural Rule 1');
|
||||
return $singular;
|
||||
}
|
||||
|
@ -2691,7 +2721,7 @@ class I18nTest extends CakeTestCase {
|
|||
*
|
||||
* @return void
|
||||
*/
|
||||
function __plural() {
|
||||
private function __plural() {
|
||||
$plurals = array();
|
||||
for ($number = 0; $number <= 25; $number++) {
|
||||
$plurals[] = sprintf(__n('%d = 1', '%d = 0 or > 1', (float)$number), (float)$number);
|
||||
|
@ -2704,7 +2734,7 @@ class I18nTest extends CakeTestCase {
|
|||
*
|
||||
* @return void
|
||||
*/
|
||||
function __singularFromCore() {
|
||||
private function __singularFromCore() {
|
||||
$singular = __('Plural Rule 1 (from core)');
|
||||
return $singular;
|
||||
}
|
||||
|
@ -2714,7 +2744,7 @@ class I18nTest extends CakeTestCase {
|
|||
*
|
||||
* @return void
|
||||
*/
|
||||
function __pluralFromCore() {
|
||||
private function __pluralFromCore() {
|
||||
$plurals = array();
|
||||
for ($number = 0; $number <= 25; $number++) {
|
||||
$plurals[] = sprintf(__n('%d = 1 (from core)', '%d = 0 or > 1 (from core)', (float)$number), (float)$number );
|
||||
|
|
|
@ -58,6 +58,24 @@ class TranslateBehaviorTest extends CakeTestCase {
|
|||
ClassRegistry::flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that count queries with conditions get the correct joins
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function testCountWithConditions() {
|
||||
$this->loadFixtures('Translate', 'TranslatedItem');
|
||||
|
||||
$Model =& new TranslatedItem();
|
||||
$Model->locale = 'eng';
|
||||
$result = $Model->find('count', array(
|
||||
'conditions' => array(
|
||||
'I18n__content.locale' => 'eng'
|
||||
)
|
||||
));
|
||||
$this->assertEqual(3, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* testTranslateModel method
|
||||
*
|
||||
|
|
|
@ -419,9 +419,22 @@ class BehaviorCollectionTest extends CakeTestCase {
|
|||
*/
|
||||
public $fixtures = array(
|
||||
'core.apple', 'core.sample', 'core.article', 'core.user', 'core.comment',
|
||||
'core.attachment', 'core.tag', 'core.articles_tag'
|
||||
'core.attachment', 'core.tag', 'core.articles_tag', 'core.translate'
|
||||
);
|
||||
|
||||
/**
|
||||
* Test load() with enabled => false
|
||||
*
|
||||
*/
|
||||
public function testLoadDisabled() {
|
||||
$Apple = new Apple();
|
||||
$this->assertSame($Apple->Behaviors->attached(), array());
|
||||
|
||||
$Apple->Behaviors->load('Translate', array('enabled' => false));
|
||||
$this->assertTrue($Apple->Behaviors->attached('Translate'));
|
||||
$this->assertFalse($Apple->Behaviors->enabled('Translate'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests loading aliased behaviors
|
||||
*/
|
||||
|
|
|
@ -111,7 +111,7 @@ class SqlserverTestDb extends Sqlserver {
|
|||
*
|
||||
* @package Cake.Test.Case.Model.Datasource.Database
|
||||
*/
|
||||
class SqlserverTestModel extends Model {
|
||||
class SqlserverTestModel extends CakeTestModel {
|
||||
|
||||
/**
|
||||
* name property
|
||||
|
@ -183,7 +183,7 @@ class SqlserverTestModel extends Model {
|
|||
*
|
||||
* @package Cake.Test.Case.Model.Datasource.Database
|
||||
*/
|
||||
class SqlserverClientTestModel extends Model {
|
||||
class SqlserverClientTestModel extends CakeTestModel {
|
||||
/**
|
||||
* name property
|
||||
*
|
||||
|
@ -224,6 +224,20 @@ class SqlserverTestResultIterator extends ArrayIterator {
|
|||
* @return void
|
||||
*/
|
||||
public function closeCursor() {}
|
||||
|
||||
/**
|
||||
* fetch method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function fetch() {
|
||||
if (!$this->valid()) {
|
||||
return null;
|
||||
}
|
||||
$current = $this->current();
|
||||
$this->next();
|
||||
return $current;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -283,7 +297,7 @@ class SqlserverTest extends CakeTestCase {
|
|||
* @return void
|
||||
*/
|
||||
public function testQuoting() {
|
||||
$expected = "1.200000";
|
||||
$expected = "1.2";
|
||||
$result = $this->db->value(1.2, 'float');
|
||||
$this->assertSame($expected, $result);
|
||||
|
||||
|
@ -586,43 +600,6 @@ class SqlserverTest extends CakeTestCase {
|
|||
$this->assertNull($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* testInsertMulti
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testInsertMulti() {
|
||||
$this->db->describe = $this->model->schema();
|
||||
|
||||
$fields = array('id', 'name', 'login');
|
||||
$values = array(
|
||||
array(1, 'Larry', 'PhpNut'),
|
||||
array(2, 'Renan', 'renan.saddam'));
|
||||
$this->db->simulated = array();
|
||||
$this->db->insertMulti($this->model, $fields, $values);
|
||||
$result = $this->db->simulated;
|
||||
$expected = array(
|
||||
'SET IDENTITY_INSERT [sqlserver_test_models] ON',
|
||||
"INSERT INTO [sqlserver_test_models] ([id], [name], [login]) VALUES (1, N'Larry', N'PhpNut')",
|
||||
"INSERT INTO [sqlserver_test_models] ([id], [name], [login]) VALUES (2, N'Renan', N'renan.saddam')",
|
||||
'SET IDENTITY_INSERT [sqlserver_test_models] OFF'
|
||||
);
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$fields = array('name', 'login');
|
||||
$values = array(
|
||||
array('Larry', 'PhpNut'),
|
||||
array('Renan', 'renan.saddam'));
|
||||
$this->db->simulated = array();
|
||||
$this->db->insertMulti($this->model, $fields, $values);
|
||||
$result = $this->db->simulated;
|
||||
$expected = array(
|
||||
"INSERT INTO [sqlserver_test_models] ([name], [login]) VALUES (N'Larry', N'PhpNut')",
|
||||
"INSERT INTO [sqlserver_test_models] ([name], [login]) VALUES (N'Renan', N'renan.saddam')",
|
||||
);
|
||||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* SQL server < 11 doesn't have proper limit/offset support, test that our hack works.
|
||||
*
|
||||
|
|
|
@ -493,6 +493,9 @@ class DboSourceTest extends CakeTestCase {
|
|||
* @return void
|
||||
*/
|
||||
public function testValue() {
|
||||
if ($this->db instanceof Sqlserver) {
|
||||
$this->markTestSkipped('Cannot run this test with SqlServer');
|
||||
}
|
||||
$result = $this->db->value('{$__cakeForeignKey__$}');
|
||||
$this->assertEquals($result, '{$__cakeForeignKey__$}');
|
||||
|
||||
|
|
|
@ -208,11 +208,11 @@ class ModelIntegrationTest extends BaseModelTest {
|
|||
public function testDynamicBehaviorAttachment() {
|
||||
$this->loadFixtures('Apple', 'Sample', 'Author');
|
||||
$TestModel = new Apple();
|
||||
$this->assertEquals($TestModel->Behaviors->attached(), array());
|
||||
$this->assertEquals(array(), $TestModel->Behaviors->attached());
|
||||
|
||||
$TestModel->Behaviors->attach('Tree', array('left' => 'left_field', 'right' => 'right_field'));
|
||||
$this->assertTrue(is_object($TestModel->Behaviors->Tree));
|
||||
$this->assertEquals($TestModel->Behaviors->attached(), array('Tree'));
|
||||
$this->assertEquals(array('Tree'), $TestModel->Behaviors->attached());
|
||||
|
||||
$expected = array(
|
||||
'parent' => 'parent_id',
|
||||
|
@ -223,16 +223,14 @@ class ModelIntegrationTest extends BaseModelTest {
|
|||
'__parentChange' => false,
|
||||
'recursive' => -1
|
||||
);
|
||||
$this->assertEquals($expected, $TestModel->Behaviors->Tree->settings['Apple']);
|
||||
|
||||
$this->assertEquals($TestModel->Behaviors->Tree->settings['Apple'], $expected);
|
||||
|
||||
$expected['enabled'] = false;
|
||||
$TestModel->Behaviors->attach('Tree', array('enabled' => false));
|
||||
$this->assertEquals($TestModel->Behaviors->Tree->settings['Apple'], $expected);
|
||||
$this->assertEquals($TestModel->Behaviors->attached(), array('Tree'));
|
||||
$this->assertEquals($expected, $TestModel->Behaviors->Tree->settings['Apple']);
|
||||
$this->assertEquals(array('Tree'), $TestModel->Behaviors->attached());
|
||||
|
||||
$TestModel->Behaviors->detach('Tree');
|
||||
$this->assertEquals($TestModel->Behaviors->attached(), array());
|
||||
$this->assertEquals(array(), $TestModel->Behaviors->attached());
|
||||
$this->assertFalse(isset($TestModel->Behaviors->Tree));
|
||||
}
|
||||
|
||||
|
|
|
@ -1236,4 +1236,16 @@ Element content.
|
|||
TEXT;
|
||||
$this->assertEquals($expected, $content);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that setting arbitrary properties still works.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testPropertySetting() {
|
||||
$this->assertFalse(isset($this->View->pageTitle));
|
||||
$this->View->pageTitle = 'test';
|
||||
$this->assertTrue(isset($this->View->pageTitle));
|
||||
$this->assertEquals('test', $this->View->pageTitle);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,5 +5,8 @@ $config = array(
|
|||
'Deeper' => array(
|
||||
'Deepest' => 'buried'
|
||||
)
|
||||
),
|
||||
'TestAcl' => array(
|
||||
'classname' => 'Original'
|
||||
)
|
||||
);
|
||||
);
|
||||
|
|
|
@ -5,5 +5,9 @@ $config = array(
|
|||
'Second' => array(
|
||||
'SecondDeepest' => 'buried2'
|
||||
)
|
||||
),
|
||||
'TestAcl' => array(
|
||||
'classname' => 'Overwrite',
|
||||
'custom' => 'one'
|
||||
)
|
||||
);
|
||||
);
|
||||
|
|
|
@ -158,7 +158,11 @@ class ClassRegistry {
|
|||
}
|
||||
}
|
||||
}
|
||||
$instance = $reflection->newInstance($settings);
|
||||
if ($reflection->getConstructor()) {
|
||||
$instance = $reflection->newInstance($settings);
|
||||
} else {
|
||||
$instance = $reflection->newInstance();
|
||||
}
|
||||
if ($strict) {
|
||||
$instance = ($instance instanceof Model) ? $instance : null;
|
||||
}
|
||||
|
|
|
@ -17,4 +17,4 @@
|
|||
// @license MIT License (http://www.opensource.org/licenses/mit-license.php)
|
||||
// +--------------------------------------------------------------------------------------------+ //
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
2.1.0-dev
|
||||
2.1.0-alpha
|
||||
|
|
|
@ -96,6 +96,9 @@ class JsonView extends View {
|
|||
return $content;
|
||||
}
|
||||
if ($view !== false && $viewFileName = $this->_getViewFileName($view)) {
|
||||
if (!$this->_helpersLoaded) {
|
||||
$this->loadHelpers();
|
||||
}
|
||||
$content = $this->_render($viewFileName);
|
||||
$this->Blocks->set('content', $content);
|
||||
return $content;
|
||||
|
|
|
@ -796,7 +796,7 @@ class View extends Object {
|
|||
* @return boolean
|
||||
*/
|
||||
public function __isset($name) {
|
||||
return isset($this->name);
|
||||
return isset($this->{$name});
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -99,6 +99,9 @@ class XmlView extends View {
|
|||
return $content;
|
||||
}
|
||||
if ($view !== false && $viewFileName = $this->_getViewFileName($view)) {
|
||||
if (!$this->_helpersLoaded) {
|
||||
$this->loadHelpers();
|
||||
}
|
||||
$content = $this->_render($viewFileName);
|
||||
$this->Blocks->set('content', (string)$content);
|
||||
return $content;
|
||||
|
|
Loading…
Add table
Reference in a new issue