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

This commit is contained in:
Jose Lorenzo Rodriguez 2012-01-11 21:26:12 -04:30
commit 1a741b853b
26 changed files with 382 additions and 180 deletions

View file

@ -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 file

@ -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])) {

View file

@ -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;

View file

@ -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]);
}
}
}

View file

@ -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;
}
/**

View file

@ -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;
}

View file

@ -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);

View file

@ -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') {

View file

@ -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]);

View file

@ -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));
}
/**

View file

@ -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
*

View file

@ -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'));
}
/**

View file

@ -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 );

View file

@ -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
*

View file

@ -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
*/

View file

@ -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.
*

View file

@ -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__$}');

View file

@ -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));
}

View file

@ -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);
}
}

View file

@ -5,5 +5,8 @@ $config = array(
'Deeper' => array(
'Deepest' => 'buried'
)
),
'TestAcl' => array(
'classname' => 'Original'
)
);
);

View file

@ -5,5 +5,9 @@ $config = array(
'Second' => array(
'SecondDeepest' => 'buried2'
)
),
'TestAcl' => array(
'classname' => 'Overwrite',
'custom' => 'one'
)
);
);

View file

@ -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;
}

View file

@ -17,4 +17,4 @@
// @license MIT License (http://www.opensource.org/licenses/mit-license.php)
// +--------------------------------------------------------------------------------------------+ //
////////////////////////////////////////////////////////////////////////////////////////////////////
2.1.0-dev
2.1.0-alpha

View file

@ -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;

View file

@ -796,7 +796,7 @@ class View extends Object {
* @return boolean
*/
public function __isset($name) {
return isset($this->name);
return isset($this->{$name});
}
/**

View file

@ -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;