Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge branch '2.1' of github.com:cakephp/cakephp into 2.1

  • Loading branch information...
commit 1a741b853b5ac336aeb7f812477eaf7c779ee920 2 parents c53f0e6 + 0f8e150
@lorenzo lorenzo authored
Showing with 381 additions and 179 deletions.
  1. +2 −1  lib/Cake/Config/config.php
  2. +2 −2 lib/Cake/Controller/Component/AuthComponent.php
  3. +1 −1  lib/Cake/Controller/Component/PaginatorComponent.php
  4. +1 −1  lib/Cake/Core/Configure.php
  5. +85 −50 lib/Cake/I18n/I18n.php
  6. +107 −36 lib/Cake/Model/Behavior/TranslateBehavior.php
  7. +4 −2 lib/Cake/Model/BehaviorCollection.php
  8. +3 −13 lib/Cake/Model/Datasource/Database/Sqlserver.php
  9. +8 −7 lib/Cake/Model/Model.php
  10. +12 −0 lib/Cake/Test/Case/Controller/Component/AuthComponentTest.php
  11. +20 −0 lib/Cake/Test/Case/Controller/Component/PaginatorComponentTest.php
  12. +2 −0  lib/Cake/Test/Case/Core/ConfigureTest.php
  13. +42 −12 lib/Cake/Test/Case/I18n/I18nTest.php
  14. +18 −0 lib/Cake/Test/Case/Model/Behavior/TranslateBehaviorTest.php
  15. +14 −1 lib/Cake/Test/Case/Model/BehaviorCollectionTest.php
  16. +17 −40 lib/Cake/Test/Case/Model/Datasource/Database/SqlserverTest.php
  17. +3 −0  lib/Cake/Test/Case/Model/Datasource/DboSourceTest.php
  18. +6 −8 lib/Cake/Test/Case/Model/ModelIntegrationTest.php
  19. +12 −0 lib/Cake/Test/Case/View/ViewTest.php
  20. +4 −1 lib/Cake/Test/test_app/Config/var_test.php
  21. +5 −1 lib/Cake/Test/test_app/Config/var_test2.php
  22. +5 −1 lib/Cake/Utility/ClassRegistry.php
  23. +1 −1  lib/Cake/VERSION.txt
  24. +3 −0  lib/Cake/View/JsonView.php
  25. +1 −1  lib/Cake/View/View.php
  26. +3 −0  lib/Cake/View/XmlView.php
