Merge branch '2.0' into 2.1

Conflicts:
	lib/Cake/Config/config.php
	lib/Cake/VERSION.txt
This commit is contained in:
mark_story 2011-11-03 22:04:00 -04:00
commit 0304bb8796
105 changed files with 896 additions and 469 deletions

View file

@ -368,7 +368,7 @@ form .submit input[type=submit]:hover {
/* Form errors */
form .error {
background: #FFDACC;
-moz-order-radius: 4px;
-moz-border-radius: 4px;
-webkit-border-radius: 4px;
border-radius: 4px;
font-weight: normal;

View file

@ -498,7 +498,7 @@ class SchemaShell extends Shell {
))->addSubcommand('dump', array(
'help' => __d('cake_console', 'Dump database SQL based on a schema file to stdout.'),
'parser' => array(
'options' => compact('plugin', 'path', 'file', 'name', 'connection'),
'options' => compact('plugin', 'path', 'file', 'name', 'connection', 'write'),
'arguments' => compact('name')
)
))->addSubcommand('create', array(

View file

@ -283,7 +283,7 @@ class DbConfigTask extends Shell {
$oldConfigs[] = array(
'name' => $configName,
'driver' => $info['driver'],
'datasource' => $info['datasource'],
'persistent' => $info['persistent'],
'host' => $info['host'],
'port' => $info['port'],

View file

@ -606,7 +606,7 @@ class ExtractTask extends Shell {
if (!empty($this->_exclude)) {
$exclude = array();
foreach ($this->_exclude as $e) {
if ($e[0] !== DS) {
if (DS !== '\\' && $e[0] !== DS) {
$e = DS . $e;
}
$exclude[] = preg_quote($e, '/');

View file

@ -178,7 +178,8 @@ class ConsoleOutput {
return $text;
}
if ($this->_outputAs == self::PLAIN) {
return strip_tags($text);
$tags = implode('|', array_keys(self::$_styles));
return preg_replace('#</?(?:' . $tags . ')>#', '', $text);
}
return preg_replace_callback(
'/<(?<tag>[a-z0-9-_]+)>(?<text>.*?)<\/(\1)>/ims', array($this, '_replaceTags'), $text

View file

@ -1,2 +1 @@
<?php echo '<?xml version="1.0" encoding="' . Configure::read('App.encoding') . '"?>'; ?>
<?php echo $content_for_layout; ?>

View file

@ -368,7 +368,7 @@ form .submit input[type=submit]:hover {
/* Form errors */
form .error {
background: #FFDACC;
-moz-order-radius: 4px;
-moz-border-radius: 4px;
-webkit-border-radius: 4px;
border-radius: 4px;
font-weight: normal;
@ -611,7 +611,7 @@ pre {
overflow: auto;
position: relative;
-moz-border-radius: 4px;
-wekbkit-border-radius: 4px;
-webkit-border-radius: 4px;
border-radius: 4px;
}
.cake-stack-trace a {

View file

@ -425,6 +425,7 @@ class AuthComponent extends Component {
*
* `$this->Auth->allow(array('edit', 'add'));` or
* `$this->Auth->allow('edit', 'add');`
* `$this->Auth->allow();` to allow all actions.
*
* allow() also supports '*' as a wildcard to mean all actions.
*
@ -452,7 +453,8 @@ class AuthComponent extends Component {
* You can use deny with either an array, or var args.
*
* `$this->Auth->deny(array('edit', 'add'));` or
* `$this->Auth->deny('edit', 'add');`
* `$this->Auth->deny('edit', 'add');` or
* `$this->Auth->deny();` to remove all items from the allowed list
*
* @param mixed $action,... Controller action name or array of actions
* @return void
@ -461,16 +463,20 @@ class AuthComponent extends Component {
*/
public function deny($action = null) {
$args = func_get_args();
if (isset($args[0]) && is_array($args[0])) {
$args = $args[0];
}
foreach ($args as $arg) {
$i = array_search($arg, $this->allowedActions);
if (is_int($i)) {
unset($this->allowedActions[$i]);
if (empty($args)) {
$this->allowedActions = array();
} else {
if (isset($args[0]) && is_array($args[0])) {
$args = $args[0];
}
foreach ($args as $arg) {
$i = array_search($arg, $this->allowedActions);
if (is_int($i)) {
unset($this->allowedActions[$i]);
}
}
$this->allowedActions = array_values($this->allowedActions);
}
$this->allowedActions = array_values($this->allowedActions);
}
/**

View file

@ -91,8 +91,12 @@ class RequestHandlerComponent extends Component {
* @param array $settings Array of settings.
*/
public function __construct(ComponentCollection $collection, $settings = array()) {
$this->addInputType('xml', array(array($this, 'convertXml')));
parent::__construct($collection, $settings);
$this->addInputType('xml', array(array($this, 'convertXml')));
$Controller = $collection->getController();
$this->request = $Controller->request;
$this->response = $Controller->response;
}
/**
@ -107,8 +111,6 @@ class RequestHandlerComponent extends Component {
* @see Router::parseExtensions()
*/
public function initialize($controller, $settings = array()) {
$this->request = $controller->request;
$this->response = $controller->response;
if (isset($this->request->params['ext'])) {
$this->ext = $this->request->params['ext'];
}

View file

@ -805,6 +805,7 @@ class Controller extends Object {
*/
public function setAction($action) {
$this->request->action = $action;
$this->view = $action;
$args = func_get_args();
unset($args[0]);
return call_user_func_array(array(&$this, $action), $args);
@ -878,7 +879,8 @@ class Controller extends Object {
list($plugin, $className) = pluginSplit($model);
$this->request->params['models'][$className] = compact('plugin', 'className');
}
} if (!empty($this->modelClass) && ($this->uses === false || $this->uses === array())) {
}
if (!empty($this->modelClass) && ($this->uses === false || $this->uses === array())) {
$this->request->params['models'][$this->modelClass] = array('plugin' => $this->plugin, 'className' => $this->modelClass);
}

View file

@ -119,12 +119,7 @@ class ExceptionRenderer {
}
if (Configure::read('debug') == 0) {
$parentClass = get_parent_class($this);
if ($parentClass != __CLASS__) {
$method = 'error400';
}
$parentMethods = (array)get_class_methods($parentClass);
if (in_array($method, $parentMethods)) {
if ($method == '_cakeError') {
$method = 'error400';
}
if ($code == 500) {
@ -223,11 +218,15 @@ class ExceptionRenderer {
* @return void
*/
public function error500($error) {
$message = $error->getMessage();
if (Configure::read('debug') == 0) {
$message = __d('cake', 'An Internal Error Has Occurred');
}
$url = $this->controller->request->here();
$code = ($error->getCode() > 500 && $error->getCode() < 506) ? $error->getCode() : 500;
$this->controller->response->statusCode($code);
$this->controller->set(array(
'name' => __d('cake', 'An Internal Error Has Occurred'),
'name' => $message,
'message' => h($url),
'error' => $error,
));

View file

@ -18,6 +18,7 @@
*/
App::uses('DboSource', 'Model/Datasource');
App::uses('String', 'Utility');
/**
* DBO implementation for the SQLite3 DBMS.
@ -249,7 +250,7 @@ class Sqlite extends DboSource {
if (in_array($col, array('text', 'integer', 'float', 'boolean', 'timestamp', 'date', 'datetime', 'time'))) {
return $col;
}
if (strpos($col, 'varchar') !== false) {
if (strpos($col, 'varchar') !== false || strpos($col, 'char') !== false) {
return 'string';
}
if (in_array($col, array('blob', 'clob'))) {
@ -281,7 +282,7 @@ class Sqlite extends DboSource {
$last = strripos($querystring, 'FROM');
if ($last !== false) {
$selectpart = substr($querystring, 7, $last - 8);
$selects = explode(',', $selectpart);
$selects = String::tokenize($selectpart, ',', '(', ')');
}
} elseif (strpos($querystring, 'PRAGMA table_info') === 0) {
$selects = array('cid', 'name', 'type', 'notnull', 'dflt_value', 'pk');

View file

@ -990,7 +990,7 @@ class DboSource extends DataSource {
$queryData = $this->_scrubQueryData($queryData);
$null = null;
$array = array();
$array = array('callbacks' => $queryData['callbacks']);
$linkedModels = array();
$bypass = false;
@ -1043,7 +1043,11 @@ class DboSource extends DataSource {
return false;
}
$filtered = $this->_filterResults($resultSet, $model);
$filtered = array();
if ($queryData['callbacks'] === true || $queryData['callbacks'] === 'after') {
$filtered = $this->_filterResults($resultSet, $model);
}
if ($model->recursive > -1) {
foreach ($_associations as $type) {
@ -1071,7 +1075,9 @@ class DboSource extends DataSource {
}
}
}
$this->_filterResults($resultSet, $model, $filtered);
if ($queryData['callbacks'] === true || $queryData['callbacks'] === 'after') {
$this->_filterResults($resultSet, $model, $filtered);
}
}
if (!is_null($recursive)) {
@ -1162,7 +1168,9 @@ class DboSource extends DataSource {
}
}
}
$this->_filterResults($fetch, $model);
if ($queryData['callbacks'] === true || $queryData['callbacks'] === 'after') {
$this->_filterResults($fetch, $model);
}
return $this->_mergeHasMany($resultSet, $fetch, $association, $model, $linkModel);
} elseif ($type === 'hasAndBelongsToMany') {
$ins = $fetch = array();
@ -2093,6 +2101,7 @@ class DboSource extends DataSource {
static $base = null;
if ($base === null) {
$base = array_fill_keys(array('conditions', 'fields', 'joins', 'order', 'limit', 'offset', 'group'), array());
$base['callbacks'] = null;
}
return (array)$data + $base;
}

View file

@ -16,6 +16,7 @@
* @since CakePHP(tm) v 2.0
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
/**
* CakeResponse is responsible for managing the response text, status and headers of a HTTP response.
*
@ -185,6 +186,7 @@ class CakeResponse {
'mp2' => 'audio/mpeg',
'mp3' => 'audio/mpeg',
'mpga' => 'audio/mpeg',
'ogg' => 'audio/ogg',
'ra' => 'audio/x-realaudio',
'ram' => 'audio/x-pn-realaudio',
'rm' => 'audio/x-pn-realaudio',
@ -347,7 +349,14 @@ class CakeResponse {
$codeMessage = $this->_statusCodes[$this->_status];
$this->_sendHeader("{$this->_protocol} {$this->_status} {$codeMessage}");
$this->_sendHeader('Content-Type', "{$this->_contentType}; charset={$this->_charset}");
$shouldSetLength = empty($this->_headers['Content-Length']) && !in_array($this->_status, range(301, 307));
if ($shouldSetLength && !$this->outputCompressed()) {
if (ini_get('mbstring.func_overload') & 2 && function_exists('mb_strlen')) {
$this->_headers['Content-Length'] = mb_strlen($this->_body, '8bit');
} else {
$this->_headers['Content-Length'] = strlen($this->_body);
}
}
foreach ($this->_headers as $header => $value) {
$this->_sendHeader($header, $value);
}
@ -643,6 +652,15 @@ class CakeResponse {
return $compressionEnabled && ob_start('ob_gzhandler');
}
/**
* Returns whether the resulting output will be compressed by PHP
*
* @return boolean
*/
public function outputCompressed() {
return ini_get("zlib.output_compression") === '1' || in_array('ob_gzhandler', ob_list_handlers());
}
/**
* Sets the correct headers to instruct the browser to dowload the response as a file.
*

View file

@ -315,6 +315,9 @@ class Dispatcher {
}
$response->type($contentType);
}
if (!$compressionEnabled) {
$response->header('Content-Length', filesize($assetFile));
}
$response->cache(filemtime($assetFile));
$response->send();
ob_clean();

View file

@ -280,11 +280,11 @@ class CakeRoute {
$separatorIsPresent = strpos($param, $namedConfig['separator']) !== false;
if ((!isset($this->options['named']) || !empty($this->options['named'])) && $separatorIsPresent) {
list($key, $val) = explode($namedConfig['separator'], $param, 2);
$val = urldecode($val);
$val = rawurldecode($val);
$hasRule = isset($rules[$key]);
$passIt = (!$hasRule && !$greedy) || ($hasRule && !$this->_matchNamed($val, $rules[$key], $context));
if ($passIt) {
$pass[] = $param;
$pass[] = rawurldecode($param);
} else {
if (preg_match_all('/\[([A-Za-z0-9_-]+)?\]/', $key, $matches, PREG_SET_ORDER)) {
$matches = array_reverse($matches);
@ -305,7 +305,7 @@ class CakeRoute {
$named = array_merge_recursive($named, array($key => $val));
}
} else {
$pass[] = $param;
$pass[] = rawurldecode($param);
}
}
return array($pass, $named);
@ -471,7 +471,7 @@ class CakeRoute {
}
if (is_array($params['pass'])) {
$params['pass'] = implode('/', $params['pass']);
$params['pass'] = implode('/', array_map('rawurlencode', $params['pass']));
}
$namedConfig = Router::namedConfig();
@ -482,10 +482,10 @@ class CakeRoute {
foreach ($params['named'] as $key => $value) {
if (is_array($value)) {
foreach ($value as $namedKey => $namedValue) {
$named[] = $key . "[$namedKey]" . $separator . $namedValue;
$named[] = $key . "[$namedKey]" . $separator . rawurlencode($namedValue);
}
} else {
$named[] = $key . $separator . $value;
$named[] = $key . $separator . rawurlencode($value);
}
}
$params['pass'] = $params['pass'] . '/' . implode('/', $named);

View file

@ -19,6 +19,7 @@
require_once CAKE . 'basics.php';
App::uses('Folder', 'Utility');
App::uses('CakeResponse', 'Network');
/**
* BasicsTest class
@ -234,6 +235,14 @@ class BasicsTest extends CakeTestCase {
'n' => '&nbsp;'
);
$this->assertEqual($expected, $result);
$obj = new stdClass();
$result = h($obj);
$this->assertEquals('(object)stdClass', $result);
$obj = new CakeResponse(array('body' => 'Body content'));
$result = h($obj);
$this->assertEquals('Body content', $result);
}
/**

View file

@ -225,4 +225,17 @@ class ConsoleOutputTest extends CakeTestCase {
$this->output->write('<error>Bad</error> Regular', false);
}
/**
* test plain output only strips tags used for formatting.
*
* @return void
*/
public function testOutputAsPlainSelectiveTagRemoval() {
$this->output->outputAs(ConsoleOutput::PLAIN);
$this->output->expects($this->once())->method('_write')
->with('Bad Regular <b>Left</b> <i>behind</i> <name>');
$this->output->write('<error>Bad</error> Regular <b>Left</b> <i>behind</i> <name>', false);
}
}

View file

@ -636,6 +636,24 @@ class AuthComponentTest extends CakeTestCase {
$this->Controller->request['action'] = 'camelCase';
$this->assertFalse($this->Controller->Auth->startup($this->Controller));
$this->Controller->Auth->allow('*');
$this->Controller->Auth->deny();
$this->Controller->request['action'] = 'camelCase';
$this->assertFalse($this->Controller->Auth->startup($this->Controller));
$this->Controller->request['action'] = 'add';
$this->assertFalse($this->Controller->Auth->startup($this->Controller));
$this->Controller->Auth->allow('camelCase');
$this->Controller->Auth->deny();
$this->Controller->request['action'] = 'camelCase';
$this->assertFalse($this->Controller->Auth->startup($this->Controller));
$this->Controller->request['action'] = 'login';
$this->assertFalse($this->Controller->Auth->startup($this->Controller));
}
/**

View file

@ -29,13 +29,6 @@ App::uses('Router', 'Routing');
*/
class RequestHandlerTestController extends Controller {
/**
* name property
*
* @var string
*/
public $name = 'RequestHandlerTest';
/**
* uses property
*
@ -117,9 +110,8 @@ class RequestHandlerComponentTest extends CakeTestCase {
$request = new CakeRequest('controller_posts/index');
$response = new CakeResponse();
$this->Controller = new RequestHandlerTestController($request, $response);
$this->Controller->constructClasses();
$this->RequestHandler = new RequestHandlerComponent($this->Controller->Components);
$this->RequestHandler->request = $request;
$this->RequestHandler->response = $response;
$this->_extensions = Router::extensions();
}
@ -148,6 +140,7 @@ class RequestHandlerComponentTest extends CakeTestCase {
'ajaxLayout' => 'test_ajax'
);
$Collection = new ComponentCollection();
$Collection->init($this->Controller);
$RequestHandler = new RequestHandlerComponent($Collection, $settings);
$this->assertEqual($RequestHandler->ajaxLayout, 'test_ajax');
}

View file

@ -967,7 +967,8 @@ class ControllerTest extends CakeTestCase {
$TestController = new TestController($request);
$TestController->setAction('index', 1, 2);
$expected = array('testId' => 1, 'test2Id' => 2);
$this->assertidentical($TestController->data, $expected);
$this->assertSame($expected, $TestController->request->data);
$this->assertSame('index', $TestController->view);
}
/**

View file

@ -819,4 +819,20 @@ class AppTest extends CakeTestCase {
$this->assertArrayHasKey('Controller', $result);
$this->assertArrayHasKey('Controller/Component', $result);
}
/**
* Proves that it is possible to load plugin libraries in top
* level Lib dir for plugins
*
* @return void
*/
public function testPluginLibClasses() {
App::build(array(
'plugins' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS)
), App::RESET);
CakePlugin::loadAll();
$this->assertFalse(class_exists('TestPluginOtherLibrary', false));
App::uses('TestPluginOtherLibrary', 'TestPlugin.Lib');
$this->assertTrue(class_exists('TestPluginOtherLibrary'));
}
}

View file

@ -287,10 +287,11 @@ class ExceptionRendererTest extends CakeTestCase {
ob_start();
$ExceptionRenderer->render();
$results = ob_get_clean();
$result = ob_get_clean();
$this->assertFalse(method_exists($ExceptionRenderer, 'missingWidgetThing'), 'no method should exist.');
$this->assertEquals('error400', $ExceptionRenderer->method, 'incorrect method coercion.');
$this->assertContains('coding fail', $result, 'Text should show up.');
}
/**
@ -302,13 +303,40 @@ class ExceptionRendererTest extends CakeTestCase {
$exception = new OutOfBoundsException('foul ball.');
$ExceptionRenderer = new ExceptionRenderer($exception);
$ExceptionRenderer->controller->response = $this->getMock('CakeResponse', array('statusCode', '_sendHeader'));
$ExceptionRenderer->controller->response->expects($this->once())->method('statusCode')->with(500);
$ExceptionRenderer->controller->response->expects($this->once())
->method('statusCode')
->with(500);
ob_start();
$ExceptionRenderer->render();
$results = ob_get_clean();
$result = ob_get_clean();
$this->assertEquals('error500', $ExceptionRenderer->method, 'incorrect method coercion.');
$this->assertContains('foul ball.', $result, 'Text should show up as its debug mode.');
}
/**
* test that unknown exceptions have messages ignored.
*
* @return void
*/
public function testUnknownExceptionInProduction() {
Configure::write('debug', 0);
$exception = new OutOfBoundsException('foul ball.');
$ExceptionRenderer = new ExceptionRenderer($exception);
$ExceptionRenderer->controller->response = $this->getMock('CakeResponse', array('statusCode', '_sendHeader'));
$ExceptionRenderer->controller->response->expects($this->once())
->method('statusCode')
->with(500);
ob_start();
$ExceptionRenderer->render();
$result = ob_get_clean();
$this->assertEquals('error500', $ExceptionRenderer->method, 'incorrect method coercion.');
$this->assertNotContains('foul ball.', $result, 'Text should no show up.');
$this->assertContains('Internal Error', $result, 'Generic message only.');
}
/**
@ -324,9 +352,10 @@ class ExceptionRendererTest extends CakeTestCase {
ob_start();
$ExceptionRenderer->render();
$results = ob_get_clean();
$result = ob_get_clean();
$this->assertEquals('error500', $ExceptionRenderer->method, 'incorrect method coercion.');
$this->assertContains('foul ball.', $result, 'Text should show up as its debug mode.');
}
/**

View file

@ -1002,7 +1002,8 @@ class MysqlTest extends CakeTestCase {
'order' => array(),
'limit' => array(),
'offset' => array(),
'group' => array()
'group' => array(),
'callbacks' => null
);
$queryData['joins'][0]['table'] = $this->Dbo->fullTableName($queryData['joins'][0]['table']);
$this->assertEqual($queryData, $expected);

View file

@ -20,6 +20,8 @@ App::uses('Model', 'Model');
App::uses('AppModel', 'Model');
App::uses('Sqlite', 'Model/Datasource/Database');
require_once dirname(dirname(dirname(__FILE__))) . DS . 'models.php';
/**
* DboSqliteTestDb class
*
@ -74,7 +76,7 @@ class SqliteTest extends CakeTestCase {
*
* @var object
*/
public $fixtures = array('core.user');
public $fixtures = array('core.user', 'core.uuid');
/**
* Actual DB connection used in testing
@ -88,6 +90,7 @@ class SqliteTest extends CakeTestCase {
*
*/
public function setUp() {
parent::setUp();
Configure::write('Cache.disable', true);
$this->Dbo = ConnectionManager::getDataSource('test');
if (!$this->Dbo instanceof Sqlite) {
@ -100,6 +103,7 @@ class SqliteTest extends CakeTestCase {
*
*/
public function tearDown() {
parent::tearDown();
Configure::write('Cache.disable', false);
}
@ -317,5 +321,58 @@ class SqliteTest extends CakeTestCase {
);
$this->assertEqual($result['id'], $expected);
$this->Dbo->query('DROP TABLE ' . $tableName);
$tableName = 'uuid_tests';
$this->Dbo->query("CREATE TABLE {$tableName} (id CHAR(36) PRIMARY KEY, name VARCHAR, created DATETIME, modified DATETIME)");
$Model = new Model(array('name' => 'UuidTest', 'ds' => 'test', 'table' => 'uuid_tests'));
$result = $this->Dbo->describe($Model);
$expected = array(
'type' => 'string',
'length' => 36,
'null' => false,
'default' => null,
'key' => 'primary',
);
$this->assertEqual($result['id'], $expected);
$this->Dbo->query('DROP TABLE ' . $tableName);
}
/**
* Test virtualFields with functions.
*
* @return void
*/
public function testVirtualFieldWithFunction() {
$this->loadFixtures('User');
$User = ClassRegistry::init('User');
$User->virtualFields = array('name' => 'SUBSTR(User.user, 5)');
$result = $User->find('first', array(
'conditions' => array('User.user' => 'garrett')
));
$this->assertEquals('ett', $result['User']['name']);
}
/**
* Test that records can be inserted with uuid primary keys, and
* that the primary key is not blank
*
* @return void
*/
public function testUuidPrimaryKeyInsertion() {
$this->loadFixtures('Uuid');
$Model = ClassRegistry::init('Uuid');
$data = array(
'title' => 'A uuid should work',
'count' => 10
);
$Model->create($data);
$this->assertTrue((bool)$Model->save());
$result = $Model->read();
$this->assertEquals($data['title'], $result['Uuid']['title']);
$this->assertTrue(Validation::uuid($result['Uuid']['id']), 'Not a uuid');
}
}

View file

@ -4933,6 +4933,95 @@ class ModelReadTest extends BaseModelTest {
$this->assertEqual($expected, $result);
}
/**
* testAssociationAfterFindCallbacksDisabled method
*
* @return void
*/
public function testAssociationAfterFindCalbacksDisabled() {
$this->loadFixtures('Post', 'Author', 'Comment');
$TestModel = new Post();
$result = $TestModel->find('all', array('callbacks' => false));
$expected = array(
array(
'Post' => array(
'id' => '1',
'author_id' => '1',
'title' => 'First Post',
'body' => 'First Post Body',
'published' => 'Y',
'created' => '2007-03-18 10:39:23',
'updated' => '2007-03-18 10:41:31'
),
'Author' => array(
'id' => '1',
'user' => 'mariano',
'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
'created' => '2007-03-17 01:16:23',
'updated' => '2007-03-17 01:18:31'
)),
array(
'Post' => array(
'id' => '2',
'author_id' => '3',
'title' => 'Second Post',
'body' => 'Second Post Body',
'published' => 'Y',
'created' => '2007-03-18 10:41:23',
'updated' => '2007-03-18 10:43:31'
),
'Author' => array(
'id' => '3',
'user' => 'larry',
'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
'created' => '2007-03-17 01:20:23',
'updated' => '2007-03-17 01:22:31'
)),
array(
'Post' => array(
'id' => '3',
'author_id' => '1',
'title' => 'Third Post',
'body' => 'Third Post Body',
'published' => 'Y',
'created' => '2007-03-18 10:43:23',
'updated' => '2007-03-18 10:45:31'
),
'Author' => array(
'id' => '1',
'user' => 'mariano',
'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
'created' => '2007-03-17 01:16:23',
'updated' => '2007-03-17 01:18:31'
)));
$this->assertEqual($expected, $result);
unset($TestModel);
$Author = new Author();
$Author->Post->bindModel(array(
'hasMany' => array(
'Comment' => array(
'className' => 'ModifiedComment',
'foreignKey' => 'article_id',
)
)));
$result = $Author->find('all', array(
'conditions' => array('Author.id' => 1),
'recursive' => 2,
'callbacks' => false
));
$expected = array(
'id' => 1,
'article_id' => 1,
'user_id' => 2,
'comment' => 'First Comment for First Article',
'published' => 'Y',
'created' => '2007-03-18 10:45:23',
'updated' => '2007-03-18 10:47:31'
);
$this->assertEqual($result[0]['Post'][0]['Comment'][0], $expected);
}
/**
* Tests that the database configuration assigned to the model can be changed using
* (before|after)Find callbacks

View file

@ -370,4 +370,59 @@ class CakeResponseTest extends CakeTestCase {
$result = $response->mapType(array('application/json', 'application/xhtml+xml', 'text/css'));
$this->assertEquals($expected, $result);
}
/**
* Tests the send and setting of Content-Length
*
*/
public function testSendContentLength() {
$response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent'));
$response->body('the response body');
$response->expects($this->once())->method('_sendContent')->with('the response body');
$response->expects($this->at(0))
->method('_sendHeader')->with('HTTP/1.1 200 OK');
$response->expects($this->at(1))
->method('_sendHeader')->with('Content-Type', 'text/html; charset=UTF-8');
$response->expects($this->at(2))
->method('_sendHeader')->with('Content-Length', strlen('the response body'));
$response->send();
$response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent'));
$body = '長い長い長いSubjectの場合はfoldingするのが正しいんだけどいったいどうなるんだろう';
$response->body($body);
$response->expects($this->once())->method('_sendContent')->with($body);
$response->expects($this->at(0))
->method('_sendHeader')->with('HTTP/1.1 200 OK');
$response->expects($this->at(1))
->method('_sendHeader')->with('Content-Type', 'text/html; charset=UTF-8');
$response->expects($this->at(2))
->method('_sendHeader')->with('Content-Length', 116);
$response->send();
$response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent', 'outputCompressed'));
$body = '長い長い長いSubjectの場合はfoldingするのが正しいんだけどいったいどうなるんだろう';
$response->body($body);
$response->expects($this->once())->method('outputCompressed')->will($this->returnValue(true));
$response->expects($this->once())->method('_sendContent')->with($body);
$response->expects($this->exactly(2))->method('_sendHeader');
$response->send();
$response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent', 'outputCompressed'));
$body = 'hwy';
$response->body($body);
$response->header('Content-Length', 1);
$response->expects($this->never())->method('outputCompressed');
$response->expects($this->once())->method('_sendContent')->with($body);
$response->expects($this->at(2))
->method('_sendHeader')->with('Content-Length', 1);
$response->send();
$response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent'));
$body = 'content';
$response->statusCode(301);
$response->body($body);
$response->expects($this->once())->method('_sendContent')->with($body);
$response->expects($this->exactly(2))->method('_sendHeader');
$response->send();
}
}

View file

@ -1291,6 +1291,14 @@ class DispatcherTest extends CakeTestCase {
$result = ob_get_clean();
$this->assertEqual('htc file', $result);
$response = $this->getMock('CakeResponse', array('_sendHeader'));
ob_start();
$Dispatcher->asset('test_plugin/css/unknown.extension', $response);
ob_end_clean();
$expected = filesize(CakePlugin::path('TestPlugin') . 'webroot' . DS . 'css' . DS . 'unknown.extension');
$headers = $response->header();
$this->assertEqual($expected, $headers['Content-Length']);
if (php_sapi_name() == 'cli') {
while (ob_get_level()) {
ob_get_clean();

View file

@ -369,6 +369,8 @@ class CakeRouteTest extends CakeTestCase {
$result = $route->match(array('controller' => 'posts', 'action' => 'view', 'plugin' => null, 5, 'page' => 1, 'limit' => 20, 'order' => 'title'));
$this->assertEqual($result, '/posts/view/5/page:1/limit:20/order:title');
$result = $route->match(array('controller' => 'posts', 'action' => 'view', 'plugin' => null, 'word space', 'order' => 'Θ'));
$this->assertEqual($result, '/posts/view/word%20space/order:%CE%98');
$route = new CakeRoute('/test2/*', array('controller' => 'pages', 'action' => 'display', 2));
$result = $route->match(array('controller' => 'pages', 'action' => 'display', 1));
@ -395,6 +397,10 @@ class CakeRouteTest extends CakeTestCase {
$result = $route->parse('/posts/index/page[]:%CE%98');
$this->assertEquals('Θ', $result['named']['page'][0]);
$result = $route->parse('/posts/index/something%20else/page[]:%CE%98');
$this->assertEquals('Θ', $result['named']['page'][0]);
$this->assertEquals('something else', $result['pass'][0]);
}
/**

View file

@ -423,7 +423,7 @@ TEXT;
*
* @return void
*/
function testNoDbCredentials() {
public function testNoDbCredentials() {
$config = array(
'driver' => 'mysql',
'persistent' => false,
@ -449,4 +449,19 @@ TEXT;
$this->assertEqual($expected, $output);
}
/**
* test trace exclude
*
* @return void
*/
public function testTraceExclude() {
$result = Debugger::trace();
$this->assertPattern('/^DebuggerTest::testTraceExclude/', $result);
$result = Debugger::trace(array(
'exclude' => array('DebuggerTest::testTraceExclude')
));
$this->assertNoPattern('/^DebuggerTest::testTraceExclude/', $result);
}
}

View file

@ -104,6 +104,7 @@ class Contact extends CakeTestModel {
'non_existing' => array(),
'idontexist' => array(),
'imrequired' => array('rule' => array('between', 5, 30), 'allowEmpty' => false),
'string_required' => 'notEmpty',
'imalsorequired' => array('rule' => 'alphaNumeric', 'allowEmpty' => false),
'imrequiredtoo' => array('rule' => 'notEmpty'),
'required_one' => array('required' => array('rule' => array('notEmpty'))),
@ -6584,6 +6585,141 @@ class FormHelperTest extends CakeTestCase {
$this->assertTags($result, $expected);
}
/**
* Test that required fields are created for various types of validation.
*
* @return void
*/
function testFormInputRequiredDetection() {
$this->Form->create('Contact');
$result = $this->Form->input('Contact.non_existing');
$expected = array(
'div' => array('class' => 'input text required'),
'label' => array('for' => 'ContactNonExisting'),
'Non Existing',
'/label',
'input' => array(
'type' => 'text', 'name' => 'data[Contact][non_existing]',
'id' => 'ContactNonExisting'
),
'/div'
);
$this->assertTags($result, $expected);
$result = $this->Form->input('Contact.imrequired');
$expected = array(
'div' => array('class' => 'input text required'),
'label' => array('for' => 'ContactImrequired'),
'Imrequired',
'/label',
'input' => array(
'type' => 'text', 'name' => 'data[Contact][imrequired]',
'id' => 'ContactImrequired'
),
'/div'
);
$this->assertTags($result, $expected);
$result = $this->Form->input('Contact.imalsorequired');
$expected = array(
'div' => array('class' => 'input text required'),
'label' => array('for' => 'ContactImalsorequired'),
'Imalsorequired',
'/label',
'input' => array(
'type' => 'text', 'name' => 'data[Contact][imalsorequired]',
'id' => 'ContactImalsorequired'
),
'/div'
);
$this->assertTags($result, $expected);
$result = $this->Form->input('Contact.imrequiredtoo');
$expected = array(
'div' => array('class' => 'input text required'),
'label' => array('for' => 'ContactImrequiredtoo'),
'Imrequiredtoo',
'/label',
'input' => array(
'type' => 'text', 'name' => 'data[Contact][imrequiredtoo]',
'id' => 'ContactImrequiredtoo'
),
'/div'
);
$this->assertTags($result, $expected);
$result = $this->Form->input('Contact.required_one');
$expected = array(
'div' => array('class' => 'input text required'),
'label' => array('for' => 'ContactRequiredOne'),
'Required One',
'/label',
'input' => array(
'type' => 'text', 'name' => 'data[Contact][required_one]',
'id' => 'ContactRequiredOne'
),
'/div'
);
$this->assertTags($result, $expected);
$result = $this->Form->input('Contact.string_required');
$expected = array(
'div' => array('class' => 'input text required'),
'label' => array('for' => 'ContactStringRequired'),
'String Required',
'/label',
'input' => array(
'type' => 'text', 'name' => 'data[Contact][string_required]',
'id' => 'ContactStringRequired'
),
'/div'
);
$this->assertTags($result, $expected);
$result = $this->Form->input('Contact.imnotrequired');
$expected = array(
'div' => array('class' => 'input text'),
'label' => array('for' => 'ContactImnotrequired'),
'Imnotrequired',
'/label',
'input' => array(
'type' => 'text', 'name' => 'data[Contact][imnotrequired]',
'id' => 'ContactImnotrequired'
),
'/div'
);
$this->assertTags($result, $expected);
$result = $this->Form->input('Contact.imalsonotrequired');
$expected = array(
'div' => array('class' => 'input text'),
'label' => array('for' => 'ContactImalsonotrequired'),
'Imalsonotrequired',
'/label',
'input' => array(
'type' => 'text', 'name' => 'data[Contact][imalsonotrequired]',
'id' => 'ContactImalsonotrequired'
),
'/div'
);
$this->assertTags($result, $expected);
$result = $this->Form->input('Contact.imnotrequiredeither');
$expected = array(
'div' => array('class' => 'input text'),
'label' => array('for' => 'ContactImnotrequiredeither'),
'Imnotrequiredeither',
'/label',
'input' => array(
'type' => 'text', 'name' => 'data[Contact][imnotrequiredeither]',
'id' => 'ContactImnotrequiredeither'
),
'/div'
);
$this->assertTags($result, $expected);
}
/**
* testFormMagicInput method
*
@ -6671,117 +6807,6 @@ class FormHelperTest extends CakeTestCase {
);
$this->assertTags($result, $expected);
$result = $this->Form->input('Contact.non_existing');
$expected = array(
'div' => array('class' => 'input text required'),
'label' => array('for' => 'ContactNonExisting'),
'Non Existing',
'/label',
'input' => array(
'type' => 'text', 'name' => 'data[Contact][non_existing]',
'id' => 'ContactNonExisting'
),
'/div'
);
$this->assertTags($result, $expected);
$result = $this->Form->input('Contact.imrequired');
$expected = array(
'div' => array('class' => 'input text required'),
'label' => array('for' => 'ContactImrequired'),
'Imrequired',
'/label',
'input' => array(
'type' => 'text', 'name' => 'data[Contact][imrequired]',
'id' => 'ContactImrequired'
),
'/div'
);
$this->assertTags($result, $expected);
$result = $this->Form->input('Contact.imalsorequired');
$expected = array(
'div' => array('class' => 'input text required'),
'label' => array('for' => 'ContactImalsorequired'),
'Imalsorequired',
'/label',
'input' => array(
'type' => 'text', 'name' => 'data[Contact][imalsorequired]',
'id' => 'ContactImalsorequired'
),
'/div'
);
$this->assertTags($result, $expected);
$result = $this->Form->input('Contact.imrequiredtoo');
$expected = array(
'div' => array('class' => 'input text required'),
'label' => array('for' => 'ContactImrequiredtoo'),
'Imrequiredtoo',
'/label',
'input' => array(
'type' => 'text', 'name' => 'data[Contact][imrequiredtoo]',
'id' => 'ContactImrequiredtoo'
),
'/div'
);
$this->assertTags($result, $expected);
$result = $this->Form->input('Contact.required_one');
$expected = array(
'div' => array('class' => 'input text required'),
'label' => array('for' => 'ContactRequiredOne'),
'Required One',
'/label',
'input' => array(
'type' => 'text', 'name' => 'data[Contact][required_one]',
'id' => 'ContactRequiredOne'
),
'/div'
);
$this->assertTags($result, $expected);
$result = $this->Form->input('Contact.imnotrequired');
$expected = array(
'div' => array('class' => 'input text'),
'label' => array('for' => 'ContactImnotrequired'),
'Imnotrequired',
'/label',
'input' => array(
'type' => 'text', 'name' => 'data[Contact][imnotrequired]',
'id' => 'ContactImnotrequired'
),
'/div'
);
$this->assertTags($result, $expected);
$result = $this->Form->input('Contact.imalsonotrequired');
$expected = array(
'div' => array('class' => 'input text'),
'label' => array('for' => 'ContactImalsonotrequired'),
'Imalsonotrequired',
'/label',
'input' => array(
'type' => 'text', 'name' => 'data[Contact][imalsonotrequired]',
'id' => 'ContactImalsonotrequired'
),
'/div'
);
$this->assertTags($result, $expected);
$result = $this->Form->input('Contact.imnotrequiredeither');
$expected = array(
'div' => array('class' => 'input text'),
'label' => array('for' => 'ContactImnotrequiredeither'),
'Imnotrequiredeither',
'/label',
'input' => array(
'type' => 'text', 'name' => 'data[Contact][imnotrequiredeither]',
'id' => 'ContactImnotrequiredeither'
),
'/div'
);
$this->assertTags($result, $expected);
extract($this->dateRegex);
$now = strtotime('now');

View file

@ -255,7 +255,7 @@ class HelperTest extends CakeTestCase {
*/
public function testSetEntityScoped() {
$this->Helper->setEntity('HelperTestPost', true);
$this->assertEquals(array('HelperTestPost'), $this->Helper->entity());
$this->assertEquals(array('HelperTestPost'), $this->Helper->entity());
$this->Helper->setEntity('id');
$expected = array('HelperTestPost', 'id');
@ -310,6 +310,19 @@ class HelperTest extends CakeTestCase {
$this->assertEquals('HelperTestComment', $this->Helper->model());
}
/**
* Test creating saveMany() compatible entities
*
* @return void
*/
public function testSetEntitySaveMany() {
$this->Helper->setEntity('HelperTestPost', true);
$this->Helper->setEntity('0.HelperTestPost.id');
$expected = array('0', 'HelperTestPost', 'id');
$this->assertEquals($expected, $this->Helper->entity());
}
/**
* Test that setEntity doesn't make CamelCase fields that are not associations an
* associated model.

View file

@ -0,0 +1,19 @@
<?php
/**
* Test Suite TestPlugin Other Library
*
* PHP 5
*
* CakePHP(tm) Tests <http://book.cakephp.org/view/1196/Testing>
* Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice
*
* @copyright Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://book.cakephp.org/view/1196/Testing CakePHP(tm) Tests
* @package Cake.Test.test_app.Plugin.TestPlugin.Lib
* @since CakePHP(tm) v 2.0.1
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
class TestPluginOtherLibrary {}

View file

@ -387,8 +387,8 @@ abstract class CakeTestCase extends PHPUnit_Framework_TestCase {
* @param string $message the text to display if the assertion is not correct
* @return void
*/
protected function assertEqual($result, $expected, $message = '') {
return $this->assertEquals($expected, $result, $message);
protected static function assertEqual($result, $expected, $message = '') {
return self::assertEquals($expected, $result, $message);
}
/**
@ -399,8 +399,8 @@ abstract class CakeTestCase extends PHPUnit_Framework_TestCase {
* @param string $message the text to display if the assertion is not correct
* @return void
*/
protected function assertNotEqual($result, $expected, $message = '') {
return $this->assertNotEquals($expected, $result, $message);
protected static function assertNotEqual($result, $expected, $message = '') {
return self::assertNotEquals($expected, $result, $message);
}
/**
@ -411,8 +411,8 @@ abstract class CakeTestCase extends PHPUnit_Framework_TestCase {
* @param string $message the text to display if the assertion is not correct
* @return void
*/
protected function assertPattern($pattern, $string, $message = '') {
return $this->assertRegExp($pattern, $string, $message);
protected static function assertPattern($pattern, $string, $message = '') {
return self::assertRegExp($pattern, $string, $message);
}
/**
@ -423,8 +423,8 @@ abstract class CakeTestCase extends PHPUnit_Framework_TestCase {
* @param string $message the text to display if the assertion is not correct
* @return void
*/
protected function assertIdentical($actual, $expected, $message = '') {
return $this->assertSame($expected, $actual, $message);
protected static function assertIdentical($actual, $expected, $message = '') {
return self::assertSame($expected, $actual, $message);
}
/**
@ -435,8 +435,8 @@ abstract class CakeTestCase extends PHPUnit_Framework_TestCase {
* @param string $message the text to display if the assertion is not correct
* @return void
*/
protected function assertNotIdentical($actual, $expected, $message = '') {
return $this->assertNotSame($expected, $actual, $message);
protected static function assertNotIdentical($actual, $expected, $message = '') {
return self::assertNotSame($expected, $actual, $message);
}
/**
@ -447,8 +447,8 @@ abstract class CakeTestCase extends PHPUnit_Framework_TestCase {
* @param string $message the text to display if the assertion is not correct
* @return void
*/
protected function assertNoPattern($pattern, $string, $message = '') {
return $this->assertNotRegExp($pattern, $string, $message);
protected static function assertNoPattern($pattern, $string, $message = '') {
return self::assertNotRegExp($pattern, $string, $message);
}
protected function assertNoErrors() {
@ -487,8 +487,8 @@ abstract class CakeTestCase extends PHPUnit_Framework_TestCase {
* @param string $message the text to display if the assertion is not correct
* @return void
*/
protected function assertReference(&$first, &$second, $message = '') {
return $this->assertSame($first, $second, $message);
protected static function assertReference(&$first, &$second, $message = '') {
return self::assertSame($first, $second, $message);
}
/**
@ -499,8 +499,8 @@ abstract class CakeTestCase extends PHPUnit_Framework_TestCase {
* @param string $message
* @return void
*/
protected function assertIsA($object, $type, $message = '') {
return $this->assertInstanceOf($type, $object, $message);
protected static function assertIsA($object, $type, $message = '') {
return self::assertInstanceOf($type, $object, $message);
}
/**
@ -512,10 +512,10 @@ abstract class CakeTestCase extends PHPUnit_Framework_TestCase {
* @param string $message the text to display if the assertion is not correct
* @return void
*/
protected function assertWithinMargin($result, $expected, $margin, $message = '') {
protected static function assertWithinMargin($result, $expected, $margin, $message = '') {
$upper = $result + $margin;
$lower = $result - $margin;
$this->assertTrue((($expected <= $upper) && ($expected >= $lower)), $message);
return self::assertTrue((($expected <= $upper) && ($expected >= $lower)), $message);
}
/**

View file

@ -59,6 +59,15 @@ class ControllerTestDispatcher extends Dispatcher {
$this->testController->helpers = array_merge(array('InterceptContent'), $this->testController->helpers);
$this->testController->setRequest($request);
$this->testController->response = $this->response;
foreach ($this->testController->Components->attached() as $component) {
$object = $this->testController->Components->{$component};
if (isset($object->response)) {
$object->response = $response;
}
}
if (isset($object->request)) {
$object->request = $request;
}
return $this->testController;
}

View file

@ -285,9 +285,9 @@ class Debugger {
'args' => false,
'start' => 0,
'scope' => null,
'exclude' => null
'exclude' => array('call_user_func_array', 'trigger_error')
);
$options += $defaults;
$options = Set::merge($defaults, $options);
$backtrace = debug_backtrace();
$count = count($backtrace);
@ -302,13 +302,15 @@ class Debugger {
for ($i = $options['start']; $i < $count && $i < $options['depth']; $i++) {
$trace = array_merge(array('file' => '[internal]', 'line' => '??'), $backtrace[$i]);
$signature = $reference = '[main]';
if (isset($backtrace[$i + 1])) {
$next = array_merge($_trace, $backtrace[$i + 1]);
$reference = $next['function'];
$signature = $reference = $next['function'];
if (!empty($next['class'])) {
$reference = $next['class'] . '::' . $reference . '(';
$signature = $next['class'] . '::' . $next['function'];
$reference = $signature . '(';
if ($options['args'] && isset($next['args'])) {
$args = array();
foreach ($next['args'] as $arg) {
@ -318,10 +320,8 @@ class Debugger {
}
$reference .= ')';
}
} else {
$reference = '[main]';
}
if (in_array($reference, array('call_user_func_array', 'trigger_error'))) {
if (in_array($signature, $options['exclude'])) {
continue;
}
if ($options['format'] == 'points' && $trace['file'] != '[internal]') {

View file

@ -444,9 +444,9 @@ class Helper extends Object {
$entity = $this->_modelScope . '.' . $entity;
}
// 0.name, 0.created.month style inputs.
// 0.name, 0.created.month style inputs. Excludes inputs with the modelScope in them.
if (
$count >= 2 && is_numeric($parts[0]) && !is_numeric($parts[1]) && $this->_modelScope
$count >= 2 && is_numeric($parts[0]) && !is_numeric($parts[1]) && $this->_modelScope && strpos($entity, $this->_modelScope) === false
) {
$entity = $this->_modelScope . '.' . $entity;
}

View file

@ -265,24 +265,26 @@ class CacheHelper extends AppHelper {
$file = '<!--cachetime:' . $cacheTime . '--><?php';
if (empty($this->_View->plugin)) {
$file .= '
App::import(\'Controller\', \'' . $this->_View->name. '\');
';
$file .= "
App::uses('{$this->_View->name}Controller', 'Controller');
";
} else {
$file .= '
App::import(\'Controller\', \'' . $this->_View->plugin . '.' . $this->_View->name. '\');
';
$file .= "
App::uses('{$this->_View->name}Controller', '{$this->_View->plugin}.Controller');
";
}
$file .= '$controller = new ' . $this->_View->name . 'Controller();
$file .= '
$request = unserialize(\'' . str_replace("'", "\\'", serialize($this->request)) . '\');
$response = new CakeResponse(array("charset" => Configure::read("App.encoding")));
$controller = new ' . $this->_View->name . 'Controller($request, $response);
$controller->plugin = $this->plugin = \'' . $this->_View->plugin . '\';
$controller->helpers = $this->helpers = unserialize(\'' . serialize($this->_View->helpers) . '\');
$controller->layout = $this->layout = \'' . $this->_View->layout. '\';
$controller->request = $this->request = unserialize(\'' . str_replace("'", "\\'", serialize($this->request)) . '\');
$controller->theme = $this->theme = \'' . $this->_View->theme . '\';
$controller->viewVars = $this->viewVars = unserialize(base64_decode(\'' . base64_encode(serialize($this->_View->viewVars)) . '\'));
Router::setRequestInfo($controller->request);';
Router::setRequestInfo($controller->request);
$this->request = $request;';
if ($useCallbacks == true) {
$file .= '

View file

@ -239,14 +239,16 @@ class FormHelper extends AppHelper {
}
/**
* Returns if a field is required to be filled based on validation properties from the validating object
* Returns if a field is required to be filled based on validation properties from the validating object.
*
* @param array $validateProperties
* @return boolean true if field is required to be filled, false otherwise
*/
protected function _isRequiredField($validateProperties) {
$required = false;
if (is_array($validateProperties)) {
if (is_string($validateProperties)) {
return true;
} elseif (is_array($validateProperties)) {
$dims = Set::countDim($validateProperties);
if ($dims == 1 || ($dims == 2 && isset($validateProperties['rule']))) {

View file

@ -1,2 +1 @@
<?php echo '<?xml version="1.0" encoding="' . Configure::read('App.encoding') . '"?>'; ?>
<?php echo $content_for_layout; ?>

View file

@ -24,7 +24,7 @@ App::uses('Debugger', 'Utility');
<p>For updates and important announcements, visit http://cakefest.org</p>
</iframe>
<h2><?php echo __d('cake_dev', 'Release Notes for CakePHP %s.', Configure::version()); ?></h2>
<a href="http://cakephp.org/changelogs/2.0.0"><?php __d('cake_dev', 'Read the changelog'); ?> </a>
<a href="http://cakephp.org/changelogs/2.0.2"><?php __d('cake_dev', 'Read the changelog'); ?> </a>
<?php
if (Configure::read('debug') > 0):
Debugger::checkSecurityKeys();

View file

@ -136,7 +136,7 @@ class View extends Object {
/**
* Sub-directory for this view file. This is often used for extension based routing.
* for example with an `xml` extension, $subDir would be `xml/`
* Eg. With an `xml` extension, $subDir would be `xml/`
*
* @var string
*/
@ -158,7 +158,7 @@ class View extends Object {
public $cacheAction = false;
/**
* holds current errors for the model validation
* Holds current errors for the model validation.
*
* @var array
*/
@ -172,7 +172,7 @@ class View extends Object {
public $hasRendered = false;
/**
* List of generated DOM UUIDs
* List of generated DOM UUIDs.
*
* @var array
*/
@ -205,7 +205,7 @@ class View extends Object {
public $elementCache = 'default';
/**
* List of variables to collect from the associated controller
* List of variables to collect from the associated controller.
*
* @var array
*/
@ -215,7 +215,7 @@ class View extends Object {
);
/**
* Scripts (and/or other <head /> tags) for the layout
* Scripts (and/or other <head /> tags) for the layout.
*
* @var array
*/
@ -229,7 +229,7 @@ class View extends Object {
protected $_paths = array();
/**
* boolean to indicate that helpers have been loaded.
* Indicate that helpers have been loaded.
*
* @var boolean
*/
@ -238,7 +238,7 @@ class View extends Object {
/**
* Constructor
*
* @param Controller $controller A controller object to pull View::__passedArgs from.
* @param Controller $controller A controller object to pull View::_passedVars from.
*/
public function __construct($controller) {
if (is_object($controller)) {
@ -337,7 +337,7 @@ class View extends Object {
* Renders view for given view file and layout.
*
* Render triggers helper callbacks, which are fired before and after the view are rendered,
* as well as before and after the layout. The helper callbacks are called
* as well as before and after the layout. The helper callbacks are called:
*
* - `beforeRender`
* - `afterRender`

View file

@ -107,7 +107,7 @@ TEXT;
}
$var = Debugger::exportVar($var, 25);
if ($showHtml) {
$var = htmlentities($var);
$var = h($var);
}
printf($template, $file, $line, $var);
}
@ -149,7 +149,9 @@ if (!function_exists('sortByKey')) {
/**
* Convenience method for htmlspecialchars.
*
* @param string $text Text to wrap through htmlspecialchars
* @param mixed $text Text to wrap through htmlspecialchars. Also works with arrays, and objects.
* Arrays will be mapped and have all their elements escaped. Objects will be string cast if they
* implement a `__toString` method. Otherwise the class name will be used.
* @param boolean $double Encode existing html entities
* @param string $charset Character set to use when escaping. Defaults to config value in 'App.encoding' or 'UTF-8'
* @return string Wrapped text
@ -162,6 +164,12 @@ function h($text, $double = true, $charset = null) {
$texts[$k] = h($t, $double, $charset);
}
return $texts;
} elseif (is_object($text)) {
if (method_exists($text, '__toString')) {
$text = (string) $text;
} else {
$text = '(object)' . get_class($text);
}
}
static $defaultCharset = false;