Merge branch 'master' into 2.5

Conflicts:
	lib/Cake/VERSION.txt
This commit is contained in:
mark_story 2013-09-02 11:35:09 -04:00
commit 59bb05b433
27 changed files with 723 additions and 283 deletions

View file

@ -34,6 +34,6 @@ Get Support!
[Lighthouse](https://cakephp.lighthouseapp.com/) - Got issues? Please tell us!
[![Bake Status](https://secure.travis-ci.org/cakephp/cakephp.png?branch=2.4)](http://travis-ci.org/cakephp/cakephp)
[![Bake Status](https://secure.travis-ci.org/cakephp/cakephp.png?branch=master)](http://travis-ci.org/cakephp/cakephp)
![Cake Power](https://raw.github.com/cakephp/cakephp/master/lib/Cake/Console/Templates/skel/webroot/img/cake.power.gif)

View file

@ -67,7 +67,7 @@ endif;
$settings = Cache::settings();
if (!empty($settings)):
echo '<span class="notice success">';
echo __d('cake_dev', 'The %s is being used for core caching. To change the config edit APP/Config/core.php ', '<em>'. $settings['engine'] . 'Engine</em>');
echo __d('cake_dev', 'The %s is being used for core caching. To change the config edit APP/Config/core.php ', '<em>' . $settings['engine'] . 'Engine</em>');
echo '</span>';
else:
echo '<span class="notice">';
@ -113,7 +113,7 @@ if (isset($filePresent)):
<?php
if ($connected && $connected->isConnected()):
echo '<span class="notice success">';
echo __d('cake_dev', 'Cake is able to connect to the database.');
echo __d('cake_dev', 'Cake is able to connect to the database.');
echo '</span>';
else:
echo '<span class="notice">';

View file

@ -44,7 +44,7 @@ class ExtractTask extends AppShell {
protected $_files = array();
/**
* Merge all domains string into the default.pot file
* Merge all domain and category strings into the default.pot file
*
* @var boolean
*/
@ -72,7 +72,7 @@ class ExtractTask extends AppShell {
protected $_tokens = array();
/**
* Extracted strings indexed by domain.
* Extracted strings indexed by category and domain.
*
* @var array
*/
@ -222,7 +222,7 @@ class ExtractTask extends AppShell {
$this->_merge = !(strtolower($this->params['merge']) === 'no');
} else {
$this->out();
$response = $this->in(__d('cake_console', 'Would you like to merge all domains strings into the default.pot file?'), array('y', 'n'), 'n');
$response = $this->in(__d('cake_console', 'Would you like to merge all domain and category strings into the default.pot file?'), array('y', 'n'), 'n');
$this->_merge = strtolower($response) === 'y';
}
@ -244,20 +244,21 @@ class ExtractTask extends AppShell {
*
* Takes care of duplicate translations
*
* @param string $category
* @param string $domain
* @param string $msgid
* @param array $details
* @return void
*/
protected function _addTranslation($domain, $msgid, $details = array()) {
if (empty($this->_translations[$domain][$msgid])) {
$this->_translations[$domain][$msgid] = array(
protected function _addTranslation($category, $domain, $msgid, $details = array()) {
if (empty($this->_translations[$category][$domain][$msgid])) {
$this->_translations[$category][$domain][$msgid] = array(
'msgid_plural' => false
);
}
if (isset($details['msgid_plural'])) {
$this->_translations[$domain][$msgid]['msgid_plural'] = $details['msgid_plural'];
$this->_translations[$category][$domain][$msgid]['msgid_plural'] = $details['msgid_plural'];
}
if (isset($details['file'])) {
@ -265,7 +266,7 @@ class ExtractTask extends AppShell {
if (isset($details['line'])) {
$line = $details['line'];
}
$this->_translations[$domain][$msgid]['references'][$details['file']][] = $line;
$this->_translations[$category][$domain][$msgid]['references'][$details['file']][] = $line;
}
}
@ -307,7 +308,7 @@ class ExtractTask extends AppShell {
->addOption('app', array('help' => __d('cake_console', 'Directory where your application is located.')))
->addOption('paths', array('help' => __d('cake_console', 'Comma separated list of paths.')))
->addOption('merge', array(
'help' => __d('cake_console', 'Merge all domain strings into the default.po file.'),
'help' => __d('cake_console', 'Merge all domain and category strings into the default.po file.'),
'choices' => array('yes', 'no')
))
->addOption('output', array('help' => __d('cake_console', 'Full path to output directory.')))
@ -368,10 +369,10 @@ class ExtractTask extends AppShell {
$this->_parse('__', array('singular'));
$this->_parse('__n', array('singular', 'plural'));
$this->_parse('__d', array('domain', 'singular'));
$this->_parse('__c', array('singular'));
$this->_parse('__dc', array('domain', 'singular'));
$this->_parse('__c', array('singular', 'category'));
$this->_parse('__dc', array('domain', 'singular', 'category'));
$this->_parse('__dn', array('domain', 'singular', 'plural'));
$this->_parse('__dcn', array('domain', 'singular', 'plural'));
$this->_parse('__dcn', array('domain', 'singular', 'plural', 'count', 'category'));
}
}
@ -379,11 +380,12 @@ class ExtractTask extends AppShell {
* Parse tokens
*
* @param string $functionName Function name that indicates translatable string (e.g: '__')
* @param array $map Array containing what variables it will find (e.g: domain, singular, plural)
* @param array $map Array containing what variables it will find (e.g: category, domain, singular, plural)
* @return void
*/
protected function _parse($functionName, $map) {
$count = 0;
$categories = array('LC_ALL', 'LC_COLLATE', 'LC_CTYPE', 'LC_MONETARY', 'LC_NUMERIC', 'LC_TIME', 'LC_MESSAGES');
$tokenCount = count($this->_tokens);
while (($tokenCount - $count) > 1) {
@ -413,6 +415,9 @@ class ExtractTask extends AppShell {
if ($mapCount == count($strings)) {
extract(array_combine($map, $strings));
$category = isset($category) ? $category : 6;
$category = intval($category);
$categoryName = $categories[$category];
$domain = isset($domain) ? $domain : 'default';
$details = array(
'file' => $this->_file,
@ -421,7 +426,7 @@ class ExtractTask extends AppShell {
if (isset($plural)) {
$details['msgid_plural'] = $plural;
}
$this->_addTranslation($domain, $singular, $details);
$this->_addTranslation($categoryName, $domain, $singular, $details);
} else {
$this->_markerError($this->_file, $line, $functionName, $count);
}
@ -500,7 +505,7 @@ class ExtractTask extends AppShell {
* @param string $domain default domain to bind the validations to
* @return void
*/
protected function _processValidationRules($field, $rules, $file, $domain) {
protected function _processValidationRules($field, $rules, $file, $domain, $category = 'LC_MESSAGES') {
if (!is_array($rules)) {
return;
}
@ -526,7 +531,7 @@ class ExtractTask extends AppShell {
'file' => $file,
'line' => 'validation for field ' . $field
);
$this->_addTranslation($domain, $msgid, $details);
$this->_addTranslation($category, $domain, $msgid, $details);
}
}
}
@ -539,31 +544,33 @@ class ExtractTask extends AppShell {
protected function _buildFiles() {
$paths = $this->_paths;
$paths[] = realpath(APP) . DS;
foreach ($this->_translations as $domain => $translations) {
foreach ($translations as $msgid => $details) {
$plural = $details['msgid_plural'];
$files = $details['references'];
$occurrences = array();
foreach ($files as $file => $lines) {
$lines = array_unique($lines);
$occurrences[] = $file . ':' . implode(';', $lines);
}
$occurrences = implode("\n#: ", $occurrences);
$header = '#: ' . str_replace(DS, '/', str_replace($paths, '', $occurrences)) . "\n";
foreach ($this->_translations as $category => $domains) {
foreach ($domains as $domain => $translations) {
foreach ($translations as $msgid => $details) {
$plural = $details['msgid_plural'];
$files = $details['references'];
$occurrences = array();
foreach ($files as $file => $lines) {
$lines = array_unique($lines);
$occurrences[] = $file . ':' . implode(';', $lines);
}
$occurrences = implode("\n#: ", $occurrences);
$header = '#: ' . str_replace(DS, '/', str_replace($paths, '', $occurrences)) . "\n";
if ($plural === false) {
$sentence = "msgid \"{$msgid}\"\n";
$sentence .= "msgstr \"\"\n\n";
} else {
$sentence = "msgid \"{$msgid}\"\n";
$sentence .= "msgid_plural \"{$plural}\"\n";
$sentence .= "msgstr[0] \"\"\n";
$sentence .= "msgstr[1] \"\"\n\n";
}
if ($plural === false) {
$sentence = "msgid \"{$msgid}\"\n";
$sentence .= "msgstr \"\"\n\n";
} else {
$sentence = "msgid \"{$msgid}\"\n";
$sentence .= "msgid_plural \"{$plural}\"\n";
$sentence .= "msgstr[0] \"\"\n";
$sentence .= "msgstr[1] \"\"\n\n";
}
$this->_store($domain, $header, $sentence);
if ($domain !== 'default' && $this->_merge) {
$this->_store('default', $header, $sentence);
$this->_store($category, $domain, $header, $sentence);
if (($category !== 'LC_MESSAGES' || $domain !== 'default') && $this->_merge) {
$this->_store('LC_MESSAGES', 'default', $header, $sentence);
}
}
}
}
@ -572,19 +579,23 @@ class ExtractTask extends AppShell {
/**
* Prepare a file to be stored
*
* @param string $category
* @param string $domain
* @param string $header
* @param string $sentence
* @return void
*/
protected function _store($domain, $header, $sentence) {
if (!isset($this->_storage[$domain])) {
$this->_storage[$domain] = array();
protected function _store($category, $domain, $header, $sentence) {
if (!isset($this->_storage[$category])) {
$this->_storage[$category] = array();
}
if (!isset($this->_storage[$domain][$sentence])) {
$this->_storage[$domain][$sentence] = $header;
if (!isset($this->_storage[$category][$domain])) {
$this->_storage[$category][$domain] = array();
}
if (!isset($this->_storage[$category][$domain][$sentence])) {
$this->_storage[$category][$domain][$sentence] = $header;
} else {
$this->_storage[$domain][$sentence] .= $header;
$this->_storage[$category][$domain][$sentence] .= $header;
}
}
@ -598,36 +609,42 @@ class ExtractTask extends AppShell {
if (!empty($this->params['overwrite'])) {
$overwriteAll = true;
}
foreach ($this->_storage as $domain => $sentences) {
$output = $this->_writeHeader();
foreach ($sentences as $sentence => $header) {
$output .= $header . $sentence;
}
$filename = $domain . '.pot';
$File = new File($this->_output . $filename);
$response = '';
while ($overwriteAll === false && $File->exists() && strtoupper($response) !== 'Y') {
$this->out();
$response = $this->in(
__d('cake_console', 'Error: %s already exists in this location. Overwrite? [Y]es, [N]o, [A]ll', $filename),
array('y', 'n', 'a'),
'y'
);
if (strtoupper($response) === 'N') {
$response = '';
while (!$response) {
$response = $this->in(__d('cake_console', "What would you like to name this file?"), null, 'new_' . $filename);
$File = new File($this->_output . $response);
$filename = $response;
}
} elseif (strtoupper($response) === 'A') {
$overwriteAll = true;
foreach ($this->_storage as $category => $domains) {
foreach ($domains as $domain => $sentences) {
$output = $this->_writeHeader();
foreach ($sentences as $sentence => $header) {
$output .= $header . $sentence;
}
$filename = $domain . '.pot';
if ($category === 'LC_MESSAGES') {
$File = new File($this->_output . $filename);
} else {
new Folder($this->_output . $category, true);
$File = new File($this->_output . $category . DS . $filename);
}
$response = '';
while ($overwriteAll === false && $File->exists() && strtoupper($response) !== 'Y') {
$this->out();
$response = $this->in(
__d('cake_console', 'Error: %s already exists in this location. Overwrite? [Y]es, [N]o, [A]ll', $filename),
array('y', 'n', 'a'),
'y'
);
if (strtoupper($response) === 'N') {
$response = '';
while (!$response) {
$response = $this->in(__d('cake_console', "What would you like to name this file?"), null, 'new_' . $filename);
$File = new File($this->_output . $response);
$filename = $response;
}
} elseif (strtoupper($response) === 'A') {
$overwriteAll = true;
}
}
$File->write($output);
$File->close();
}
$File->write($output);
$File->close();
}
}
@ -665,7 +682,7 @@ class ExtractTask extends AppShell {
protected function _getStrings(&$position, $target) {
$strings = array();
$count = count($strings);
while ($count < $target && ($this->_tokens[$position] === ',' || $this->_tokens[$position][0] == T_CONSTANT_ENCAPSED_STRING)) {
while ($count < $target && ($this->_tokens[$position] === ',' || $this->_tokens[$position][0] == T_CONSTANT_ENCAPSED_STRING || $this->_tokens[$position][0] == T_LNUMBER)) {
$count = count($strings);
if ($this->_tokens[$position][0] == T_CONSTANT_ENCAPSED_STRING && $this->_tokens[$position + 1] === '.') {
$string = '';
@ -678,6 +695,8 @@ class ExtractTask extends AppShell {
$strings[] = $string;
} elseif ($this->_tokens[$position][0] == T_CONSTANT_ENCAPSED_STRING) {
$strings[] = $this->_formatString($this->_tokens[$position][1]);
} elseif ($this->_tokens[$position][0] == T_LNUMBER) {
$strings[] = $this->_tokens[$position][1];
}
$position++;
}

View file

@ -32,12 +32,24 @@ class ConsoleInput {
*/
protected $_input;
/**
* Can this instance use readline?
* Two conditions must be met:
* 1. Readline support must be enabled.
* 2. Handle we are attached to must be stdin.
* Allows rich editing with arrow keys and history when inputting a string.
*
* @var bool
*/
protected $_canReadline;
/**
* Constructor
*
* @param string $handle The location of the stream to use as input.
*/
public function __construct($handle = 'php://stdin') {
$this->_canReadline = extension_loaded('readline') && $handle == 'php://stdin' ? true : false;
$this->_input = fopen($handle, 'r');
}
@ -47,6 +59,13 @@ class ConsoleInput {
* @return mixed The value of the stream
*/
public function read() {
if ($this->_canReadline) {
$line = readline('');
if (!empty($line)) {
readline_add_history($line);
}
return $line;
}
return fgets($this->_input);
}

View file

@ -175,7 +175,7 @@ class AuthComponent extends Component {
/**
* An URL (defined as a string or array) to the controller action that handles
* logins. Defaults to `/users/login`
* logins. Defaults to `/users/login`.
*
* @var mixed
*/
@ -250,14 +250,14 @@ class AuthComponent extends Component {
public $response;
/**
* Method list for bound controller
* Method list for bound controller.
*
* @var array
*/
protected $_methods = array();
/**
* Initializes AuthComponent for use in the controller
* Initializes AuthComponent for use in the controller.
*
* @param Controller $controller A reference to the instantiating controller object
* @return void
@ -610,7 +610,7 @@ class AuthComponent extends Component {
/**
* Log a user out.
*
* Returns the login action to redirect to. Triggers the logout() method of
* Returns the logout action to redirect to. Triggers the logout() method of
* all the authenticate objects, so they can perform custom logout logic.
* AuthComponent will remove the session data, so there is no need to do that
* in an authentication object. Logging out will also renew the session id.
@ -688,7 +688,7 @@ class AuthComponent extends Component {
}
/**
* Backwards compatible alias for AuthComponent::redirectUrl()
* Backwards compatible alias for AuthComponent::redirectUrl().
*
* @param string|array $url Optional URL to write as the login redirect URL.
* @return string Redirect URL
@ -760,7 +760,7 @@ class AuthComponent extends Component {
}
/**
* loads the configured authentication objects.
* Loads the configured authentication objects.
*
* @return mixed either null on empty authenticate value, or an array of loaded objects.
* @throws CakeException

View file

@ -549,11 +549,11 @@ class I18n {
continue;
}
$count = count($parts);
if ($count == 2) {
if ($count === 2) {
$currentToken = $parts[0];
$value = $parts[1];
} elseif ($count == 1) {
$value .= $parts[0];
} elseif ($count === 1) {
$value = is_array($value) ? $parts[0] : $value . $parts[0];
} else {
continue;
}
@ -575,7 +575,7 @@ class I18n {
$val = str_replace($replacements, $mustEscape, $val);
$value[$i] = $val;
}
if (count($value) == 1) {
if (count($value) === 1) {
$definitions[$currentToken] = array_pop($value);
} else {
$definitions[$currentToken] = $value;

View file

@ -375,6 +375,12 @@ class TreeBehavior extends ModelBehavior {
} else {
array_unshift($valuePath, '%s' . $valuePath[0], '{n}.tree_prefix');
}
$conditions = (array)$conditions;
if ($scope) {
$conditions[] = $scope;
}
$order = $Model->escapeField($left) . " asc";
$results = $Model->find('all', compact('conditions', 'fields', 'order', 'recursive'));
$stack = array();

View file

@ -2818,9 +2818,9 @@ class Model extends Object implements CakeEventListener {
protected function _findAll($state, $query, $results = array()) {
if ($state === 'before') {
return $query;
} elseif ($state === 'after') {
return $results;
}
return $results;
}
/**
@ -2836,12 +2836,12 @@ class Model extends Object implements CakeEventListener {
if ($state === 'before') {
$query['limit'] = 1;
return $query;
} elseif ($state === 'after') {
if (empty($results[0])) {
return array();
}
return $results[0];
}
if (empty($results[0])) {
return array();
}
return $results[0];
}
/**
@ -2877,17 +2877,17 @@ class Model extends Object implements CakeEventListener {
));
}
return $query;
} elseif ($state === 'after') {
foreach (array(0, $this->alias) as $key) {
if (isset($results[0][$key]['count'])) {
if ($query['group']) {
return count($results);
}
return intval($results[0][$key]['count']);
}
}
return false;
}
foreach (array(0, $this->alias) as $key) {
if (isset($results[0][$key]['count'])) {
if ($query['group']) {
return count($results);
}
return intval($results[0][$key]['count']);
}
}
return false;
}
/**
@ -2939,12 +2939,12 @@ class Model extends Object implements CakeEventListener {
}
list($query['list']['keyPath'], $query['list']['valuePath'], $query['list']['groupPath']) = $list;
return $query;
} elseif ($state === 'after') {
if (empty($results)) {
return array();
}
return Hash::combine($results, $query['list']['keyPath'], $query['list']['valuePath'], $query['list']['groupPath']);
}
if (empty($results)) {
return array();
}
return Hash::combine($results, $query['list']['keyPath'], $query['list']['valuePath'], $query['list']['groupPath']);
}
/**
@ -2974,34 +2974,34 @@ class Model extends Object implements CakeEventListener {
$query['field'] = $field;
$query['value'] = $value;
return $query;
} elseif ($state === 'after') {
extract($query);
unset($query['conditions'][$field . ' <']);
$return = array();
if (isset($results[0])) {
$prevVal = Hash::get($results[0], $field);
$query['conditions'][$field . ' >='] = $prevVal;
$query['conditions'][$field . ' !='] = $value;
$query['limit'] = 2;
} else {
$return['prev'] = null;
$query['conditions'][$field . ' >'] = $value;
$query['limit'] = 1;
}
$query['order'] = $field . ' ASC';
$neighbors = $this->find('all', $query);
if (!array_key_exists('prev', $return)) {
$return['prev'] = isset($neighbors[0]) ? $neighbors[0] : null;
}
if (count($neighbors) === 2) {
$return['next'] = $neighbors[1];
} elseif (count($neighbors) === 1 && !$return['prev']) {
$return['next'] = $neighbors[0];
} else {
$return['next'] = null;
}
return $return;
}
extract($query);
unset($query['conditions'][$field . ' <']);
$return = array();
if (isset($results[0])) {
$prevVal = Hash::get($results[0], $field);
$query['conditions'][$field . ' >='] = $prevVal;
$query['conditions'][$field . ' !='] = $value;
$query['limit'] = 2;
} else {
$return['prev'] = null;
$query['conditions'][$field . ' >'] = $value;
$query['limit'] = 1;
}
$query['order'] = $field . ' ASC';
$neighbors = $this->find('all', $query);
if (!array_key_exists('prev', $return)) {
$return['prev'] = isset($neighbors[0]) ? $neighbors[0] : null;
}
if (count($neighbors) === 2) {
$return['next'] = $neighbors[1];
} elseif (count($neighbors) === 1 && !$return['prev']) {
$return['next'] = $neighbors[0];
} else {
$return['next'] = null;
}
return $return;
}
/**
@ -3016,16 +3016,16 @@ class Model extends Object implements CakeEventListener {
protected function _findThreaded($state, $query, $results = array()) {
if ($state === 'before') {
return $query;
} elseif ($state === 'after') {
$parent = 'parent_id';
if (isset($query['parent'])) {
$parent = $query['parent'];
}
return Hash::nest($results, array(
'idPath' => '{n}.' . $this->alias . '.' . $this->primaryKey,
'parentPath' => '{n}.' . $this->alias . '.' . $parent
));
}
$parent = 'parent_id';
if (isset($query['parent'])) {
$parent = $query['parent'];
}
return Hash::nest($results, array(
'idPath' => '{n}.' . $this->alias . '.' . $this->primaryKey,
'parentPath' => '{n}.' . $this->alias . '.' . $parent
));
}
/**

View file

@ -1611,6 +1611,7 @@ class CakeEmail {
$View = new $viewClass(null);
$View->viewVars = $this->_viewVars;
$View->helpers = $this->_helpers;
$View->loadHelpers();
list($templatePlugin, $template) = pluginSplit($this->_template);
list($layoutPlugin, $layout) = pluginSplit($this->_layout);

View file

@ -178,6 +178,32 @@ class ExtractTaskTest extends CakeTestCase {
$this->assertRegExp($pattern, $result);
}
/**
* testExtractCategory method
*
* @return void
*/
public function testExtractCategory() {
$this->Task->interactive = false;
$this->Task->params['paths'] = CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS . 'Pages';
$this->Task->params['output'] = $this->path . DS;
$this->Task->params['extract-core'] = 'no';
$this->Task->params['merge'] = 'no';
$this->Task->expects($this->never())->method('err');
$this->Task->expects($this->any())->method('in')
->will($this->returnValue('y'));
$this->Task->expects($this->never())->method('_stop');
$this->Task->execute();
$this->assertTrue(file_exists($this->path . DS . 'LC_TIME' . DS . 'default.pot'));
$result = file_get_contents($this->path . DS . 'default.pot');
$pattern = '/\#: .*extract\.ctp:31\n/';
$this->assertNotRegExp($pattern, $result);
}
/**
* test exclusions
*

View file

@ -1864,6 +1864,18 @@ class I18nTest extends CakeTestCase {
I18n::translate('Plural Rule 1', null, '');
}
/**
* testLoadLocaleDefinition method
*
* @return void
*/
public function testLoadLocaleDefinition() {
$path = current(App::path('locales'));
$result = I18n::loadLocaleDefinition($path . 'nld' . DS . 'LC_TIME');
$expected = array('zondag', 'maandag', 'dinsdag', 'woensdag', 'donderdag', 'vrijdag', 'zaterdag');
$this->assertSame($expected, $result['day']);
}
/**
* Singular method
*

View file

@ -340,4 +340,44 @@ class TreeBehaviorScopedTest extends CakeTestCase {
));
$this->assertEquals($expected, $result);
}
/**
* testGenerateTreeListWithScope method
*
* @return void
*/
public function testGenerateTreeListWithScope() {
extract($this->settings);
$this->Tree = new $modelClass();
$this->Tree->order = null;
$this->Tree->initialize(2, 3);
$this->Tree->id = 1;
$this->Tree->saveField('flag', 1);
$this->Tree->id = 2;
$this->Tree->saveField('flag', 1);
$this->Tree->Behaviors->attach('Tree', array('scope' => array('FlagTree.flag' => 1)));
$result = $this->Tree->generateTreeList();
$expected = array(
1 => '1. Root',
2 => '_1.1'
);
$this->assertEquals($expected, $result);
// As string.
$this->Tree->Behaviors->attach('Tree', array('scope' => 'FlagTree.flag = 1'));
$result = $this->Tree->generateTreeList();
$this->assertEquals($expected, $result);
// Merging conditions.
$result = $this->Tree->generateTreeList(array('FlagTree.id >' => 1));
$expected = array(
2 => '1.1'
);
$this->assertEquals($expected, $result);
}
}

View file

@ -334,6 +334,8 @@ object(View) {
response => object(CakeResponse) {}
elementCache => 'default'
elementCacheSettings => array()
Html => object(HtmlHelper) {}
Form => object(FormHelper) {}
int => (int) 2
float => (float) 1.333
@ -358,7 +360,6 @@ TEXT;
)
[protected] _scripts => array()
[protected] _paths => array()
[protected] _helpersLoaded => false
[protected] _parents => array()
[protected] _current => null
[protected] _currentType => ''

View file

@ -859,7 +859,7 @@ class HtmlHelperTest extends CakeTestCase {
* @return void
*/
public function testScriptTimestamping() {
$this->skipIf(!is_writable(JS), 'webroot/js is not Writable, timestamp testing has been skipped.');
$this->skipIf(!is_writable(WWW_ROOT . 'js'), 'webroot/js is not Writable, timestamp testing has been skipped.');
Configure::write('debug', 2);
Configure::write('Asset.timestamp', true);

View file

@ -975,8 +975,7 @@ class HelperTest extends CakeTestCase {
$Helper->OtherHelper;
$result = $this->View->Helpers->enabled();
$expected = array();
$this->assertEquals($expected, $result, 'Helper helpers were attached to the collection.');
$this->assertEquals(array(), $result, 'Helper helpers were attached to the collection.');
}
/**

View file

@ -53,6 +53,25 @@ class JsonViewTest extends CakeTestCase {
$this->assertSame('application/json', $Response->type());
}
/**
* Test that rendering with _serialize does not load helpers
*
* @return void
*/
public function testRenderSerializeNoHelpers() {
$Request = new CakeRequest();
$Response = new CakeResponse();
$Controller = new Controller($Request, $Response);
$Controller->helpers = array('Html');
$Controller->set(array(
'_serialize' => 'tags',
'tags' => array('cakephp', 'framework')
));
$View = new JsonView($Controller);
$View->render();
$this->assertFalse(isset($View->Html), 'No helper loaded.');
}
/**
* Test render with an array in _serialize
*
@ -146,8 +165,8 @@ class JsonViewTest extends CakeTestCase {
)
);
$Controller->set('user', $data);
$Controller->helpers = array('Paginator');
$View = new JsonView($Controller);
$View->helpers = array('Paginator');
$output = $View->render('index');
$expected = array('user' => 'fake', 'list' => array('item1', 'item2'), 'paging' => array('page' => 2));

View file

@ -219,6 +219,27 @@ class TestAfterHelper extends Helper {
}
/**
* Class TestObjectWithToString
*
* An object with the magic method __toString() for testing with view blocks.
*/
class TestObjectWithToString {
public function __toString() {
return "I'm ObjectWithToString";
}
}
/**
* Class TestObjectWithoutToString
*
* An object without the magic method __toString() for testing with view blocks.
*/
class TestObjectWithoutToString {
}
/**
* ViewTest class
*
@ -282,7 +303,7 @@ class ViewTest extends CakeTestCase {
}
/**
* testGetTemplate method
* Test getViewFileName method
*
* @return void
*/
@ -320,7 +341,7 @@ class ViewTest extends CakeTestCase {
}
/**
* testPluginGetTemplate method
* Test getLayoutFileName method on plugin
*
* @return void
*/
@ -342,7 +363,7 @@ class ViewTest extends CakeTestCase {
}
/**
* testPluginGetTemplate method
* Test getViewFileName method on plugin
*
* @return void
*/
@ -368,7 +389,7 @@ class ViewTest extends CakeTestCase {
}
/**
* test that plugin/$plugin_name is only appended to the paths it should be.
* Test that plugin/$plugin_name is only appended to the paths it should be.
*
* @return void
*/
@ -396,7 +417,7 @@ class ViewTest extends CakeTestCase {
}
/**
* test that CamelCase plugins still find their view files.
* Test that CamelCase'd plugins still find their view files.
*
* @return void
*/
@ -423,7 +444,7 @@ class ViewTest extends CakeTestCase {
}
/**
* testGetTemplate method
* Test getViewFileName method
*
* @return void
*/
@ -516,7 +537,7 @@ class ViewTest extends CakeTestCase {
}
/**
* testMissingView method
* Test for missing views
*
* @expectedException MissingViewException
* @return void
@ -545,7 +566,7 @@ class ViewTest extends CakeTestCase {
}
/**
* testMissingLayout method
* Test for missing layouts
*
* @expectedException MissingLayoutException
* @return void
@ -572,7 +593,7 @@ class ViewTest extends CakeTestCase {
}
/**
* testViewVars method
* Test viewVars method
*
* @return void
*/
@ -581,7 +602,7 @@ class ViewTest extends CakeTestCase {
}
/**
* testUUIDGeneration method
* Test generation of UUIDs method
*
* @return void
*/
@ -595,7 +616,7 @@ class ViewTest extends CakeTestCase {
}
/**
* testAddInlineScripts method
* Test addInlineScripts method
*
* @return void
*/
@ -610,7 +631,7 @@ class ViewTest extends CakeTestCase {
}
/**
* testElementExists method
* Test elementExists method
*
* @return void
*/
@ -633,7 +654,7 @@ class ViewTest extends CakeTestCase {
}
/**
* testElement method
* Test element method
*
* @return void
*/
@ -656,7 +677,7 @@ class ViewTest extends CakeTestCase {
}
/**
* testElementInexistent method
* Test elementInexistent method
*
* @expectedException PHPUnit_Framework_Error_Notice
* @return void
@ -666,7 +687,7 @@ class ViewTest extends CakeTestCase {
}
/**
* testElementInexistent2 method
* Test elementInexistent2 method
*
* @expectedException PHPUnit_Framework_Error_Notice
* @return void
@ -676,7 +697,7 @@ class ViewTest extends CakeTestCase {
}
/**
* testElementInexistent3 method
* Test elementInexistent3 method
*
* @expectedException PHPUnit_Framework_Error_Notice
* @return void
@ -686,8 +707,7 @@ class ViewTest extends CakeTestCase {
}
/**
* test that elements can have callbacks
*
* Test that elements can have callbacks
*/
public function testElementCallbacks() {
$this->getMock('Helper', array(), array($this->View), 'ElementCallbackMockHtmlHelper');
@ -702,7 +722,7 @@ class ViewTest extends CakeTestCase {
}
/**
* test that additional element viewVars don't get overwritten with helpers.
* Test that additional element viewVars don't get overwritten with helpers.
*
* @return void
*/
@ -720,7 +740,7 @@ class ViewTest extends CakeTestCase {
}
/**
* testElementCacheHelperNoCache method
* Test elementCacheHelperNoCache method
*
* @return void
*/
@ -733,7 +753,7 @@ class ViewTest extends CakeTestCase {
}
/**
* testElementCache method
* Test elementCache method
*
* @return void
*/
@ -787,7 +807,7 @@ class ViewTest extends CakeTestCase {
}
/**
* test __get allowing access to helpers.
* Test __get allowing access to helpers.
*
* @return void
*/
@ -798,7 +818,7 @@ class ViewTest extends CakeTestCase {
}
/**
* test that ctp is used as a fallback file extension for elements
* Test that ctp is used as a fallback file extension for elements
*
* @return void
*/
@ -813,7 +833,7 @@ class ViewTest extends CakeTestCase {
}
/**
* testLoadHelpers method
* Test loadHelpers method
*
* @return void
*/
@ -828,7 +848,7 @@ class ViewTest extends CakeTestCase {
}
/**
* test lazy loading helpers
* Test lazy loading helpers
*
* @return void
*/
@ -841,7 +861,7 @@ class ViewTest extends CakeTestCase {
}
/**
* test the correct triggering of helper callbacks
* Test the correct triggering of helper callbacks
*
* @return void
*/
@ -924,7 +944,7 @@ class ViewTest extends CakeTestCase {
}
/**
* testBeforeLayout method
* Test beforeLayout method
*
* @return void
*/
@ -936,7 +956,7 @@ class ViewTest extends CakeTestCase {
}
/**
* testAfterLayout method
* Test afterLayout method
*
* @return void
*/
@ -954,7 +974,7 @@ class ViewTest extends CakeTestCase {
}
/**
* testRenderLoadHelper method
* Test renderLoadHelper method
*
* @return void
*/
@ -980,7 +1000,7 @@ class ViewTest extends CakeTestCase {
}
/**
* testRender method
* Test render method
*
* @return void
*/
@ -1023,7 +1043,7 @@ class ViewTest extends CakeTestCase {
}
/**
* test that View::$view works
* Test that View::$view works
*
* @return void
*/
@ -1054,7 +1074,7 @@ class ViewTest extends CakeTestCase {
}
/**
* test that view vars can replace the local helper variables
* Test that view vars can replace the local helper variables
* and not overwrite the $this->Helper references
*
* @return void
@ -1071,7 +1091,7 @@ class ViewTest extends CakeTestCase {
}
/**
* testGetViewFileName method
* Test getViewFileName method
*
* @return void
*/
@ -1099,7 +1119,7 @@ class ViewTest extends CakeTestCase {
}
/**
* testRenderCache method
* Test renderCache method
*
* @return void
*/
@ -1323,29 +1343,124 @@ class ViewTest extends CakeTestCase {
}
/**
* Test appending to a block with append.
* Test setting a block's content to null
*
* @return void
* @link https://cakephp.lighthouseapp.com/projects/42648/tickets/3938-this-redirectthis-auth-redirecturl-broken
*/
public function testBlockAppend() {
$this->View->assign('test', 'Block');
$this->View->append('test', ' content');
$result = $this->View->fetch('test');
$this->assertEquals('Block content', $result);
public function testBlockSetNull() {
$this->View->assign('testWithNull', null);
$result = $this->View->fetch('testWithNull');
$this->assertSame('', $result);
}
/**
* Test prepending to a block with append.
* Test setting a block's content to an object with __toString magic method
*
* @return void
*/
public function testBlockPrepend() {
public function testBlockSetObjectWithToString() {
$objectWithToString = new TestObjectWithToString();
$this->View->assign('testWithObjectWithToString', $objectWithToString);
$result = $this->View->fetch('testWithObjectWithToString');
$this->assertSame("I'm ObjectWithToString", $result);
}
/**
* Test setting a block's content to an object without __toString magic method
*
* This should produce a "Object of class TestObjectWithoutToString could not be converted to string" error
* which gets thrown as a PHPUnit_Framework_Error Exception by PHPUnit.
*
* @expectedException PHPUnit_Framework_Error
* @return void
*/
public function testBlockSetObjectWithoutToString() {
$objectWithToString = new TestObjectWithoutToString();
$this->View->assign('testWithObjectWithoutToString', $objectWithToString);
}
/**
* Test setting a block's content to a decimal
*
* @return void
*/
public function testBlockSetDecimal() {
$this->View->assign('testWithDecimal', 1.23456789);
$result = $this->View->fetch('testWithDecimal');
$this->assertEqual('1.23456789', $result);
}
/**
* Data provider for block related tests.
*
* @return array
*/
public static function blockValueProvider() {
return array(
'string' => array('A string value'),
'null' => array(null),
'decimal' => array(1.23456),
'object with __toString' => array(new TestObjectWithToString()),
);
}
/**
* Test appending to a block with append.
*
* @dataProvider blockValueProvider
* @return void
*/
public function testBlockAppend($value) {
$this->View->assign('testBlock', 'Block');
$this->View->append('testBlock', $value);
$result = $this->View->fetch('testBlock');
$this->assertSame('Block' . $value, $result);
}
/**
* Test appending an object without __toString magic method to a block with append.
*
* This should produce a "Object of class TestObjectWithoutToString could not be converted to string" error
* which gets thrown as a PHPUnit_Framework_Error Exception by PHPUnit.
*
* @expectedException PHPUnit_Framework_Error
* @return void
*/
public function testBlockAppendObjectWithoutToString() {
$object = new TestObjectWithoutToString();
$this->View->assign('testBlock', 'Block ');
$this->View->append('testBlock', $object);
}
/**
* Test prepending to a block with prepend.
*
* @dataProvider blockValueProvider
* @return void
*/
public function testBlockPrepend($value) {
$this->View->assign('test', 'Block');
$this->View->prepend('test', 'Before ');
$this->View->prepend('test', $value);
$result = $this->View->fetch('test');
$this->assertEquals('Before Block', $result);
$this->assertEquals($value . 'Block', $result);
}
/**
* Test prepending an object without __toString magic method to a block with prepend.
*
* This should produce a "Object of class TestObjectWithoutToString could not be converted to string" error
* which gets thrown as a PHPUnit_Framework_Error Exception by PHPUnit.
*
* @expectedException PHPUnit_Framework_Error
* @return void
*/
public function testBlockPrependObjectWithoutToString() {
$object = new TestObjectWithoutToString();
$this->View->assign('test', 'Block ');
$this->View->prepend('test', $object);
}
/**
@ -1370,26 +1485,6 @@ class ViewTest extends CakeTestCase {
$this->assertEquals('Unknown', $result);
}
/**
* setting an array should cause an exception.
*
* @expectedException CakeException
* @return void
*/
public function testBlockSetArrayException() {
$this->View->assign('test', array(1, 2, 3));
}
/**
* Appending an array should cause an exception.
*
* @expectedException CakeException
* @return void
*/
public function testBlockAppendArrayException() {
$this->View->append('test', array(1, 2, 3));
}
/**
* Test getting block names
*
@ -1542,7 +1637,7 @@ TEXT;
}
/**
* test memory leaks that existed in _paths at one point.
* Test memory leaks that existed in _paths at one point.
*
* @return void
*/
@ -1565,7 +1660,7 @@ TEXT;
}
/**
* tests that a vew block uses default value when not assigned and uses assigned value when it is
* Tests that a vew block uses default value when not assigned and uses assigned value when it is
*
* @return void
*/

View file

@ -79,6 +79,25 @@ class XmlViewTest extends CakeTestCase {
$this->assertSame($expected, $output);
}
/**
* Test that rendering with _serialize does not load helpers
*
* @return void
*/
public function testRenderSerializeNoHelpers() {
$Request = new CakeRequest();
$Response = new CakeResponse();
$Controller = new Controller($Request, $Response);
$Controller->helpers = array('Html');
$Controller->set(array(
'_serialize' => 'tags',
'tags' => array('cakephp', 'framework')
));
$View = new XmlView($Controller);
$View->render();
$this->assertFalse(isset($View->Html), 'No helper loaded.');
}
/**
* Test render with an array in _serialize
*

View file

@ -0,0 +1,169 @@
comment_char %
escape_char /
%
% Dutch Language Locale for the Netherlands
% Source: RAP
% Address: Sankt Jo//rgens Alle 8
% DK-1615 Ko//benhavn V, Danmark
% Contact: Keld Simonsen
% Email: Keld.Simonsen@dkuug.dk
% Tel: +45 - 31226543
% Fax: +45 - 31205521
% Language: nl
% Territory: NL
% Revision: 4.3
% Date: 1996-10-15
% Users: general
% Charset: ISO-8859-1
% Distribution and use is free, also
% for commercial purposes.
LC_IDENTIFICATION
title "Dutch locale for the Netherlands"
source "RAP"
address "Sankt J<U00F8>rgens Alle 8, DK-1615 K<U00F8>benhavn V, Danmark"
contact ""
email "bug-glibc-locales@gnu.org"
tel ""
fax ""
language "Dutch"
territory "Netherlands"
revision "1.0"
date "2000-06-29"
%
category "nl_NL:2000";LC_IDENTIFICATION
category "nl_NL:2000";LC_CTYPE
category "nl_NL:2000";LC_COLLATE
category "nl_NL:2000";LC_TIME
category "nl_NL:2000";LC_NUMERIC
category "nl_NL:2000";LC_MONETARY
category "nl_NL:2000";LC_MESSAGES
category "nl_NL:2000";LC_PAPER
category "nl_NL:2000";LC_NAME
category "nl_NL:2000";LC_ADDRESS
category "nl_NL:2000";LC_TELEPHONE
END LC_IDENTIFICATION
LC_CTYPE
copy "i18n"
translit_start
include "translit_combining";""
translit_end
END LC_CTYPE
LC_COLLATE
copy "iso14651_t1"
END LC_COLLATE
LC_MESSAGES
yesexpr "<U005E><U005B><U006A><U004A><U0079><U0059><U005D><U002E><U002A>"
noexpr "<U005E><U005B><U006E><U004E><U005D><U002E><U002A>"
END LC_MESSAGES
LC_MONETARY
int_curr_symbol "<U0045><U0055><U0052><U0020>"
currency_symbol "<U20AC>"
mon_decimal_point "<U002C>"
mon_thousands_sep "<U0020>"
mon_grouping 3;3
positive_sign ""
negative_sign "<U002D>"
int_frac_digits 2
frac_digits 2
p_cs_precedes 1
p_sep_by_space 1
n_cs_precedes 1
n_sep_by_space 1
p_sign_posn 1
n_sign_posn 2
END LC_MONETARY
LC_NUMERIC
decimal_point "<U002C>"
thousands_sep ""
grouping 0;0
END LC_NUMERIC
LC_TIME
abday "<U007A><U006F>";"<U006D><U0061>";"<U0064><U0069>";/
"<U0077><U006F>";"<U0064><U006F>";"<U0076><U0072>";/
"<U007A><U0061>"
day "<U007A><U006F><U006E><U0064><U0061><U0067>";/
"<U006D><U0061><U0061><U006E><U0064><U0061><U0067>";/
"<U0064><U0069><U006E><U0073><U0064><U0061><U0067>";/
"<U0077><U006F><U0065><U006E><U0073><U0064><U0061><U0067>";/
"<U0064><U006F><U006E><U0064><U0065><U0072><U0064><U0061><U0067>";/
"<U0076><U0072><U0069><U006A><U0064><U0061><U0067>";/
"<U007A><U0061><U0074><U0065><U0072><U0064><U0061><U0067>"
abmon "<U006A><U0061><U006E>";"<U0066><U0065><U0062>";/
"<U006D><U0072><U0074>";"<U0061><U0070><U0072>";/
"<U006D><U0065><U0069>";"<U006A><U0075><U006E>";/
"<U006A><U0075><U006C>";"<U0061><U0075><U0067>";/
"<U0073><U0065><U0070>";"<U006F><U006B><U0074>";/
"<U006E><U006F><U0076>";"<U0064><U0065><U0063>"
mon "<U006A><U0061><U006E><U0075><U0061><U0072><U0069>";/
"<U0066><U0065><U0062><U0072><U0075><U0061><U0072><U0069>";/
"<U006D><U0061><U0061><U0072><U0074>";/
"<U0061><U0070><U0072><U0069><U006C>";/
"<U006D><U0065><U0069>";/
"<U006A><U0075><U006E><U0069>";/
"<U006A><U0075><U006C><U0069>";/
"<U0061><U0075><U0067><U0075><U0073><U0074><U0075><U0073>";/
"<U0073><U0065><U0070><U0074><U0065><U006D><U0062><U0065><U0072>";/
"<U006F><U006B><U0074><U006F><U0062><U0065><U0072>";/
"<U006E><U006F><U0076><U0065><U006D><U0062><U0065><U0072>";/
"<U0064><U0065><U0063><U0065><U006D><U0062><U0065><U0072>"
d_t_fmt "<U0025><U0061><U0020><U0025><U0064><U0020><U0025><U0062><U0020><U0025><U0059><U0020><U0025><U0054><U0020><U0025><U005A>"
d_fmt "<U0025><U0064><U002D><U0025><U006D><U002D><U0025><U0079>"
t_fmt "<U0025><U0054>"
am_pm "";""
t_fmt_ampm ""
date_fmt "<U0025><U0061><U0020><U0025><U0062><U0020><U0025><U0065>/
<U0020><U0025><U0048><U003A><U0025><U004D><U003A><U0025><U0053><U0020>/
<U0025><U005A><U0020><U0025><U0059>"
week 7;19971130;4
first_weekday 2
first_workday 2
END LC_TIME
LC_PAPER
% FIXME
height 297
% FIXME
width 210
END LC_PAPER
LC_TELEPHONE
tel_int_fmt "<U002B><U0025><U0063><U0020><U0025><U0061><U0020><U0025>/
<U006C>"
int_prefix "<U0033><U0031>"
END LC_TELEPHONE
LC_MEASUREMENT
% FIXME
measurement 1
END LC_MEASUREMENT
LC_NAME
name_fmt "<U0025><U0064><U0025><U0074><U0025><U0067><U0025><U0074>/
<U0025><U006D><U0025><U0074><U0025><U0066>"
END LC_NAME
LC_ADDRESS
postal_fmt "<U0025><U0066><U0025><U004E><U0025><U0061><U0025><U004E>/
<U0025><U0064><U0025><U004E><U0025><U0062><U0025><U004E><U0025><U0073>/
<U0020><U0025><U0068><U0020><U0025><U0065><U0020><U0025><U0072><U0025>/
<U004E><U0025><U007A><U0020><U0025><U0054><U0025>/
<U004E><U0025><U0063><U0025><U004E>"
country_ab2 "<U004E><U004C>"
country_ab3 "<U004E><U004C><U0044>"
country_num 528
country_car "<U004E><U004C>"
lang_name "<U0064><U0075><U0074><U0063><U0068>"
lang_ab "<U006E><U006C>"
lang_term "<U006E><U006C><U0064>"
lang_lib "<U0064><U0075><U0074>"
END LC_ADDRESS

View file

@ -26,3 +26,6 @@ __('Hot features!'
. ' Just look at the name...It\'s Cake'
. "\n - Active, Friendly Community:"
. ' Join us #cakephp on IRC. We\'d love to help you get started');
// Category
echo __c('You have a new message (category: LC_TIME).', 5);

View file

@ -135,6 +135,7 @@ class CakeNumber {
* @param mixed $default Value to be returned when invalid size was used, for example 'Unknown type'
* @return mixed Number of bytes as integer on success, `$default` on failure if not false
* @throws CakeException On invalid Unit type.
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/number.html#NumberHelper::fromReadableSize
*/
public static function fromReadableSize($size, $default = false) {
if (ctype_digit($size)) {
@ -246,6 +247,7 @@ class CakeNumber {
* @param float $value A floating point number
* @param array $options
* @return string formatted delta
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/number.html#NumberHelper::formatDelta
*/
public static function formatDelta($value, $options = array()) {
$places = isset($options['places']) ? $options['places'] : 0;
@ -404,6 +406,7 @@ class CakeNumber {
*
* @param string $currency Default currency string used by currency() if $currency argument is not provided
* @return string Currency
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/number.html#NumberHelper::defaultCurrency
*/
public static function defaultCurrency($currency = null) {
if ($currency) {

View file

@ -131,7 +131,7 @@ class CakeTime {
* Accepts the special specifier %S which mimics the modifier S for date()
* @param string $time UNIX timestamp
* @return string windows safe and date() function compatible format for strftime
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#TimeHelper::convertSpecifiers
*/
public static function convertSpecifiers($format, $time = null) {
if (!$time) {
@ -244,7 +244,7 @@ class CakeTime {
* @param string $serverTime UNIX timestamp
* @param string|DateTimeZone $timezone User's timezone string or DateTimeZone object
* @return integer UNIX timestamp
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#TimeHelper::convert
*/
public static function convert($serverTime, $timezone) {
static $serverTimezone = null;
@ -269,6 +269,7 @@ class CakeTime {
* @param string|DateTimeZone $timezone Timezone string or DateTimeZone object
* If null it tries to get timezone from 'Config.timezone' config var
* @return DateTimeZone Timezone object
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#TimeHelper::timezone
*/
public static function timezone($timezone = null) {
static $tz = null;
@ -297,7 +298,7 @@ class CakeTime {
* Returns server's offset from GMT in seconds.
*
* @return integer Offset
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#TimeHelper::serverOffset
*/
public static function serverOffset() {
return date('Z', time());
@ -309,7 +310,7 @@ class CakeTime {
* @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
* @param string|DateTimeZone $timezone Timezone string or DateTimeZone object
* @return string Parsed timestamp
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#TimeHelper::fromString
*/
public static function fromString($dateString, $timezone = null) {
if (empty($dateString)) {
@ -360,7 +361,7 @@ class CakeTime {
* @param string|DateTimeZone $timezone Timezone string or DateTimeZone object
* @param string $format The format to use. If null, `TimeHelper::$niceFormat` is used
* @return string Formatted date string
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#TimeHelper::nice
*/
public static function nice($dateString = null, $timezone = null, $format = null) {
if (!$dateString) {
@ -387,7 +388,7 @@ class CakeTime {
* @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
* @param string|DateTimeZone $timezone Timezone string or DateTimeZone object
* @return string Described, relative date string
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#TimeHelper::niceShort
*/
public static function niceShort($dateString = null, $timezone = null) {
if (!$dateString) {
@ -437,7 +438,7 @@ class CakeTime {
* @param string $fieldName Name of database field to compare with
* @param string|DateTimeZone $timezone Timezone string or DateTimeZone object
* @return string Partial SQL string.
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#TimeHelper::daysAsSql
*/
public static function daysAsSql($begin, $end, $fieldName, $timezone = null) {
$begin = self::fromString($begin, $timezone);
@ -456,7 +457,7 @@ class CakeTime {
* @param string $fieldName Name of database field to compare with
* @param string|DateTimeZone $timezone Timezone string or DateTimeZone object
* @return string Partial SQL string.
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#TimeHelper::dayAsSql
*/
public static function dayAsSql($dateString, $fieldName, $timezone = null) {
return self::daysAsSql($dateString, $dateString, $fieldName);
@ -468,7 +469,7 @@ class CakeTime {
* @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
* @param string|DateTimeZone $timezone Timezone string or DateTimeZone object
* @return boolean True if datetime string is today
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#testing-time
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#TimeHelper::isToday
*/
public static function isToday($dateString, $timezone = null) {
$timestamp = self::fromString($dateString, $timezone);
@ -482,7 +483,7 @@ class CakeTime {
* @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
* @param string|DateTimeZone $timezone Timezone string or DateTimeZone object
* @return boolean True if datetime string is in the future
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#testing-time
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#TimeHelper::isFuture
*/
public static function isFuture($dateString, $timezone = null) {
$timestamp = self::fromString($dateString, $timezone);
@ -495,7 +496,7 @@ class CakeTime {
* @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
* @param string|DateTimeZone $timezone Timezone string or DateTimeZone object
* @return boolean True if datetime string is in the past
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#testing-time
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#TimeHelper::isPast
*/
public static function isPast($dateString, $timezone = null) {
$timestamp = self::fromString($dateString, $timezone);
@ -508,7 +509,7 @@ class CakeTime {
* @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
* @param string|DateTimeZone $timezone Timezone string or DateTimeZone object
* @return boolean True if datetime string is within current week
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#testing-time
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#TimeHelper::isThisWeek
*/
public static function isThisWeek($dateString, $timezone = null) {
$timestamp = self::fromString($dateString, $timezone);
@ -522,7 +523,7 @@ class CakeTime {
* @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
* @param string|DateTimeZone $timezone Timezone string or DateTimeZone object
* @return boolean True if datetime string is within current month
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#testing-time
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#TimeHelper::isThisMonth
*/
public static function isThisMonth($dateString, $timezone = null) {
$timestamp = self::fromString($dateString, $timezone);
@ -536,7 +537,7 @@ class CakeTime {
* @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
* @param string|DateTimeZone $timezone Timezone string or DateTimeZone object
* @return boolean True if datetime string is within current year
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#testing-time
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#TimeHelper::isThisYear
*/
public static function isThisYear($dateString, $timezone = null) {
$timestamp = self::fromString($dateString, $timezone);
@ -550,8 +551,7 @@ class CakeTime {
* @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
* @param string|DateTimeZone $timezone Timezone string or DateTimeZone object
* @return boolean True if datetime string was yesterday
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#testing-time
*
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#TimeHelper::wasYesterday
*/
public static function wasYesterday($dateString, $timezone = null) {
$timestamp = self::fromString($dateString, $timezone);
@ -565,7 +565,7 @@ class CakeTime {
* @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
* @param string|DateTimeZone $timezone Timezone string or DateTimeZone object
* @return boolean True if datetime string was yesterday
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#testing-time
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#TimeHelper::isTomorrow
*/
public static function isTomorrow($dateString, $timezone = null) {
$timestamp = self::fromString($dateString, $timezone);
@ -579,7 +579,7 @@ class CakeTime {
* @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
* @param boolean $range if true returns a range in Y-m-d format
* @return mixed 1, 2, 3, or 4 quarter of year or array if $range true
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#TimeHelper::toQuarter
*/
public static function toQuarter($dateString, $range = false) {
$time = self::fromString($dateString);
@ -603,10 +603,11 @@ class CakeTime {
/**
* Returns a UNIX timestamp from a textual datetime description. Wrapper for PHP function strtotime().
*
* @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
* @param string|DateTimeZone $timezone Timezone string or DateTimeZone object
* @return integer Unix timestamp
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#TimeHelper::toUnix
*/
public static function toUnix($dateString, $timezone = null) {
return self::fromString($dateString, $timezone);
@ -625,6 +626,7 @@ class CakeTime {
* @param string|DateTimeZone $timezone Timezone string or DateTimeZone object
* @param string $format date format string
* @return mixed Formatted date
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#TimeHelper::toServer
*/
public static function toServer($dateString, $timezone = null, $format = 'Y-m-d H:i:s') {
if ($timezone === null) {
@ -656,7 +658,7 @@ class CakeTime {
* @param string $dateString Datetime string or Unix timestamp
* @param string|DateTimeZone $timezone Timezone string or DateTimeZone object
* @return string Formatted date string
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#TimeHelper::toAtom
*/
public static function toAtom($dateString, $timezone = null) {
return date('Y-m-d\TH:i:s\Z', self::fromString($dateString, $timezone));
@ -668,7 +670,7 @@ class CakeTime {
* @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
* @param string|DateTimeZone $timezone Timezone string or DateTimeZone object
* @return string Formatted date string
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#TimeHelper::toRSS
*/
public static function toRSS($dateString, $timezone = null) {
$date = self::fromString($dateString, $timezone);
@ -733,7 +735,7 @@ class CakeTime {
* @param integer|string|DateTime $dateTime Datetime UNIX timestamp, strtotime() valid string or DateTime object
* @param array $options Default format if timestamp is used in $dateString
* @return string Relative time string.
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#TimeHelper::timeAgoInWords
*/
public static function timeAgoInWords($dateTime, $options = array()) {
$timezone = null;
@ -945,7 +947,7 @@ class CakeTime {
* @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
* @param string|DateTimeZone $timezone Timezone string or DateTimeZone object
* @return boolean
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#testing-time
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#TimeHelper::wasWithinLast
*/
public static function wasWithinLast($timeInterval, $dateString, $timezone = null) {
$tmp = str_replace(' ', '', $timeInterval);
@ -968,7 +970,6 @@ class CakeTime {
* @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
* @param string|DateTimeZone $timezone Timezone string or DateTimeZone object
* @return boolean
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#testing-time
*/
public static function isWithinNext($timeInterval, $dateString, $timezone = null) {
$tmp = str_replace(' ', '', $timeInterval);
@ -988,7 +989,7 @@ class CakeTime {
*
* @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
* @return integer UNIX timestamp
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#TimeHelper::gmt
*/
public static function gmt($dateString = null) {
$time = time();
@ -1026,7 +1027,7 @@ class CakeTime {
* @param boolean|string $default if an invalid date is passed it will output supplied default value. Pass false if you want raw conversion value
* @param string|DateTimeZone $timezone Timezone string or DateTimeZone object
* @return string Formatted date string
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#TimeHelper::format
* @see CakeTime::i18nFormat()
*/
public static function format($date, $format = null, $default = false, $timezone = null) {
@ -1048,7 +1049,7 @@ class CakeTime {
* @param boolean|string $default if an invalid date is passed it will output supplied default value. Pass false if you want raw conversion value
* @param string|DateTimeZone $timezone Timezone string or DateTimeZone object
* @return string Formatted and translated date string
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#TimeHelper::i18nFormat
*/
public static function i18nFormat($date, $format = null, $default = false, $timezone = null) {
$date = self::fromString($date, $timezone);
@ -1071,6 +1072,7 @@ class CakeTime {
* @param boolean $group If true (default value) groups the identifiers list by primary region
* @return array List of timezone identifiers
* @since 2.2
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#TimeHelper::listTimezones
*/
public static function listTimezones($filter = null, $country = null, $group = true) {
$regex = null;

View file

@ -38,6 +38,7 @@ class Hash {
* @param string|array $path The path being searched for. Either a dot
* separated string, or an array of path segments.
* @return mixed The value fetched from the array, or null.
* @link http://book.cakephp.org/2.0/en/core-utility-libraries/hash.html#Hash::get
*/
public static function get(array $data, $path) {
if (empty($data)) {
@ -85,6 +86,7 @@ class Hash {
* @param string $path The path to extract.
* @return array An array of the extracted values. Returns an empty array
* if there are no matches.
* @link http://book.cakephp.org/2.0/en/core-utility-libraries/hash.html#Hash::extract
*/
public static function extract(array $data, $path) {
if (empty($path)) {
@ -231,6 +233,7 @@ class Hash {
* @param string $path The path to insert at.
* @param array $values The values to insert.
* @return array The data with $values inserted.
* @link http://book.cakephp.org/2.0/en/core-utility-libraries/hash.html#Hash::insert
*/
public static function insert(array $data, $path, $values = null) {
if (strpos($path, '[') === false) {
@ -313,6 +316,7 @@ class Hash {
* @param array $data The data to operate on
* @param string $path A path expression to use to remove.
* @return array The modified array.
* @link http://book.cakephp.org/2.0/en/core-utility-libraries/hash.html#Hash::remove
*/
public static function remove(array $data, $path) {
if (strpos($path, '[') === false) {
@ -429,6 +433,7 @@ class Hash {
* @link http://book.cakephp.org/2.0/en/core-utility-libraries/hash.html#Hash::format
* @see sprintf()
* @see Hash::extract()
* @link http://book.cakephp.org/2.0/en/core-utility-libraries/hash.html#Hash::format
*/
public static function format(array $data, array $paths, $format) {
$extracted = array();
@ -506,6 +511,7 @@ class Hash {
* @param string $path The path to check for.
* @return boolean Existence of path.
* @see Hash::extract()
* @link http://book.cakephp.org/2.0/en/core-utility-libraries/hash.html#Hash::check
*/
public static function check(array $data, $path) {
$results = self::extract($data, $path);
@ -596,6 +602,7 @@ class Hash {
* @param array $data Flattened array
* @param string $separator The delimiter used
* @return array
* @link http://book.cakephp.org/2.0/en/core-utility-libraries/hash.html#Hash::expand
*/
public static function expand($data, $separator = '.') {
$result = array();
@ -718,6 +725,7 @@ class Hash {
* @param string $path The path to extract for mapping over.
* @param callable $function The function to call on each extracted value.
* @return array An array of the modified values.
* @link http://book.cakephp.org/2.0/en/core-utility-libraries/hash.html#Hash::map
*/
public static function map(array $data, $path, $function) {
$values = (array)self::extract($data, $path);
@ -731,6 +739,7 @@ class Hash {
* @param string $path The path to extract from $data.
* @param callable $function The function to call on each extracted value.
* @return mixed The reduced value.
* @link http://book.cakephp.org/2.0/en/core-utility-libraries/hash.html#Hash::reduce
*/
public static function reduce(array $data, $path, $function) {
$values = (array)self::extract($data, $path);
@ -898,11 +907,12 @@ class Hash {
}
/**
* Merges the difference between $data and $push onto $data.
* Merges the difference between $data and $compare onto $data.
*
* @param array $data The data to append onto.
* @param array $compare The data to compare and append onto.
* @return array The merged array.
* @link http://book.cakephp.org/2.0/en/core-utility-libraries/hash.html#Hash::mergeDiff
*/
public static function mergeDiff(array $data, $compare) {
if (empty($data) && !empty($compare)) {
@ -972,6 +982,7 @@ class Hash {
* @param array $options Options are:
* @return array of results, nested
* @see Hash::extract()
* @link http://book.cakephp.org/2.0/en/core-utility-libraries/hash.html#Hash::nest
*/
public static function nest(array $data, $options = array()) {
if (!$data) {

View file

@ -72,6 +72,18 @@ class JsonView extends View {
}
}
/**
* Skip loading helpers if this is a _serialize based view.
*
* @return void
*/
public function loadHelpers() {
if (isset($this->viewVars['_serialize'])) {
return;
}
parent::loadHelpers();
}
/**
* Render a JSON view.
*

View file

@ -98,7 +98,7 @@ class View extends Object {
*
* @var mixed A single name as a string or a list of names as an array.
*/
public $helpers = array('Html');
public $helpers = array();
/**
* Path to View.
@ -253,13 +253,6 @@ class View extends Object {
*/
protected $_paths = array();
/**
* Indicate that helpers have been loaded.
*
* @var boolean
*/
protected $_helpersLoaded = false;
/**
* The names of views and their parents used with View::extend();
*
@ -347,6 +340,7 @@ class View extends Object {
}
$this->Helpers = new HelperCollection($this);
$this->Blocks = new ViewBlock();
$this->loadHelpers();
parent::__construct();
}
@ -454,15 +448,12 @@ class View extends Object {
* @param string $view Name of view file to use
* @param string $layout Layout to use.
* @return string Rendered Element
* @throws CakeException if there is an error in the view.
* @throws CakeException If there is an error in the view.
*/
public function render($view = null, $layout = null) {
if ($this->hasRendered) {
return true;
}
if (!$this->_helpersLoaded) {
$this->loadHelpers();
}
$this->Blocks->set('content', '');
if ($view !== false && $viewFileName = $this->_getViewFileName($view)) {
@ -511,9 +502,6 @@ class View extends Object {
return $this->Blocks->get('content');
}
if (!$this->_helpersLoaded) {
$this->loadHelpers();
}
if (empty($content)) {
$content = $this->Blocks->get('content');
}
@ -640,9 +628,8 @@ class View extends Object {
* block will create the block.
*
* @param string $name Name of the block
* @param string $value The content for the block.
* @param mixed $value The content for the block.
* @return void
* @throws CakeException when you use non-string values.
* @see ViewBlock::concat()
*/
public function append($name, $value = null) {
@ -654,9 +641,8 @@ class View extends Object {
* block will create the block.
*
* @param string $name Name of the block
* @param string $value The content for the block.
* @param mixed $value The content for the block.
* @return void
* @throws CakeException when you use non-string values.
* @see ViewBlock::concat()
*/
public function prepend($name, $value = null) {
@ -668,9 +654,8 @@ class View extends Object {
* existing content.
*
* @param string $name Name of the block
* @param string $value The content for the block.
* @param mixed $value The content for the block.
* @return void
* @throws CakeException when you use non-string values.
* @see ViewBlock::set()
*/
public function assign($name, $value) {
@ -841,7 +826,7 @@ class View extends Object {
* Magic accessor for deprecated attributes.
*
* @param string $name Name of the attribute to set.
* @param string $value Value of the attribute to set.
* @param mixed $value Value of the attribute to set.
* @return mixed
*/
public function __set($name, $value) {
@ -881,7 +866,6 @@ class View extends Object {
list(, $class) = pluginSplit($properties['class']);
$this->{$class} = $this->Helpers->load($properties['class'], $properties['settings']);
}
$this->_helpersLoaded = true;
}
/**
@ -1194,9 +1178,6 @@ class View extends Object {
* @return string
*/
protected function _renderElement($file, $data, $options) {
if (!$this->_helpersLoaded) {
$this->loadHelpers();
}
if ($options['callbacks']) {
$this->getEventManager()->dispatch(new CakeEvent('View.beforeRender', $this, array($file)));
}

View file

@ -131,17 +131,13 @@ class ViewBlock {
* of the new capturing context will be added to the existing block context.
*
* @param string $name Name of the block
* @param string $value The content for the block
* @param mixed $value The content for the block
* @param string $mode If ViewBlock::APPEND content will be appended to existing content.
* If ViewBlock::PREPEND it will be prepended.
* @return void
* @throws CakeException when you use non-string values.
*/
public function concat($name, $value = null, $mode = ViewBlock::APPEND) {
if (isset($value)) {
if (!is_string($value)) {
throw new CakeException(__d('cake_dev', '%s must be a string.', '$value'));
}
if (!isset($this->_blocks[$name])) {
$this->_blocks[$name] = '';
}
@ -166,7 +162,6 @@ class ViewBlock {
* @param string $name Name of the block
* @param string $value The content for the block.
* @return void
* @throws CakeException when you use non-string values.
* @deprecated As of 2.3 use ViewBlock::concat() instead.
*/
public function append($name, $value = null) {
@ -178,15 +173,11 @@ class ViewBlock {
* existing content.
*
* @param string $name Name of the block
* @param string $value The content for the block.
* @param mixed $value The content for the block.
* @return void
* @throws CakeException when you use non-string values.
*/
public function set($name, $value) {
if (!is_string($value)) {
throw new CakeException(__d('cake_dev', 'Blocks can only contain strings.'));
}
$this->_blocks[$name] = $value;
$this->_blocks[$name] = (string)$value;
}
/**

View file

@ -72,6 +72,18 @@ class XmlView extends View {
}
}
/**
* Skip loading helpers if this is a _serialize based view.
*
* @return void
*/
public function loadHelpers() {
if (isset($this->viewVars['_serialize'])) {
return;
}
parent::loadHelpers();
}
/**
* Render a XML view.
*