View
3  lib/Cake/Config/config.php
@@ -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;
View
4 lib/Cake/Controller/Component/AuthComponent.php
@@ -432,7 +432,7 @@ public function constructAuthorize() {
*/
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 @@ public function allow($action = null) {
*/
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])) {
View
2  lib/Cake/Controller/Component/PaginatorComponent.php
@@ -333,7 +333,7 @@ public function validateSort($object, $options, $whitelist = array()) {
$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;
View
2  lib/Cake/Core/Configure.php
@@ -312,7 +312,7 @@ public static function load($key, $config = 'default', $merge = true) {
$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]);
}
}
}
View
135 lib/Cake/I18n/I18n.php
@@ -46,6 +46,13 @@ class I18n {
public $l10n = null;
/**
+ * Default domain of translation
+ *
+ * @var string
+ */
+ public static $defaultDomain = 'default';
+
+/**
* Current domain of translation
*
* @var string
@@ -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 @@ public static function &getInstance() {
* @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 @@ public static function translate($singular, $plural = null, $domain = null, $cat
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 @@ public static function translate($singular, $plural = null, $domain = null, $cat
}
if (is_null($domain)) {
- $domain = 'default';
+ $domain = self::$defaultDomain;
}
$_this->domain = $domain . '_' . $_this->l10n->lang;
@@ -304,41 +315,51 @@ protected function _bindTextDomain($domain) {
}
}
-
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);
- $this->_noLocale = false;
- break 2;
- } elseif (file_exists($fn = "$file.po") && ($f = fopen($fn, "r"))) {
- $this->_loadPo($f, $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 (is_file($localeDef) && ($f = fopen($localeDef, "r"))) {
- $this->_loadLocaleDefinition($f, $domain);
- $this->_noLocale = false;
- return $domain;
}
}
}
@@ -368,20 +389,21 @@ protected function _bindTextDomain($domain) {
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 @@ protected function _loadMo($file, $domain) {
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 @@ protected function _loadPo($file, $domain) {
}
} 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 @@ protected function _loadLocaleDefinition($file, $domain = null) {
$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;
}
/**
View
143 lib/Cake/Model/Behavior/TranslateBehavior.php
@@ -35,6 +35,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
*
* $config for TranslateBehavior should be
@@ -94,6 +108,7 @@ public function beforeFind($model, $query) {
}
$db = $model->getDataSource();
$RuntimeModel = $this->translateModel($model);
+
if (!empty($RuntimeModel->tablePrefix)) {
$tablePrefix = $RuntimeModel->tablePrefix;
} else {
@@ -104,8 +119,11 @@ public function beforeFind($model, $query) {
$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 @@ public function beforeFind($model, $query) {
$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 @@ public function beforeFind($model, $query) {
unset($query['fields'][$key]);
}
}
+ $query = $this->_addJoin($model, $query, $field, $aliasField, $locale);
+ }
+ }
+ $this->runtime[$model->alias]['beforeFind'] = $addFields;
+ unset($this->_joinTable, $this->_runtimeModel);
+ return $query;
+ }
- 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
- )
- );
+/**
+ * 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;
}
}
}
- $this->runtime[$model->alias]['beforeFind'] = $addFields;
+ 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;
}
View
6 lib/Cake/Model/BehaviorCollection.php
@@ -107,6 +107,9 @@ public function load($behavior, $config = array()) {
$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 @@ public function load($behavior, $config = array()) {
}
}
- $enable = isset($config['enabled']) ? $config['enabled'] : true;
- if ($enable) {
+ if (!in_array($alias, $this->_enabled) && !$configDisabled) {
$this->enable($alias);
} else {
$this->disable($alias);
View
16 lib/Cake/Model/Datasource/Database/Sqlserver.php
@@ -182,7 +182,7 @@ public function listSources($data = null) {
} else {
$tables = array();
- while ($line = $result->fetch()) {
+ while ($line = $result->fetch(PDO::FETCH_NUM)) {
$tables[] = $line[0];
}
@@ -222,7 +222,7 @@ public function describe($model) {
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 @@ public function insertMulti($table, $fields, $values) {
$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 @@ public function buildIndex($indexes, $table = null) {
* @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') {
View
15 lib/Cake/Model/Model.php
@@ -2815,16 +2815,17 @@ protected function _findThreaded($state, $query, $results = array()) {
$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]);
View
12 lib/Cake/Test/Case/Controller/Component/AuthComponentTest.php
@@ -654,6 +654,18 @@ public function testAllowDenyAll() {
$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));
}
/**
View
20 lib/Cake/Test/Case/Controller/Component/PaginatorComponentTest.php
@@ -777,6 +777,26 @@ public function testValidateSortMultiple() {
}
/**
+ * 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
*
* @return void
View
2  lib/Cake/Test/Case/Core/ConfigureTest.php
@@ -224,6 +224,8 @@ public function testLoadWithMerge() {
$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'));
}
/**
View
54 lib/Cake/Test/Case/I18n/I18nTest.php
@@ -50,10 +50,14 @@ public function tearDown() {
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 @@ public function testTranslationCaching() {
$this->assertEquals('FOO', I18n::translate('dom1.foo', false, 'dom1'));
}
-
/**
* testDefaultStrings method
*
@@ -2588,6 +2591,11 @@ public function testCategoryThenSingular() {
$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 @@ public function testTimeDefinition() {
$this->assertEquals($expected, $result);
}
+/**
+ * testTimeDefinitionJapanese method
+ *
+ * @return void
+ */
public function testTimeDefinitionJapanese() {
Configure::write('Config.language', 'ja_jp');
$result = __c('d_fmt', 5);
@@ -2621,11 +2634,28 @@ public function testTimeDefinitionJapanese() {
}
/**
+ * 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 @@ function __domainCategorySingular($domain = 'test_plugin', $category = 3) {
*
* @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 @@ function __domainCategoryPlural($domain = 'test_plugin', $category = 3) {
*
* @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 @@ function __domainSingular($domain = 'test_plugin') {
*
* @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 @@ function __domainPlural($domain = 'test_plugin') {
*
* @return void
*/
- function __category($category = 3) {
+ private function __category($category = 3) {
$singular = __c('Plural Rule 1', $category);
return $singular;
}
@@ -2681,7 +2711,7 @@ function __category($category = 3) {
*
* @return void
*/
- function __singular() {
+ private function __singular() {
$singular = __('Plural Rule 1');
return $singular;
}
@@ -2691,7 +2721,7 @@ function __singular() {
*
* @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 @@ function __plural() {
*
* @return void
*/
- function __singularFromCore() {
+ private function __singularFromCore() {
$singular = __('Plural Rule 1 (from core)');
return $singular;
}
@@ -2714,7 +2744,7 @@ function __singularFromCore() {
*
* @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 );
View
18 lib/Cake/Test/Case/Model/Behavior/TranslateBehaviorTest.php
@@ -59,6 +59,24 @@ public function tearDown() {
}
/**
+ * 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
*
* @return void
View
15 lib/Cake/Test/Case/Model/BehaviorCollectionTest.php
@@ -419,10 +419,23 @@ 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
*/
public function testLoadAlias() {
View
57 lib/Cake/Test/Case/Model/Datasource/Database/SqlserverTest.php
@@ -111,7 +111,7 @@ public function describe($model) {
*
* @package Cake.Test.Case.Model.Datasource.Database
*/
-class SqlserverTestModel extends Model {
+class SqlserverTestModel extends CakeTestModel {
/**
* name property
@@ -183,7 +183,7 @@ public function find($conditions = null, $fields = null, $order = null, $recursi
*
* @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 @@ public function tearDown() {
* @return void
*/
public function testQuoting() {
- $expected = "1.200000";
+ $expected = "1.2";
$result = $this->db->value(1.2, 'float');
$this->assertSame($expected, $result);
@@ -587,43 +601,6 @@ public function testGetPrimaryKey() {
}
/**
- * 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.
*
* @return void
View
3  lib/Cake/Test/Case/Model/Datasource/DboSourceTest.php
@@ -493,6 +493,9 @@ public function testDirectCallThrowsException() {
* @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__$}');
View
14 lib/Cake/Test/Case/Model/ModelIntegrationTest.php
@@ -208,11 +208,11 @@ public function testPkInHabtmLinkModel() {
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 @@ public function testDynamicBehaviorAttachment() {
'__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));
}
View
12 lib/Cake/Test/Case/View/ViewTest.php
@@ -1236,4 +1236,16 @@ public function testExtendElement() {
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);
+ }
}
View
5 lib/Cake/Test/test_app/Config/var_test.php
@@ -5,5 +5,8 @@
'Deeper' => array(
'Deepest' => 'buried'
)
+ ),
+ 'TestAcl' => array(
+ 'classname' => 'Original'
)
-);
+);
View
6 lib/Cake/Test/test_app/Config/var_test2.php
@@ -5,5 +5,9 @@
'Second' => array(
'SecondDeepest' => 'buried2'
)
+ ),
+ 'TestAcl' => array(
+ 'classname' => 'Overwrite',
+ 'custom' => 'one'
)
-);
+);
View
6 lib/Cake/Utility/ClassRegistry.php
@@ -158,7 +158,11 @@ public static function init($class, $strict = false) {
}
}
}
- $instance = $reflection->newInstance($settings);
+ if ($reflection->getConstructor()) {
+ $instance = $reflection->newInstance($settings);
+ } else {
+ $instance = $reflection->newInstance();
+ }
if ($strict) {
$instance = ($instance instanceof Model) ? $instance : null;
}
View
2  lib/Cake/VERSION.txt
@@ -17,4 +17,4 @@
// @license MIT License (http://www.opensource.org/licenses/mit-license.php)
// +--------------------------------------------------------------------------------------------+ //
////////////////////////////////////////////////////////////////////////////////////////////////////
-2.1.0-dev
+2.1.0-alpha
View
3  lib/Cake/View/JsonView.php
@@ -96,6 +96,9 @@ public function render($view = null, $layout = null) {
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;
View
2  lib/Cake/View/View.php
@@ -796,7 +796,7 @@ public function __set($name, $value) {
* @return boolean
*/
public function __isset($name) {
- return isset($this->name);
+ return isset($this->{$name});
}
/**
View
3  lib/Cake/View/XmlView.php
@@ -99,6 +99,9 @@ public function render($view = null, $layout = null) {
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;
Please sign in to comment.
Something went wrong with that request. Please try again.