Merge branch '1.2' into 1.2-merger

Conflicts:
	cake/VERSION.txt
	cake/config/config.php
	cake/dispatcher.php
	cake/libs/controller/scaffold.php
	cake/libs/inflector.php
	cake/libs/view/view.php
	cake/tests/cases/libs/controller/scaffold.test.php
	cake/tests/cases/libs/inflector.test.php
	cake/tests/cases/libs/view/view.test.php
	cake/tests/fixtures/counter_cache_post_fixture.php
	cake/tests/fixtures/counter_cache_user_fixture.php
This commit is contained in:
mark_story 2009-09-13 13:52:58 -04:00
commit 326424592d
17 changed files with 191 additions and 60 deletions

View file

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

View file

@ -121,7 +121,7 @@ class ApiShell extends Shell {
$this->out($list);
$methods = array_keys($parsed);
while ($number = $this->in(__('Select a number to see the more information about a specific method. q to quit. l to list.', true), null, 'q')) {
while ($number = strtolower($this->in(__('Select a number to see the more information about a specific method. q to quit. l to list.', true), null, 'q'))) {
if ($number === 'q') {
$this->out(__('Done', true));
$this->_stop();

View file

@ -82,18 +82,18 @@ class I18nShell extends Shell {
$this->out(__('[H]elp', true));
$this->out(__('[Q]uit', true));
$choice = strtoupper($this->in(__('What would you like to do?', true), array('E', 'I', 'H', 'Q')));
$choice = strtolower($this->in(__('What would you like to do?', true), array('E', 'I', 'H', 'Q')));
switch ($choice) {
case 'E':
case 'e':
$this->Extract->execute();
break;
case 'I':
case 'i':
$this->initdb();
break;
case 'H':
case 'h':
$this->help();
break;
case 'Q':
case 'q':
exit(0);
break;
default:

View file

@ -135,7 +135,7 @@ class SchemaShell extends Shell {
if (!$snapshot && file_exists($this->Schema->path . DS . $this->params['file'])) {
$snapshot = true;
$result = $this->in("Schema file exists.\n [O]verwrite\n [S]napshot\n [Q]uit\nWould you like to do?", array('o', 's', 'q'), 's');
$result = strtolower($this->in("Schema file exists.\n [O]verwrite\n [S]napshot\n [Q]uit\nWould you like to do?", array('o', 's', 'q'), 's'));
if ($result === 'q') {
return $this->_stop();
}
@ -380,8 +380,7 @@ class SchemaShell extends Shell {
Configure::write('debug', 2);
$db =& ConnectionManager::getDataSource($this->Schema->connection);
$db->fullDebug = true;
$errors = array();
foreach ($contents as $table => $sql) {
if (empty($sql)) {
$this->out(sprintf(__('%s is up to date.', true), $table));
@ -393,15 +392,16 @@ class SchemaShell extends Shell {
if (!$Schema->before(array($event => $table))) {
return false;
}
if (!$db->_execute($sql)) {
$error = null;
if (!$db->execute($sql)) {
$error = $table . ': ' . $db->lastError();
}
$Schema->after(array($event => $table, 'errors'=> $errors));
$Schema->after(array($event => $table, 'errors' => $error));
if (isset($error)) {
if (!empty($error)) {
$this->out($error);
} elseif ($this->__dry !== true) {
} else {
$this->out(sprintf(__('%s updated.', true), $table));
}
}

View file

@ -318,22 +318,28 @@ class Dispatcher extends Object {
$params['url'] = $url;
}
}
foreach ($_FILES as $name => $data) {
if ($name != 'data') {
$params['form'][$name] = $data;
}
}
if (isset($_FILES['data'])) {
foreach ($_FILES['data'] as $key => $data) {
foreach ($data as $model => $fields) {
foreach ($fields as $field => $value) {
if (is_array($value)) {
foreach ($value as $k => $v) {
$params['data'][$model][$field][$k][$key] = $v;
if (is_array($fields)) {
foreach ($fields as $field => $value) {
if (is_array($value)) {
foreach ($value as $k => $v) {
$params['data'][$model][$field][$k][$key] = $v;
}
} else {
$params['data'][$model][$field][$key] = $value;
}
} else {
$params['data'][$model][$field][$key] = $value;
}
} else {
$params['data'][$model][$key] = $fields;
}
}
}
@ -641,7 +647,7 @@ class Dispatcher extends Object {
if ($pos > 0) {
$plugin = substr($url, 0, $pos - 1);
$url = str_replace($plugin . '/', '', $url);
$url = preg_replace('/^' . preg_quote($plugin, '/') . '\//i', '', $url);
$pluginPaths = App::path('plugins');
$count = count($pluginPaths);
for ($i = 0; $i < $count; $i++) {

View file

@ -498,7 +498,7 @@ class DboOracle extends DboSource {
* @access public
*/
function describe(&$model) {
$table = $model->fullTableName($model, false);
$table = $this->fullTableName($model, false);
if (!empty($model->sequence)) {
$this->_sequenceMap[$table] = $model->sequence;

View file

@ -86,8 +86,8 @@ class DboSource extends DataSource {
* @access protected
*/
var $_commands = array(
'begin' => 'BEGIN',
'commit' => 'COMMIT',
'begin' => 'BEGIN',
'commit' => 'COMMIT',
'rollback' => 'ROLLBACK'
);
@ -429,14 +429,15 @@ class DboSource extends DataSource {
$data[$i] = str_replace($this->startQuote . $this->startQuote, $this->startQuote, $data[$i]);
$data[$i] = str_replace($this->startQuote . '(', '(', $data[$i]);
$data[$i] = str_replace(')' . $this->startQuote, ')', $data[$i]);
$alias = !empty($this->alias) ? $this->alias : 'AS ';
if (preg_match('/\s+AS\s+/', $data[$i])) {
if (preg_match('/\w+\s+AS\s+/', $data[$i])) {
$quoted = $this->endQuote . ' AS ' . $this->startQuote;
$data[$i] = str_replace(' AS ', $quoted, $data[$i]);
if (preg_match('/\s+' . $alias . '\s*/', $data[$i])) {
if (preg_match('/\w+\s+' . $alias . '\s*/', $data[$i])) {
$quoted = $this->endQuote . ' ' . $alias . $this->startQuote;
$data[$i] = str_replace(' ' . $alias, $quoted, $data[$i]);
} else {
$quoted = ' AS ' . $this->startQuote;
$data[$i] = str_replace(' AS ', $quoted, $data[$i]) . $this->endQuote;
$quoted = $alias . $this->startQuote;
$data[$i] = str_replace($alias, $quoted, $data[$i]) . $this->endQuote;
}
}
@ -1745,7 +1746,9 @@ class DboSource extends DataSource {
if ($count >= 1 && !in_array($fields[0], array('*', 'COUNT(*)'))) {
for ($i = 0; $i < $count; $i++) {
if (!preg_match('/^.+\\(.*\\)/', $fields[$i])) {
if (preg_match('/^\(.*\)\s' . $this->alias . '.*/i', $fields[$i])){
continue;
} elseif (!preg_match('/^.+\\(.*\\)/', $fields[$i])) {
$prepend = '';
if (strpos($fields[$i], 'DISTINCT') !== false) {

View file

@ -397,7 +397,10 @@ class Set extends Object {
$contexts = $data;
$options = array_merge(array('flatten' => true), $options);
if (!isset($contexts[0])) {
$contexts = array($data);
$current = current($data);
if ((is_array($current) && count($data) <= 1) || !is_array($current)) {
$contexts = array($data);
}
}
$tokens = array_slice(preg_split('/(?<!=)\/(?![a-z-]*\])/', $path), 1);

View file

@ -315,8 +315,8 @@ class TimeHelper extends AppHelper {
* Relative dates look something like this:
* 3 weeks, 4 days ago
* 15 seconds ago
* Formatted dates look like this:
* on 02/18/2004
*
* Default date formatting is d/m/yy e.g: on 18/2/09
*
* The returned string includes 'ago' or 'on' and assumes you'll properly add a word
* like 'Posted ' before the function output.

View file

@ -708,7 +708,6 @@ class XmlNode extends Object {
if ($child->attributes) {
$value = array_merge(array('value' => $value), $child->attributes);
}
if (isset($out[$child->name]) || isset($multi[$key])) {
if (!isset($multi[$key])) {
$multi[$key] = array($out[$child->name]);
@ -721,15 +720,16 @@ class XmlNode extends Object {
continue;
} elseif (count($child->children) === 0 && $child->value == '') {
$value = $child->attributes;
if (isset($out[$child->name]) || isset($multi[$key])) {
if (!isset($multi[$key])) {
$multi[$key] = array($out[$child->name]);
unset($out[$child->name]);
}
$multi[$key][] = $value;
} else {
} elseif (!empty($value)) {
$out[$key] = $value;
} else {
$out[$child->name] = $value;
}
continue;
} else {
@ -851,19 +851,19 @@ class Xml extends XmlNode {
* Constructor. Sets up the XML parser with options, gives it this object as
* its XML object, and sets some variables.
*
* ### Options
* - 'root': The name of the root element, defaults to '#document'
* - 'version': The XML version, defaults to '1.0'
* - 'encoding': Document encoding, defaults to 'UTF-8'
* - 'namespaces': An array of namespaces (as strings) used in this document
* - 'format': Specifies the format this document converts to when parsed or
* rendered out as text, either 'attributes' or 'tags', defaults to 'attributes'
* - 'tags': An array specifying any tag-specific formatting options, indexed
* by tag name. See XmlNode::normalize().
* @param mixed $input The content with which this XML document should be initialized. Can be a
* string, array or object. If a string is specified, it may be a literal XML
* document, or a URL or file path to read from.
* @param array $options Options to set up with, valid options are as follows:
* - 'root': The name of the root element, defaults to '#document'
* - 'version': The XML version, defaults to '1.0'
* - 'encoding': Document encoding, defaults to 'UTF-8'
* - 'namespaces': An array of namespaces (as strings) used in this document
* - 'format': Specifies the format this document converts to when parsed or
* rendered out as text, either 'attributes' or 'tags',
* defaults to 'attributes'
* - 'tags': An array specifying any tag-specific formatting options, indexed
* by tag name. See XmlNode::normalize().
* string, array or object. If a string is specified, it may be a literal XML
* document, or a URL or file path to read from.
* @param array $options Options to set up with, for valid options see above:
* @see XmlNode::normalize()
*/
function __construct($input = null, $options = array()) {
@ -892,9 +892,6 @@ class Xml extends XmlNode {
$Root->append($input, $options);
}
}
// if (Configure::read('App.encoding') !== null) {
// $this->encoding = Configure::read('App.encoding');
// }
}
/**
@ -938,8 +935,8 @@ class Xml extends XmlNode {
$this->__initParser();
$this->__rawData = trim($this->__rawData);
$this->__header = trim(str_replace(
a('<' . '?', '?' . '>'),
a('', ''),
array('<' . '?', '?' . '>'),
array('', ''),
substr($this->__rawData, 0, strpos($this->__rawData, '?' . '>'))
));
@ -950,7 +947,6 @@ class Xml extends XmlNode {
for ($i = 0; $i < $count; $i++) {
$data = $vals[$i];
$data += array('tag' => null, 'value' => null, 'attributes' => array());
switch ($data['type']) {
case "open" :
$xml =& $xml->createElement($data['tag'], $data['value'], $data['attributes']);

View file

@ -940,6 +940,32 @@ class DispatcherTest extends CakeTestCase {
)
);
$this->assertEqual($result['data'], $expected);
$_FILES = array(
'data' => array(
'name' => array('birth_cert' => 'born on.txt'),
'type' => array('birth_cert' => 'application/octet-stream'),
'tmp_name' => array('birth_cert' => '/private/var/tmp/phpbsUWfH'),
'error' => array('birth_cert' => 0),
'size' => array('birth_cert' => 123)
)
);
$Dispatcher =& new Dispatcher();
$result = $Dispatcher->parseParams('/');
$expected = array(
'birth_cert' => array(
'name' => 'born on.txt',
'type' => 'application/octet-stream',
'tmp_name' => '/private/var/tmp/phpbsUWfH',
'error' => 0,
'size' => 123
)
);
$this->assertEqual($result['data'], $expected);
}
/**
@ -1780,6 +1806,20 @@ class DispatcherTest extends CakeTestCase {
$this->assertEqual('this is the test asset css file', $result);
ob_start();
$Dispatcher->cached('test_plugin/js/test_plugin/test.js');
$result = ob_get_clean();
$this->assertEqual('alert("Test App");', $result);
Configure::write('debug', 0);
$Dispatcher->params = $Dispatcher->parseParams('test_plugin/js/test_plugin/test.js');
ob_start();
$Dispatcher->cached('test_plugin/js/test_plugin/test.js');
$result = ob_get_clean();
$this->assertEqual('alert("Test App");', $result);
Configure::write('debug', 0);
$Dispatcher->params = $Dispatcher->parseParams('test_plugin/css/test_plugin_asset.css');
ob_start();
@ -1787,6 +1827,7 @@ class DispatcherTest extends CakeTestCase {
$result = ob_get_clean();
$this->assertEqual('this is the test plugin asset css file', $result);
Configure::write('debug', 0);
$Dispatcher->params = $Dispatcher->parseParams('test_plugin/img/cake.icon.gif');
ob_start();

View file

@ -621,7 +621,6 @@ class ScaffoldTest extends CakeTestCase {
* @access public
*/
var $fixtures = array('core.article', 'core.user', 'core.comment', 'core.posts_tag', 'core.tag');
/**
* startTest method
*

View file

@ -113,6 +113,7 @@ class InflectorTest extends CakeTestCase {
$this->assertEqual(Inflector::singularize('faxes'), 'fax');
$this->assertEqual(Inflector::singularize('waxes'), 'wax');
$this->assertEqual(Inflector::singularize('niches'), 'niche');
$this->assertEqual(Inflector::singularize('waves'), 'wave');
$this->assertEqual(Inflector::singularize(''), '');
}
@ -158,6 +159,7 @@ class InflectorTest extends CakeTestCase {
$this->assertEqual(Inflector::pluralize('glove'), 'gloves');
$this->assertEqual(Inflector::pluralize('crisis'), 'crises');
$this->assertEqual(Inflector::pluralize('tax'), 'taxes');
$this->assertEqual(Inflector::pluralize('wave'), 'waves');
$this->assertEqual(Inflector::pluralize(''), '');
}

View file

@ -2850,6 +2850,10 @@ class DboSourceTest extends CakeTestCase {
);
$this->assertEqual($result, $expected);
$result = $this->testDb->fields($this->Model, null, "(`Provider`.`star_total` / `Provider`.`total_ratings`) as `rating`");
$expected = array("(`Provider`.`star_total` / `Provider`.`total_ratings`) as `rating`");
$this->assertEqual($result, $expected);
$result = $this->testDb->fields($this->Model, 'Post');
$expected = array(
'`Post`.`id`', '`Post`.`client_id`', '`Post`.`name`', '`Post`.`login`',
@ -2927,7 +2931,7 @@ class DboSourceTest extends CakeTestCase {
$expected = array(
'`Foo`.`id`',
'`Foo`.`title`',
'(user_count + discussion_count + post_count) AS `score`'
'(user_count + discussion_count + post_count) AS score'
);
$this->assertEqual($result, $expected);
}

View file

@ -545,6 +545,30 @@ class SetTest extends CakeTestCase {
$r = Set::extract('/User/@*', $tricky);
$this->assertEqual($r, $expected);
$nonZero = array(
1 => array(
'User' => array(
'id' => 1,
'name' => 'John',
)
),
2 => array(
'User' => array(
'id' => 2,
'name' => 'Bob',
)
),
3 => array(
'User' => array(
'id' => 3,
'name' => 'Tony',
)
)
);
$expected = array(1, 2, 3);
$r = Set::extract('/User/id', $nonZero);
$this->assertEqual($r, $expected);
$common = array(
array(
'Article' => array(
@ -979,7 +1003,6 @@ class SetTest extends CakeTestCase {
$expected = array(array('name' => 'zipfile.zip','type' => 'application/zip','tmp_name' => '/tmp/php178.tmp','error' => 0,'size' => '564647'));
$r = Set::extract('/file/.[type=application/zip]', $f);
$this->assertEqual($r, $expected);
}
/**
@ -2423,7 +2446,7 @@ class SetTest extends CakeTestCase {
array(
'Item' => array(
'title' => 'An example of a correctly reversed XMLNode',
'Desc' => array(),
'desc' => array(),
)
)
);

View file

@ -782,6 +782,60 @@ class XmlTest extends CakeTestCase {
$this->assertEqual($result, $expected);
}
/**
* test that empty values do not casefold collapse
*
* @see http://code.cakephp.org/tickets/view/8
* @return void
**/
function testCaseFoldingWithEmptyValues() {
$filledValue = '<method name="set_user_settings">
<title>update user information</title>
<user>1</user>
<User>
<id>1</id>
<name>varchar(45)</name>
</User>
</method>';
$xml =& new XML($filledValue);
$expected = array(
'Method' => array(
'name' => 'set_user_settings',
'title' => 'update user information',
'user' => '1',
'User' => array(
'id' => 1,
'name' => 'varchar(45)',
),
)
);
$result = $xml->toArray();
$this->assertEqual($result, $expected);
$emptyValue ='<method name="set_user_settings">
<title>update user information</title>
<user></user>
<User>
<id>1</id>
<name>varchar(45)</name>
</User>
</method>';
$xml =& new XML($emptyValue);
$expected = array(
'Method' => array(
'name' => 'set_user_settings',
'title' => 'update user information',
'user' => array(),
'User' => array(
'id' => 1,
'name' => 'varchar(45)',
),
)
);
$result = $xml->toArray();
$this->assertEqual($result, $expected);
}
/**
* testMixedParsing method
*
@ -950,7 +1004,7 @@ class XmlTest extends CakeTestCase {
'Example' => array(
'Item' => array(
'title' => 'An example of a correctly reversed XMLNode',
'Desc' => array(),
'desc' => array(),
)
)
);

View file

@ -0,0 +1 @@
alert("Test App");