Merge branch '2.0' into 2.0-phpunit-upgrade

This commit is contained in:
José Lorenzo Rodríguez 2010-09-27 22:42:10 -04:30
commit 2635733aba
124 changed files with 3506 additions and 2606 deletions

View file

@ -79,6 +79,7 @@
if (isset($_GET['url']) && $_GET['url'] === 'favicon.ico') {
return;
} else {
require CAKE . 'dispatcher.php';
$Dispatcher = new Dispatcher();
$Dispatcher->dispatch();
}

View file

@ -18,5 +18,6 @@
// @license MIT License (http://www.opensource.org/licenses/mit-license.php)
// +--------------------------------------------------------------------------------------------+ //
////////////////////////////////////////////////////////////////////////////////////////////////////
1.3.3
1.3.4

View file

@ -25,12 +25,15 @@ if (!defined('E_DEPRECATED')) {
error_reporting(E_ALL & ~E_DEPRECATED);
require CORE_PATH . 'cake' . DS . 'basics.php';
$TIME_START = microtime(true);
require CORE_PATH . 'cake' . DS . 'config' . DS . 'paths.php';
require LIBS . 'exceptions.php';
require LIBS . 'object.php';
require LIBS . 'inflector.php';
require LIBS . 'configure.php';
require LIBS . 'set.php';
require LIBS . 'cache.php';
Configure::bootstrap();
require CAKE . 'dispatcher.php';
require LIBS . 'error_handler.php';
set_exception_handler(array('ErrorHandler', 'handleException'));
Configure::bootstrap(isset($boot) ? $boot : true);

View file

@ -17,4 +17,4 @@
* @since CakePHP(tm) v 1.1.11.4062
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
return $config['Cake.version'] = '1.3.3';
return $config['Cake.version'] = '1.3.4';

View file

@ -20,9 +20,7 @@
* @since CakePHP(tm) v 1.2.0.5012
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
if (!defined('E_DEPRECATED')) {
define('E_DEPRECATED', 8192);
}
/**
* Shell dispatcher
*
@ -172,7 +170,6 @@ class ShellDispatcher {
}
}
}
require_once(CORE_PATH . 'cake' . DS . 'basics.php');
}
/**
@ -258,26 +255,10 @@ class ShellDispatcher {
define('TMP', CORE_PATH . 'cake' . DS . 'console' . DS . 'templates' . DS . 'skel' . DS . 'tmp' . DS);
}
$includes = array(
CORE_PATH . 'cake' . DS . 'config' . DS . 'paths.php',
CORE_PATH . 'cake' . DS . 'libs' . DS . 'object.php',
CORE_PATH . 'cake' . DS . 'libs' . DS . 'inflector.php',
CORE_PATH . 'cake' . DS . 'libs' . DS . 'configure.php',
CORE_PATH . 'cake' . DS . 'libs' . DS . 'file.php',
CORE_PATH . 'cake' . DS . 'libs' . DS . 'cache.php',
CORE_PATH . 'cake' . DS . 'libs' . DS . 'string.php',
CORE_PATH . 'cake' . DS . 'libs' . DS . 'class_registry.php',
CORE_PATH . 'cake' . DS . 'console' . DS . 'error.php'
);
foreach ($includes as $inc) {
if (!require($inc)) {
$this->stderr("Failed to load Cake core file {$inc}");
return false;
}
}
Configure::bootstrap(file_exists(CONFIGS . 'bootstrap.php'));
$boot = file_exists(ROOT . DS . APP_DIR . DS . 'config' . DS . 'bootstrap.php');
require CORE_PATH . 'cake' . DS . 'bootstrap.php';
require_once CORE_PATH . 'cake' . DS . 'console' . DS . 'console_error_handler.php';
set_exception_handler(array('ConsoleErrorHandler', 'handleException'));
if (!file_exists(APP_PATH . 'config' . DS . 'core.php')) {
include_once CORE_PATH . 'cake' . DS . 'console' . DS . 'templates' . DS . 'skel' . DS . 'config' . DS . 'core.php';

View file

@ -0,0 +1,119 @@
<?php
/**
* ErrorHandler for Console Shells
*
* PHP versions 4 and 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @package cake
* @subpackage cake.cake.console
* @since CakePHP(tm) v 1.2.0.5074
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
App::import('Core', 'ErrorHandler');
/**
* Error Handler for Cake console. Does simple printing of the
* exception that occurred and the stack trace of the error.
*
* @package cake
* @subpackage cake.cake.console
*/
class ConsoleErrorHandler extends ErrorHandler {
/**
* Standard error stream.
*
* @var filehandle
* @access public
*/
public $stderr;
/**
* Class constructor.
*
* @param Exception $error Exception to handle.
* @param array $messages Error messages
*/
function __construct($error) {
$this->stderr = fopen('php://stderr', 'w');
parent::__construct($error);
}
/**
* Handle a exception in the console environment.
*
* @return void
*/
public static function handleException($exception) {
$error = new ConsoleErrorHandler($exception);
$error->render();
}
/**
* Do nothing, no controllers are needed in the console.
*
* @return void
*/
protected function _getController($exception) {
return null;
}
/**
* Overwrite how _cakeError behaves for console. There is no reason
* to prepare urls as they are not relevant for this.
*
* @param $error Exception Exception being handled.
* @return void
*/
protected function _cakeError($error) {
$this->_outputMessage();
}
/**
* Override error404 method
*
* @param Exception $error Exception
* @return void
*/
public function error400($error) {
$this->_outputMessage();
}
/**
* Override error500 method
*
* @param Exception $error Exception
* @return void
*/
public function error500($error) {
$this->_outputMessage();
}
/**
* Outputs the exception to STDERR.
*
* @param string $template The name of the template to render.
* @return void
*/
public function _outputMessage($template = null) {
$this->stderr($this->error->getMessage() . "\n" . $this->error->getTraceAsString());
}
/**
* Outputs to the stderr filehandle.
*
* @param string $string Error text to output.
*/
public function stderr($string) {
fwrite($this->stderr, "Error: ". $string . "\n");
}
}

View file

@ -1,248 +0,0 @@
<?php
/**
* ErrorHandler for Console Shells
*
* PHP versions 4 and 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @package cake
* @subpackage cake.cake.console
* @since CakePHP(tm) v 1.2.0.5074
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
/**
* Error Handler for Cake console.
*
* @package cake
* @subpackage cake.cake.console
*/
class ErrorHandler extends Object {
/**
* Standard output stream.
*
* @var filehandle
* @access public
*/
public $stdout;
/**
* Standard error stream.
*
* @var filehandle
* @access public
*/
public $stderr;
/**
* Class constructor.
*
* @param string $method Method dispatching an error
* @param array $messages Error messages
*/
function __construct($method, $messages) {
$this->stdout = fopen('php://stdout', 'w');
$this->stderr = fopen('php://stderr', 'w');
call_user_func_array(array(&$this, $method), $messages);
}
/**
* Displays an error page (e.g. 404 Not found).
*
* @param array $params Parameters (code, name, and message)
*/
public function error($params) {
extract($params, EXTR_OVERWRITE);
$this->stderr($code . $name . $message."\n");
$this->_stop();
}
/**
* Convenience method to display a 404 page.
*
* @param array $params Parameters (url, message)
*/
public function error404($params) {
extract($params, EXTR_OVERWRITE);
$this->error(array(
'code' => '404',
'name' => 'Not found',
'message' => sprintf(__('The requested address %s was not found on this server.'), $url, $message)
));
$this->_stop();
}
/**
* Renders the Missing Controller web page.
*
* @param array $params Parameters (className)
*/
public function missingController($params) {
extract($params, EXTR_OVERWRITE);
$controllerName = str_replace('Controller', '', $className);
$this->stderr(sprintf(__("Missing Controller '%s'"), $controllerName));
$this->_stop();
}
/**
* Renders the Missing Action web page.
*
* @param array $params Parameters (action, className)
*/
public function missingAction($params) {
extract($params, EXTR_OVERWRITE);
$this->stderr(sprintf(__("Missing Method '%s' in '%s'"), $action, $className));
$this->_stop();
}
/**
* Renders the Private Action web page.
*
* @param array $params Parameters (action, className)
*/
public function privateAction($params) {
extract($params, EXTR_OVERWRITE);
$this->stderr(sprintf(__("Trying to access private method '%s' in '%s'"), $action, $className));
$this->_stop();
}
/**
* Renders the Missing Table web page.
*
* @param array $params Parameters (table, className)
*/
public function missingTable($params) {
extract($params, EXTR_OVERWRITE);
$this->stderr(sprintf(__("Missing database table '%s' for model '%s'"), $table, $className));
$this->_stop();
}
/**
* Renders the Missing Database web page.
*
* @param array $params Parameters
*/
public function missingDatabase($params = array()) {
$this->stderr(__('Missing Database'));
$this->_stop();
}
/**
* Renders the Missing View web page.
*
* @param array $params Parameters (file, action, className)
*/
public function missingView($params) {
extract($params, EXTR_OVERWRITE);
$this->stderr(sprintf(__("Missing View '%s' for '%s' in '%s'"), $file, $action, $className));
$this->_stop();
}
/**
* Renders the Missing Layout web page.
*
* @param array $params Parameters (file)
*/
public function missingLayout($params) {
extract($params, EXTR_OVERWRITE);
$this->stderr(sprintf(__("Missing Layout '%s'"), $file));
$this->_stop();
}
/**
* Renders the Database Connection web page.
*
* @param array $params Parameters
*/
public function missingConnection($params) {
extract($params, EXTR_OVERWRITE);
$this->stderr(__("Missing Database Connection. Try 'cake bake'"));
$this->_stop();
}
/**
* Renders the Missing Helper file web page.
*
* @param array $params Parameters (file, helper)
*/
public function missingHelperFile($params) {
extract($params, EXTR_OVERWRITE);
$this->stderr(sprintf(__("Missing Helper file '%s' for '%s'"), $file, Inflector::camelize($helper)));
$this->_stop();
}
/**
* Renders the Missing Helper class web page.
*
* @param array $params Parameters (file, helper)
*/
public function missingHelperClass($params) {
extract($params, EXTR_OVERWRITE);
$this->stderr(sprintf(__("Missing Helper class '%s' in '%s'"), Inflector::camelize($helper), $file));
$this->_stop();
}
/**
* Renders the Missing Component file web page.
*
* @param array $params Parameters (file, component)
*/
public function missingComponentFile($params) {
extract($params, EXTR_OVERWRITE);
$this->stderr(sprintf(__("Missing Component file '%s' for '%s'"), $file, Inflector::camelize($component)));
$this->_stop();
}
/**
* Renders the Missing Component class web page.
*
* @param array $params Parameters (file, component)
*/
public function missingComponentClass($params) {
extract($params, EXTR_OVERWRITE);
$this->stderr(sprintf(__("Missing Component class '%s' in '%s'"), Inflector::camelize($component), $file));
$this->_stop();
}
/**
* Renders the Missing Model class web page.
*
* @param array $params Parameters (className)
*/
public function missingModel($params) {
extract($params, EXTR_OVERWRITE);
$this->stderr(sprintf(__("Missing model '%s'"), $className));
$this->_stop();
}
/**
* Outputs to the stdout filehandle.
*
* @param string $string String to output.
* @param boolean $newline If true, the outputs gets an added newline.
*/
public function stdout($string, $newline = true) {
if ($newline) {
fwrite($this->stdout, $string . "\n");
} else {
fwrite($this->stdout, $string);
}
}
/**
* Outputs to the stderr filehandle.
*
* @param string $string Error text to output.
*/
public function stderr($string) {
fwrite($this->stderr, "Error: ". $string . "\n");
}
}

View file

@ -91,7 +91,8 @@ class AclShell extends Shell {
require_once (CONFIGS.'database.php');
if (!in_array($this->command, array('initdb'))) {
$this->Acl =& new AclComponent();
$collection = new ComponentCollection();
$this->Acl =& new AclComponent($collection);
$controller = null;
$this->Acl->startup($controller);
}

View file

@ -85,9 +85,3 @@ class TaskCollection extends ObjectCollection {
}
}
/**
* Exceptions used by the TaskCollection.
*/
class MissingTaskFileException extends RuntimeException { }
class MissingTaskClassException extends RuntimeException { }

View file

@ -272,8 +272,9 @@ class ControllerTask extends BakeTask {
*/
public function bakeActions($controllerName, $admin = null, $wannaUseSession = true) {
$currentModelName = $modelImport = $this->_modelName($controllerName);
if ($this->plugin) {
$modelImport = $this->plugin . '.' . $modelImport;
$plugin = $this->plugin;
if ($plugin) {
$modelImport = $plugin . '.' . $modelImport;
}
if (!App::import('Model', $modelImport)) {
$this->err(__('You must have a model for this class to build basic methods. Please try again.'));
@ -287,7 +288,7 @@ class ControllerTask extends BakeTask {
$singularHumanName = $this->_singularHumanName($controllerName);
$pluralHumanName = $this->_pluralName($controllerName);
$this->Template->set(compact('admin', 'controllerPath', 'pluralName', 'singularName', 'singularHumanName',
$this->Template->set(compact('plugin', 'admin', 'controllerPath', 'pluralName', 'singularName', 'singularHumanName',
'pluralHumanName', 'modelObj', 'wannaUseSession', 'currentModelName'));
$actions = $this->Template->generate('actions', 'controller_actions');
return $actions;

View file

@ -362,6 +362,9 @@ class ViewTask extends BakeTask {
if ($content === true) {
$content = $this->getContent($action);
}
if (empty($content)) {
return false;
}
$path = $this->getPath();
$filename = $path . $this->controllerPath . DS . Inflector::underscore($action) . '.ctp';
return $this->createFile($filename, $content);

View file

@ -79,7 +79,7 @@ ul, li {
}
#header h1 {
line-height:20px;
background: #003d4c url('../img/cake.icon.gif') no-repeat left;
background: #003d4c url('../img/cake.icon.png') no-repeat left;
color: #fff;
padding: 0px 30px;
}

View file

@ -78,10 +78,9 @@ class Dispatcher {
public $request = null;
/**
* The response object
* Response object used for asset/cached responses.
*
* @var CakeResponse
* @access public
*/
public $response = null;
@ -109,6 +108,8 @@ class Dispatcher {
* It will be used to create the request object.
* @param array $additionalParams Settings array ("bare", "return") which is melded with the GET and POST params
* @return boolean Success
* @throws MissingControllerException, MissingActionException, PrivateActionException if any of those error states
* are encountered.
*/
public function dispatch($url = null, $additionalParams = array()) {
if (is_array($url)) {
@ -133,12 +134,9 @@ class Dispatcher {
if (!is_object($controller)) {
Router::setRequestInfo($request);
return $this->cakeError('missingController', array(array(
'className' => Inflector::camelize($request->params['controller']) . 'Controller',
'webroot' => $request->webroot,
'url' => $url,
'base' => $request->base
)));
throw new MissingControllerException(array(
'controller' => Inflector::camelize($request->params['controller']) . 'Controller'
));
}
$privateAction = $request->params['action'][0] === '_';
$prefixes = Router::prefixes();
@ -155,13 +153,10 @@ class Dispatcher {
Router::setRequestInfo($request);
if ($privateAction) {
return $this->cakeError('privateAction', array(array(
'className' => Inflector::camelize($request->params['controller'] . "Controller"),
'action' => $request->params['action'],
'webroot' => $request->webroot,
'url' => $request->url,
'base' => $request->base
)));
throw new PrivateActionException(array(
'controller' => Inflector::camelize($request->params['controller']) . "Controller",
'action' => $request->params['action']
));
}
return $this->_invoke($controller, $request);
@ -189,27 +184,25 @@ class Dispatcher {
App::import('Controller', 'Scaffold', false);
return new Scaffold($controller, $request);
}
return $this->cakeError('missingAction', array(array(
'className' => Inflector::camelize($request->params['controller']."Controller"),
'action' => $request->params['action'],
'webroot' => $request->webroot,
'url' => $request->here,
'base' => $request->base
)));
throw new MissingActionException(array(
'controller' => Inflector::camelize($request->params['controller']) . "Controller",
'action' => $request->params['action']
));
}
$output =& call_user_func_array(array(&$controller, $request->params['action']), $request->params['pass']);
$result =& call_user_func_array(array(&$controller, $request->params['action']), $request->params['pass']);
$response = $controller->getResponse();
if ($controller->autoRender) {
$controller->render();
} elseif ($this->response->body() === null) {
$this->response->body($output);
} elseif ($response->body() === null) {
$response->body($result);
}
$controller->shutdownProcess();
if (isset($request->params['return'])) {
return $this->response->body();
return $response->body();
}
$this->response->send();
$response->send();
}
/**
@ -261,14 +254,9 @@ class Dispatcher {
if (!$ctrlClass) {
return $controller;
}
if (!$this->response) {
$this->response = new CakeResponse(array(
'charset' => Configure::read('App.encoding')
));
}
$ctrlClass .= 'Controller';
if (class_exists($ctrlClass)) {
$controller = new $ctrlClass($this->request, $this->response);
$controller = new $ctrlClass($this->request);
}
return $controller;
}
@ -322,11 +310,7 @@ class Dispatcher {
}
$controller = null;
$view = new View($controller);
$return = $view->renderCache($filename, microtime(true));
if (!$return) {
ClassRegistry::removeObject('view');
}
return $return;
return $view->renderCache($filename, microtime(true));
}
}
return false;

View file

@ -36,13 +36,6 @@ class Cache {
*/
protected static $_config = array();
/**
* Holds name of the current configuration name being used.
*
* @var array
*/
protected static $_name = 'default';
/**
* Whether to reset the settings with the next call to Cache::set();
*
@ -60,8 +53,7 @@ class Cache {
/**
* Set the cache configuration to use. config() can
* both create new configurations, return the settings for already configured
* configurations. It also sets the 'default' configuration to use for subsequent
* operations.
* configurations.
*
* To create a new configuration:
*
@ -82,10 +74,6 @@ class Cache {
$settings = $name;
}
if ($name === null || !is_string($name)) {
$name = self::$_name;
}
$current = array();
if (isset(self::$_config[$name])) {
$current = self::$_config[$name];
@ -100,12 +88,11 @@ class Cache {
}
$engine = self::$_config[$name]['engine'];
self::$_name = $name;
if (!isset(self::$_engines[$name])) {
self::_buildEngine($name);
$settings = self::$_config[$name] = self::settings($name);
} elseif ($settings = self::set(self::$_config[$name])) {
} elseif ($settings = self::set(self::$_config[$name], null, $name)) {
self::$_config[$name] = $settings;
}
return compact('engine', 'settings');
@ -185,18 +172,35 @@ class Cache {
}
/**
* Temporarily change settings to current config options. if no params are passed, resets settings if needed
* Cache::write() will reset the configuration changes made
* Temporarily change the settings on a cache config. The settings will persist for the next write
* operation (write, decrement, increment, clear). Any reads that are done before the write, will
* use the modified settings. If `$settings` is empty, the settings will be reset to the
* original configuration.
*
* Can be called with 2 or 3 parameters. To set multiple values at once.
*
* `Cache::set(array('duration' => '+30 minutes'), 'my_config');`
*
* Or to set one value.
*
* `Cache::set('duration', '+30 minutes', 'my_config');`
*
* To reset a config back to the originally configured values.
*
* `Cache::set(null, 'my_config');`
*
* @param mixed $settings Optional string for simple name-value pair or array
* @param string $value Optional for a simple name-value pair
* @param string $config The configuration name you are changing. Defaults to 'default'
* @return array Array of settings.
*/
public static function set($settings = array(), $value = null) {
if (!isset(self::$_config[self::$_name]) || !isset(self::$_engines[self::$_name])) {
public static function set($settings = array(), $value = null, $config = 'default') {
if (is_array($settings) && $value !== null) {
$config = $value;
}
if (!isset(self::$_config[$config]) || !isset(self::$_engines[$config])) {
return false;
}
$name = self::$_name;
if (!empty($settings)) {
self::$_reset = true;
}
@ -204,19 +208,19 @@ class Cache {
if (self::$_reset === true) {
if (empty($settings)) {
self::$_reset = false;
$settings = self::$_config[$name];
$settings = self::$_config[$config];
} else {
if (is_string($settings) && $value !== null) {
$settings = array($settings => $value);
}
$settings = array_merge(self::$_config[$name], $settings);
$settings = array_merge(self::$_config[$config], $settings);
if (isset($settings['duration']) && !is_numeric($settings['duration'])) {
$settings['duration'] = strtotime($settings['duration']) - time();
}
}
self::$_engines[$name]->settings = $settings;
self::$_engines[$config]->settings = $settings;
}
return self::settings($name);
return self::settings($config);
}
/**
@ -224,10 +228,11 @@ class Cache {
*
* Permanently remove all expired and deleted data
*
* @param string $config The config name you wish to have garbage collected. Defaults to 'default'
* @return void
*/
public static function gc() {
self::$_engines[self::$_name]->gc();
public static function gc($config = 'default') {
self::$_engines[$config]->gc();
}
/**
@ -247,13 +252,10 @@ class Cache {
*
* @param string $key Identifier for the data
* @param mixed $value Data to be cached - anything except a resource
* @param string $config Optional string configuration name to write to.
* @param string $config Optional string configuration name to write to. Defaults to 'default'
* @return boolean True if the data was successfully cached, false on failure
*/
public static function write($key, $value, $config = null) {
if (!$config) {
$config = self::$_name;
}
public static function write($key, $value, $config = 'default') {
$settings = self::settings($config);
if (empty($settings)) {
@ -269,7 +271,7 @@ class Cache {
}
$success = self::$_engines[$config]->write($settings['prefix'] . $key, $value, $settings['duration']);
self::set();
self::set(null, $config);
if ($success === false && $value !== '') {
trigger_error(
sprintf(__("%s cache was unable to write '%s' to cache", true), $config, $key),
@ -295,13 +297,10 @@ class Cache {
* `Cache::read('my_data', 'long_term');`
*
* @param string $key Identifier for the data
* @param string $config optional name of the configuration to use.
* @param string $config optional name of the configuration to use. Defaults to 'default'
* @return mixed The cached data, or false if the data doesn't exist, has expired, or if there was an error fetching it
*/
public static function read($key, $config = null) {
if (!$config) {
$config = self::$_name;
}
public static function read($key, $config = 'default') {
$settings = self::settings($config);
if (empty($settings)) {
@ -314,12 +313,7 @@ class Cache {
if (!$key) {
return false;
}
$success = self::$_engines[$config]->read($settings['prefix'] . $key);
if ($config !== null && $config !== self::$_name) {
self::set();
}
return $success;
return self::$_engines[$config]->read($settings['prefix'] . $key);
}
/**
@ -327,15 +321,11 @@ class Cache {
*
* @param string $key Identifier for the data
* @param integer $offset How much to add
* @param string $config Optional string configuration name. If not specified the current
* default config will be used.
* @param string $config Optional string configuration name. Defaults to 'default'
* @return mixed new value, or false if the data doesn't exist, is not integer,
* or if there was an error fetching it.
*/
public static function increment($key, $offset = 1, $config = null) {
if (!$config) {
$config = self::$_name;
}
public static function increment($key, $offset = 1, $config = 'default') {
$settings = self::settings($config);
if (empty($settings)) {
@ -350,7 +340,7 @@ class Cache {
return false;
}
$success = self::$_engines[$config]->increment($settings['prefix'] . $key, $offset);
self::set();
self::set(null, $config);
return $success;
}
/**
@ -358,15 +348,11 @@ class Cache {
*
* @param string $key Identifier for the data
* @param integer $offset How much to substract
* @param string $config Optional string configuration name, if not specified the current
* default config will be used.
* @param string $config Optional string configuration name. Defaults to 'default'
* @return mixed new value, or false if the data doesn't exist, is not integer,
* or if there was an error fetching it
*/
public static function decrement($key, $offset = 1, $config = null) {
if (!$config) {
$config = self::$_name;
}
public static function decrement($key, $offset = 1, $config = 'default') {
$settings = self::settings($config);
if (empty($settings)) {
@ -381,13 +367,11 @@ class Cache {
return false;
}
$success = self::$_engines[$config]->decrement($settings['prefix'] . $key, $offset);
self::set();
self::set(null, $config);
return $success;
}
/**
* Delete a key from the cache. Will automatically use the currently
* active cache configuration. To set the currently active configuration use
* Cache::config()
* Delete a key from the cache.
*
* ### Usage:
*
@ -400,13 +384,10 @@ class Cache {
* `Cache::delete('my_data', 'long_term');`
*
* @param string $key Identifier for the data
* @param string $config name of the configuration to use
* @param string $config name of the configuration to use. Defaults to 'default'
* @return boolean True if the value was succesfully deleted, false if it didn't exist or couldn't be removed
*/
public static function delete($key, $config = null) {
if (!$config) {
$config = self::$_name;
}
public static function delete($key, $config = 'default') {
$settings = self::settings($config);
if (empty($settings)) {
@ -421,7 +402,7 @@ class Cache {
}
$success = self::$_engines[$config]->delete($settings['prefix'] . $key);
self::set();
self::set(null, $config);
return $success;
}
@ -429,59 +410,42 @@ class Cache {
* Delete all keys from the cache.
*
* @param boolean $check if true will check expiration, otherwise delete all
* @param string $config name of the configuration to use
* @param string $config name of the configuration to use. Defaults to 'default'
* @return boolean True if the cache was succesfully cleared, false otherwise
*/
public static function clear($check = false, $config = null) {
if (!$config) {
$config = self::$_name;
}
$settings = self::settings($config);
if (empty($settings)) {
return null;
}
public static function clear($check = false, $config = 'default') {
if (!self::isInitialized($config)) {
return false;
}
$success = self::$_engines[$config]->clear($check);
self::set();
self::set(null, $config);
return $success;
}
/**
* Check if Cache has initialized a working config for the given name.
*
* @param string $engine Name of the engine
* @param string $engine Name of the engine, Defaults to default
* @param string $config Name of the configuration setting
* @return bool Whether or not the config name has been initialized.
*/
public static function isInitialized($name = null) {
public static function isInitialized($name = 'default') {
if (Configure::read('Cache.disable')) {
return false;
}
if (!$name && isset(self::$_config[self::$_name])) {
$name = self::$_name;
}
return isset(self::$_engines[$name]);
}
/**
* Return the settings for current cache engine. If no name is supplied the settings
* for the 'active default' configuration will be returned. To set the 'active default'
* configuration use `Cache::config()`
* Return the settings for the named cache engine.
*
* @param string $engine Name of the configuration to get settings for.
* @param string $engine Name of the configuration to get settings for. Defaults to 'default'
* @return array list of settings for this engine
* @see Cache::config()
* @access public
* @static
*/
public static function settings($name = null) {
if (!$name && isset(self::$_config[self::$_name])) {
$name = self::$_name;
}
public static function settings($name = 'default') {
if (!empty(self::$_engines[$name])) {
return self::$_engines[$name]->settings();
}

View file

@ -106,7 +106,7 @@ class ApcEngine extends CacheEngine {
}
/**
* Delete all keys from the cache
* Delete all keys from the cache. This will clear every cache config using APC.
*
* @return boolean True if the cache was succesfully cleared, false otherwise
*/

View file

@ -107,7 +107,7 @@ class MemcacheEngine extends CacheEngine {
* @return boolean True if the data was succesfully cached, false on failure
* @see http://php.net/manual/en/memcache.set.php
*/
public function write($key, &$value, $duration) {
public function write($key, $value, $duration) {
return $this->__Memcache->set($key, $value, $this->settings['compress'], $duration);
}

View file

@ -1,11 +1,6 @@
<?php
/**
* A class that helps wrap Request information and particulars about a single request.
* Provides methods commonly used to introspect on the request headers and request body.
*
* Has both an Array and Object interface. You can access framework parameters using indexes
*
* `$request['controller']` or `$request->controller`.
* CakeRequest
*
* PHP 5
*
@ -24,6 +19,15 @@
*/
App::import('Core', 'Set');
/**
* A class that helps wrap Request information and particulars about a single request.
* Provides methods commonly used to introspect on the request headers and request body.
*
* Has both an Array and Object interface. You can access framework parameters using indexes:
*
* `$request['controller']` or `$request->controller`.
*
*/
class CakeRequest implements ArrayAccess {
/**
* Array of parameters parsed from the url.
@ -105,7 +109,7 @@ class CakeRequest implements ArrayAccess {
/**
* Constructor
*
* @param string $url Url string to use
* @param string $url Trimmed url string to use. Should not contain the application base path.
* @param boolean $parseEnvironment Set to false to not auto parse the environment. ie. GET, POST and FILES.
* @return void
*/
@ -355,7 +359,7 @@ class CakeRequest implements ArrayAccess {
*
* @param boolean $safe Use safe = false when you think the user might manipulate their HTTP_CLIENT_IP
* header. Setting $safe = false will will also look at HTTP_X_FORWARDED_FOR
* @return void
* @return string The client IP.
*/
public function clientIp($safe = true) {
if (!$safe && env('HTTP_X_FORWARDED_FOR') != null) {
@ -428,6 +432,8 @@ class CakeRequest implements ArrayAccess {
/**
* Magic get method allows access to parsed routing parameters directly on the object.
*
* Allows access to `$this->params['controller']` via `$this->controller`
*
* @param string $name The property being accessed.
* @return mixed Either the value of the parameter or null.
*/
@ -441,7 +447,7 @@ class CakeRequest implements ArrayAccess {
/**
* Check whether or not a Request is a certain type. Uses the built in detection rules
* as well as additional rules defined with CakeRequest::addDetector(). Any detector can be called
* with `is($type)` or `is$Type()`.
* as `is($type)` or `is$Type()`.
*
* @param string $type The type of request you want to check.
* @return boolean Whether or not the request is the type you are checking.
@ -513,7 +519,7 @@ class CakeRequest implements ArrayAccess {
}
/**
* Add parameters to the request's parsed parameter set.
* Add parameters to the request's parsed parameter set. This will overwrite any existing parameters
*
* @param array $params Array of parameters to merge in
* @return The current object, you can chain this method.
@ -524,7 +530,7 @@ class CakeRequest implements ArrayAccess {
}
/**
* Add paths to the requests' paths vars
* Add paths to the requests' paths vars. This will overwrite any existing paths.
*
* @param array $paths Array of paths to merge in
* @return the current object, you can chain this method.
@ -552,10 +558,59 @@ class CakeRequest implements ArrayAccess {
return false;
}
/**
* Get the HTTP method used for this request.
*
* @return string The name of the HTTP method used.
*/
public function method() {
return env('REQUEST_METHOD');
}
/**
* Get the host that the request was handled on.
*
* @return void
*/
public function host() {
return env('HTTP_HOST');
}
/**
* Get the domain name and include $tldLength segments of the tld.
*
* @param int $tldLength Number of segments your tld contains
* @return string Domain name without subdomains.
*/
function domain($tldLength = 1) {
$segments = explode('.', $this->host());
$domain = array_slice($segments, -1 * ($tldLength + 1));
return implode('.', $domain);
}
/**
* Get the subdomains for a host.
*
* @param int $tldLength Number of segments your tld contains.
* @return array of subdomains.
*/
function subdomains($tldLength = 1) {
$segments = explode('.', $this->host());
return array_slice($segments, 0, -1 * ($tldLength + 1));
}
/**
* Find out which content types the client accepts or check if they accept a
* particular type of content.
*
* #### Get all types:
*
* `$request->accepts();`
*
* #### Check for a single type:
*
* `$request->accepts('json');`
*
* @param string $type The content type to check for. Leave null to get all types a client accepts.
* @return mixed Either an array of all the types the client accepts or a boolean if they accept the
* provided type.
@ -574,6 +629,36 @@ class CakeRequest implements ArrayAccess {
return in_array($type, $acceptTypes);
}
/**
* Provides a read/write accessor for `$this->data`. Allows you
* to use a syntax similar to `CakeSession` for reading post data.
*
* ## Reading values.
*
* `$request->data('Post.title');`
*
* When reading values you will get `null` for keys/values that do not exist.
*
* ## Writing values
*
* `$request->data('Post.title', 'New post!');`
*
* You can write to any value, even paths/keys that do not exist, and the arrays
* will be created for you.
*
* @param string $name Dot separated name of the value to read/write
* @param mixed $value Value to write to the data array.
* @return mixed Either the value being read, or this so you can chain consecutive writes.
*/
public function data($name) {
$args = func_get_args();
if (count($args) == 2) {
$this->data = Set::insert($this->data, $name, $args[1]);
return $this;
}
return Set::classicExtract($this->data, $name);
}
/**
* Array access read implementation
*

View file

@ -1,7 +1,9 @@
<?php
/**
* A class reposible for managing the response text, status and headers of a HTTP response
* CakeResponse is responsible for managing the response text, status and headers of a HTTP response.
*
* By default controllers will use this class to render their response. If you are going to use
* a custom response class it should subclass this object in order to ensure compatibility.
*
* PHP 5
*
@ -18,14 +20,13 @@
* @since CakePHP(tm) v 2.0
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
class CakeResponse {
/**
* Holds HTTP response statuses
*
* @var array
*/
* Holds HTTP response statuses
*
* @var array
*/
protected $_statusCodes = array(
100 => 'Continue',
101 => 'Switching Protocols',
@ -69,10 +70,10 @@ class CakeResponse {
);
/**
* Holds known mime type mappings
*
* @var array
*/
* Holds known mime type mappings
*
* @var array
*/
protected $_mimeTypes = array(
'ai' => 'application/postscript',
'bcpio' => 'application/x-bcpio',
@ -262,58 +263,58 @@ class CakeResponse {
);
/**
* Protocol header to send to the client
*
* @var string
*/
* Protocol header to send to the client
*
* @var string
*/
protected $_protocol = 'HTTP/1.1';
/**
* Status code to send to the client
*
* @var integer
*/
* Status code to send to the client
*
* @var integer
*/
protected $_status = 200;
/**
* Content type to send. This can be an 'extension' that will be transformed using the $_mimetypes array
* or a complete mime-type
*
* @var integer
*/
* Content type to send. This can be an 'extension' that will be transformed using the $_mimetypes array
* or a complete mime-type
*
* @var integer
*/
protected $_contentType = 'text/html';
/**
* Buffer list of headers
*
* @var array
*/
* Buffer list of headers
*
* @var array
*/
protected $_headers = array();
/**
* Buffer string for response message
*
* @var string
*/
* Buffer string for response message
*
* @var string
*/
protected $_body = null;
/**
* The charset the response body is encoded with
*
* @var string
*/
* The charset the response body is encoded with
*
* @var string
*/
protected $_charset = 'UTF-8';
/**
* Class constructor
*
* @param array $options list of parameters to setup the response. Possible values are:
* - body: the rensonse text that should be sent to the client
* - status: the HTTP status code to respond with
* - type: a complete mime-type string or an extension mapepd in this class
* - charset: the charset for the response body
* @return void
*/
* Class constructor
*
* @param array $options list of parameters to setup the response. Possible values are:
* - body: the rensonse text that should be sent to the client
* - status: the HTTP status code to respond with
* - type: a complete mime-type string or an extension mapepd in this class
* - charset: the charset for the response body
* @return void
*/
public function __construct(array $options = array()) {
if (isset($options['body'])) {
$this->body($options['body']);
@ -330,9 +331,11 @@ class CakeResponse {
}
/**
* Sends the complete response to the client including headers and message body
*
*/
* Sends the complete response to the client including headers and message body.
* Will echo out the content in the response body.
*
* @return void
*/
public function send() {
if (isset($this->_headers['Location']) && $this->_status === 200) {
$this->statusCode(302);
@ -349,11 +352,12 @@ class CakeResponse {
}
/**
* Sends a header to the client
*
* @param $name the header name
* @param $value the header value
*/
* Sends a header to the client.
*
* @param $name the header name
* @param $value the header value
* @return void
*/
protected function _sendHeader($name, $value = null) {
if (is_null($value)) {
header($name);
@ -363,41 +367,42 @@ class CakeResponse {
}
/**
* Sends a content string to the client
*
* @param $content string to send as response body
*/
* Sends a content string to the client.
*
* @param $content string to send as response body
* @return void
*/
protected function _sendContent($content) {
echo $content;
}
/**
* Buffers a header string to be sent
* Returns the complete list of buffered headers
*
* ### Single header
* e.g `header('Location', 'http://example.com');`
*
* ### Multiple headers
* e.g `header(array('Location' => 'http://example.com', 'X-Extra' => 'My header'));`
*
* ### String header
* e.g `header('WWW-Authenticate: Negotiate');`
*
* ### Array of string headers
* e.g `header(array('WWW-Authenticate: Negotiate'), array('Content-type: application/pdf'));`
*
* Multiple calls for setting the same header name will have the same effect as setting the header once
* with the last value sent for it
* e.g `header('WWW-Authenticate: Negotiate'); header('WWW-Authenticate: Not-Negotiate');`
* will have the same effect as only doing `header('WWW-Authenticate: Not-Negotiate');`
*
* @param mixed $header. An array of header strings or a single header string
* - an assotiative array of "header name" => "header value" is also accepted
* - an array of string headers is also accepted
* @param mixed $value. The header value.
* @return array list of headers to be sent
*/
* Buffers a header string to be sent
* Returns the complete list of buffered headers
*
* ### Single header
* e.g `header('Location', 'http://example.com');`
*
* ### Multiple headers
* e.g `header(array('Location' => 'http://example.com', 'X-Extra' => 'My header'));`
*
* ### String header
* e.g `header('WWW-Authenticate: Negotiate');`
*
* ### Array of string headers
* e.g `header(array('WWW-Authenticate: Negotiate'), array('Content-type: application/pdf'));`
*
* Multiple calls for setting the same header name will have the same effect as setting the header once
* with the last value sent for it
* e.g `header('WWW-Authenticate: Negotiate'); header('WWW-Authenticate: Not-Negotiate');`
* will have the same effect as only doing `header('WWW-Authenticate: Not-Negotiate');`
*
* @param mixed $header. An array of header strings or a single header string
* - an assotiative array of "header name" => "header value" is also accepted
* - an array of string headers is also accepted
* @param mixed $value. The header value.
* @return array list of headers to be sent
*/
public function header($header = null, $value = null) {
if (is_null($header)) {
return $this->_headers;
@ -424,12 +429,12 @@ class CakeResponse {
}
/**
* Buffers the response message to be sent
* if $content is null the current buffer is returned
*
* @param string $content the string message to be sent
* @return string current message buffer if $content param is passed as null
*/
* Buffers the response message to be sent
* if $content is null the current buffer is returned
*
* @param string $content the string message to be sent
* @return string current message buffer if $content param is passed as null
*/
public function body($content = null) {
if (is_null($content)) {
return $this->_body;
@ -438,12 +443,12 @@ class CakeResponse {
}
/**
* Sets the HTTP status code to be sent
* if $code is null the current code is returned
*
* @param integer $code
* @return integer current status code
*/
* Sets the HTTP status code to be sent
* if $code is null the current code is returned
*
* @param integer $code
* @return integer current status code
*/
public function statusCode($code = null) {
if (is_null($code)) {
return $this->_status;
@ -489,26 +494,26 @@ class CakeResponse {
}
/**
* Sets the response content type. It can be either a file extension
* which will be mapped internally to a mime-type or a string representing a mime-type
* if $contentType is null the current content type is returned
* if $contentType is an associative array, it will be stored as a content type definition
*
* ### Setting the content type
* e.g `type('jpg');`
*
* ### Returning the current content type
* e.g `type();`
*
* ### Storing a content type definition
* e.g `type(array('keynote' => 'application/keynote'));`
*
* ### Replacing a content type definition
* e.g `type(array('jpg' => 'text/plain'));`
*
* @param string $contentType
* @return mixed current content type or false if supplied an invalid content type
*/
* Sets the response content type. It can be either a file extension
* which will be mapped internally to a mime-type or a string representing a mime-type
* if $contentType is null the current content type is returned
* if $contentType is an associative array, it will be stored as a content type definition
*
* ### Setting the content type
* e.g `type('jpg');`
*
* ### Returning the current content type
* e.g `type();`
*
* ### Storing a content type definition
* e.g `type(array('keynote' => 'application/keynote'));`
*
* ### Replacing a content type definition
* e.g `type(array('jpg' => 'text/plain'));`
*
* @param string $contentType
* @return mixed current content type or false if supplied an invalid content type
*/
public function type($contentType = null) {
if (is_null($contentType)) {
return $this->_contentType;
@ -570,12 +575,12 @@ class CakeResponse {
}
/**
* Sets the response charset
* if $charset is null the current charset is returned
*
* @param string $charset
* @return string current charset
*/
* Sets the response charset
* if $charset is null the current charset is returned
*
* @param string $charset
* @return string current charset
*/
public function charset($charset = null) {
if (is_null($charset)) {
return $this->_charset;
@ -584,10 +589,10 @@ class CakeResponse {
}
/**
* Sets the correct headers to instruct the client to not cache te response
*
* @return void
*/
* Sets the correct headers to instruct the client to not cache the response
*
* @return void
*/
public function disableCache() {
$this->header(array(
'Expires' => 'Mon, 26 Jul 1997 05:00:00 GMT',
@ -598,12 +603,12 @@ class CakeResponse {
}
/**
* Sets the correct headers to instruct the client to cache the response
*
* @param string $since a valid time since the response text has not been modified
* @param string $time a valid time for cache expiry
* @return void
*/
* Sets the correct headers to instruct the client to cache the response.
*
* @param string $since a valid time since the response text has not been modified
* @param string $time a valid time for cache expiry
* @return void
*/
public function cache($since, $time = '+1 day') {
if (!is_integer($time)) {
$time = strtotime($time);
@ -617,10 +622,10 @@ class CakeResponse {
}
/**
* Sets the correct output buffering handler to send a compressed response
*
* @return boolean false if client does not accept compressed responses or no handler is available, true otherwise
*/
* Sets the correct output buffering handler to send a compressed response
*
* @return boolean false if client does not accept compressed responses or no handler is available, true otherwise
*/
public function compress() {
$compressionEnabled = ini_get("zlib.output_compression") !== '1' &&
extension_loaded("zlib") &&
@ -629,11 +634,11 @@ class CakeResponse {
}
/**
* Sets the correct headers to instruct the browser to dowload the response as a file
*
* @param string $filename the name of the file as the browser will download the response
* @return void
*/
* Sets the correct headers to instruct the browser to dowload the response as a file
*
* @param string $filename the name of the file as the browser will download the response
* @return void
*/
public function download($filename) {
$this->header('Content-Disposition', 'attachment; filename="' . $filename . '"');
}

View file

@ -149,7 +149,6 @@ class CakeSession {
self::$_userAgent = md5(env('HTTP_USER_AGENT') . Configure::read('Security.salt'));
}
self::_setupDatabase();
if ($start === true) {
self::_setPath($base);
self::_setHost(env('HTTP_HOST'));
@ -192,37 +191,6 @@ class CakeSession {
}
}
/**
* Setup database configuration for Session, if enabled.
*
* @return void
*/
protected function _setupDatabase() {
if (Configure::read('Session.defaults') !== 'database') {
return;
}
$modelName = Configure::read('Session.handler.model');
$database = Configure::read('Session.handler.database');
$table = Configure::read('Session.handler.table');
if (empty($database)) {
$database = 'default';
}
$settings = array(
'class' => 'Session',
'alias' => 'Session',
'table' => 'cake_sessions',
'ds' => $database
);
if (!empty($modelName)) {
$settings['class'] = $modelName;
}
if (!empty($table)) {
$settings['table'] = $table;
}
ClassRegistry::init($settings);
}
/**
* Starts the Session.
*
@ -559,14 +527,14 @@ class CakeSession {
call_user_func_array('session_set_save_handler', $sessionConfig['handler']);
}
if (!empty($sessionConfig['handler']['engine'])) {
$class = self::_getHandler($sessionConfig['handler']['engine']);
$handler = self::_getHandler($sessionConfig['handler']['engine']);
session_set_save_handler(
array($class, 'open'),
array($class, 'close'),
array($class, 'read'),
array($class, 'write'),
array($class, 'destroy'),
array($class, 'gc')
array($handler, 'open'),
array($handler, 'close'),
array($handler, 'read'),
array($handler, 'write'),
array($handler, 'destroy'),
array($handler, 'gc')
);
}
Configure::write('Session', $sessionConfig);
@ -587,11 +555,11 @@ class CakeSession {
if (!class_exists($class)) {
throw new Exception(sprintf(__('Could not load %s to handle the session.'), $class));
}
$reflect = new ReflectionClass($class);
if (!$reflect->implementsInterface('CakeSessionHandlerInterface')) {
throw new Exception(__('Chosen SessionHandler does not implement CakeSessionHandlerInterface it cannot be used with an engine key.'));
$handler = new $class();
if ($handler instanceof CakeSessionHandlerInterface) {
return $handler;
}
return $class;
throw new Exception(__('Chosen SessionHandler does not implement CakeSessionHandlerInterface it cannot be used with an engine key.'));
}
/**
@ -768,14 +736,14 @@ interface CakeSessionHandlerInterface {
*
* @return boolean Success
*/
public static function open();
public function open();
/**
* Method called on close of a session.
*
* @return boolean Success
*/
public static function close();
public function close();
/**
* Method used to read from a session.
@ -783,7 +751,7 @@ interface CakeSessionHandlerInterface {
* @param mixed $id The key of the value to read
* @return mixed The value of the key or false if it does not exist
*/
public static function read($id);
public function read($id);
/**
* Helper function called on write for sessions.
@ -792,7 +760,7 @@ interface CakeSessionHandlerInterface {
* @param mixed $data The value of the data to be saved.
* @return boolean True for successful write, false otherwise.
*/
public static function write($id, $data);
public function write($id, $data);
/**
* Method called on the destruction of a session.
@ -800,7 +768,7 @@ interface CakeSessionHandlerInterface {
* @param integer $id ID that uniquely identifies session in database
* @return boolean True for successful delete, false otherwise.
*/
public static function destroy($id);
public function destroy($id);
/**
* Run the Garbage collection on the session storage. This method should vacuum all
@ -809,7 +777,7 @@ interface CakeSessionHandlerInterface {
* @param integer $expires Timestamp (defaults to current time)
* @return boolean Success
*/
public static function gc($expires = null);
public function gc($expires = null);
}

View file

@ -87,6 +87,7 @@ class Configure {
break;
case 3:
self::$_values[$names[0]][$names[1]][$names[2]] = $value;
break;
case 4:
$names = explode('.', $name, 2);
if (!isset(self::$_values[$names[0]])) {
@ -377,7 +378,6 @@ class Configure {
'serialize' => true, 'duration' => $duration
)));
}
Cache::config('default');
}
App::init();
App::build();
@ -780,7 +780,8 @@ class App {
}
/**
* Finds classes based on $name or specific file(s) to search.
* Finds classes based on $name or specific file(s) to search. Calling App::import() will
* not construct any classes contained in the files. It will only find and require() the file.
*
* @link http://book.cakephp.org/view/934/Using-App-import
* @param mixed $type The type of Class if passed as a string, or all params can be passed as
@ -1107,6 +1108,7 @@ class App {
return array('class' => $type, 'suffix' => $type, 'path' => $path);
break;
case 'component':
App::import('Core', 'Component', false);
if ($plugin) {
$path = $pluginPath . DS . 'controllers' . DS . 'components' . DS;
}
@ -1119,6 +1121,7 @@ class App {
return array('class' => null, 'suffix' => null, 'path' => $path);
break;
case 'view':
App::import('View', 'View', false);
if ($plugin) {
$path = $pluginPath . DS . 'views' . DS;
}
@ -1230,4 +1233,4 @@ class App {
Cache::write('object_map', self::$__objects, '_cake_core_');
}
}
}
}

View file

@ -0,0 +1,48 @@
<?php
/**
* Error Handling Controller
*
* Controller used by ErrorHandler to render error views.
*
* @package cake
* @subpackage cake.cake.libs
*/
class CakeErrorController extends AppController {
public $name = 'CakeError';
/**
* Uses Property
*
* @var array
*/
public $uses = array();
/**
* __construct
*
* @access public
* @return void
*/
function __construct() {
parent::__construct();
$this->_set(Router::getPaths());
$this->request = $this->params = Router::getRequest(false);
$this->constructClasses();
$this->Components->trigger('initialize', array(&$this));
$this->_set(array('cacheAction' => false, 'viewPath' => 'errors'));
}
/**
* Escapes the viewVars.
*
* @return void
*/
function beforeRender() {
parent::beforeRender();
foreach ($this->viewVars as $key => $value) {
if (!is_object($value)){
$this->viewVars[$key] = h($value);
}
}
}
}

View file

@ -23,6 +23,18 @@ App::import('Controller', 'ComponentCollection', false);
* controller logic that can be composed into a controller. Components also
* provide request life-cycle callbacks for injecting logic at specific points.
*
* ## Life cycle callbacks
*
* Components can provide several callbacks that are fired at various stages of the request
* cycle. The available callbacks are:
*
* - `initialize()` - Fired before the controller's beforeFilter method.
* - `startup()` - Fired after the controller's beforeFilter method.
* - `beforeRender()` - Fired before the view + layout are rendered.
* - `shutdown()` - Fired after the action is complete and the view has been rendered
* but before Controller::afterFilter().
* - `beforeRedirect()` - Fired before a redirect() is done.
*
* @package cake
* @subpackage cake.cake.libs.controller
* @link http://book.cakephp.org/view/993/Components

View file

@ -20,6 +20,13 @@ App::import('Core', 'ObjectCollection');
class ComponentCollection extends ObjectCollection {
/**
* The controller that this collection was initialized with.
*
* @var Controller
*/
protected $_Controller = null;
/**
* Initializes all the Components for a controller.
* Attaches a reference of each component to the Controller.
@ -31,12 +38,22 @@ class ComponentCollection extends ObjectCollection {
if (empty($Controller->components)) {
return;
}
$this->_Controller = $Controller;
$components = ComponentCollection::normalizeObjectArray($Controller->components);
foreach ($components as $name => $properties) {
$Controller->{$name} = $this->load($properties['class'], $properties['settings']);
}
}
/**
* Get the controller associated with the collection.
*
* @return Controller.
*/
public function getController() {
return $this->_Controller;
}
/**
* Loads/constructs a component. Will return the instance in the registry if it already exists.
*
@ -54,10 +71,16 @@ class ComponentCollection extends ObjectCollection {
$componentClass = $name . 'Component';
if (!class_exists($componentClass)) {
if (!App::import('Component', $component)) {
throw new MissingComponentFileException(Inflector::underscore($component) . '.php');
throw new MissingComponentFileException(array(
'file' => Inflector::underscore($component) . '.php',
'class' => $componentClass
));
}
if (!class_exists($componentClass)) {
throw new MissingComponentFileException($component);
throw new MissingComponentFileException(array(
'file' => Inflector::underscore($component) . '.php',
'class' => $componentClass
));
}
}
$this->_loaded[$name] = new $componentClass($this, $settings);
@ -67,10 +90,4 @@ class ComponentCollection extends ObjectCollection {
return $this->_loaded[$name];
}
}
/**
* Exceptions used by the ComponentCollection.
*/
class MissingComponentFileException extends RuntimeException { }
class MissingComponentClassException extends RuntimeException { }
}

View file

@ -160,10 +160,11 @@ class AclComponent extends Component {
* @param string $aco ACO The controlled object identifier.
* @param string $action Action (defaults to *)
* @return boolean Success
* @deprecated
*/
public function grant($aro, $aco, $action = "*") {
trigger_error(__('AclComponent::grant() is deprecated, use allow() instead'), E_USER_WARNING);
return $this->_Instance->grant($aro, $aco, $action);
return $this->_Instance->allow($aro, $aco, $action);
}
/**
@ -173,10 +174,11 @@ class AclComponent extends Component {
* @param string $aco ACO The controlled object identifier.
* @param string $action Action (defaults to *)
* @return boolean Success
* @deprecated
*/
public function revoke($aro, $aco, $action = "*") {
trigger_error(__('AclComponent::revoke() is deprecated, use deny() instead'), E_USER_WARNING);
return $this->_Instance->revoke($aro, $aco, $action);
return $this->_Instance->deny($aro, $aco, $action);
}
}

View file

@ -377,7 +377,7 @@ class AuthComponent extends Component {
return false;
} else {
if (!$this->user()) {
if (!$this->RequestHandler->isAjax()) {
if (!$request->is('ajax')) {
$this->Session->setFlash($this->authError, $this->flashElement, array(), 'auth');
if (!empty($request->query) && count($request->query) >= 2) {
$query = $request->query;

View file

@ -298,13 +298,23 @@ class EmailComponent extends Component {
*/
protected $_smtpConnection = null;
/**
* Constructor
*
* @param ComponentCollection $collection A ComponentCollection this component can use to lazy load its components
* @param array $settings Array of configuration settings.
*/
public function __construct(ComponentCollection $collection, $settings = array()) {
$this->Controller = $collection->getController();
parent::__construct($collection, $settings);
}
/**
* Initialize component
*
* @param object $controller Instantiating controller
*/
public function initialize(&$controller) {
$this->Controller = $controller;
if (Configure::read('App.encoding') !== null) {
$this->charset = Configure::read('App.encoding');
}
@ -738,19 +748,21 @@ class EmailComponent extends Component {
* @access private
*/
function _formatAddress($string, $smtp = false) {
if (strpos($string, '<') !== false) {
$value = explode('<', $string);
if ($smtp) {
$string = '<' . $value[1];
} else {
$string = $this->_encode($value[0]) . ' <' . $value[1];
}
$hasAlias = preg_match('/((.*)\s)?<(.+)>/', $string, $matches);
if ($smtp && $hasAlias) {
return $this->_strip(' <' . $matches[3] . '>');
} elseif ($smtp) {
return $this->_strip(' <' . $string . '>');
}
if ($hasAlias && !empty($matches[2])) {
return $this->_strip($matches[2] . ' <' . $matches[3] . '>');
}
return $this->_strip($string);
}
/**
* Remove certain elements (such as bcc:, to:, %0a) from given value
* Remove certain elements (such as bcc:, to:, %0a) from given value.
* Helps prevent header injection / mainipulation on user content.
*
* @param string $value Value to strip
* @param boolean $message Set to true to indicate main message content

View file

@ -392,10 +392,9 @@ class RequestHandlerComponent extends Component {
* types the client accepts. If a string is passed, returns true
* if the client accepts it. If an array is passed, returns true
* if the client accepts one or more elements in the array.
* @access public
* @see RequestHandlerComponent::setContent()
*/
function accepts($type = null) {
public function accepts($type = null) {
$accepted = $this->request->accepts();
if ($type == null) {
@ -455,10 +454,9 @@ class RequestHandlerComponent extends Component {
* 'html', 'xml', 'js', etc.
* @return mixed If $type is null or not provided, the first content-type in the
* list, based on preference, is returned.
* @access public
* @see RequestHandlerComponent::setContent()
*/
function prefers($type = null) {
public function prefers($type = null) {
$accepts = $this->accepts();
if ($type == null) {
@ -480,7 +478,6 @@ class RequestHandlerComponent extends Component {
return ($types[0] == $accepts[0]);
}
$intersect = array_values(array_intersect($accepts, $types));
if (empty($intersect)) {
return false;
@ -490,20 +487,31 @@ class RequestHandlerComponent extends Component {
/**
* Sets the layout and template paths for the content type defined by $type.
*
* ### Usage:
*
* Render the response as an 'ajax' response.
*
* `$this->RequestHandler->renderAs($this, 'ajax');`
*
* Render the response as an xml file and force the result as a file download.
*
* `$this->RequestHandler->renderAs($this, 'xml', array('attachment' => 'myfile.xml');`
*
* @param object $controller A reference to a controller object
* @param string $type Type of response to send (e.g: 'ajax')
* @param array $options Array of options to use
* @return void
* @access public
* @see RequestHandlerComponent::setContent()
* @see RequestHandlerComponent::respondAs()
*/
function renderAs(&$controller, $type) {
$options = array('charset' => 'UTF-8');
public function renderAs(&$controller, $type, $options = array()) {
$defaults = array('charset' => 'UTF-8');
if (Configure::read('App.encoding') !== null) {
$options = array('charset' => Configure::read('App.encoding'));
$defaults['charset'] = Configure::read('App.encoding');
}
$options = array_merge($defaults, $options);
if ($type == 'ajax') {
$controller->layout = $this->ajaxLayout;
@ -538,8 +546,8 @@ class RequestHandlerComponent extends Component {
}
/**
* Sets the response header based on type map index name. If DEBUG is greater than 2, the header
* is not set.
* Sets the response header based on type map index name. This wraps several methods
* available on CakeResponse. It also allows you to use Content-Type aliases.
*
* @param mixed $type Friendly type name, i.e. 'html' or 'xml', or a full content-type,
* like 'application/x-shockwave'.
@ -548,10 +556,9 @@ class RequestHandlerComponent extends Component {
* @return boolean Returns false if the friendly type name given in $type does
* not exist in the type map, or if the Content-type header has
* already been set by this method.
* @access public
* @see RequestHandlerComponent::setContent()
*/
function respondAs($type, $options = array()) {
public function respondAs($type, $options = array()) {
$defaults = array('index' => null, 'charset' => null, 'attachment' => false);
$options = $options + $defaults;
@ -604,6 +611,7 @@ class RequestHandlerComponent extends Component {
*
* @param mixed $cType Either a string content type to map, or an array of types.
* @return mixed Aliases for the types provided.
* @deprecated Use $this->response->mapType() in your controller instead.
*/
public function mapType($cType) {
return $this->response->mapType($cType);
@ -629,5 +637,4 @@ class RequestHandlerComponent extends Component {
}
return null;
}
}

View file

@ -176,17 +176,6 @@ class SecurityComponent extends Component {
*/
public $request;
/**
* Initialize the SecurityComponent
*
* @param object $controller Controller instance for the request
* @param array $settings Settings to set to the component
* @return void
*/
public function initialize(&$controller, $settings = array()) {
$this->_set($settings);
}
/**
* Component startup. All security checking happens here.
*

View file

@ -21,7 +21,9 @@
/**
* Include files
*/
App::import('Core', 'CakeResponse', false);
App::import('Controller', 'Component', false);
App::import('Core', 'CakeResponse', false);
App::import('View', 'View', false);
/**
@ -45,29 +47,6 @@ class Controller extends Object {
*/
public $name = null;
/**
* Stores the current URL, relative to the webroot of the application.
*
* @var string
* @deprecated Will be removed in future versions. Use $this->request->here instead
*/
public $here = null;
/**
* The webroot of the application.
*
* @var string
* @deprecated Will be removed in future versions. Use $this->request->webroot instead
*/
public $webroot = null;
/**
* The name of the currently requested controller action.
*
* @var string
*/
public $action = null;
/**
* An array containing the class names of models this controller uses.
*
@ -92,32 +71,29 @@ class Controller extends Object {
*/
public $helpers = array('Session', 'Html', 'Form');
/**
* Parameters received in the current request: GET and POST data, information
* about the request, etc.
*
* @var array
* @link http://book.cakephp.org/view/963/The-Parameters-Attribute-params
* @deprecated Will be removed in future versions. Use $this->request instead
*/
public $params = array();
/**
* Data POSTed to the controller using the HtmlHelper. Data here is accessible
* using the `$this->data['ModelName']['fieldName']` pattern.
*
* @var array
* @deprecated Will be removed in future versions. Use $this->request->data instead
*/
public $data = array();
/**
* An instance of a CakeRequest object that contains information about the current request.
* This object contains all the information about a request and several methods for reading
* additional information about the request.
*
* @var CakeRequest
*/
public $request;
/**
* An instance of a CakeResponse object that contains information about the impending response
*
* @var CakeResponse
*/
public $response;
/**
* The classname to use for creating the response object.
*
* @var string
*/
protected $_responseClass = 'CakeResponse';
/**
* Holds pagination defaults for controller actions. The keys that can be included
* in this array are: 'conditions', 'fields', 'order', 'limit', 'page', and 'recursive',
@ -166,14 +142,6 @@ class Controller extends Object {
*/
public $modelNames = array();
/**
* Base URL path.
*
* @var string
* @deprecated Will be removed in future versions. Use $this->request->base instead
*/
public $base = null;
/**
* The name of the layout file to render the view inside of. The name specified
* is the filename of the layout in /app/views/layouts without the .ctp
@ -329,9 +297,8 @@ class Controller extends Object {
*
* @param CakeRequest $request Request object for this controller can be null for testing.
* But expect that features that use the params will not work.
* @param CakeResponse $response Response object for this controller
*/
public function __construct($request = null, $response = null) {
public function __construct($request = null) {
if ($this->name === null) {
$r = null;
if (!preg_match('/(.*)Controller/i', get_class($this), $r)) {
@ -356,10 +323,51 @@ class Controller extends Object {
if ($request instanceof CakeRequest) {
$this->_setRequest($request);
}
$this->response = $response;
$this->getResponse();
parent::__construct();
}
/**
* Provides backwards compatbility access to the request object properties.
* Also provides the params alias.
*
* @return void
*/
public function __get($name) {
switch ($name) {
case 'base':
case 'here':
case 'webroot':
case 'data':
return $this->request->{$name};
case 'action':
return isset($this->request->params['action']) ? $this->request->params['action'] : '';
case 'params':
return $this->request;
}
return null;
}
/**
* Provides backwards compatiblity access for setting values to the request object.
*
* @return void
*/
public function __set($name, $value) {
switch ($name) {
case 'base':
case 'here':
case 'webroot':
case 'data':
return $this->request->{$name} = $value;
case 'action':
return $this->request->params['action'] = $value;
case 'params':
return $this->request->params = $value;
}
return $this->{$name} = $value;
}
/**
* Sets the request objects and configures a number of controller properties
* based on the contents of the request.
@ -368,20 +376,13 @@ class Controller extends Object {
* @return void
*/
protected function _setRequest(CakeRequest $request) {
$this->base = $request->base;
$this->here = $request->here;
$this->webroot = $request->webroot;
$this->request = $request;
$this->plugin = isset($request->params['plugin']) ? $request->params['plugin'] : null;
$this->params = $this->request = $request;
$this->action =& $request->params['action'];
if (isset($request->params['pass']) && isset($request->params['named'])) {
$this->passedArgs = array_merge($request->params['pass'], $request->params['named']);
}
$this->data = null;
if (!empty($request->params['data'])) {
$this->data =& $request->params['data'];
}
if (array_key_exists('return', $request->params) && $request->params['return'] == 1) {
$this->autoRender = false;
}
@ -476,9 +477,10 @@ class Controller extends Object {
* see Controller::loadModel(); for more info.
* Loads Components and prepares them for initialization.
*
* @return mixed true if models found and instance created, or cakeError if models not found.
* @return mixed true if models found and instance created.
* @see Controller::loadModel()
* @link http://book.cakephp.org/view/977/Controller-Methods#constructClasses-986
* @throws MissingModelException
*/
public function constructClasses() {
$this->__mergeVars();
@ -495,10 +497,7 @@ class Controller extends Object {
$this->loadModel($this->modelClass, $id);
} elseif ($this->uses) {
$uses = is_array($this->uses) ? $this->uses : array($this->uses);
$modelClassName = $uses[0];
if (strpos($uses[0], '.') !== false) {
list($plugin, $modelClassName) = explode('.', $uses[0]);
}
list($plugin, $modelClassName) = pluginSplit($uses[0]);
$this->modelClass = $modelClassName;
foreach ($uses as $modelClass) {
$this->loadModel($modelClass);
@ -508,6 +507,18 @@ class Controller extends Object {
return true;
}
/**
* Gets the response object for this controller. Will construct the response if it has not already been built.
*
* @return CakeResponse
*/
public function getResponse() {
if (empty($this->response)) {
$this->response = new $this->_responseClass(array('charset' => Configure::read('App.encoding')));
}
return $this->response;
}
/**
* Perform the startup process for this controller.
* Fire the Components and Controller callbacks in the correct order.
@ -571,6 +582,7 @@ class Controller extends Object {
* @param string $modelClass Name of model class to load
* @param mixed $id Initial ID the instanced model class should have
* @return mixed true when single model found and instance created, error returned if model not found.
* @throws MissingModelException if the model class cannot be found.
*/
public function loadModel($modelClass = null, $id = null) {
if ($modelClass === null) {
@ -592,9 +604,7 @@ class Controller extends Object {
));
if (!$this->{$modelClass}) {
return $this->cakeError('missingModel', array(array(
'className' => $modelClass, 'webroot' => '', 'base' => $this->base
)));
throw new MissingModelException($modelClass);
}
if ($this->persistModel === true) {
@ -723,7 +733,7 @@ class Controller extends Object {
* @return mixed Returns the return value of the called action
*/
public function setAction($action) {
$this->action = $action;
$this->request->action = $action;
$args = func_get_args();
unset($args[0]);
return call_user_func_array(array(&$this, $action), $args);
@ -805,7 +815,7 @@ class Controller extends Object {
App::import('View', $this->view);
}
$this->params['models'] = $this->modelNames;
$this->request->params['models'] = $this->modelNames;
$View = new $viewClass($this);
@ -906,8 +916,8 @@ class Controller extends Object {
*/
public function postConditions($data = array(), $op = null, $bool = 'AND', $exclusive = false) {
if (!is_array($data) || empty($data)) {
if (!empty($this->data)) {
$data = $this->data;
if (!empty($this->request->data)) {
$data = $this->request->data;
} else {
return null;
}
@ -1226,3 +1236,5 @@ class Controller extends Object {
return false;
}
}
class MissingModelException extends RuntimeException {}

View file

@ -122,11 +122,7 @@ class Scaffold {
$this->modelKey = $controller->modelKey;
if (!is_object($this->controller->{$this->modelClass})) {
return $this->cakeError('missingModel', array(array(
'className' => $this->modelClass,
'webroot' => $request->webroot,
'base' => $request->base
)));
throw new MissingModelException($this->modelClass);
}
$this->ScaffoldModel = $this->controller->{$this->modelClass};
@ -164,7 +160,7 @@ class Scaffold {
*/
protected function _output() {
$this->controller->afterFilter();
echo($this->controller->output);
$this->controller->getResponse()->send();
}
/**
@ -418,17 +414,13 @@ class Scaffold {
break;
}
} else {
return $this->cakeError('missingAction', array(array(
'className' => $this->controller->name . "Controller",
'base' => $request->base,
'action' => $request->action,
'webroot' => $request->webroot
)));
throw new MissingActionException(array(
'controller' => $this->controller->name,
'action' => $request->action
));
}
} else {
return $this->cakeError('missingDatabase', array(array(
'webroot' => $request->webroot
)));
throw new MissingDatabaseException(array('connection' => $this->ScaffoldModel->useDbConfig));
}
}
@ -470,9 +462,7 @@ class Scaffold {
* @package cake
* @subpackage cake.cake.libs.controller
*/
if (!class_exists('ThemeView')) {
App::import('View', 'Theme');
}
App::import('View', 'Theme');
/**
* ScaffoldView provides specific view file loading features for scaffolded views.
@ -537,6 +527,6 @@ class ScaffoldView extends ThemeView {
return LIBS . 'view' . DS . 'errors' . DS . 'scaffold_error.ctp';
}
return $this->_missingView($paths[0] . $name . $this->ext, 'missingView');
throw new MissingViewException($paths[0] . $name . $this->ext);
}
}

View file

@ -1,442 +0,0 @@
<?php
/**
* Error handler
*
* Provides Error Capturing for Framework errors.
*
* PHP versions 4 and 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @package cake
* @subpackage cake.cake.libs
* @since CakePHP(tm) v 0.10.5.1732
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
App::import('Controller', 'App');
/**
* Error Handling Controller
*
* Controller used by ErrorHandler to render error views.
*
* @package cake
* @subpackage cake.cake.libs
*/
class CakeErrorController extends AppController {
public $name = 'CakeError';
/**
* Uses Property
*
* @var array
*/
public $uses = array();
/**
* __construct
*
* @access public
* @return void
*/
function __construct() {
parent::__construct();
$this->_set(Router::getPaths());
$this->request = $this->params = Router::getRequest();
$this->constructClasses();
$this->Component->initialize($this);
$this->_set(array('cacheAction' => false, 'viewPath' => 'errors'));
}
}
/**
* Error Handler.
*
* Captures and handles all cakeError() calls.
* Displays helpful framework errors when debug > 1.
* When debug < 1 cakeError() will render 404 or 500 errors.
*
* @package cake
* @subpackage cake.cake.libs
*/
class ErrorHandler extends Object {
/**
* Controller instance.
*
* @var Controller
* @access public
*/
public $controller = null;
/**
* Class constructor.
*
* @param string $method Method producing the error
* @param array $messages Error messages
*/
function __construct($method, $messages) {
App::import('Core', 'Sanitize');
static $__previousError = null;
if ($__previousError != array($method, $messages)) {
$__previousError = array($method, $messages);
$this->controller = new CakeErrorController();
} else {
$this->controller = new Controller();
$this->controller->viewPath = 'errors';
}
$options = array('escape' => false);
$messages = Sanitize::clean($messages, $options);
if (!isset($messages[0])) {
$messages = array($messages);
}
if (method_exists($this->controller, 'apperror')) {
return $this->controller->appError($method, $messages);
}
if (!in_array(strtolower($method), array_map('strtolower', get_class_methods($this)))) {
$method = 'error';
}
if ($method !== 'error') {
if (Configure::read('debug') == 0) {
$parentClass = get_parent_class($this);
if (strtolower($parentClass) != 'errorhandler') {
$method = 'error404';
}
$parentMethods = array_map('strtolower', get_class_methods($parentClass));
if (in_array(strtolower($method), $parentMethods)) {
$method = 'error404';
}
if (isset($code) && $code == 500) {
$method = 'error500';
}
}
}
$this->dispatchMethod($method, $messages);
$this->_stop();
}
/**
* Displays an error page (e.g. 404 Not found).
*
* @param array $params Parameters for controller
*/
public function error($params) {
extract($params, EXTR_OVERWRITE);
$this->controller->set(array(
'code' => $code,
'name' => $name,
'message' => $message,
'title' => $code . ' ' . $name
));
$this->_outputMessage('error404');
}
/**
* Convenience method to display a 404 page.
*
* @param array $params Parameters for controller
*/
public function error404($params) {
extract($params, EXTR_OVERWRITE);
if (!isset($url)) {
$url = $this->controller->here;
}
$url = Router::normalize($url);
$this->controller->header("HTTP/1.0 404 Not Found");
$this->controller->set(array(
'code' => '404',
'name' => __('Not Found'),
'message' => h($url),
'base' => $this->controller->request->base
));
$this->_outputMessage('error404');
}
/**
* Convenience method to display a 500 page.
*
* @param array $params Parameters for controller
*/
public function error500($params) {
extract($params, EXTR_OVERWRITE);
if (!isset($url)) {
$url = $this->controller->request->here;
}
$url = Router::normalize($url);
$this->controller->header("HTTP/1.0 500 Internal Server Error");
$this->controller->set(array(
'code' => '500',
'name' => __('An Internal Error Has Occurred'),
'message' => h($url),
'base' => $this->controller->request->base
));
$this->_outputMessage('error500');
}
/**
* Renders the Missing Controller web page.
*
* @param array $params Parameters for controller
*/
public function missingController($params) {
extract($params, EXTR_OVERWRITE);
$controllerName = str_replace('Controller', '', $className);
$this->controller->set(array(
'controller' => $className,
'controllerName' => $controllerName,
'title' => __('Missing Controller')
));
$this->_outputMessage('missingController');
}
/**
* Renders the Missing Action web page.
*
* @param array $params Parameters for controller
*/
public function missingAction($params) {
extract($params, EXTR_OVERWRITE);
$controllerName = str_replace('Controller', '', $className);
$this->controller->set(array(
'controller' => $className,
'controllerName' => $controllerName,
'action' => $action,
'title' => __('Missing Method in Controller')
));
$this->_outputMessage('missingAction');
}
/**
* Renders the Private Action web page.
*
* @param array $params Parameters for controller
*/
public function privateAction($params) {
extract($params, EXTR_OVERWRITE);
$this->controller->set(array(
'controller' => $className,
'action' => $action,
'title' => __('Trying to access private method in class')
));
$this->_outputMessage('privateAction');
}
/**
* Renders the Missing Table web page.
*
* @param array $params Parameters for controller
*/
public function missingTable($params) {
extract($params, EXTR_OVERWRITE);
$this->controller->header("HTTP/1.0 500 Internal Server Error");
$this->controller->set(array(
'code' => '500',
'model' => $className,
'table' => $table,
'title' => __('Missing Database Table')
));
$this->_outputMessage('missingTable');
}
/**
* Renders the Missing Database web page.
*
* @param array $params Parameters for controller
*/
public function missingDatabase($params = array()) {
$this->controller->header("HTTP/1.0 500 Internal Server Error");
$this->controller->set(array(
'code' => '500',
'title' => __('Scaffold Missing Database Connection')
));
$this->_outputMessage('missingScaffolddb');
}
/**
* Renders the Missing View web page.
*
* @param array $params Parameters for controller
*/
public function missingView($params) {
extract($params, EXTR_OVERWRITE);
$this->controller->set(array(
'controller' => $className,
'action' => $action,
'file' => $file,
'title' => __('Missing View')
));
$this->_outputMessage('missingView');
}
/**
* Renders the Missing Layout web page.
*
* @param array $params Parameters for controller
*/
public function missingLayout($params) {
extract($params, EXTR_OVERWRITE);
$this->controller->layout = 'default';
$this->controller->set(array(
'file' => $file,
'title' => __('Missing Layout')
));
$this->_outputMessage('missingLayout');
}
/**
* Renders the Database Connection web page.
*
* @param array $params Parameters for controller
*/
public function missingConnection($params) {
extract($params, EXTR_OVERWRITE);
$this->controller->header("HTTP/1.0 500 Internal Server Error");
$this->controller->set(array(
'code' => '500',
'model' => $className,
'title' => __('Missing Database Connection')
));
$this->_outputMessage('missingConnection');
}
/**
* Renders the Missing Helper file web page.
*
* @param array $params Parameters for controller
*/
public function missingHelperFile($params) {
extract($params, EXTR_OVERWRITE);
$this->controller->set(array(
'helperClass' => Inflector::camelize($helper) . "Helper",
'file' => $file,
'title' => __('Missing Helper File')
));
$this->_outputMessage('missingHelperFile');
}
/**
* Renders the Missing Helper class web page.
*
* @param array $params Parameters for controller
*/
public function missingHelperClass($params) {
extract($params, EXTR_OVERWRITE);
$this->controller->set(array(
'helperClass' => Inflector::camelize($helper) . "Helper",
'file' => $file,
'title' => __('Missing Helper Class')
));
$this->_outputMessage('missingHelperClass');
}
/**
* Renders the Missing Behavior file web page.
*
* @param array $params Parameters for controller
*/
public function missingBehaviorFile($params) {
extract($params, EXTR_OVERWRITE);
$this->controller->set(array(
'behaviorClass' => Inflector::camelize($behavior) . "Behavior",
'file' => $file,
'title' => __('Missing Behavior File')
));
$this->_outputMessage('missingBehaviorFile');
}
/**
* Renders the Missing Behavior class web page.
*
* @param array $params Parameters for controller
*/
public function missingBehaviorClass($params) {
extract($params, EXTR_OVERWRITE);
$this->controller->set(array(
'behaviorClass' => Inflector::camelize($behavior) . "Behavior",
'file' => $file,
'title' => __('Missing Behavior Class')
));
$this->_outputMessage('missingBehaviorClass');
}
/**
* Renders the Missing Component file web page.
*
* @param array $params Parameters for controller
*/
public function missingComponentFile($params) {
extract($params, EXTR_OVERWRITE);
$this->controller->set(array(
'controller' => $className,
'component' => $component,
'file' => $file,
'title' => __('Missing Component File')
));
$this->_outputMessage('missingComponentFile');
}
/**
* Renders the Missing Component class web page.
*
* @param array $params Parameters for controller
*/
public function missingComponentClass($params) {
extract($params, EXTR_OVERWRITE);
$this->controller->set(array(
'controller' => $className,
'component' => $component,
'file' => $file,
'title' => __('Missing Component Class')
));
$this->_outputMessage('missingComponentClass');
}
/**
* Renders the Missing Model class web page.
*
* @param unknown_type $params Parameters for controller
*/
public function missingModel($params) {
extract($params, EXTR_OVERWRITE);
$this->controller->set(array(
'model' => $className,
'title' => __('Missing Model')
));
$this->_outputMessage('missingModel');
}
/**
* Output message
*
*/
protected function _outputMessage($template) {
$this->controller->render($template);
$this->controller->afterFilter();
echo $this->controller->output;
}
}

257
cake/libs/error_handler.php Normal file
View file

@ -0,0 +1,257 @@
<?php
/**
* Error handler
*
* Provides Error Capturing for Framework errors.
*
* PHP 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @package cake
* @subpackage cake.cake.libs
* @since CakePHP(tm) v 0.10.5.1732
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
/**
* Error Handler.
*
* Captures and handles all unhandled exceptions. Displays helpful framework errors when debug > 1.
* When debug < 1 a CakeException will render 404 or 500 errors. If an uncaught exception is thrown
* and it is a type that ErrorHandler does not know about it will be treated as a 500 error.
*
* ### Implementing application specific exception handling
*
* You can implement application specific exception handling in one of a few ways:
*
* - Create a AppController::appError();
* - Create an AppError class.
*
* #### Using AppController::appError();
*
* This controller method is called instead of the default exception handling. It receives the
* thrown exception as its only argument. You should implement your error handling in that method.
*
* #### Using an AppError class
*
* This approach gives more flexibility and power in how you handle exceptions. You can create
* `app/libs/app_error.php` and create a class called `AppError`. The core ErrorHandler class
* will attempt to construct this class and let it handle the exception. This provides a more
* flexible way to handle exceptions in your application.
*
* Finally, in your `app/config/bootstrap.php` you can configure use `set_exception_handler()`
* to take total control over application exception handling.
*
* @package cake
* @subpackage cake.cake.libs
*/
class ErrorHandler {
/**
* Controller instance.
*
* @var Controller
* @access public
*/
public $controller = null;
/**
* template to render for CakeException
*
* @var string
*/
public $template = '';
/**
* The method corresponding to the Exception this object is for.
*
* @var string
*/
public $method = '';
/**
* The exception being handled.
*
* @var Exception
*/
public $error = null;
/**
* Creates the controller to perform rendering on the error response.
* If the error is a CakeException it will be converted to either a 400 or a 500
* code error depending on the code used to construct the error.
*
* @param string $method Method producing the error
* @param array $messages Error messages
*/
function __construct(Exception $exception) {
App::import('Core', 'Sanitize');
$this->controller = $this->_getController($exception);
if (method_exists($this->controller, 'apperror')) {
return $this->controller->appError($exception);
}
$method = $template = Inflector::variable(str_replace('Exception', '', get_class($exception)));
$code = $exception->getCode();
$methodExists = method_exists($this, $method);
if ($exception instanceof CakeException && !$methodExists) {
$method = '_cakeError';
if ($template == 'internalError') {
$template = 'error500';
}
} elseif (!$methodExists) {
$method = 'error500';
if ($code >= 400) {
$method = 'error400';
}
}
if (Configure::read('debug') == 0) {
$parentClass = get_parent_class($this);
if ($parentClass != 'ErrorHandler') {
$method = 'error400';
}
$parentMethods = (array)get_class_methods($parentClass);
if (in_array($method, $parentMethods)) {
$method = 'error400';
}
if ($code == 500) {
$method = 'error500';
}
}
$this->template = $template;
$this->method = $method;
$this->error = $exception;
}
/**
* Get the controller instance to handle the exception.
* Override this method in subclasses to customize the controller used.
* This method returns the built in `CakeErrorController` normally, or if an error is repeated
* a bare controller will be used.
*
* @param Exception $exception The exception to get a controller for.
* @return Controller
*/
protected function _getController($exception) {
static $__previousError = null;
App::import('Controller', 'CakeError');
if ($__previousError != $exception) {
$__previousError = $exception;
$controller = new CakeErrorController();
} else {
$controller = new Controller();
$controller->viewPath = 'errors';
}
return $controller;
}
/**
* Set as the default exception handler by the CakePHP bootstrap process.
*
* This will either use an AppError class if your application has one,
* or use the default ErrorHandler.
*
* @return void
* @see http://php.net/manual/en/function.set-exception-handler.php
*/
public static function handleException(Exception $exception) {
if (file_exists(APP . 'app_error.php') || class_exists('AppError')) {
if (!class_exists('AppError')) {
require(APP . 'app_error.php');
}
$AppError = new AppError($exception);
return $AppError->render();
}
$error = new ErrorHandler($exception);
$error->render();
}
/**
* Renders the response for the exception.
*
* @return void
*/
public function render() {
call_user_func_array(array($this, $this->method), array($this->error));
}
/**
* Generic handler for the internal framework errors CakePHP can generate.
*
* @param CakeExeption $error
* @return void
*/
protected function _cakeError(CakeException $error) {
$url = Router::normalize($this->controller->request->here);
$code = $error->getCode();
$this->controller->response->statusCode($code);
$this->controller->set(array(
'code' => $code,
'url' => h($url),
'name' => $error->getMessage(),
'error' => $error,
));
$this->controller->set($error->getAttributes());
$this->_outputMessage($this->template);
}
/**
* Convenience method to display a 400 series page.
*
* @param array $params Parameters for controller
*/
public function error400($error) {
$message = $error->getMessage();
if (Configure::read('debug') == 0 && $error instanceof CakeException) {
$message = __('Not Found');
}
$url = Router::normalize($this->controller->request->here);
$this->controller->response->statusCode($error->getCode());
$this->controller->set(array(
'name' => $message,
'url' => h($url),
'error' => $error,
));
$this->_outputMessage('error400');
}
/**
* Convenience method to display a 500 page.
*
* @param array $params Parameters for controller
*/
public function error500($error) {
$url = Router::normalize($this->controller->request->here);
$code = ($error->getCode() > 500) ? $error->getCode() : 500;
$this->controller->response->statusCode($code);
$this->controller->set(array(
'name' => __('An Internal Error Has Occurred'),
'message' => h($url),
'error' => $error,
));
$this->_outputMessage('error500');
}
/**
* Generate the response using the controller object.
*
* @param string $template The template to render.
*/
protected function _outputMessage($template) {
$this->controller->render($template);
$this->controller->afterFilter();
$this->controller->response->send();
}
}

323
cake/libs/exceptions.php Normal file
View file

@ -0,0 +1,323 @@
<?php
/**
* Exceptions file. Contains the various exceptions CakePHP will throw until they are
* moved into their permanent location.
*
* PHP 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://book.cakephp.org/view/1196/Testing CakePHP(tm) Tests
* @package cake
* @subpackage cake.libs
* @since CakePHP(tm) v 2.0
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
/**
* Represents an HTTP 400 error.
*
* @package cake.libs
*/
class BadRequestException extends RuntimeException {
/**
* Constructor
*
* @param string $message If no message is given 'Bad Request' will be the message
* @param string $code Status code, defaults to 401
*/
public function __construct($message = null, $code = 400) {
if (empty($message)) {
$message = 'Bad Request';
}
parent::__construct($message, $code);
}
}
/**
* Represents an HTTP 401 error.
*
* @package cake.libs
*/
class UnauthorizedException extends RuntimeException {
/**
* Constructor
*
* @param string $message If no message is given 'Unauthorized' will be the message
* @param string $code Status code, defaults to 401
*/
public function __construct($message = null, $code = 401) {
if (empty($message)) {
$message = 'Unauthorized';
}
parent::__construct($message, $code);
}
}
/**
* Represents an HTTP 403 error.
*
* @package cake.libs
*/
class ForbiddenException extends RuntimeException {
/**
* Constructor
*
* @param string $message If no message is given 'Forbidden' will be the message
* @param string $code Status code, defaults to 401
*/
public function __construct($message = null, $code = 403) {
if (empty($message)) {
$message = 'Forbidden';
}
parent::__construct($message, $code);
}
}
/**
* Represents an HTTP 404 error.
*
* @package cake.libs
*/
class NotFoundException extends RuntimeException {
/**
* Constructor
*
* @param string $message If no message is given 'Not Found' will be the message
* @param string $code Status code, defaults to 404
*/
public function __construct($message = null, $code = 404) {
if (empty($message)) {
$message = 'Not Found';
}
parent::__construct($message, $code);
}
}
/**
* Represents an HTTP 500 error.
*
* @package cake.libs
*/
class InternalErrorException extends CakeException {
/**
* Constructor
*
* @param string $message If no message is given 'Not Found' will be the message
* @param string $code Status code, defaults to 404
*/
public function __construct($message = null, $code = 500) {
if (empty($message)) {
$message = 'Internal Server Error';
}
parent::__construct($message, $code);
}
}
/**
* CakeException is used a base class for CakePHP's internal exceptions.
* In general framework errors are interpreted as 500 code errors.
*
* @package cake.libs
*/
class CakeException extends RuntimeException {
/**
* Array of attributes that are passed in from the constructor, and
* made available in the view when a development error is displayed.
*
* @var array
*/
protected $_attributes = array();
/**
* Template string that has attributes sprintf()'ed into it.
*
* @var string
*/
protected $_messageTemplate = '';
/**
* Constructor.
*
* Allows you to create exceptions that are treated as framework errors and disabled
* when debug = 0.
*
* @param mixed $message Either the string of the error message, or an array of attributes
* that are made available in the view, and sprintf()'d into CakeException::$_messageTemplate
* @param string $code The code of the error, is also the HTTP status code for the error.
*/
public function __construct($message, $code = 500) {
if (is_array($message)) {
$this->_attributes = $message;
$message = vsprintf(__($this->_messageTemplate), $message);
}
parent::__construct($message, $code);
}
/**
* Get the passed in attributes
*
* @return array
*/
public function getAttributes() {
return $this->_attributes;
}
}
/**
* Missing Controller exception - used when a controller
* cannot be found.
*
* @package cake.libs
*/
class MissingControllerException extends CakeException {
protected $_messageTemplate = 'Controller class %s could not be found.';
public function __construct($message, $code = 404) {
parent::__construct($message, $code);
}
}
/**
* Missing Action exception - used when a controller action
* cannot be found.
*
* @package cake.libs
*/
class MissingActionException extends CakeException {
protected $_messageTemplate = 'Action %s::%s() could not be found.';
public function __construct($message, $code = 404) {
parent::__construct($message, $code);
}
}
/**
* Private Action exception - used when a controller action
* is protected, or starts with a `_`.
*
* @package cake.libs
*/
class PrivateActionException extends CakeException {
protected $_messageTemplate = 'Private Action %s::%s() is not directly accessible.';
public function __construct($message, $code = 404, Exception $previous = null) {
parent::__construct($message, $code, $previous);
}
}
/**
* Used when a Component file cannot be found.
*
* @package cake.libs
*/
class MissingComponentFileException extends CakeException {
protected $_messageTemplate = 'Component File "%s" is missing.';
}
/**
* Used when a Component class cannot be found.
*
* @package cake.libs
*/
class MissingComponentClassException extends CakeException {
protected $_messageTemplate = 'Component class "%s" is missing.';
}
/**
* Used when a Behavior file cannot be found.
*
* @package cake.libs
*/
class MissingBehaviorFileException extends CakeException { }
/**
* Used when a Behavior class cannot be found.
*
* @package cake.libs
*/
class MissingBehaviorClassException extends CakeException { }
/**
* Used when a view file cannot be found.
*
* @package cake.libs
*/
class MissingViewException extends CakeException {
protected $_messageTemplate = 'View file "%s" is missing.';
}
/**
* Used when a layout file cannot be found.
*
* @package cake.libs
*/
class MissingLayoutException extends CakeException {
protected $_messageTemplate = 'Layout file "%s" is missing.';
}
/**
* Used when a helper file cannot be found.
*
* @package cake.libs
*/
class MissingHelperFileException extends CakeException {
protected $_messageTemplate = 'Helper File "%s" is missing.';
}
/**
* Used when a helper class cannot be found.
*
* @package cake.libs
*/
class MissingHelperClassException extends CakeException {
protected $_messageTemplate = 'Helper class "%s" is missing.';
}
/**
* Runtime Exceptions for ConnectionManager
*/
class MissingDatabaseException extends CakeException {
protected $_messageTemplate = 'Database connection "%s" could not be found.';
}
/**
* Used when no connections can be found.
*
* @package cake.libs
*/
class MissingConnectionException extends CakeException {
protected $_messageTemplate = 'Database connection "%s" is missing.';
}
/**
* Used when a Task file cannot be found.
*
* @package cake.libs
*/
class MissingTaskFileException extends CakeException {
protected $_messageTemplate = 'Task file "%s" is missing.';
}
/**
* Used when a Task class cannot be found.
*
* @package cake.libs
*/
class MissingTaskClassException extends CakeException {
protected $_messageTemplate = 'Task class "%s" is missing.';
}
/**
* Exception class to be thrown when a database table is not found in the datasource
*
* @package cake.libs
*/
class MissingTableException extends CakeException {
protected $_messageTemplate = 'Database table %s for model %s was not found.';
}

View file

@ -55,7 +55,7 @@ class Inflector {
'/(c)hild$/i' => '\1hildren',
'/(buffal|tomat)o$/i' => '\1\2oes',
'/(alumn|bacill|cact|foc|fung|nucle|radi|stimul|syllab|termin|vir)us$/i' => '\1i',
'/us$/' => 'uses',
'/us$/i' => 'uses',
'/(alias)$/i' => '\1es',
'/(ax|cris|test)is$/i' => '\1es',
'/s$/' => 's',

View file

@ -65,7 +65,7 @@ class BehaviorCollection extends ObjectCollection {
if (!empty($behaviors)) {
foreach (Set::normalize($behaviors) as $behavior => $config) {
$this->attach($behavior, $config);
$this->load($behavior, $config);
}
}
}
@ -94,10 +94,16 @@ class BehaviorCollection extends ObjectCollection {
$class = $name . 'Behavior';
if (!App::import('Behavior', $behavior)) {
throw new MissingBehaviorFileException(Inflector::underscore($behavior) . '.php');
throw new MissingBehaviorFileException(array(
'file' => Inflector::underscore($behavior) . '.php',
'class' => $class
));
}
if (!class_exists($class)) {
throw new MissingBehaviorClassException(Inflector::underscore($class));
throw new MissingBehaviorClassException(array(
'file' => Inflector::underscore($behavior) . '.php',
'class' => $class
));
}
if (!isset($this->{$name})) {
@ -191,10 +197,6 @@ class BehaviorCollection extends ObjectCollection {
*/
public function dispatchMethod(&$model, $method, $params = array(), $strict = false) {
$methods = array_keys($this->__methods);
foreach ($methods as $key => $value) {
$methods[$key] = strtolower($value);
}
$method = strtolower($method);
$check = array_flip($methods);
$found = isset($check[$method]);
$call = null;
@ -273,10 +275,4 @@ class BehaviorCollection extends ObjectCollection {
return $this->__methods;
}
}
/**
* Runtime Exceptions for behaviors
*/
class MissingBehaviorFileException extends RuntimeException { }
class MissingBehaviorClassException extends RuntimeException { }
}

View file

@ -278,7 +278,7 @@ class TreeBehavior extends ModelBehavior {
if (!$id) {
$conditions = $scope;
} else {
$result = array_values($Model->find('first', array(
$result = array_values((array)$Model->find('first', array(
'conditions' => array($scope, $Model->escapeField() => $id),
'fields' => array($left, $right),
'recursive' => $recursive

View file

@ -222,7 +222,7 @@ class ConnectionManager {
$this->_connectionsEnum[$name] = $this->__connectionData($config);
}
} else {
$this->cakeError('missingConnection', array(array('className' => 'ConnectionManager')));
throw new MissingConnectionException(array('class' => 'ConnectionManager'));
}
}
@ -269,8 +269,8 @@ class ConnectionManager {
*
*/
function __destruct() {
if (Configure::read('Session.save') == 'database' && function_exists('session_write_close')) {
if (Configure::read('Session.defaults') == 'database' && function_exists('session_write_close')) {
session_write_close();
}
}
}
}

View file

@ -657,16 +657,19 @@ class DboMysql extends DboMysqlBase {
if ($data === '') {
return 'NULL';
}
if ((is_int($data) || is_float($data) || $data === '0') || (
if (is_float($data)) {
return sprintf('%F', $data);
}
if ((is_int($data) || $data === '0') || (
is_numeric($data) && strpos($data, ',') === false &&
$data[0] != '0' && strpos($data, 'e') === false)) {
return $data;
}
$data[0] != '0' && strpos($data, 'e') === false)
) {
return $data;
}
default:
$data = "'" . mysql_real_escape_string($data, $this->connection) . "'";
return "'" . mysql_real_escape_string($data, $this->connection) . "'";
break;
}
return $data;
}
/**

View file

@ -299,8 +299,11 @@ class DboPostgres extends DboSource {
}
switch($column) {
case 'inet':
case 'float':
if (is_float($data)) {
$data = sprintf('%F', $data);
}
case 'inet':
case 'integer':
case 'date':
case 'datetime':

View file

@ -54,7 +54,7 @@ class DboSource extends DataSource {
/**
* Caches result from query parsing operations. Cached results for both DboSource::name() and
* DboSource::conditions() will be stored here. Method caching uses `crc32()` which is
* DboSource::conditions() will be stored here. Method caching uses `crc32()` which is
* fast but can collisions more easily than other hashing algorithms. If you have problems
* with collisions, set DboSource::$cacheMethods to false.
*
@ -504,7 +504,7 @@ class DboSource extends DataSource {
* because the method uses a simple hashing algorithm it can infrequently have collisions.
* Setting DboSource::$cacheMethods to false will disable the memory cache.
*
* @param mixed $data Either a string with a column to quote. An array of columns to quote or an
* @param mixed $data Either a string with a column to quote. An array of columns to quote or an
* object from DboSource::expression() or DboSource::identifier()
* @return string SQL field
*/
@ -611,7 +611,7 @@ class DboSource extends DataSource {
$controller = null;
$View =& new View($controller, false);
$View->set('logs', array($this->configKeyName => $log));
echo $View->element('sql_dump');
echo $View->element('sql_dump', array('_forced_from_dbo_' => true));
} else {
foreach ($log['log'] as $k => $i) {
print (($k + 1) . ". {$i['query']} {$i['error']}\n");
@ -822,6 +822,10 @@ class DboSource extends DataSource {
$stack = array($assoc);
$db->queryAssociation($model, $linkModel, $type, $assoc, $assocData, $array, true, $resultSet, $model->recursive - 1, $stack);
unset($db);
if ($type === 'hasMany') {
$filtered []= $assoc;
}
}
}
}
@ -1878,7 +1882,7 @@ class DboSource extends DataSource {
foreach ($fields as $field) {
$virtualField = $this->name($alias . $this->virtualFieldSeparator . $field);
$expression = $this->__quoteFields($model->getVirtualField($field));
$virtual[] = '(' .$expression . ") {$this->alias} {$virtualField}";
$virtual[] = '(' . $expression . ") {$this->alias} {$virtualField}";
}
return $virtual;
}

View file

@ -799,7 +799,10 @@ class Model extends Object {
if ($db->isInterfaceSupported('listSources')) {
$sources = $db->listSources();
if (is_array($sources) && !in_array(strtolower($this->tablePrefix . $tableName), array_map('strtolower', $sources))) {
throw new MissingTableException($this->alias, $this->tablePrefix . $tableName);
throw new MissingTableException(array(
'table' => $this->tablePrefix . $tableName,
'class' => $this->alias
));
}
$this->_schema = null;
}
@ -1613,6 +1616,7 @@ class Model extends Object {
if (Set::numeric(array_keys($data))) {
while ($validates) {
$return = array();
foreach ($data as $key => $record) {
if (!$currentValidates = $this->__save($record, $options)) {
$validationErrors[$key] = $this->validationErrors;
@ -1644,7 +1648,6 @@ class Model extends Object {
break;
case ($options['validate'] === 'first'):
$options['validate'] = true;
$return = array();
break;
default:
if ($options['atomic']) {
@ -2522,7 +2525,7 @@ class Model extends Object {
$_validate = $this->validate;
$whitelist = $this->whitelist;
if (array_key_exists('fieldList', $options)) {
if (!empty($options['fieldList'])) {
$whitelist = $options['fieldList'];
}
@ -2825,7 +2828,7 @@ class Model extends Object {
}
if (empty($db) || !is_object($db)) {
return $this->cakeError('missingConnection', array(array('className' => $this->alias)));
throw new MissingConnectionException(array('class' => $this->name));
}
}
@ -3064,53 +3067,3 @@ class Model extends Object {
}
}
/**
* Exception class to be thrown when a database table is not found in the datasource
*
*/
class MissingTableException extends RuntimeException {
/**
* The name of the model wanting to load the database table
*
* @var string
*/
protected $model;
/**
* The name of the missing table
*
* @var string
*/
protected $table;
/**
* Exception costructor
*
* @param string $model The name of the model wanting to load the database table
* @param string $table The name of the missing table
* @return void
*/
public function __construct($model, $table) {
$this->model = $model;
$this->$table = $table;
$message = sprintf(__('Database table %s for model %s was not found.'), $table, $model);
parent::__construct($message);
}
/**
* Returns the name of the model wanting to load the database table
*
* @return string
*/
public function getModel() {
return $this->model;
}
/**
* Returns the name of the missing table
*
* @return string
*/
public function getTable() {
return $this->table;
}
}

View file

@ -22,7 +22,7 @@
*/
/**
* Object class, allowing __construct and __destruct in PHP4.
* Object class provides a few generic methods used in several subclasses.
*
* Also includes methods for logging and the special method RequestAction,
* to call other Controllers' Actions from anywhere.
@ -155,34 +155,6 @@ class Object {
}
}
/**
* Used to report user friendly errors.
* If there is a file app/error.php or app/app_error.php this file will be loaded
* error.php is the AppError class it should extend ErrorHandler class.
*
* @param string $method Method to be called in the error class (AppError or ErrorHandler classes)
* @param array $messages Message that is to be displayed by the error class
* @return error message
*/
public function cakeError($method, $messages = array()) {
if (!class_exists('ErrorHandler')) {
App::import('Core', 'Error');
if (file_exists(APP . 'error.php')) {
include_once (APP . 'error.php');
} elseif (file_exists(APP . 'app_error.php')) {
include_once (APP . 'app_error.php');
}
}
if (class_exists('AppError')) {
$error = new AppError($method, $messages);
} else {
$error = new ErrorHandler($method, $messages);
}
return $error;
}
/**
* Checks for a persistent class file, if found file is opened and true returned
* If file is not found a file is created and false returned

View file

@ -57,6 +57,8 @@ abstract class ObjectCollection {
* - `break` Set to true to enabled breaking. Defaults to `false`.
* - `collectReturn` Set to true to collect the return of each object into an array.
* This array of return values will be returned from the trigger() call. Defaults to `false`.
* - `triggerDisabled` Will trigger the callback on all objects in the collection even the non-enabled
* objects. Defaults to false.
*
* @param string $callback Method to fire on all the objects. Its assumed all the objects implement
* the method you are calling.
@ -69,11 +71,15 @@ abstract class ObjectCollection {
return true;
}
$options = array_merge(
array('break' => false, 'breakOn' => false, 'collectReturn' => false),
array('break' => false, 'breakOn' => false, 'collectReturn' => false, 'triggerDisabled' => false),
$options
);
$collected = array();
foreach ($this->_enabled as $name) {
$list = $this->_enabled;
if ($options['triggerDisabled'] === true) {
$list = array_keys($this->_loaded);
}
foreach ($list as $name) {
$result = call_user_func_array(array(&$this->_loaded[$name], $callback), $params);
if ($options['collectReturn'] === true) {
$collected[] = $result;

View file

@ -29,7 +29,7 @@ class CacheSession implements CakeSessionHandlerInterface {
* @return boolean Success
* @access private
*/
public static function open() {
public function open() {
return true;
}
@ -39,7 +39,7 @@ class CacheSession implements CakeSessionHandlerInterface {
* @return boolean Success
* @access private
*/
public static function close() {
public function close() {
$probability = mt_rand(1, 150);
if ($probability <= 3) {
Cache::gc();
@ -54,7 +54,7 @@ class CacheSession implements CakeSessionHandlerInterface {
* @return mixed The value of the key or false if it does not exist
* @access private
*/
public static function read($id) {
public function read($id) {
return Cache::read($id, Configure::read('Session.handler.config'));
}
@ -66,7 +66,7 @@ class CacheSession implements CakeSessionHandlerInterface {
* @return boolean True for successful write, false otherwise.
* @access private
*/
public static function write($id, $data) {
public function write($id, $data) {
return Cache::write($id, $data, Configure::read('Session.handler.config'));
}
@ -77,7 +77,7 @@ class CacheSession implements CakeSessionHandlerInterface {
* @return boolean True for successful delete, false otherwise.
* @access private
*/
public static function destroy($id) {
public function destroy($id) {
return Cache::delete($id, Configure::read('Session.handler.config'));
}
@ -88,7 +88,7 @@ class CacheSession implements CakeSessionHandlerInterface {
* @return boolean Success
* @access private
*/
public static function gc($expires = null) {
public function gc($expires = null) {
return Cache::gc();
}
}

View file

@ -23,13 +23,43 @@
* @package cake.libs
*/
class DatabaseSession implements CakeSessionHandlerInterface {
/**
* Constructor. Looks at Session configuration information and
* sets up the session model.
*
* @return void
*/
function __construct() {
$modelName = Configure::read('Session.handler.model');
$database = Configure::read('Session.handler.database');
$table = Configure::read('Session.handler.table');
if (empty($database)) {
$database = 'default';
}
$settings = array(
'class' => 'Session',
'alias' => 'Session',
'table' => 'cake_sessions',
'ds' => $database
);
if (!empty($modelName)) {
$settings['class'] = $modelName;
}
if (!empty($table)) {
$settings['table'] = $table;
}
ClassRegistry::init($settings);
}
/**
* Method called on open of a database session.
*
* @return boolean Success
* @access private
*/
public static function open() {
public function open() {
return true;
}
@ -39,7 +69,7 @@ class DatabaseSession implements CakeSessionHandlerInterface {
* @return boolean Success
* @access private
*/
public static function close() {
public function close() {
$probability = mt_rand(1, 150);
if ($probability <= 3) {
DatabaseSession::gc();
@ -54,8 +84,8 @@ class DatabaseSession implements CakeSessionHandlerInterface {
* @return mixed The value of the key or false if it does not exist
* @access private
*/
public static function read($id) {
$model =& ClassRegistry::getObject('Session');
public function read($id) {
$model = ClassRegistry::getObject('Session');
$row = $model->find('first', array(
'conditions' => array($model->primaryKey => $id)
@ -76,11 +106,9 @@ class DatabaseSession implements CakeSessionHandlerInterface {
* @return boolean True for successful write, false otherwise.
* @access private
*/
public static function write($id, $data) {
public function write($id, $data) {
$expires = time() + (Configure::read('Session.timeout') * 60);
$model =& ClassRegistry::getObject('Session');
$return = $model->save(compact('id', 'data', 'expires'));
return $return;
return ClassRegistry::getObject('Session')->save(compact('id', 'data', 'expires'));
}
/**
@ -90,11 +118,8 @@ class DatabaseSession implements CakeSessionHandlerInterface {
* @return boolean True for successful delete, false otherwise.
* @access private
*/
public static function destroy($id) {
$model =& ClassRegistry::getObject('Session');
$return = $model->delete($id);
return $return;
public function destroy($id) {
return ClassRegistry::getObject('Session')->delete($id);
}
/**
@ -104,14 +129,11 @@ class DatabaseSession implements CakeSessionHandlerInterface {
* @return boolean Success
* @access private
*/
public static function gc($expires = null) {
$model =& ClassRegistry::getObject('Session');
public function gc($expires = null) {
if (!$expires) {
$expires = time();
}
$return = $model->deleteAll(array($model->alias . ".expires <" => $expires), false, false);
return $return;
$model = ClassRegistry::getObject('Session');
return $model->deleteAll(array($model->alias . ".expires <" => $expires), false, false);
}
}

View file

@ -0,0 +1,24 @@
<?php
/**
* Prints a stack trace for an exception
*
* PHP 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright 2005-2009, Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @package cake
* @subpackage cake.cake.libs.view.templates.elements
* @since CakePHP(tm) v 1.3
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
?>
<h4>Stack Trace</h4>
<pre>
<?php echo $error->getTraceAsString(); ?>
</pre>

View file

@ -20,7 +20,8 @@
if (!class_exists('ConnectionManager') || Configure::read('debug') < 2) {
return false;
}
if (!isset($logs)):
$noLogs = !isset($logs);
if ($noLogs):
$sources = ConnectionManager::sourceList();
$logs = array();
@ -31,8 +32,9 @@ if (!isset($logs)):
endif;
$logs[$source] = $db->getLog();
endforeach;
endif;
if ($noLogs || isset($_forced_from_dbo_)):
foreach ($logs as $source => $logInfo):
$text = $logInfo['count'] > 1 ? 'queries' : 'query';
printf(
@ -52,6 +54,8 @@ if (!isset($logs)):
?>
</tbody></table>
<?php
endforeach;
endforeach;
else:
echo '<p>Encountered unexpected $logs cannot generate SQL log</p>';
endif;
?>

View file

@ -20,5 +20,13 @@
<h2><?php echo $name; ?></h2>
<p class="error">
<strong><?php echo __('Error'); ?>: </strong>
<?php printf(__('The requested address %s was not found on this server.'), "<strong>'{$message}'</strong>"); ?>
</p>
<?php printf(
__('The requested address %s was not found on this server.'),
"<strong>'{$url}'</strong>"
); ?>
</p>
<?php
if (Configure::read('debug') > 0 ):
echo $this->element('exception_stack_trace');
endif;
?>

View file

@ -19,6 +19,11 @@
?>
<h2><?php echo $name; ?></h2>
<p class="error">
<strong><?php echo __('Error'); ?>: </strong>
<?php printf(__('An Internal Error Has Occurred.'), "<strong>'{$message}'</strong>"); ?>
<strong><?php echo __('Error', true); ?>: </strong>
<?php echo __('An Internal Error Has Occurred.'); ?>
</p>
<?php
if (Configure::read('debug') > 0 ):
echo $this->element('exception_stack_trace');
endif;
?>

View file

@ -30,10 +30,8 @@
&lt;?php
class <?php echo $controller;?> extends AppController {
public $name = '<?php echo $controllerName;?>';
<strong>
function <?php echo $action;?>() {
function <?php echo $action;?> {
}
</strong>
@ -43,4 +41,5 @@ class <?php echo $controller;?> extends AppController {
<p class="notice">
<strong><?php echo __('Notice'); ?>: </strong>
<?php printf(__('If you want to customize this error message, create %s.'), APP_DIR . DS . 'views' . DS . 'errors' . DS . 'missing_action.ctp'); ?>
</p>
</p>
<?php echo $this->element('exception_stack_trace'); ?>

View file

@ -20,7 +20,7 @@
<h2><?php echo __('Missing Behavior Class'); ?></h2>
<p class="error">
<strong><?php echo __('Error'); ?>: </strong>
<?php printf(__('The behavior class <em>%s</em> can not be found or does not exist.'), $behaviorClass); ?>
<?php printf(__('The behavior class <em>%s</em> can not be found or does not exist.'), $class); ?>
</p>
<p class="error">
<strong><?php echo __('Error'); ?>: </strong>
@ -28,7 +28,7 @@
</p>
<pre>
&lt;?php
class <?php echo $behaviorClass;?> extends ModelBehavior {
class <?php echo $class;?> extends ModelBehavior {
}
?&gt;
@ -36,4 +36,6 @@ class <?php echo $behaviorClass;?> extends ModelBehavior {
<p class="notice">
<strong><?php echo __('Notice'); ?>: </strong>
<?php printf(__('If you want to customize this error message, create %s'), APP_DIR . DS . 'views' . DS . 'errors' . DS . 'missing_behavior_class.ctp'); ?>
</p>
</p>
<?php echo $this->element('exception_stack_trace'); ?>

View file

@ -28,7 +28,7 @@
</p>
<pre>
&lt;?php
class <?php echo $behaviorClass;?> extends ModelBehavior {
class <?php echo $class;?> extends ModelBehavior {
}
?&gt;
@ -37,3 +37,5 @@ class <?php echo $behaviorClass;?> extends ModelBehavior {
<strong><?php echo __('Notice'); ?>: </strong>
<?php printf(__('If you want to customize this error message, create %s'), APP_DIR . DS . 'views' . DS . 'errors' . DS . 'missing_behavior_file.ctp'); ?>
</p>
<?php echo $this->element('exception_stack_trace'); ?>

View file

@ -20,15 +20,15 @@
<h2><?php echo __('Missing Component Class'); ?></h2>
<p class="error">
<strong><?php echo __('Error'); ?>: </strong>
<?php printf(__('Component class %1$s in %2$s was not found.'), '<em>' . $component . 'Component</em>', '<em>' . $controller . 'Controller</em>'); ?>
<?php printf(__('Component class %1$s was not found.'), '<em>' . $class . '</em>'); ?>
</p>
<p class="error">
<strong><?php echo __('Error'); ?>: </strong>
<?php printf(__('Create the class %s in file: %s'), '<em>' . $component . 'Component</em>', APP_DIR . DS . 'controllers' . DS . 'components' . DS . $file); ?>
<?php printf(__('Create the class %s in file: %s'), '<em>' . $class . '</em>', APP_DIR . DS . 'controllers' . DS . 'components' . DS . $file); ?>
</p>
<pre>
&lt;?php
class <?php echo $component;?>Component extends Object {<br />
class <?php echo $class;?> extends Component {<br />
}
?&gt;
@ -36,4 +36,6 @@ class <?php echo $component;?>Component extends Object {<br />
<p class="notice">
<strong><?php echo __('Notice'); ?>: </strong>
<?php printf(__('If you want to customize this error message, create %s'), APP_DIR . DS . 'views' . DS . 'errors' . DS . 'missing_component_class.ctp'); ?>
</p>
</p>
<?php echo $this->element('exception_stack_trace'); ?>

View file

@ -24,11 +24,11 @@
</p>
<p class="error">
<strong><?php echo __('Error'); ?>: </strong>
<?php printf(__('Create the class %s in file: %s'), '<em>' . $component . 'Component</em>', APP_DIR . DS . 'controllers' . DS . 'components' . DS . $file); ?>
<?php printf(__('Create the class %s in file: %s'), '<em>' . $class . '</em>', APP_DIR . DS . 'controllers' . DS . 'components' . DS . $file); ?>
</p>
<pre>
&lt;?php
class <?php echo $component;?>Component extends Object {<br />
class <?php echo $class;?> extends Component {<br />
}
?&gt;
@ -36,4 +36,6 @@ class <?php echo $component;?>Component extends Object {<br />
<p class="notice">
<strong><?php echo __('Notice'); ?>: </strong>
<?php printf(__('If you want to customize this error message, create %s'), APP_DIR . DS . 'views' . DS . 'errors' . DS . 'missing_component_file.ctp'); ?>
</p>
</p>
<?php echo $this->element('exception_stack_trace'); ?>

View file

@ -20,7 +20,7 @@
<h2><?php echo __('Missing Database Connection'); ?></h2>
<p class="error">
<strong><?php echo __('Error'); ?>: </strong>
<?php printf(__('%s requires a database connection'), $model); ?>
<?php printf(__('%s requires a database connection'), $class); ?>
</p>
<p class="error">
<strong><?php echo __('Error'); ?>: </strong>
@ -29,4 +29,6 @@
<p class="notice">
<strong><?php echo __('Notice'); ?>: </strong>
<?php printf(__('If you want to customize this error message, create %s.'), APP_DIR . DS . 'views' . DS . 'errors' . DS . basename(__FILE__)); ?>
</p>
</p>
<?php echo $this->element('exception_stack_trace'); ?>

View file

@ -30,11 +30,12 @@
&lt;?php
class <?php echo $controller;?> extends AppController {
public $name = '<?php echo $controllerName;?>';
}
?&gt;
</pre>
<p class="notice">
<strong><?php echo __('Notice'); ?>: </strong>
<?php printf(__('If you want to customize this error message, create %s'), APP_DIR . DS . 'views' . DS . 'errors' . DS . 'missing_controller.ctp'); ?>
</p>
</p>
<?php echo $this->element('exception_stack_trace'); ?>

View file

@ -29,4 +29,6 @@
<p class="notice">
<strong><?php echo __('Notice'); ?>: </strong>
<?php printf(__('If you want to customize this error message, create %s'), APP_DIR . DS . 'views' . DS . 'errors' . DS . 'missing_scaffolddb.ctp'); ?>
</p>
</p>
<?php echo $this->element('exception_stack_trace'); ?>

View file

@ -20,7 +20,7 @@
<h2><?php echo __('Missing Helper Class'); ?></h2>
<p class="error">
<strong><?php echo __('Error'); ?>: </strong>
<?php printf(__('The helper class <em>%s</em> can not be found or does not exist.'), $helperClass); ?>
<?php printf(__('The helper class <em>%s</em> can not be found or does not exist.'), $class); ?>
</p>
<p class="error">
<strong><?php echo __('Error'); ?>: </strong>
@ -28,7 +28,7 @@
</p>
<pre>
&lt;?php
class <?php echo $helperClass;?> extends AppHelper {
class <?php echo $class;?> extends AppHelper {
}
?&gt;
@ -36,4 +36,6 @@ class <?php echo $helperClass;?> extends AppHelper {
<p class="notice">
<strong><?php echo __('Notice'); ?>: </strong>
<?php printf(__('If you want to customize this error message, create %s'), APP_DIR . DS . 'views' . DS . 'errors' . DS . 'missing_helper_class.ctp'); ?>
</p>
</p>
<?php echo $this->element('exception_stack_trace'); ?>

View file

@ -28,7 +28,7 @@
</p>
<pre>
&lt;?php
class <?php echo $helperClass;?> extends AppHelper {
class <?php echo $class;?> extends AppHelper {
}
?&gt;
@ -37,3 +37,5 @@ class <?php echo $helperClass;?> extends AppHelper {
<strong><?php echo __('Notice'); ?>: </strong>
<?php printf(__('If you want to customize this error message, create %s'), APP_DIR . DS . 'views' . DS . 'errors' . DS . 'missing_helper_file.ctp'); ?>
</p>
<?php echo $this->element('exception_stack_trace'); ?>

View file

@ -29,4 +29,6 @@
<p class="notice">
<strong><?php echo __('Notice'); ?>: </strong>
<?php printf(__('If you want to customize this error message, create %s'), APP_DIR . DS . 'views' . DS . 'errors' . DS . 'missing_layout.ctp'); ?>
</p>
</p>
<?php echo $this->element('exception_stack_trace'); ?>

View file

@ -1,41 +0,0 @@
<?php
/**
*
* PHP versions 4 and 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @package cake
* @subpackage cake.cake.libs.view.templates.errors
* @since CakePHP(tm) v 0.10.0.1076
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
?>
<h2><?php echo __('Missing Model'); ?></h2>
<p class="error">
<strong><?php echo __('Error'); ?>: </strong>
<?php printf(__('<em>%s</em> could not be found.'), $model); ?>
</p>
<p class="error">
<strong><?php echo __('Error'); ?>: </strong>
<?php printf(__('Create the class %s in file: %s'), '<em>' . $model . '</em>', APP_DIR . DS . 'models' . DS . Inflector::underscore($model) . '.php'); ?>
</p>
<pre>
&lt;?php
class <?php echo $model;?> extends AppModel {
public $name = '<?php echo $model;?>';
}
?&gt;
</pre>
<p class="notice">
<strong><?php echo __('Notice'); ?>: </strong>
<?php printf(__('If you want to customize this error message, create %s'), APP_DIR . DS . 'views' . DS . 'errors' . DS . 'missing_model.ctp'); ?>
</p>

View file

@ -20,9 +20,11 @@
<h2><?php echo __('Missing Database Table'); ?></h2>
<p class="error">
<strong><?php echo __('Error'); ?>: </strong>
<?php printf(__('Database table %1$s for model %2$s was not found.'), '<em>' . $table . '</em>', '<em>' . $model . '</em>'); ?>
<?php printf(__('Database table %1$s for model %2$s was not found.'), '<em>' . $table . '</em>', '<em>' . $class . '</em>'); ?>
</p>
<p class="notice">
<strong><?php echo __('Notice'); ?>: </strong>
<?php printf(__('If you want to customize this error message, create %s'), APP_DIR . DS . 'views' . DS . 'errors' . DS . 'missing_table.ctp'); ?>
</p>
</p>
<?php echo $this->element('exception_stack_trace'); ?>

View file

@ -20,7 +20,7 @@
<h2><?php echo __('Missing View'); ?></h2>
<p class="error">
<strong><?php echo __('Error'); ?>: </strong>
<?php printf(__('The view for %1$s%2$s was not found.'), '<em>' . $controller . 'Controller::</em>', '<em>' . $action . '()</em>'); ?>
<?php printf(__('The view for %1$s%2$s was not found.'), '<em>' . Inflector::camelize($this->request->controller) . 'Controller::</em>', '<em>' . $this->request->action . '()</em>'); ?>
</p>
<p class="error">
<strong><?php echo __('Error'); ?>: </strong>
@ -29,4 +29,6 @@
<p class="notice">
<strong><?php echo __('Notice'); ?>: </strong>
<?php printf(__('If you want to customize this error message, create %s'), APP_DIR . DS . 'views' . DS . 'errors' . DS . 'missing_view.ctp'); ?>
</p>
</p>
<?php echo $this->element('exception_stack_trace'); ?>

View file

@ -25,4 +25,6 @@
<p class="notice">
<strong><?php echo __('Notice'); ?>: </strong>
<?php printf(__('If you want to customize this error message, create %s'), APP_DIR . DS . 'views' . DS . 'errors' . DS . 'private_action.ctp'); ?>
</p>
</p>
<?php echo $this->element('exception_stack_trace'); ?>

View file

@ -32,4 +32,6 @@ function _scaffoldError() {<br />
}
?&gt;
</pre>
</pre>
<?php echo $this->element('exception_stack_trace'); ?>

View file

@ -47,22 +47,6 @@ class Helper extends Object {
*/
protected $_helperMap = array();
/**
* Base URL
*
* @deprecated use $request->base instead
* @var string
*/
public $base = null;
/**
* Webroot path
*
* @deprecated use $request->webroot instead
* @var string
*/
public $webroot = null;
/**
* The current theme name if any.
*
@ -70,22 +54,6 @@ class Helper extends Object {
*/
public $theme = null;
/**
* URL to current action.
*
* @deprecated use $request->here instead
* @var string
*/
public $here = null;
/**
* Parameter array.
*
* @deprecated use $request instead
* @var array
*/
public $params = array();
/**
* Request object
*
@ -93,14 +61,6 @@ class Helper extends Object {
*/
public $request = null;
/**
* Current action.
*
* @deprecated use $request->action instead
* @var string
*/
public $action = null;
/**
* Plugin path
*
@ -108,14 +68,6 @@ class Helper extends Object {
*/
public $plugin = null;
/**
* POST data for models
*
* @deprecated use $request->data instead
* @var array
*/
public $data = null;
/**
* Contains model validation errors of form post-backs
*
@ -164,6 +116,7 @@ class Helper extends Object {
public function __construct(View $View, $settings = array()) {
$this->_View = $View;
$this->params = $View->params;
$this->request = $View->request;
if (!empty($this->helpers)) {
$this->_helperMap = ObjectCollection::normalizeObjectArray($this->helpers);
}
@ -180,7 +133,7 @@ class Helper extends Object {
}
/**
* Lazy loads helpers
* Lazy loads helpers. Provides access to deprecated request properties as well.
*
* @param string $name Name of the property being accessed.
* @return mixed Helper or property found at $name
@ -194,6 +147,35 @@ class Helper extends Object {
if (isset($this->{$name})) {
return $this->{$name};
}
switch ($name) {
case 'base':
case 'here':
case 'webroot':
case 'data':
return $this->request->{$name};
case 'action':
return isset($this->request->params['action']) ? $this->request->params['action'] : '';
case 'params':
return $this->request;
}
}
/**
* Provides backwards compatiblity access for setting values to the request object.
*
* @return void
*/
public function __set($name, $value) {
switch ($name) {
case 'base':
case 'here':
case 'webroot':
case 'data':
return $this->request->{$name} = $value;
case 'action':
return $this->request->params['action'] = $value;
}
return $this->{$name} = $value;
}
/**
@ -476,7 +458,11 @@ class Helper extends Object {
if (ClassRegistry::isKeySet($model)) {
$ModelObj =& ClassRegistry::getObject($model);
for ($i = 0; $i < $count; $i++) {
if ($ModelObj->hasField($parts[$i]) || array_key_exists($parts[$i], $ModelObj->validate)) {
if (
is_a($ModelObj, 'Model') &&
($ModelObj->hasField($parts[$i]) ||
array_key_exists($parts[$i], $ModelObj->validate))
) {
$hasField = $i;
if ($hasField === 0 || ($hasField === 1 && is_numeric($parts[0]))) {
$sameScope = true;
@ -722,13 +708,13 @@ class Helper extends Object {
$data = $this->request->data;
$entity = $this->_View->entity();
if (!empty($this->data) && !empty($entity)) {
$result = Set::extract($this->data, join('.', $entity));
if (!empty($data) && !empty($entity)) {
$result = Set::extract($data, join('.', $entity));
}
$habtmKey = $this->field();
if (empty($result) && isset($data[$habtmKey][$habtmKey])) {
$result = $this->data[$habtmKey][$habtmKey];
$result = $data[$habtmKey][$habtmKey];
} elseif (empty($result) && isset($data[$habtmKey]) && is_array($data[$habtmKey])) {
if (ClassRegistry::isKeySet($habtmKey)) {
$model =& ClassRegistry::getObject($habtmKey);

View file

@ -54,15 +54,21 @@ class HelperCollection extends ObjectCollection {
$helperClass = $name . 'Helper';
if (!class_exists($helperClass)) {
if (!App::import('Helper', $helper)) {
throw new MissingHelperFileException(Inflector::underscore($name) . '.php');
throw new MissingHelperFileException(array(
'class' => $helperClass,
'file' => Inflector::underscore($name) . '.php'
));
}
if (!class_exists($helperClass)) {
throw new MissingHelperClassException($helperClass);
throw new MissingHelperClassException(array(
'class' => $helperClass,
'file' => Inflector::underscore($name) . '.php'
));
}
}
$this->_loaded[$name] = new $helperClass($this->_View, $settings);
$vars = array('base', 'webroot', 'here', 'params', 'action', 'data', 'theme', 'plugin');
$vars = array('request', 'theme', 'plugin');
foreach ($vars as $var) {
$this->_loaded[$name]->{$var} = $this->_View->{$var};
}
@ -73,10 +79,4 @@ class HelperCollection extends ObjectCollection {
return $this->_loaded[$name];
}
}
/**
* Exceptions used by the HelperCollection.
*/
class MissingHelperFileException extends RuntimeException { }
class MissingHelperClassException extends RuntimeException { }
}

View file

@ -170,7 +170,7 @@ class FormHelper extends AppHelper {
* ### Options:
*
* - `type` Form method defaults to POST
* - `action` The Action the form submits to. Can be a string or array,
* - `action` The controller action the form submits to, (optional).
* - `url` The url the form submits to. Can be a string or a url array,
* - `default` Allows for the creation of Ajax forms.
* - `onsubmit` Used in conjunction with 'default' to create ajax forms.
@ -1449,7 +1449,8 @@ class FormHelper extends AppHelper {
$hiddenAttributes = array(
'value' => '',
'id' => $attributes['id'] . ($style ? '' : '_'),
'secure' => false
'secure' => false,
'name' => $attributes['name']
);
$select[] = $this->hidden(null, $hiddenAttributes);
} else {
@ -1483,7 +1484,7 @@ class FormHelper extends AppHelper {
$selected,
array(),
$showParents,
array('escape' => $escapeOptions, 'style' => $style)
array('escape' => $escapeOptions, 'style' => $style, 'name' => $attributes['name'])
));
$template = ($style == 'checkbox') ? 'checkboxmultipleend' : 'selectend';
@ -2027,7 +2028,7 @@ class FormHelper extends AppHelper {
$label['class'] = 'selected';
}
list($name) = array_values($this->_name());
$name = $attributes['name'];
if (empty($attributes['class'])) {
$attributes['class'] = 'checkbox';

View file

@ -21,7 +21,7 @@ if (Configure::read() == 0):
endif;
?>
<h2><?php echo sprintf(__('Release Notes for CakePHP %s.', true), Configure::version()); ?></h2>
<a href="http://cakephp.lighthouseapp.com/projects/42648/changelog-1-3-3"><?php __('Read the changelog'); ?> </a>
<a href="http://cakephp.lighthouseapp.com/projects/42648/changelog-1-3-4"><?php __('Read the changelog'); ?> </a>
<?php
if (Configure::read() > 0):
Debugger::checkSecurityKeys();
@ -106,7 +106,7 @@ You can also add some CSS styles for your pages at: APP/webroot/css.');
<p>
<?php
echo $this->Html->link(
sprintf('<strong>%s</strong>%s', __('new', true), __('CakePHP 1.3 Docs', true)),
sprintf('<strong>%s</strong> %s', __('New', true), __('CakePHP 1.3 Docs', true)),
'http://book.cakephp.org/view/875/x1-3-Collection',
array('target' => '_blank', 'escape' => false)
);
@ -115,8 +115,8 @@ You can also add some CSS styles for your pages at: APP/webroot/css.');
<p>
<?php
echo $this->Html->link(
__('The 15 min Blog Tutorial'),
'http://book.cakephp.org/view/219/the-cakephp-blog-tutorial',
__('The 15 min Blog Tutorial', true),
'http://book.cakephp.org/view/1528/Blog',
array('target' => '_blank', 'escape' => false)
);
?>

View file

@ -17,6 +17,7 @@
* @since CakePHP(tm) v 0.10.0.1076
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
App::import('View', 'View');
/**
* Theme view class
@ -39,7 +40,7 @@ class ThemeView extends View {
*/
function __construct(&$controller) {
parent::__construct($controller);
$this->theme =& $controller->theme;
$this->theme = $controller->theme;
}
/**

View file

@ -42,21 +42,6 @@ class View extends Object {
*/
public $Helpers;
/**
* Path parts for creating links in views.
*
* @var string Base URL
* @access public
*/
public $base = null;
/**
* Stores the current URL (for links etc.)
*
* @var string Current URL
*/
public $here = null;
/**
* Name of the plugin.
*
@ -73,21 +58,6 @@ class View extends Object {
*/
public $name = null;
/**
* Action to be performed.
*
* @var string Name of action
* @access public
*/
public $action = null;
/**
* Array of parameter data
*
* @var array Parameter data
*/
public $params = array();
/**
* Current passed params
*
@ -95,13 +65,6 @@ class View extends Object {
*/
public $passedArgs = array();
/**
* Array of data
*
* @var array Parameter data
*/
public $data = array();
/**
* An array of names of built-in helpers to include.
*
@ -269,6 +232,15 @@ class View extends Object {
*/
public $output = false;
/**
* An instance of a CakeRequest object that contains information about the current request.
* This object contains all the information about a request and several methods for reading
* additional information about the request.
*
* @var CakeRequest
*/
public $request;
/**
* List of variables to collect from the associated controller
*
@ -276,9 +248,8 @@ class View extends Object {
* @access protected
*/
private $__passedVars = array(
'viewVars', 'action', 'autoLayout', 'autoRender', 'ext', 'base', 'webroot',
'helpers', 'here', 'layout', 'name', 'layoutPath', 'viewPath',
'params', 'request', 'data', 'plugin', 'passedArgs', 'cacheAction'
'viewVars', 'autoLayout', 'autoRender', 'ext', 'helpers', 'layout', 'name',
'layoutPath', 'viewPath', 'request', 'plugin', 'passedArgs', 'cacheAction'
);
/**
@ -645,14 +616,26 @@ class View extends Object {
}
/**
* Magic accessor for helpers.
* Magic accessor for helpers. Provides access to attributes that were deprecated.
*
* @return void
* @param string $name Name of the attribute to get.
* @return mixed
*/
public function __get($name) {
if (isset($this->Helpers->{$name})) {
return $this->Helpers->{$name};
}
switch ($name) {
case 'base':
case 'here':
case 'webroot':
case 'data':
return $this->request->{$name};
case 'action':
return isset($this->request->params['action']) ? $this->request->params['action'] : '';
case 'params':
return $this->request;
}
return null;
}
@ -708,10 +691,10 @@ class View extends Object {
if ($caching) {
if (isset($this->Helpers->Cache)) {
$cache =& $this->Helpers->Cache;
$cache->base = $this->base;
$cache->here = $this->here;
$cache->base = $this->request->base;
$cache->here = $this->request->here;
$cache->helpers = $this->helpers;
$cache->action = $this->action;
$cache->action = $this->request->action;
$cache->controllerName = $this->name;
$cache->layout = $this->layout;
$cache->cacheAction = $this->cacheAction;
@ -791,7 +774,7 @@ class View extends Object {
}
}
}
throw new MissingViewException($defaultPath . $name . $this->ext);
throw new MissingViewException(array('file' => $defaultPath . $name . $this->ext));
}
/**
@ -824,7 +807,7 @@ class View extends Object {
}
}
}
throw new MissingLayoutException($paths[0] . $file . $this->ext);
throw new MissingLayoutException(array('file' => $paths[0] . $file . $this->ext));
}
/**
@ -855,6 +838,3 @@ class View extends Object {
return $this->__paths;
}
}
class MissingViewException extends RuntimeException { }
class MissingLayoutException extends RuntimeException { }

View file

@ -39,6 +39,7 @@ class AllShellsTest extends PHPUnit_Framework_TestSuite {
$path = CORE_TEST_CASES . DS . 'console' . DS . 'libs' . DS;
$suite->addTestFile(CORE_TEST_CASES . DS . 'console' . DS . 'cake.test.php');
$suite->addTestFile(CORE_TEST_CASES . DS . 'console' . DS . 'console_error_handler.test.php');
$tasks = array('acl', 'api', 'bake', 'schema', 'shell');
foreach ($tasks as $task) {
$suite->addTestFile($path . $task . '.test.php');

View file

@ -0,0 +1,109 @@
<?php
/**
* ConsoleErrorHandler Test case
*
* PHP versions 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @package cake
* @subpackage cake.cake.tests.cases.console
* @since CakePHP(tm) v 2.0
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
require_once CAKE . 'console' . DS . 'console_error_handler.php';
/**
* ConsoleErrorHandler Test case.
*
* @package cake.tests.cases.console
*/
class ConsoleErrorHandlerTest extends CakeTestCase {
/**
* Factory method for error handlers with stderr() mocked out.
*
* @return Mock object
*/
function getErrorHandler($exception) {
return $this->getMock('ConsoleErrorHandler', array('stderr'), array($exception));
}
/**
* test that the console error handler can deal with CakeExceptions.
*
* @return void
*/
function testCakeErrors() {
$exception = new MissingActionException('Missing action');
$error = $this->getErrorHandler($exception);
$error->expects($this->once())->method('stderr')
->with($this->stringContains('Missing action'));
$error->render();
}
/**
* test a non CakeException exception.
*
* @return void
*/
function testNonCakeExceptions() {
$exception = new InvalidArgumentException('Too many parameters.');
$error = $this->getErrorHandler($exception);
$error->expects($this->once())->method('stderr')
->with($this->stringContains('Too many parameters.'));
$error->render();
}
/**
* test a Error404 exception.
*
* @return void
*/
function testError404Exception() {
$exception = new NotFoundException('dont use me in cli.');
$error = $this->getErrorHandler($exception);
$error->expects($this->once())->method('stderr')
->with($this->stringContains('dont use me in cli.'));
$error->render();
}
/**
* test a Error500 exception.
*
* @return void
*/
function testError500Exception() {
$exception = new InternalErrorException('dont use me in cli.');
$error = $this->getErrorHandler($exception);
$error->expects($this->once())->method('stderr')
->with($this->stringContains('dont use me in cli.'));
$error->render();
}
/**
* test that ConsoleErrorHandler has a stderr file handle.
*
* @return void
*/
function testStdErrFilehandle() {
$exception = new InternalErrorException('dont use me in cli.');
$error = new ConsoleErrorHandler($exception);
$this->assertTrue(is_resource($error->stderr), 'No handle.');
}
}

View file

@ -63,7 +63,7 @@ class AclShellTest extends CakeTestCase {
Configure::write('Acl.classname', 'DbAcl');
$this->Dispatcher = $this->getMock(
'ShellDispather',
'ShellDispatcher',
array('getInput', 'stdout', 'stderr', '_stop', '_initEnvironment', 'dispatch')
);
$this->Task = $this->getMock(
@ -71,7 +71,8 @@ class AclShellTest extends CakeTestCase {
array('in', 'out', 'hr', 'createFile', 'error', 'err'),
array(&$this->Dispatcher)
);
$this->Task->Acl = new AclComponent();
$collection = new ComponentCollection();
$this->Task->Acl = new AclComponent($collection);
$this->Task->params['datasource'] = 'test_suite';
}

View file

@ -84,21 +84,22 @@ class ApiShellTest extends CakeTestCase {
'4. constructClasses()',
'5. disableCache()',
'6. flash($message, $url, $pause = 1, $layout = \'flash\')',
'7. header($status)',
'8. httpCodes($code = NULL)',
'9. isAuthorized()',
'10. loadModel($modelClass = NULL, $id = NULL)',
'11. paginate($object = NULL, $scope = array (), $whitelist = array ())',
'12. postConditions($data = array (), $op = NULL, $bool = \'AND\', $exclusive = false)',
'13. redirect($url, $status = NULL, $exit = true)',
'14. referer($default = NULL, $local = false)',
'15. render($action = NULL, $layout = NULL, $file = NULL)',
'16. set($one, $two = NULL)',
'17. setAction($action)',
'18. shutdownProcess()',
'19. startupProcess()',
'20. validate()',
'21. validateErrors()'
'7. getResponse()',
'8. header($status)',
'9. httpCodes($code = NULL)',
'10. isAuthorized()',
'11. loadModel($modelClass = NULL, $id = NULL)',
'12. paginate($object = NULL, $scope = array (), $whitelist = array ())',
'13. postConditions($data = array (), $op = NULL, $bool = \'AND\', $exclusive = false)',
'14. redirect($url, $status = NULL, $exit = true)',
'15. referer($default = NULL, $local = false)',
'16. render($action = NULL, $layout = NULL, $file = NULL)',
'17. set($one, $two = NULL)',
'18. setAction($action)',
'19. shutdownProcess()',
'20. startupProcess()',
'21. validate()',
'22. validateErrors()'
);
$this->Shell->expects($this->at(2))->method('out')->with($expected);

View file

@ -91,10 +91,10 @@ class BakeShellTest extends CakeTestCase {
if ($this->skipIf($userExists, 'User class exists, cannot test `bake all [param]`. %s')) {
return;
}
$this->Shell->Model = $this->getMock('ModelTask', array(), array(&$this->Dispatch));
$this->Shell->Controller = $this->getMock('ControllerTask', array(), array(&$this->Dispatch));
$this->Shell->View = $this->getMock('ModelTask', array(), array(&$this->Dispatch));
$this->Shell->DbConfig = $this->getMock('DbConfigTask', array(), array(&$this->Dispatch));
$this->Shell->Model = $this->getMock('ModelTask', array(), array(&$this->Dispatcher));
$this->Shell->Controller = $this->getMock('ControllerTask', array(), array(&$this->Dispatcher));
$this->Shell->View = $this->getMock('ModelTask', array(), array(&$this->Dispatcher));
$this->Shell->DbConfig = $this->getMock('DbConfigTask', array(), array(&$this->Dispatcher));
$this->Shell->DbConfig->expects($this->once())->method('getConfig')->will($this->returnValue('test_suite'));

View file

@ -328,6 +328,8 @@ class ControllerTaskTest extends CakeTestCase {
$this->Task->plugin = 'controllerTest';
$path = APP . 'plugins' . DS . 'controller_test' . DS . 'controllers' . DS . 'articles_controller.php';
$this->Task->bake('Articles', '--actions--', array(), array(), array());
$this->assertEqual($this->Task->Template->templateVars['plugin'], 'ControllerTest');
}
/**

View file

@ -87,8 +87,8 @@ class FixtureTaskTest extends CakeTestCase {
* @return void
*/
public function testConstruct() {
$this->Dispatch->params['working'] = DS . 'my' . DS . 'path';
$Task = new FixtureTask($this->Dispatch);
$this->Dispatcher->params['working'] = DS . 'my' . DS . 'path';
$Task = new FixtureTask($this->Dispatcher);
$expected = DS . 'my' . DS . 'path' . DS . 'tests' . DS . 'fixtures' . DS;
$this->assertEqual($Task->path, $expected);

View file

@ -179,7 +179,7 @@ class ModelTaskTest extends CakeTestCase {
* @return void
*/
function testGetNameWithOutOfBoundsOption() {
$this->Task->expects($this->any())->method('in')->will($this->onConsecutiveCalls(10, 1));
$this->Task->expects($this->any())->method('in')->will($this->onConsecutiveCalls(99, 1));
$this->Task->expects($this->once())->method('err');
$result = $this->Task->getName('test_suite');

View file

@ -368,7 +368,7 @@ class TestTaskTest extends CakeTestCase {
)
));
$keys = ClassRegistry::keys();
$this->assertTrue(in_array('random', $keys));
$this->assertTrue(in_array('test_task_comment', $keys));
$object =& $this->Task->buildTestSubject('Model', 'TestTaskComment');
$keys = ClassRegistry::keys();

View file

@ -380,6 +380,19 @@ class ViewTaskTest extends CakeTestCase {
$this->Task->bake('index', true);
}
/**
* test that baking a view with no template doesn't make a file.
*
* @return void
*/
function testBakeWithNoTemplate() {
$this->Task->controllerName = 'ViewTaskComments';
$this->Task->controllerPath = 'view_task_comments';
$this->Task->expectNever('createFile');
$this->Task->bake('delete', true);
}
/**
* test bake() with a -plugin param
*

View file

@ -707,6 +707,23 @@ class DispatcherTest extends CakeTestCase {
$this->assertEqual($result['url']['coffee'], 'life');
}
/**
* testMissingController method
*
* @return void
*/
public function testMissingController() {
try {
$Dispatcher = new TestDispatcher();
Configure::write('App.baseUrl', '/index.php');
$url = 'some_controller/home/param:value/param2:value2';
$controller = $Dispatcher->dispatch($url, array('return' => 1));
$this->fail('No exception thrown');
} catch (MissingControllerException $e) {
$this->assertEquals('Controller class SomeControllerController could not be found.', $e->getMessage());
}
}
/**
* testPrivate method
*
@ -717,16 +734,14 @@ class DispatcherTest extends CakeTestCase {
Configure::write('App.baseUrl','/index.php');
$url = 'some_pages/_protected/param:value/param2:value2';
$controller = $Dispatcher->dispatch($url, array('return' => 1));
$expected = array('privateAction', array(array(
'className' => 'SomePagesController',
'action' => '_protected',
'webroot' => '/',
'url' => 'some_pages/_protected/param:value/param2:value2',
'base' => '/index.php'
)));
$this->assertEqual($controller, $expected);
try {
$controller = $Dispatcher->dispatch($url, array('return' => 1));
$this->fail('No exception thrown');
} catch (PrivateActionException $e) {
$this->assertEquals(
'Private Action SomePagesController::_protected() is not directly accessible.', $e->getMessage()
);
}
}
/**
@ -739,31 +754,30 @@ class DispatcherTest extends CakeTestCase {
Configure::write('App.baseUrl', '/index.php');
$url = 'some_pages/home/param:value/param2:value2';
$controller = $Dispatcher->dispatch($url, array('return'=> 1));
$expected = array('missingAction', array(array(
'className' => 'SomePagesController',
'action' => 'home',
'webroot' => '/',
'url' => '/index.php/some_pages/home/param:value/param2:value2',
'base' => '/index.php'
)));
$this->assertEqual($expected, $controller);
try {
$controller = $Dispatcher->dispatch($url, array('return'=> 1));
$this->fail('No exception thrown');
} catch (MissingActionException $e) {
$this->assertEquals('Action SomePagesController::home() could not be found.', $e->getMessage());
}
}
/**
* test that methods declared in Controller are treated as missing methods.
*
* @return void
*/
function testMissingActionFromBaseClassMethods() {
$Dispatcher = new TestDispatcher();
Configure::write('App.baseUrl','/index.php');
$url = 'some_pages/redirect/param:value/param2:value2';
$controller = $Dispatcher->dispatch($url, array('return'=> 1));
$expected = array('missingAction', array(array(
'className' => 'SomePagesController',
'action' => 'redirect',
'webroot' => '/',
'url' => '/index.php/some_pages/redirect/param:value/param2:value2',
'base' => '/index.php'
)));
$this->assertEqual($expected, $controller);
try {
$controller = $Dispatcher->dispatch($url, array('return'=> 1));
$this->fail('No exception thrown');
} catch (MissingActionException $e) {
$this->assertEquals('Action SomePagesController::redirect() could not be found.', $e->getMessage());
}
}
/**
@ -840,7 +854,6 @@ class DispatcherTest extends CakeTestCase {
Router::reload();
Configure::write('App.baseUrl', '/index.php');
$Dispatcher = new TestDispatcher();
Configure::write('App.baseUrl','/index.php');
$url = array('controller' => 'pages', 'action' => 'display');
$controller = $Dispatcher->dispatch($url, array(
@ -854,7 +867,7 @@ class DispatcherTest extends CakeTestCase {
$expected = array('0' => 'home', 'param' => 'value', 'param2' => 'value2');
$this->assertIdentical($expected, $controller->passedArgs);
$this->assertEqual($Dispatcher->base . '/pages/display/home/param:value/param2:value2', $Dispatcher->here);
$this->assertEqual($Dispatcher->request->base . '/pages/display/home/param:value/param2:value2', $Dispatcher->request->here);
}
/**
@ -1139,32 +1152,25 @@ class DispatcherTest extends CakeTestCase {
$Dispatcher->base = false;
$url = 'my_plugin/not_here/param:value/param2:value2';
$controller = $Dispatcher->dispatch($url, array('return'=> 1));
$expected = array('missingAction', array(array(
'className' => 'MyPluginController',
'action' => 'not_here',
'webroot' => '/cake/repo/branches/1.2.x.x/',
'url' => '/cake/repo/branches/1.2.x.x/my_plugin/not_here/param:value/param2:value2',
'base' => '/cake/repo/branches/1.2.x.x'
)));
$this->assertIdentical($expected, $controller);
try {
$controller = $Dispatcher->dispatch($url, array('return'=> 1));
$this->fail('No exception.');
} catch (MissingActionException $e) {
$this->assertEquals('Action MyPluginController::not_here() could not be found.', $e->getMessage());
}
Router::reload();
$Dispatcher = new TestDispatcher();
$Dispatcher->base = false;
$url = 'my_plugin/param:value/param2:value2';
$controller = $Dispatcher->dispatch($url, array('return'=> 1));
$expected = array('missingAction', array(array(
'className' => 'MyPluginController',
'action' => 'param:value',
'webroot' => '/cake/repo/branches/1.2.x.x/',
'url' => '/cake/repo/branches/1.2.x.x/my_plugin/param:value/param2:value2',
'base' => '/cake/repo/branches/1.2.x.x'
)));
$this->assertIdentical($expected, $controller);
try {
$controller = $Dispatcher->dispatch($url, array('return'=> 1));
$this->fail('No exception.');
} catch (MissingActionException $e) {
$this->assertEquals('Action MyPluginController::param:value() could not be found.', $e->getMessage());
}
}
/**
@ -1182,16 +1188,15 @@ class DispatcherTest extends CakeTestCase {
$Dispatcher = new TestDispatcher();
$url = 'test_dispatch_pages/admin_index/param:value/param2:value2';
$controller = $Dispatcher->dispatch($url, array('return' => 1));
$expected = array('privateAction', array(array(
'className' => 'TestDispatchPagesController',
'action' => 'admin_index',
'webroot' => '/cake/repo/branches/1.2.x.x/',
'url' => 'test_dispatch_pages/admin_index/param:value/param2:value2',
'base' => '/cake/repo/branches/1.2.x.x'
)));
$this->assertIdentical($expected, $controller);
try {
$controller = $Dispatcher->dispatch($url, array('return'=> 1));
$this->fail('No exception.');
} catch (PrivateActionException $e) {
$this->assertEquals(
'Private Action TestDispatchPagesController::admin_index() is not directly accessible.',
$e->getMessage()
);
}
}
/**
@ -1230,16 +1235,13 @@ class DispatcherTest extends CakeTestCase {
$_SERVER['PHP_SELF'] = '/cake/repo/branches/1.2.x.x/index.php';
$Dispatcher = new TestDispatcher();
$url = 'some_posts/index/param:value/param2:value2';
$controller = $Dispatcher->dispatch($url, array('return' => 1));
$expected = array('missingAction', array(array(
'className' => 'SomePostsController',
'action' => 'view',
'webroot' => '/cake/repo/branches/1.2.x.x/',
'url' => '/cake/repo/branches/1.2.x.x/some_posts/index/param:value/param2:value2',
'base' => '/cake/repo/branches/1.2.x.x'
)));
$this->assertEqual($expected, $controller);
try {
$controller = $Dispatcher->dispatch($url, array('return'=> 1));
$this->fail('No exception.');
} catch (MissingActionException $e) {
$this->assertEquals('Action SomePostsController::view() could not be found.', $e->getMessage());
}
$url = 'some_posts/something_else/param:value/param2:value2';
$controller = $Dispatcher->dispatch($url, array('return' => 1));
@ -1273,15 +1275,19 @@ class DispatcherTest extends CakeTestCase {
$debug = Configure::read('debug');
//Configure::write('debug', 0);
ob_start();
$Dispatcher->dispatch('theme/test_theme/../webroot/css/test_asset.css');
$result = ob_get_clean();
$this->assertEquals($result, '');
ob_start();
$Dispatcher->dispatch('theme/test_theme/pdfs');
$result = ob_get_clean();
$this->assertEquals($result, '');
try {
$Dispatcher->dispatch('theme/test_theme/../webroot/css/test_asset.css');
$this->fail('No exception');
} catch (MissingControllerException $e) {
$this->assertEquals('Controller class ThemeController could not be found.', $e->getMessage());
}
try {
$Dispatcher->dispatch('theme/test_theme/pdfs');
$this->fail('No exception');
} catch (MissingControllerException $e) {
$this->assertEquals('Controller class ThemeController could not be found.', $e->getMessage());
}
ob_start();
$Dispatcher->dispatch('theme/test_theme/flash/theme_test.swf');
@ -1581,50 +1587,6 @@ class DispatcherTest extends CakeTestCase {
unlink($filename);
}
/**
* test that cached() registers a view and un-registers it. Tests
* that helpers using don't fail
*
* @return void
*/
function testCachedRegisteringViewObject() {
Configure::write('Cache.disable', false);
Configure::write('Cache.check', true);
Configure::write('debug', 2);
$_POST = array();
$_SERVER['PHP_SELF'] = '/';
Router::reload();
App::build(array(
'views' => array(TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'views'. DS)
));
$dispatcher = new TestDispatcher();
$dispatcher->response = $this->getMock('CakeResponse', array('_sendHeader'));
$dispatcher->base = false;
$url = 'test_cached_pages/cache_form';
ob_start();
$dispatcher->dispatch($url);
$out = ob_get_clean();
ClassRegistry::flush();
ob_start();
$dispatcher->cached($url);
$cached = ob_get_clean();
$result = str_replace(array("\t", "\r\n", "\n"), "", $out);
$cached = preg_replace('/<!--+[^<>]+-->/', '', $cached);
$expected = str_replace(array("\t", "\r\n", "\n"), "", $cached);
$this->assertEqual($result, $expected);
$filename = $this->__cachePath($dispatcher->here);
@unlink($filename);
ClassRegistry::flush();
}
/**
* testHttpMethodOverrides method
*
@ -1686,29 +1648,6 @@ class DispatcherTest extends CakeTestCase {
unset($_POST['_method']);
}
/**
* Tests that the Dispatcher does not return an empty action
*
* @return void
*/
public function testTrailingSlash() {
$_POST = array();
$_SERVER['PHP_SELF'] = '/cake/repo/branches/1.2.x.x/index.php';
Router::reload();
$Dispatcher = new TestDispatcher();
Router::connect('/myalias/:action/*', array('controller' => 'my_controller', 'action' => null));
$Dispatcher->base = false;
$url = 'myalias/'; //Fails
$result = $Dispatcher->parseParams(new CakeRequest($url));
$this->assertEqual('index', $result['action']);
$url = 'myalias'; //Passes
$result = $Dispatcher->parseParams(new CakeRequest($url));
$this->assertEqual('index', $result['action']);
}
/**
* backupEnvironment method
*

View file

@ -36,7 +36,7 @@ class AllBehaviorsTest extends PHPUnit_Framework_TestSuite {
$suite = new PHPUnit_Framework_TestSuite('Model Behavior and all behaviors');
$path = CORE_TEST_CASES . DS . 'libs' . DS . 'model' . DS . 'behaviors' . DS;
$suite->addTestFile(CORE_TEST_CASES . DS . 'libs' . DS . 'model' . DS . 'model_behavior.test.php');
$suite->addTestFile(CORE_TEST_CASES . DS . 'libs' . DS . 'model' . DS . 'behavior_collection.test.php');
$suite->addTestFile($path . 'acl.test.php');
// $suite->addTestFile($path . 'containable.test.php');

View file

@ -39,7 +39,7 @@ class AllLibsTest extends PHPUnit_Framework_TestSuite {
$suite->addTestFile(CORE_TEST_CASES . DS . 'basics.test.php');
$suite->addTestFile(CORE_TEST_CASES . DS . 'libs' . DS . 'cake_session.test.php');
$suite->addTestFile(CORE_TEST_CASES . DS . 'libs' . DS . 'debugger.test.php');
$suite->addTestFile(CORE_TEST_CASES . DS . 'libs' . DS . 'error.test.php');
$suite->addTestFile(CORE_TEST_CASES . DS . 'libs' . DS . 'error_handler.test.php');
$suite->addTestFile(CORE_TEST_CASES . DS . 'libs' . DS . 'file.test.php');
$suite->addTestFile(CORE_TEST_CASES . DS . 'libs' . DS . 'folder.test.php');
$suite->addTestFile(CORE_TEST_CASES . DS . 'libs' . DS . 'log' . DS . 'file_log.test.php');

View file

@ -172,12 +172,10 @@ class CacheTest extends CakeTestCase {
function testConfigSettingDefaultConfigKey() {
Cache::config('test_name', array('engine' => 'File', 'prefix' => 'test_name_'));
Cache::config('test_name');
Cache::write('value_one', 'I am cached');
$result = Cache::read('value_one');
Cache::write('value_one', 'I am cached', 'test_name');
$result = Cache::read('value_one', 'test_name');
$this->assertEqual($result, 'I am cached');
Cache::config('default');
$result = Cache::read('value_one');
$this->assertEqual($result, null);
@ -185,13 +183,11 @@ class CacheTest extends CakeTestCase {
$result = Cache::read('value_one');
$this->assertEqual($result, 'I am in default config!');
Cache::config('test_name');
$result = Cache::read('value_one');
$result = Cache::read('value_one', 'test_name');
$this->assertEqual($result, 'I am cached');
Cache::delete('value_one');
Cache::config('default');
Cache::delete('value_one');
Cache::delete('value_one', 'test_name');
Cache::delete('value_one', 'default');
}
/**
@ -345,34 +341,34 @@ class CacheTest extends CakeTestCase {
Configure::write('Cache.disable', false);
Cache::config('test_cache_disable_1', array('engine'=> 'File', 'path' => TMP . 'tests'));
$this->assertTrue(Cache::write('key_1', 'hello'));
$this->assertIdentical(Cache::read('key_1'), 'hello');
$this->assertTrue(Cache::write('key_1', 'hello', 'test_cache_disable_1'));
$this->assertIdentical(Cache::read('key_1', 'test_cache_disable_1'), 'hello');
Configure::write('Cache.disable', true);
$this->assertFalse(Cache::write('key_2', 'hello'));
$this->assertFalse(Cache::read('key_2'));
$this->assertFalse(Cache::write('key_2', 'hello', 'test_cache_disable_1'));
$this->assertFalse(Cache::read('key_2', 'test_cache_disable_1'));
Configure::write('Cache.disable', false);
$this->assertTrue(Cache::write('key_3', 'hello'));
$this->assertIdentical(Cache::read('key_3'), 'hello');
$this->assertTrue(Cache::write('key_3', 'hello', 'test_cache_disable_1'));
$this->assertIdentical(Cache::read('key_3', 'test_cache_disable_1'), 'hello');
Configure::write('Cache.disable', true);
Cache::config('test_cache_disable_2', array('engine'=> 'File', 'path' => TMP . 'tests'));
$this->assertFalse(Cache::write('key_4', 'hello'));
$this->assertFalse(Cache::read('key_4'));
$this->assertFalse(Cache::write('key_4', 'hello', 'test_cache_disable_2'));
$this->assertFalse(Cache::read('key_4', 'test_cache_disable_2'));
Configure::write('Cache.disable', false);
$this->assertTrue(Cache::write('key_5', 'hello'));
$this->assertIdentical(Cache::read('key_5'), 'hello');
$this->assertTrue(Cache::write('key_5', 'hello', 'test_cache_disable_2'));
$this->assertIdentical(Cache::read('key_5', 'test_cache_disable_2'), 'hello');
Configure::write('Cache.disable', true);
$this->assertFalse(Cache::write('key_6', 'hello'));
$this->assertFalse(Cache::read('key_6'));
$this->assertFalse(Cache::write('key_6', 'hello', 'test_cache_disable_2'));
$this->assertFalse(Cache::read('key_6', 'test_cache_disable_2'));
}
/**
@ -403,4 +399,17 @@ class CacheTest extends CakeTestCase {
Cache::set($_cacheSet);
}
/**
* test set() parameter handling for user cache configs.
*
* @return void
*/
function testSetOnAlternateConfigs() {
Cache::config('file_config', array('engine' => 'File', 'prefix' => 'test_file_'));
Cache::set(array('duration' => '+1 year'), 'file_config');
$settings = Cache::settings('file_config');
$this->assertEquals('test_file_', $settings['prefix']);
$this->assertEquals(31536000, $settings['duration']);
}
}

View file

@ -74,21 +74,21 @@ class ApcEngineTest extends CakeTestCase {
* @return void
*/
function testReadAndWriteCache() {
Cache::set(array('duration' => 1));
Cache::set(array('duration' => 1), 'apc');
$result = Cache::read('test');
$result = Cache::read('test', 'apc');
$expecting = '';
$this->assertEqual($result, $expecting);
$data = 'this is a test of the emergency broadcasting system';
$result = Cache::write('test', $data);
$result = Cache::write('test', $data, 'apc');
$this->assertTrue($result);
$result = Cache::read('test');
$result = Cache::read('test', 'apc');
$expecting = $data;
$this->assertEqual($result, $expecting);
Cache::delete('test');
Cache::delete('test', 'apc');
}
/**
@ -98,31 +98,31 @@ class ApcEngineTest extends CakeTestCase {
* @return void
*/
function testExpiry() {
Cache::set(array('duration' => 1));
Cache::set(array('duration' => 1), 'apc');
$result = Cache::read('test');
$result = Cache::read('test', 'apc');
$this->assertFalse($result);
$data = 'this is a test of the emergency broadcasting system';
$result = Cache::write('other_test', $data);
$result = Cache::write('other_test', $data, 'apc');
$this->assertTrue($result);
sleep(2);
$result = Cache::read('other_test');
$result = Cache::read('other_test', 'apc');
$this->assertFalse($result);
Cache::set(array('duration' => 1));
Cache::set(array('duration' => 1), 'apc');
$data = 'this is a test of the emergency broadcasting system';
$result = Cache::write('other_test', $data);
$result = Cache::write('other_test', $data, 'apc');
$this->assertTrue($result);
sleep(2);
$result = Cache::read('other_test');
$result = Cache::read('other_test', 'apc');
$this->assertFalse($result);
sleep(2);
$result = Cache::read('other_test');
$result = Cache::read('other_test', 'apc');
$this->assertFalse($result);
}
@ -134,10 +134,10 @@ class ApcEngineTest extends CakeTestCase {
*/
function testDeleteCache() {
$data = 'this is a test of the emergency broadcasting system';
$result = Cache::write('delete_test', $data);
$result = Cache::write('delete_test', $data, 'apc');
$this->assertTrue($result);
$result = Cache::delete('delete_test');
$result = Cache::delete('delete_test', 'apc');
$this->assertTrue($result);
}
@ -151,19 +151,19 @@ class ApcEngineTest extends CakeTestCase {
if ($this->skipIf(!function_exists('apc_dec'), 'No apc_dec() function, cannot test decrement() %s')) {
return;
}
$result = Cache::write('test_decrement', 5);
$result = Cache::write('test_decrement', 5, 'apc');
$this->assertTrue($result);
$result = Cache::decrement('test_decrement');
$result = Cache::decrement('test_decrement', 1, 'apc');
$this->assertEqual(4, $result);
$result = Cache::read('test_decrement');
$result = Cache::read('test_decrement', 'apc');
$this->assertEqual(4, $result);
$result = Cache::decrement('test_decrement', 2);
$result = Cache::decrement('test_decrement', 2, 'apc');
$this->assertEqual(2, $result);
$result = Cache::read('test_decrement');
$result = Cache::read('test_decrement', 'apc');
$this->assertEqual(2, $result);
}
@ -178,19 +178,32 @@ class ApcEngineTest extends CakeTestCase {
if ($this->skipIf(!function_exists('apc_inc'), 'No apc_inc() function, cannot test increment() %s')) {
return;
}
$result = Cache::write('test_increment', 5);
$result = Cache::write('test_increment', 5, 'apc');
$this->assertTrue($result);
$result = Cache::increment('test_increment');
$result = Cache::increment('test_increment', 1, 'apc');
$this->assertEqual(6, $result);
$result = Cache::read('test_increment');
$result = Cache::read('test_increment', 'apc');
$this->assertEqual(6, $result);
$result = Cache::increment('test_increment', 2);
$result = Cache::increment('test_increment', 2, 'apc');
$this->assertEqual(8, $result);
$result = Cache::read('test_increment');
$result = Cache::read('test_increment', 'apc');
$this->assertEqual(8, $result);
}
/**
* test the clearing of cache keys
*
* @return void
*/
function testClear() {
Cache::write('some_value', 'value', 'apc');
$result = Cache::clear(false, 'apc');
$this->assertTrue($result);
$this->assertFalse(Cache::read('some_value', 'apc'));
}
}

View file

@ -78,7 +78,7 @@ class MemcacheEngineTest extends CakeTestCase {
* @return void
*/
function testSettings() {
$settings = Cache::settings();
$settings = Cache::settings('memcache');
unset($settings['serialize'], $settings['path']);
$expecting = array(
'prefix' => 'cake_',
@ -141,21 +141,21 @@ class MemcacheEngineTest extends CakeTestCase {
* @return void
*/
function testReadAndWriteCache() {
Cache::set(array('duration' => 1));
Cache::set(array('duration' => 1), null, 'memcache');
$result = Cache::read('test');
$result = Cache::read('test', 'memcache');
$expecting = '';
$this->assertEqual($result, $expecting);
$data = 'this is a test of the emergency broadcasting system';
$result = Cache::write('test', $data);
$result = Cache::write('test', $data, 'memcache');
$this->assertTrue($result);
$result = Cache::read('test');
$result = Cache::read('test', 'memcache');
$expecting = $data;
$this->assertEqual($result, $expecting);
Cache::delete('test');
Cache::delete('test', 'memcache');
}
/**
@ -165,48 +165,45 @@ class MemcacheEngineTest extends CakeTestCase {
* @return void
*/
function testExpiry() {
Cache::set(array('duration' => 1));
Cache::set(array('duration' => 1), 'memcache');
$result = Cache::read('test');
$result = Cache::read('test', 'memcache');
$this->assertFalse($result);
$data = 'this is a test of the emergency broadcasting system';
$result = Cache::write('other_test', $data);
$result = Cache::write('other_test', $data, 'memcache');
$this->assertTrue($result);
sleep(2);
$result = Cache::read('other_test');
$result = Cache::read('other_test', 'memcache');
$this->assertFalse($result);
Cache::set(array('duration' => "+1 second"));
Cache::set(array('duration' => "+1 second"), 'memcache');
$data = 'this is a test of the emergency broadcasting system';
$result = Cache::write('other_test', $data);
$result = Cache::write('other_test', $data, 'memcache');
$this->assertTrue($result);
sleep(2);
$result = Cache::read('other_test');
$result = Cache::read('other_test', 'memcache');
$this->assertFalse($result);
Cache::config('memcache', array('duration' => '+1 second'));
sleep(2);
$result = Cache::read('other_test');
$result = Cache::read('other_test', 'memcache');
$this->assertFalse($result);
Cache::config('memcache', array('duration' => '+31 day'));
Cache::config('memcache', array('duration' => '+30 days'));
$data = 'this is a test of the emergency broadcasting system';
$result = Cache::write('long_expiry_test', $data);
$result = Cache::write('long_expiry_test', $data, 'memcache');
$this->assertTrue($result);
sleep(2);
$result = Cache::read('long_expiry_test');
$result = Cache::read('long_expiry_test', 'memcache');
$expecting = $data;
$this->assertEqual($result, $expecting);
$result = Cache::read('long_expiry_test');
$this->assertEquals($expecting, $result);
Cache::config('memcache', array('duration' => 3600));
}
@ -218,10 +215,10 @@ class MemcacheEngineTest extends CakeTestCase {
*/
function testDeleteCache() {
$data = 'this is a test of the emergency broadcasting system';
$result = Cache::write('delete_test', $data);
$result = Cache::write('delete_test', $data, 'memcache');
$this->assertTrue($result);
$result = Cache::delete('delete_test');
$result = Cache::delete('delete_test', 'memcache');
$this->assertTrue($result);
}
@ -232,19 +229,19 @@ class MemcacheEngineTest extends CakeTestCase {
* @return void
*/
function testDecrement() {
$result = Cache::write('test_decrement', 5);
$result = Cache::write('test_decrement', 5, 'memcache');
$this->assertTrue($result);
$result = Cache::decrement('test_decrement');
$result = Cache::decrement('test_decrement', 1, 'memcache');
$this->assertEqual(4, $result);
$result = Cache::read('test_decrement');
$result = Cache::read('test_decrement', 'memcache');
$this->assertEqual(4, $result);
$result = Cache::decrement('test_decrement', 2);
$result = Cache::decrement('test_decrement', 2, 'memcache');
$this->assertEqual(2, $result);
$result = Cache::read('test_decrement');
$result = Cache::read('test_decrement', 'memcache');
$this->assertEqual(2, $result);
}
@ -255,19 +252,19 @@ class MemcacheEngineTest extends CakeTestCase {
* @return void
*/
function testIncrement() {
$result = Cache::write('test_increment', 5);
$result = Cache::write('test_increment', 5, 'memcache');
$this->assertTrue($result);
$result = Cache::increment('test_increment');
$result = Cache::increment('test_increment', 1, 'memcache');
$this->assertEqual(6, $result);
$result = Cache::read('test_increment');
$result = Cache::read('test_increment', 'memcache');
$this->assertEqual(6, $result);
$result = Cache::increment('test_increment', 2);
$result = Cache::increment('test_increment', 2, 'memcache');
$this->assertEqual(8, $result);
$result = Cache::read('test_increment');
$result = Cache::read('test_increment', 'memcache');
$this->assertEqual(8, $result);
}
@ -306,4 +303,16 @@ class MemcacheEngineTest extends CakeTestCase {
Cache::delete('short_duration_test', 'short_memcache');
}
/**
* test clearing memcache.
*
* @return void
*/
function testClear() {
Cache::write('some_value', 'value', 'memcache');
$result = Cache::clear(false, 'memcache');
$this->assertTrue($result);
$this->assertFalse(Cache::read('some_value', 'memcache'));
}
}

View file

@ -1,4 +1,25 @@
<?php
/**
* CakeRequest Test case file.
*
* PHP 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @package cake
* @subpackage cake.tests.cases.libs
* @since CakePHP(tm) v 2.0
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
if (!class_exists('dispatcher')) {
require CAKE . 'dispatcher.php';
}
App::import('Core', 'CakeRequest');
class CakeRequestTestCase extends CakeTestCase {
@ -500,6 +521,66 @@ class CakeRequestTestCase extends CakeTestCase {
$this->assertFalse($request->is('delete'));
}
/**
* test the method() method.
*
* @return void
*/
function testMethod() {
$_SERVER['REQUEST_METHOD'] = 'delete';
$request = new CakeRequest('some/path');
$this->assertEquals('delete', $request->method());
}
/**
* test host retrieval.
*
* @return void
*/
function testHost() {
$_SERVER['HTTP_HOST'] = 'localhost';
$request = new CakeRequest('some/path');
$this->assertEquals('localhost', $request->host());
}
/**
* test domain retrieval.
*
* @return void
*/
function testDomain() {
$_SERVER['HTTP_HOST'] = 'something.example.com';
$request = new CakeRequest('some/path');
$this->assertEquals('example.com', $request->domain());
$_SERVER['HTTP_HOST'] = 'something.example.co.uk';
$this->assertEquals('example.co.uk', $request->domain(2));
}
/**
* test getting subdomains for a host.
*
* @return void
*/
function testSubdomain() {
$_SERVER['HTTP_HOST'] = 'something.example.com';
$request = new CakeRequest('some/path');
$this->assertEquals(array('something'), $request->subdomains());
$_SERVER['HTTP_HOST'] = 'www.something.example.com';
$this->assertEquals(array('www', 'something'), $request->subdomains());
$_SERVER['HTTP_HOST'] = 'www.something.example.co.uk';
$this->assertEquals(array('www', 'something'), $request->subdomains(2));
$_SERVER['HTTP_HOST'] = 'example.co.uk';
$this->assertEquals(array(), $request->subdomains(2));
}
/**
* test ajax, flash and friends
*
@ -618,10 +699,10 @@ class CakeRequestTestCase extends CakeTestCase {
$request->addDetector('compare', array('env' => 'TEST_VAR', 'value' => 'something'));
$_SERVER['TEST_VAR'] = 'something';
$this->assertTrue($request->is('compare'), 'Value match failed %s.');
$this->assertTrue($request->is('compare'), 'Value match failed.');
$_SERVER['TEST_VAR'] = 'wrong';
$this->assertFalse($request->is('compare'), 'Value mis-match failed %s.');
$this->assertFalse($request->is('compare'), 'Value mis-match failed.');
$request->addDetector('banana', array('env' => 'TEST_VAR', 'pattern' => '/^ban.*$/'));
$_SERVER['TEST_VAR'] = 'banana';
@ -1181,6 +1262,68 @@ class CakeRequestTestCase extends CakeTestCase {
$this->assertEqual($request->base, $expected);
}
/**
* test the data() method reading
*
* @return void
*/
function testDataReading() {
$_POST['data'] = array(
'Model' => array(
'field' => 'value'
)
);
$request = new CakeRequest('posts/index');
$result = $request->data('Model');
$this->assertEquals($_POST['data']['Model'], $result);
$result = $request->data('Model.imaginary');
$this->assertNull($result);
}
/**
* test writing with data()
*
* @return void
*/
function testDataWriting() {
$_POST['data'] = array(
'Model' => array(
'field' => 'value'
)
);
$request = new CakeRequest('posts/index');
$result = $request->data('Model.new_value', 'new value');
$this->assertSame($result, $request, 'Return was not $this');
$this->assertEquals($request->data['Model']['new_value'], 'new value');
$request->data('Post.title', 'New post')->data('Comment.1.author', 'Mark');
$this->assertEquals($request->data['Post']['title'], 'New post');
$this->assertEquals($request->data['Comment']['1']['author'], 'Mark');
}
/**
* test writing falsey values.
*
* @return void
*/
function testDataWritingFalsey() {
$request = new CakeRequest('posts/index');
$request->data('Post.null', null);
$this->assertNull($request->data['Post']['null']);
$request->data('Post.false', false);
$this->assertFalse($request->data['Post']['false']);
$request->data('Post.zero', 0);
$this->assertSame(0, $request->data['Post']['zero']);
$request->data('Post.empty', '');
$this->assertSame('', $request->data['Post']['empty']);
}
/**
* backupEnvironment method
*

View file

@ -18,6 +18,7 @@
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
App::import('Component', array('Cookie', 'Security'));
App::import('Core', 'ComponentCollection');
class ComponentCollectionTest extends CakeTestCase {
@ -145,10 +146,37 @@ class ComponentCollectionTest extends CakeTestCase {
->with(null);
$this->Components->TriggerMockSecurity->expects($this->once())->method('startup')
->with(null);
$this->mockObjects[] = $this->Components->TriggerMockCookie;
$this->mockObjects[] = $this->Components->TriggerMockSecurity;
$this->assertTrue($this->Components->trigger('startup', array(&$controller)));
}
/**
* test that the initalize callback is triggered on all components even those that are disabled.
*
* @return void
*/
function testTriggerWithTriggerDisabledObjects() {
$controller = 'Not a controller';
$this->_makeMockClasses();
$this->Components->load('TriggerMockCookie', array(), false);
$this->Components->load('TriggerMockSecurity');
$this->Components->TriggerMockCookie->expects($this->once())->method('initialize')
->with($controller);
$this->Components->TriggerMockSecurity->expects($this->once())->method('initialize')
->with($controller);
$this->mockObjects[] = $this->Components->TriggerMockCookie;
$this->mockObjects[] = $this->Components->TriggerMockSecurity;
$result = $this->Components->trigger('initialize', array(&$controller), array('triggerDisabled' => true));
$this->assertTrue($result);
}
/**
* test trigger and disabled helpers.
*
@ -161,9 +189,11 @@ class ComponentCollectionTest extends CakeTestCase {
$this->Components->load('TriggerMockSecurity');
$this->Components->TriggerMockCookie->expects($this->once())->method('startup')
->with(null);
$this->Components->TriggerMockSecurity->expects($this->never())->method('startup')
->with(null);
->with($controller);
$this->Components->TriggerMockSecurity->expects($this->never())->method('startup');
$this->mockObjects[] = $this->Components->TriggerMockCookie;
$this->mockObjects[] = $this->Components->TriggerMockSecurity;
$this->Components->disable('TriggerMockSecurity');
@ -185,6 +215,9 @@ class ComponentCollectionTest extends CakeTestCase {
->will($this->returnValue(array('one', 'two')));
$this->Components->TriggerMockSecurity->expects($this->once())->method('startup')
->will($this->returnValue(array('three', 'four')));
$this->mockObjects[] = $this->Components->TriggerMockCookie;
$this->mockObjects[] = $this->Components->TriggerMockSecurity;
$result = $this->Components->trigger('startup', array(&$controller), array('collectReturn' => true));
$expected = array(
@ -208,6 +241,9 @@ class ComponentCollectionTest extends CakeTestCase {
$this->Components->TriggerMockCookie->expects($this->once())->method('startup')
->will($this->returnValue(false));
$this->Components->TriggerMockSecurity->expects($this->never())->method('startup');
$this->mockObjects[] = $this->Components->TriggerMockCookie;
$this->mockObjects[] = $this->Components->TriggerMockSecurity;
$result = $this->Components->trigger(
'startup',
@ -238,4 +274,18 @@ class ComponentCollectionTest extends CakeTestCase {
);
$this->assertEquals($expected, $result);
}
/**
* test getting the controller out of the collection
*
* @return void
*/
function testGetController() {
$controller = $this->getMock('Controller');
$controller->components = array('Security');
$this->Components->init($controller);
$result = $this->Components->getController();
$this->assertSame($controller, $result);
}
}

View file

@ -17,6 +17,7 @@
* @since CakePHP(tm) v 1.2.0.5347
* @license http://www.opensource.org/licenses/opengroup.php The Open Group Test Suite License
*/
App::import('Core', 'Controller');
App::import('Component', array('Auth', 'Acl'));
App::import('Model', 'DbAcl');
App::import('Core', 'Xml');
@ -493,8 +494,10 @@ class AuthTest extends CakeTestCase {
$request = new CakeRequest(null, false);
$this->Controller = new AuthTestController($request);
$this->Controller->Component->init($this->Controller);
$this->Controller->Component->initialize($this->Controller);
$this->Controller->Components->init($this->Controller);
$this->Controller->Components->trigger(
'initialize', array(&$this->Controller), array('triggerDisabled' => true)
);
$this->Controller->beforeFilter();
ClassRegistry::addObject('view', new View($this->Controller));
@ -641,7 +644,6 @@ class AuthTest extends CakeTestCase {
* @return void
*/
function testLoginActionNotSettingAuthRedirect() {
$_referer = $_SERVER['HTTP_REFERER'];
$_SERVER['HTTP_REFERER'] = '/pages/display/about';
$this->Controller->data = array();
@ -1065,7 +1067,9 @@ class AuthTest extends CakeTestCase {
);
$this->Controller->Session->delete('Auth');
$url = '/posts/index/29';
$this->Controller->request = Dispatcher::parseParams(new CakeRequest($url));
$this->Controller->request = new CakeRequest($url);
$this->Controller->request->addParams(Router::parse($url));
$this->Controller->Auth->initialize($this->Controller);
$this->Controller->Auth->loginAction = array('controller' => 'AuthTest', 'action' => 'login');
$this->Controller->Auth->userModel = 'AuthUser';
@ -1081,7 +1085,9 @@ class AuthTest extends CakeTestCase {
);
$this->Controller->Session->delete('Auth');
$url = '/posts/index/29';
$this->Controller->request = Dispatcher::parseParams(new CakeRequest($url));
$this->Controller->request = new CakeRequest($url);
$this->Controller->request->addParams(Router::parse($url));
$this->Controller->Auth->initialize($this->Controller);
$this->Controller->Auth->loginAction = array('controller' => 'AuthTest', 'action' => 'login');
$this->Controller->Auth->userModel = 'AuthUser';
@ -1094,6 +1100,7 @@ class AuthTest extends CakeTestCase {
$_SERVER['HTTP_REFERER'] = 'http://webmail.example.com/view/message';
$this->Controller->Session->delete('Auth');
$url = '/posts/edit/1';
$this->Controller->request = new CakeRequest($url);
$this->Controller->request->addParams(Router::parse($url));
$this->Controller->request->query = array('url' => Router::normalize($url));
$this->Controller->Auth->initialize($this->Controller);
@ -1107,6 +1114,7 @@ class AuthTest extends CakeTestCase {
$_SERVER['HTTP_REFERER'] = 'http://webmail.example.com/view/message';
$this->Controller->Session->delete('Auth');
$url = '/AuthTest/login';
$this->Controller->request = new CakeRequest($url);
$this->Controller->request->addParams(Router::parse($url));
$this->Controller->request->query['url'] = Router::normalize($url);
$this->Controller->Auth->initialize($this->Controller);
@ -1192,8 +1200,12 @@ class AuthTest extends CakeTestCase {
$this->Controller->Session->delete($this->Controller->Auth->sessionKey);
$this->Controller->data['AuthUser']['username'] = 'nate';
$this->Controller->data['AuthUser']['password'] = 'cake1';
$this->Controller->request->data = array(
'AuthUser' => array(
'username' => 'nate',
'password' => 'cake1'
)
);
$this->Controller->request->query['url'] = 'auth_test/login';
$this->Controller->Auth->initialize($this->Controller);
@ -1204,22 +1216,26 @@ class AuthTest extends CakeTestCase {
$this->Controller->Session->delete($this->Controller->Auth->sessionKey);
$this->Controller->data['AuthUser']['username'] = '> n';
$this->Controller->data['AuthUser']['password'] = 'cake';
$this->Controller->request->data = array(
'AuthUser' => array(
'username' => '> n',
'password' => 'cake'
)
);
$this->Controller->Auth->initialize($this->Controller);
$this->Controller->Auth->startup($this->Controller);
$this->assertTrue(is_null($this->Controller->Auth->user()));
unset($this->Controller->data['AuthUser']['password']);
$this->Controller->data['AuthUser']['username'] = "1'1";
unset($this->Controller->request->data['AuthUser']['password']);
$this->Controller->request->data['AuthUser']['username'] = "1'1";
$this->Controller->Auth->initialize($this->Controller);
$this->Controller->Auth->startup($this->Controller);
$this->assertTrue(is_null($this->Controller->Auth->user()));
unset($this->Controller->data['AuthUser']['username']);
$this->Controller->data['AuthUser']['password'] = "1'1";
unset($this->Controller->request->data['AuthUser']['username']);
$this->Controller->request->data['AuthUser']['password'] = "1'1";
$this->Controller->Auth->initialize($this->Controller);
$this->Controller->Auth->startup($this->Controller);

View file

@ -138,6 +138,15 @@ class EmailTestComponent extends EmailComponent {
function strip($content, $message = false) {
return parent::_strip($content, $message);
}
/**
* Wrapper for testing.
*
* @return void
*/
function formatAddress($string, $smtp = false) {
return parent::_formatAddress($string, $smtp);
}
}
/**
@ -258,6 +267,9 @@ class EmailComponentTest extends CakeTestCase {
* @return void
*/
function testSmtpConfig() {
if ($this->skipIf(!@fsockopen('localhost', 25), '%s No SMTP server running on localhost')) {
return;
}
$this->Controller->EmailTest->delivery = 'smtp';
$this->Controller->EmailTest->smtpOptions = array();
$this->Controller->EmailTest->send('anything');
@ -282,6 +294,9 @@ class EmailComponentTest extends CakeTestCase {
* @return void
*/
function testBadSmtpSend() {
if ($this->skipIf(!@fsockopen('localhost', 25), '%s No SMTP server running on localhost')) {
return;
}
$this->Controller->EmailTest->smtpOptions['host'] = 'blah';
$this->Controller->EmailTest->delivery = 'smtp';
$this->assertFalse($this->Controller->EmailTest->send('Should not work'));
@ -294,7 +309,7 @@ class EmailComponentTest extends CakeTestCase {
* @return void
*/
function testSmtpSend() {
if (!$this->skipIf(!@fsockopen('localhost', 25), '%s No SMTP server running on localhost')) {
if ($this->skipIf(!@fsockopen('localhost', 25), '%s No SMTP server running on localhost')) {
return;
}
@ -343,7 +358,7 @@ TEMPDOC;
* @return void
*/
function testSmtpEhlo() {
if (!$this->skipIf(!@fsockopen('localhost', 25), '%s No SMTP server running on localhost')) {
if ($this->skipIf(!@fsockopen('localhost', 25), '%s No SMTP server running on localhost')) {
return;
}
@ -400,7 +415,7 @@ TEMPDOC;
* @return void
*/
function testSmtpSendMultipleTo() {
if (!$this->skipIf(!@fsockopen('localhost', 25), '%s No SMTP server running on localhost')) {
if ($this->skipIf(!@fsockopen('localhost', 25), '%s No SMTP server running on localhost')) {
return;
}
$this->Controller->EmailTest->reset();
@ -449,7 +464,9 @@ TEMPDOC;
* @return void
*/
function testAuthenticatedSmtpSend() {
$this->skipIf(!@fsockopen('localhost', 25), '%s No SMTP server running on localhost');
if ($this->skipIf(!@fsockopen('localhost', 25), '%s No SMTP server running on localhost')) {
return;
}
$this->Controller->EmailTest->to = 'postmaster@localhost';
$this->Controller->EmailTest->from = 'noreply@example.com';
@ -640,7 +657,9 @@ TEXTBLOC;
* @return void
*/
function testSmtpSendSocket() {
$this->skipIf(!@fsockopen('localhost', 25), '%s No SMTP server running on localhost');
if ($this->skipIf(!@fsockopen('localhost', 25), '%s No SMTP server running on localhost')) {
return;
}
$socket = new CakeSocket(array_merge(array('protocol'=>'smtp'), $this->Controller->EmailTest->smtpOptions));
$this->Controller->EmailTest->setConnectionSocket($socket);
@ -1032,6 +1051,7 @@ HTMLBLOC;
$this->Controller->EmailTest->additionalParams = 'X-additional-header';
$this->Controller->EmailTest->delivery = 'smtp';
$this->Controller->EmailTest->smtpOptions['host'] = 'blah';
$this->Controller->EmailTest->smtpOptions['timeout'] = 0.5;
$this->Controller->EmailTest->attachments = array('attachment1', 'attachment2');
$this->Controller->EmailTest->textMessage = 'This is the body of the message';
$this->Controller->EmailTest->htmlMessage = 'This is the body of the message';
@ -1155,4 +1175,32 @@ HTMLBLOC;
);
$this->assertEqual($expected, $result);
}
/**
* Test that _formatName doesn't jack up email addresses with alias parts.
*
* @return void
*/
function testFormatAddressAliases() {
$result = $this->Controller->EmailTest->formatAddress('email@example.com');
$this->assertEqual($result, 'email@example.com');
$result = $this->Controller->EmailTest->formatAddress('alias <email@example.com>');
$this->assertEqual($result, 'alias <email@example.com>');
$result = $this->Controller->EmailTest->formatAddress('email@example.com');
$this->assertEqual($result, 'email@example.com');
$result = $this->Controller->EmailTest->formatAddress('<email@example.com>');
$this->assertEqual($result, '<email@example.com>');
$result = $this->Controller->EmailTest->formatAddress('email@example.com', true);
$this->assertEqual($result, ' <email@example.com>');
$result = $this->Controller->EmailTest->formatAddress('<email@example.com>', true);
$this->assertEqual($result, ' <email@example.com>');
$result = $this->Controller->EmailTest->formatAddress('alias name <email@example.com>', true);
$this->assertEqual($result, ' <email@example.com>');
}
}

View file

@ -319,6 +319,34 @@ class RequestHandlerComponentTest extends CakeTestCase {
$this->assertEqual($this->Controller->viewPath, 'request_handler_test' . DS . 'js');
}
/**
* test that attachment headers work with renderAs
*
* @return void
*/
function testRenderAsWithAttachment() {
$this->RequestHandler->request = $this->getMock('CakeRequest');
$this->RequestHandler->request->expects($this->any())
->method('accepts')
->will($this->returnValue(array('application/xml')));
$this->RequestHandler->response = $this->getMock('CakeResponse', array('type', 'download', 'charset'));
$this->RequestHandler->response->expects($this->at(0))
->method('type')
->with('application/xml');
$this->RequestHandler->response->expects($this->at(1))
->method('charset')
->with('UTF-8');
$this->RequestHandler->response->expects($this->at(2))
->method('download')
->with('myfile.xml');
$this->RequestHandler->renderAs($this->Controller, 'xml', array('attachment' => 'myfile.xml'));
$expected = 'request_handler_test' . DS . 'xml';
$this->assertEquals($expected, $this->Controller->viewPath);
}
/**
* test that respondAs works as expected.
*
@ -344,15 +372,23 @@ class RequestHandlerComponentTest extends CakeTestCase {
* @return void
*/
function testRespondAsWithAttachment() {
$this->RequestHandler = $this->getMock('RequestHandlerComponent', array('_header'), array(&$this->Controller->Components));
$this->RequestHandler = $this->getMock(
'RequestHandlerComponent',
array('_header'),
array(&$this->Controller->Components)
);
$this->RequestHandler->response = $this->getMock('CakeResponse', array('type', 'download'));
$this->RequestHandler->request = $this->getMock('CakeRequest');
$this->RequestHandler->request->expects($this->once())
->method('accepts')
->will($this->returnValue(array('application/xml')));
$this->RequestHandler->response->expects($this->once())->method('download')
->with('myfile.xml');
$this->RequestHandler->response->expects($this->once())->method('type')
->with('application/xml');
$result = $this->RequestHandler->respondAs('xml', array('attachment' => 'myfile.xml'));
$this->assertTrue($result);
}

View file

@ -144,7 +144,9 @@ class SecurityComponentTest extends CakeTestCase {
* @return void
*/
function startTest() {
$this->Controller = new SecurityTestController(new CakeRequest(null, false));
$request = new CakeRequest('posts/index', false);
$request->addParams(array('controller' => 'posts', 'action' => 'index'));
$this->Controller = new SecurityTestController($request);
$this->Controller->Components->init($this->Controller);
$this->Controller->Security = $this->Controller->TestSecurity;
$this->Controller->Security->blackHoleCallback = 'fail';

View file

@ -345,8 +345,10 @@ class TestController extends AppController {
* @return void
*/
function index($testId, $test2Id) {
$this->data['testId'] = $testId;
$this->data['test2Id'] = $test2Id;
$this->data = array(
'testId' => $testId,
'test2Id' => $test2Id
);
}
}
@ -856,7 +858,8 @@ class ControllerTest extends CakeTestCase {
function testFlash() {
$request = new CakeRequest('controller_posts/index');
$Controller = new Controller($request, $this->getMock('CakeResponse', array('_sendHeader')));
$Controller = new Controller($request);
$Controller->response = $this->getMock('CakeResponse', array('_sendHeader'));
$Controller->flash('this should work', '/flash');
$result = $Controller->response->body();
@ -879,8 +882,11 @@ class ControllerTest extends CakeTestCase {
$expected = str_replace(array("\t", "\r\n", "\n"), "", $expected);
$this->assertEqual($result, $expected);
App::build(array('views' => array(TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'views'. DS)));
$Controller = new Controller(null, $this->getMock('CakeResponse', array('_sendHeader')));
App::build(array(
'views' => array(TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'views'. DS)
));
$Controller = new Controller($request);
$Controller->response = $this->getMock('CakeResponse', array('_sendHeader'));
$Controller->flash('this should work', '/flash', 1, 'ajax2');
$result = $Controller->response->body();
$this->assertPattern('/Ajax!/', $result);
@ -977,7 +983,7 @@ class ControllerTest extends CakeTestCase {
$core[0]
)
), true);
$Controller =& new Controller(null, $this->getMock('CakeResponse'));
$Controller =& new Controller($this->getMock('CakeRequest'));
$Controller->uses = array();
$Controller->components = array('Test');
$Controller->constructClasses();
@ -1030,10 +1036,11 @@ class ControllerTest extends CakeTestCase {
* @return void
*/
function testRedirectByCode($code, $msg) {
$Controller = new Controller(null, $this->getMock('CakeResponse', array('header', 'statusCode')));
$Controller = new Controller(null);
$Controller->response = $this->getMock('CakeResponse', array('header', 'statusCode'));
$Controller->Components = $this->getMock('ComponentCollection');
$Controller->Component = new Component();
$Controller->Component->init($Controller);
$Controller->response->expects($this->once())->method('statusCode')
->with($code);
$Controller->response->expects($this->once())->method('header')
@ -1050,7 +1057,8 @@ class ControllerTest extends CakeTestCase {
* @return void
*/
function testRedirectByMessage($code, $msg) {
$Controller = new Controller(null, $this->getMock('CakeResponse', array('header', 'statusCode')));
$Controller = new Controller(null);
$Controller->response = $this->getMock('CakeResponse', array('header', 'statusCode'));
$Controller->Components = $this->getMock('ComponentCollection');
@ -1070,8 +1078,9 @@ class ControllerTest extends CakeTestCase {
* @return void
*/
function testRedirectTriggeringComponentsReturnNull() {
$Controller = new Controller(null, $this->getMock('CakeResponse', array('header', 'statusCode')));
$Controller->Component = $this->getMock('Component');
$Controller = new Controller(null);
$Controller->response = $this->getMock('CakeResponse', array('header', 'statusCode'));
$Controller->Components = $this->getMock('ComponentCollection');
$Controller->Components->expects($this->once())->method('trigger')
->will($this->returnValue(null));
@ -1091,8 +1100,9 @@ class ControllerTest extends CakeTestCase {
* @return void
*/
function testRedirectBeforeRedirectModifyingParams() {
$Controller = new Controller(null, $this->getMock('CakeResponse', array('header', 'statusCode')));
$Controller->Component = $this->getMock('Component');
$Controller = new Controller(null);
$Controller->response = $this->getMock('CakeResponse', array('header', 'statusCode'));
$Controller->Components = $this->getMock('ComponentCollection');
$Controller->Components->expects($this->once())->method('trigger')
->will($this->returnValue(array('http://book.cakephp.org')));
@ -1129,11 +1139,11 @@ class ControllerTest extends CakeTestCase {
$Controller->Components->expects($this->once())->method('trigger')
->will($this->returnValue($return));
$Controller->expects($this->at(0))->method('header')
->with('HTTP/1.1 302 Found');
$Controller->response->expects($this->at(0))->method('header')
->with('Location', 'http://example.com/test/2');
$Controller->expects($this->at(1))->method('header')
->with('Location: http://example.com/test/2');
$Controller->response->expects($this->at(1))->method('statusCode')
->with(302);
$Controller->expects($this->never())->method('_stop');
$Controller->redirect('http://cakephp.org', 301);
@ -1431,23 +1441,23 @@ class ControllerTest extends CakeTestCase {
$Controller->modelClass='ControllerPost';
$Controller->params['url'] = array('ext' => 'rss');
$Controller->constructClasses();
$Controller->Component->initialize($Controller);
$Controller->Components->trigger('initialize', array(&$Controller));
$Controller->beforeFilter();
$Controller->Component->startup($Controller);
$Controller->Components->trigger('startup', array(&$Controller));
$this->assertEqual($Controller->RequestHandler->prefers(), 'rss');
unset($Controller);
}
/**
>>>>>>> 2.0-request
* testControllerHttpCodes method
*
* @access public
* @return void
*/
function testControllerHttpCodes() {
$Controller = new Controller(null, $this->getMock('CakeResponse', array('httpCodes')));
$Controller = new Controller(null);
$Controller->response = $this->getMock('CakeResponse', array('httpCodes'));
$Controller->response->expects($this->at(0))->method('httpCodes')->with(null);
$Controller->response->expects($this->at(1))->method('httpCodes')->with(100);
$Controller->httpCodes();
@ -1493,4 +1503,40 @@ class ControllerTest extends CakeTestCase {
$Controller->shutdownProcess();
}
/**
* test that BC works for attributes on the request object.
*
* @return void
*/
function testPropertyBackwardsCompatibility() {
$request = new CakeRequest('posts/index', null);
$request->addParams(array('controller' => 'posts', 'action' => 'index'));
$request->data = array('Post' => array('id' => 1));
$request->here = '/posts/index';
$request->webroot = '/';
$Controller = new TestController($request);
$this->assertEquals($request->data, $Controller->data);
$this->assertEquals($request->webroot, $Controller->webroot);
$this->assertEquals($request->here, $Controller->here);
$this->assertEquals($request->action, $Controller->action);
$this->assertEquals($request, $Controller->params);
$this->assertEquals($request->params['controller'], $Controller->params['controller']);
}
/**
* test that the BC wrapper doesn't interfere with models and components.
*
* @return void
*/
function testPropertyCompatibilityAndModelsComponents() {
$request = new CakeRequest('controller_posts/index');
$Controller = new TestController($request);
$Controller->constructClasses();
$this->assertType('SecurityComponent', $Controller->Security);
$this->assertType('ControllerComment', $Controller->ControllerComment);
}
}

View file

@ -60,12 +60,12 @@ class PagesControllerTest extends CakeTestCase {
$Pages->viewPath = 'posts';
$Pages->display('index');
$this->assertPattern('/posts index/', $Pages->output);
$this->assertPattern('/posts index/', $Pages->getResponse()->body());
$this->assertEqual($Pages->viewVars['page'], 'index');
$Pages->viewPath = 'themed';
$Pages->display('test_theme', 'posts', 'index');
$this->assertPattern('/posts index themed view/', $Pages->output);
$this->assertPattern('/posts index themed view/', $Pages->getResponse()->body());
$this->assertEqual($Pages->viewVars['page'], 'test_theme');
$this->assertEqual($Pages->viewVars['subpage'], 'posts');
}

View file

@ -17,7 +17,8 @@
* @since CakePHP(tm) v 1.2.0.5436
* @license http://www.opensource.org/licenses/opengroup.php The Open Group Test Suite License
*/
App::import('Core', 'Scaffold');
App::import('Core', 'Scaffold', false);
App::import('Core', 'Controller', false);
/**
* ScaffoldMockController class
@ -515,14 +516,14 @@ class ScaffoldViewTest extends CakeTestCase {
new Scaffold($this->Controller, $this->Controller->request);
$result = ob_get_clean();
$this->assertPattern('/<form id="ScaffoldMockEditForm" method="post" action="\/scaffold_mock\/edit\/1"/', $result);
$this->assertPattern('/<legend>Edit Scaffold Mock<\/legend>/', $result);
$this->assertContains('<form id="ScaffoldMockEditForm" method="post" action="/scaffold_mock/edit/1"', $result);
$this->assertContains('<legend>Edit Scaffold Mock</legend>', $result);
$this->assertPattern('/input type="hidden" name="data\[ScaffoldMock\]\[id\]" value="1" id="ScaffoldMockId"/', $result);
$this->assertPattern('/select name="data\[ScaffoldMock\]\[user_id\]" id="ScaffoldMockUserId"/', $result);
$this->assertPattern('/input name="data\[ScaffoldMock\]\[title\]" type="text" maxlength="255" value="First Article" id="ScaffoldMockTitle"/', $result);
$this->assertPattern('/input name="data\[ScaffoldMock\]\[published\]" type="text" maxlength="1" value="Y" id="ScaffoldMockPublished"/', $result);
$this->assertPattern('/textarea name="data\[ScaffoldMock\]\[body\]" cols="30" rows="6" id="ScaffoldMockBody"/', $result);
$this->assertContains('input type="hidden" name="data[ScaffoldMock][id]" value="1" id="ScaffoldMockId"', $result);
$this->assertContains('select name="data[ScaffoldMock][user_id]" id="ScaffoldMockUserId"', $result);
$this->assertContains('input name="data[ScaffoldMock][title]" maxlength="255" type="text" value="First Article" id="ScaffoldMockTitle"', $result);
$this->assertContains('input name="data[ScaffoldMock][published]" maxlength="1" type="text" value="Y" id="ScaffoldMockPublished"', $result);
$this->assertContains('textarea name="data[ScaffoldMock][body]" cols="30" rows="6" id="ScaffoldMockBody"', $result);
$this->assertPattern('/<li><a href="\/scaffold_mock\/delete\/1"[^>]*>Delete<\/a>\s*<\/li>/', $result);
}
@ -789,7 +790,7 @@ class ScaffoldTest extends CakeTestCase {
$this->Controller->theme = 'test_theme';
$this->Controller->view = 'Theme';
$this->Controller->constructClasses();
$Scaffold =& new TestScaffoldMock($this->Controller, array());
$Scaffold =& new TestScaffoldMock($this->Controller, $this->Controller->request);
$this->assertEqual($this->Controller->view, 'Scaffold');
}

View file

@ -216,7 +216,9 @@ class DebuggerTest extends CakeTestCase {
$Controller->helpers = array('Html', 'Form');
$View = new View($Controller);
$result = Debugger::exportVar($View);
$expected = 'ViewView::$base = NULL
$expected = 'View
View::$Helpers = HelperCollection object
View::$base = NULL
View::$here = NULL
View::$plugin = NULL
View::$name = ""
@ -237,7 +239,6 @@ class DebuggerTest extends CakeTestCase {
View::$cacheAction = false
View::$validationErrors = array
View::$hasRendered = false
View::$loaded = array
View::$modelScope = false
View::$model = NULL
View::$association = NULL
@ -246,7 +247,8 @@ class DebuggerTest extends CakeTestCase {
View::$modelId = NULL
View::$uuids = array
View::$output = false
View::$webroot = NULL';
View::$webroot = NULL
View::$request = NULL';
$result = str_replace(array("\t", "\r\n", "\n"), "", strtolower($result));
$expected = str_replace(array("\t", "\r\n", "\n"), "", strtolower($expected));
$this->assertEqual($result, $expected);

View file

@ -1,610 +0,0 @@
<?php
/**
* ErrorHandlerTest file
*
* PHP versions 4 and 5
*
* CakePHP(tm) Tests <http://book.cakephp.org/view/1196/Testing>
* Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The Open Group Test Suite License
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://book.cakephp.org/view/1196/Testing CakePHP(tm) Tests
* @package cake
* @subpackage cake.tests.cases.libs
* @since CakePHP(tm) v 1.2.0.5432
* @license http://www.opensource.org/licenses/opengroup.php The Open Group Test Suite License
*/
if (class_exists('TestErrorHandler')) {
return;
}
if (!defined('CAKEPHP_UNIT_TEST_EXECUTION')) {
define('CAKEPHP_UNIT_TEST_EXECUTION', 1);
}
/**
* BlueberryComponent class
*
* @package cake
* @subpackage cake.tests.cases.libs
*/
class BlueberryComponent extends Object {
/**
* testName property
*
* @access public
* @return void
*/
public $testName = null;
/**
* initialize method
*
* @access public
* @return void
*/
function initialize(&$controller) {
$this->testName = 'BlueberryComponent';
}
}
/**
* BlueberryDispatcher class
*
* @package cake
* @subpackage cake.tests.cases.libs
*/
class BlueberryDispatcher extends Dispatcher {
/**
* cakeError method
*
* @access public
* @return void
*/
function cakeError($method, $messages = array()) {
$error = new TestErrorHandler($method, $messages);
return $error;
}
}
/**
* Short description for class.
*
* @package cake
* @subpackage cake.tests.cases.libs
*/
class AuthBlueberryUser extends CakeTestModel {
/**
* name property
*
* @var string 'AuthBlueberryUser'
* @access public
*/
public $name = 'AuthBlueberryUser';
/**
* useTable property
*
* @var string
* @access public
*/
public $useTable = false;
}
if (!class_exists('AppController')) {
/**
* AppController class
*
* @package cake
* @subpackage cake.tests.cases.libs
*/
class AppController extends Controller {
/**
* components property
*
* @access public
* @return void
*/
public $components = array('Blueberry');
/**
* beforeRender method
*
* @access public
* @return void
*/
function beforeRender() {
echo $this->Blueberry->testName;
}
/**
* header method
*
* @access public
* @return void
*/
function header($header) {
echo $header;
}
/**
* _stop method
*
* @access public
* @return void
*/
function _stop($status = 0) {
echo 'Stopped with status: ' . $status;
}
}
} elseif (!defined('APP_CONTROLLER_EXISTS')){
define('APP_CONTROLLER_EXISTS', true);
}
App::import('Core', array('Error', 'Controller'));
/**
* TestErrorController class
*
* @package cake
* @subpackage cake.tests.cases.libs
*/
class TestErrorController extends AppController {
/**
* uses property
*
* @var array
* @access public
*/
public $uses = array();
/**
* index method
*
* @access public
* @return void
*/
function index() {
$this->autoRender = false;
return 'what up';
}
}
/**
* BlueberryController class
*
* @package cake
* @subpackage cake.tests.cases.libs
*/
class BlueberryController extends AppController {
/**
* name property
*
* @access public
* @return void
*/
public $name = 'BlueberryController';
/**
* uses property
*
* @access public
* @return void
*/
public $uses = array();
}
/**
* MyCustomErrorHandler class
*
* @package cake
* @subpackage cake.tests.cases.libs
*/
class MyCustomErrorHandler extends ErrorHandler {
/**
* custom error message type.
*
* @return void
*/
function missingWidgetThing() {
echo 'widget thing is missing';
}
/**
* stop method
*
* @access public
* @return void
*/
function _stop() {
return;
}
}
/**
* TestErrorHandler class
*
* @package cake
* @subpackage cake.tests.cases.libs
*/
class TestErrorHandler extends ErrorHandler {
/**
* stop method
*
* @access public
* @return void
*/
function _stop() {
return;
}
}
/**
* ErrorHandlerTest class
*
* @package cake
* @subpackage cake.tests.cases.libs
*/
class ErrorHandlerTest extends CakeTestCase {
/**
* skip method
*
* @access public
* @return void
*/
function skip() {
$this->skipIf(PHP_SAPI === 'cli', '%s Cannot be run from console');
}
/**
* setup create a request object to get out of router later.
*
* @return void
*/
function setUp() {
$request = new CakeRequest(null, false);
$request->base = '';
Router::setRequestInfo($request);
}
/**
* test that methods declared in an ErrorHandler subclass are not converted
* into error404 when debug == 0
*
* @return void
*/
function testSubclassMethodsNotBeingConvertedToError() {
$back = Configure::read('debug');
Configure::write('debug', 2);
ob_start();
$ErrorHandler = new MyCustomErrorHandler('missingWidgetThing', array('message' => 'doh!'));
$result = ob_get_clean();
$this->assertEqual($result, 'widget thing is missing');
Configure::write('debug', 0);
ob_start();
$ErrorHandler = new MyCustomErrorHandler('missingWidgetThing', array('message' => 'doh!'));
$result = ob_get_clean();
$this->assertEqual($result, 'widget thing is missing', 'Method declared in subclass converted to error404. %s');
Configure::write('debug', 0);
ob_start();
$ErrorHandler = new MyCustomErrorHandler('missingController', array(
'className' => 'Missing', 'message' => 'Page not found'
));
$result = ob_get_clean();
$this->assertPattern('/Not Found/', $result, 'Method declared in error handler not converted to error404. %s');
Configure::write('debug', $back);
}
/**
* testError method
*
* @access public
* @return void
*/
function testError() {
ob_start();
$TestErrorHandler = new TestErrorHandler('error404', array('message' => 'Page not found'));
ob_clean();
ob_start();
$TestErrorHandler->error(array(
'code' => 404,
'message' => 'Page not Found',
'name' => "Couldn't find what you were looking for"
));
$result = ob_get_clean();
$this->assertPattern("/<h2>Couldn't find what you were looking for<\/h2>/", $result);
$this->assertPattern('/Page not Found/', $result);
}
/**
* testError404 method
*
* @access public
* @return void
*/
function testError404() {
App::build(array(
'views' => array(TEST_CAKE_CORE_INCLUDE_PATH . 'libs' . DS . 'view' . DS)
), true);
ob_start();
$TestErrorHandler = new TestErrorHandler('error404', array('message' => 'Page not found', 'url' => '/test_error'));
$result = ob_get_clean();
$this->assertPattern('/<h2>Not Found<\/h2>/', $result);
$this->assertPattern("/<strong>'\/test_error'<\/strong>/", $result);
ob_start();
$TestErrorHandler = new TestErrorHandler('error404', array('message' => 'Page not found'));
ob_get_clean();
ob_start();
$TestErrorHandler->error404(array(
'url' => 'pages/<span id=333>pink</span></id><script>document.body.style.background = t=document.getElementById(333).innerHTML;window.alert(t);</script>',
'message' => 'Page not found'
));
$result = ob_get_clean();
$this->assertNoPattern('#<script>#', $result);
$this->assertNoPattern('#</script>#', $result);
App::build();
}
/**
* testError500 method
*
* @access public
* @return void
*/
function testError500() {
ob_start();
$TestErrorHandler = new TestErrorHandler('error500', array(
'message' => 'An Internal Error Has Occurred'
));
$result = ob_get_clean();
$this->assertPattern('/<h2>An Internal Error Has Occurred<\/h2>/', $result);
ob_start();
$TestErrorHandler = new TestErrorHandler('error500', array(
'message' => 'An Internal Error Has Occurred',
'code' => '500'
));
$result = ob_get_clean();
$this->assertPattern('/<h2>An Internal Error Has Occurred<\/h2>/', $result);
}
/**
* testMissingController method
*
* @access public
* @return void
*/
function testMissingController() {
$this->skipIf(defined('APP_CONTROLLER_EXISTS'), '%s Need a non-existent AppController');
ob_start();
$TestErrorHandler = new TestErrorHandler('missingController', array('className' => 'PostsController'));
$result = ob_get_clean();
$this->assertPattern('/<h2>Missing Controller<\/h2>/', $result);
$this->assertPattern('/<em>PostsController<\/em>/', $result);
$this->assertPattern('/BlueberryComponent/', $result);
}
/**
* testMissingAction method
*
* @access public
* @return void
*/
function testMissingAction() {
ob_start();
$TestErrorHandler = new TestErrorHandler('missingAction', array('className' => 'PostsController', 'action' => 'index'));
$result = ob_get_clean();
$this->assertPattern('/<h2>Missing Method in PostsController<\/h2>/', $result);
$this->assertPattern('/<em>PostsController::<\/em><em>index\(\)<\/em>/', $result);
ob_start();
$dispatcher = new BlueberryDispatcher('/blueberry/inexistent');
$result = ob_get_clean();
$this->assertPattern('/<h2>Missing Method in BlueberryController<\/h2>/', $result);
$this->assertPattern('/<em>BlueberryController::<\/em><em>inexistent\(\)<\/em>/', $result);
$this->assertNoPattern('/Location: (.*)\/users\/login/', $result);
$this->assertNoPattern('/Stopped with status: 0/', $result);
}
/**
* testPrivateAction method
*
* @access public
* @return void
*/
function testPrivateAction() {
ob_start();
$TestErrorHandler = new TestErrorHandler('privateAction', array('className' => 'PostsController', 'action' => '_secretSauce'));
$result = ob_get_clean();
$this->assertPattern('/<h2>Private Method in PostsController<\/h2>/', $result);
$this->assertPattern('/<em>PostsController::<\/em><em>_secretSauce\(\)<\/em>/', $result);
}
/**
* testMissingTable method
*
* @access public
* @return void
*/
function testMissingTable() {
ob_start();
$TestErrorHandler = new TestErrorHandler('missingTable', array('className' => 'Article', 'table' => 'articles'));
$result = ob_get_clean();
$this->assertPattern('/HTTP\/1\.0 500 Internal Server Error/', $result);
$this->assertPattern('/<h2>Missing Database Table<\/h2>/', $result);
$this->assertPattern('/table <em>articles<\/em> for model <em>Article<\/em>/', $result);
}
/**
* testMissingDatabase method
*
* @access public
* @return void
*/
function testMissingDatabase() {
ob_start();
$TestErrorHandler = new TestErrorHandler('missingDatabase', array());
$result = ob_get_clean();
$this->assertPattern('/HTTP\/1\.0 500 Internal Server Error/', $result);
$this->assertPattern('/<h2>Missing Database Connection<\/h2>/', $result);
$this->assertPattern('/Confirm you have created the file/', $result);
}
/**
* testMissingView method
*
* @access public
* @return void
*/
function testMissingView() {
ob_start();
$TestErrorHandler = new TestErrorHandler('missingView', array('className' => 'Pages', 'action' => 'display', 'file' => 'pages/about.ctp', 'base' => ''));
$expected = ob_get_clean();
$this->assertPattern("/PagesController::/", $expected);
$this->assertPattern("/pages\/about.ctp/", $expected);
}
/**
* testMissingLayout method
*
* @access public
* @return void
*/
function testMissingLayout() {
ob_start();
$TestErrorHandler = new TestErrorHandler('missingLayout', array( 'layout' => 'my_layout', 'file' => 'layouts/my_layout.ctp', 'base' => ''));
$expected = ob_get_clean();
$this->assertPattern("/Missing Layout/", $expected);
$this->assertPattern("/layouts\/my_layout.ctp/", $expected);
}
/**
* testMissingConnection method
*
* @access public
* @return void
*/
function testMissingConnection() {
ob_start();
$TestErrorHandler = new TestErrorHandler('missingConnection', array('className' => 'Article'));
$result = ob_get_clean();
$this->assertPattern('/<h2>Missing Database Connection<\/h2>/', $result);
$this->assertPattern('/Article requires a database connection/', $result);
}
/**
* testMissingHelperFile method
*
* @access public
* @return void
*/
function testMissingHelperFile() {
ob_start();
$TestErrorHandler = new TestErrorHandler('missingHelperFile', array('helper' => 'MyCustom', 'file' => 'my_custom.php'));
$result = ob_get_clean();
$this->assertPattern('/<h2>Missing Helper File<\/h2>/', $result);
$this->assertPattern('/Create the class below in file:/', $result);
$this->assertPattern('/(\/|\\\)my_custom.php/', $result);
}
/**
* testMissingHelperClass method
*
* @access public
* @return void
*/
function testMissingHelperClass() {
ob_start();
$TestErrorHandler = new TestErrorHandler('missingHelperClass', array('helper' => 'MyCustom', 'file' => 'my_custom.php'));
$result = ob_get_clean();
$this->assertPattern('/<h2>Missing Helper Class<\/h2>/', $result);
$this->assertPattern('/The helper class <em>MyCustomHelper<\/em> can not be found or does not exist./', $result);
$this->assertPattern('/(\/|\\\)my_custom.php/', $result);
}
/**
* test missingBehaviorFile method
*
* @access public
* @return void
*/
function testMissingBehaviorFile() {
ob_start();
$TestErrorHandler = new TestErrorHandler('missingBehaviorFile', array('behavior' => 'MyCustom', 'file' => 'my_custom.php'));
$result = ob_get_clean();
$this->assertPattern('/<h2>Missing Behavior File<\/h2>/', $result);
$this->assertPattern('/Create the class below in file:/', $result);
$this->assertPattern('/(\/|\\\)my_custom.php/', $result);
}
/**
* test MissingBehaviorClass method
*
* @access public
* @return void
*/
function testMissingBehaviorClass() {
ob_start();
$TestErrorHandler = new TestErrorHandler('missingBehaviorClass', array('behavior' => 'MyCustom', 'file' => 'my_custom.php'));
$result = ob_get_clean();
$this->assertPattern('/The behavior class <em>MyCustomBehavior<\/em> can not be found or does not exist./', $result);
$this->assertPattern('/(\/|\\\)my_custom.php/', $result);
}
/**
* testMissingComponentFile method
*
* @access public
* @return void
*/
function testMissingComponentFile() {
ob_start();
$TestErrorHandler = new TestErrorHandler('missingComponentFile', array('className' => 'PostsController', 'component' => 'Sidebox', 'file' => 'sidebox.php'));
$result = ob_get_clean();
$this->assertPattern('/<h2>Missing Component File<\/h2>/', $result);
$this->assertPattern('/Create the class <em>SideboxComponent<\/em> in file:/', $result);
$this->assertPattern('/(\/|\\\)sidebox.php/', $result);
}
/**
* testMissingComponentClass method
*
* @access public
* @return void
*/
function testMissingComponentClass() {
ob_start();
$TestErrorHandler = new TestErrorHandler('missingComponentClass', array('className' => 'PostsController', 'component' => 'Sidebox', 'file' => 'sidebox.php'));
$result = ob_get_clean();
$this->assertPattern('/<h2>Missing Component Class<\/h2>/', $result);
$this->assertPattern('/Create the class <em>SideboxComponent<\/em> in file:/', $result);
$this->assertPattern('/(\/|\\\)sidebox.php/', $result);
}
/**
* testMissingModel method
*
* @access public
* @return void
*/
function testMissingModel() {
ob_start();
$TestErrorHandler = new TestErrorHandler('missingModel', array('className' => 'Article', 'file' => 'article.php'));
$result = ob_get_clean();
$this->assertPattern('/<h2>Missing Model<\/h2>/', $result);
$this->assertPattern('/<em>Article<\/em> could not be found./', $result);
$this->assertPattern('/(\/|\\\)article.php/', $result);
}
}

View file

@ -0,0 +1,640 @@
<?php
/**
* ErrorHandlerTest file
*
* PHP versions 4 and 5
*
* CakePHP(tm) Tests <http://book.cakephp.org/view/1196/Testing>
* Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The Open Group Test Suite License
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://book.cakephp.org/view/1196/Testing CakePHP(tm) Tests
* @package cake
* @subpackage cake.tests.cases.libs
* @since CakePHP(tm) v 1.2.0.5432
* @license http://www.opensource.org/licenses/opengroup.php The Open Group Test Suite License
*/
App::import('Core', array('ErrorHandler', 'Controller', 'Component'));
/**
* Short description for class.
*
* @package cake
* @subpackage cake.tests.cases.libs
*/
class AuthBlueberryUser extends CakeTestModel {
/**
* name property
*
* @var string 'AuthBlueberryUser'
* @access public
*/
public $name = 'AuthBlueberryUser';
/**
* useTable property
*
* @var string
* @access public
*/
public $useTable = false;
}
if (!class_exists('AppController')) {
/**
* AppController class
*
* @package cake
* @subpackage cake.tests.cases.libs
*/
class AppController extends Controller {
/**
* components property
*
* @access public
* @return void
*/
public $components = array('Blueberry');
/**
* beforeRender method
*
* @access public
* @return void
*/
function beforeRender() {
echo $this->Blueberry->testName;
}
/**
* header method
*
* @access public
* @return void
*/
function header($header) {
echo $header;
}
/**
* _stop method
*
* @access public
* @return void
*/
function _stop($status = 0) {
echo 'Stopped with status: ' . $status;
}
}
} elseif (!defined('APP_CONTROLLER_EXISTS')){
define('APP_CONTROLLER_EXISTS', true);
}
/**
* BlueberryComponent class
*
* @package cake
* @subpackage cake.tests.cases.libs
*/
class BlueberryComponent extends Component {
/**
* testName property
*
* @access public
* @return void
*/
public $testName = null;
/**
* initialize method
*
* @access public
* @return void
*/
function initialize(&$controller) {
$this->testName = 'BlueberryComponent';
}
}
/**
* TestErrorController class
*
* @package cake
* @subpackage cake.tests.cases.libs
*/
class TestErrorController extends AppController {
/**
* uses property
*
* @var array
* @access public
*/
public $uses = array();
/**
* index method
*
* @access public
* @return void
*/
function index() {
$this->autoRender = false;
return 'what up';
}
}
/**
* BlueberryController class
*
* @package cake
* @subpackage cake.tests.cases.libs
*/
class BlueberryController extends AppController {
/**
* name property
*
* @access public
* @return void
*/
public $name = 'BlueberryController';
/**
* uses property
*
* @access public
* @return void
*/
public $uses = array();
}
/**
* MyCustomErrorHandler class
*
* @package cake
* @subpackage cake.tests.cases.libs
*/
class MyCustomErrorHandler extends ErrorHandler {
/**
* custom error message type.
*
* @return void
*/
function missingWidgetThing() {
echo 'widget thing is missing';
}
}
/**
* Exception class for testing app error handlers and custom errors.
*
* @package cake.test.cases.libs
*/
class MissingWidgetThingException extends NotFoundException { }
/**
* ErrorHandlerTest class
*
* @package cake
* @subpackage cake.tests.cases.libs
*/
class ErrorHandlerTest extends CakeTestCase {
/**
* skip method
*
* @access public
* @return void
*/
function skip() {
$this->skipIf(PHP_SAPI === 'cli', '%s Cannot be run from console');
}
/**
* setup create a request object to get out of router later.
*
* @return void
*/
function setUp() {
$request = new CakeRequest(null, false);
$request->base = '';
Router::setRequestInfo($request);
$this->_debug = Configure::read('debug');
}
function teardown() {
Configure::write('debug', $this->_debug);
}
/**
* test handleException generating a page.
*
* @return void
*/
function testHandleException() {
if ($this->skipIf(file_exists(APP . 'app_error.php'), 'App error exists cannot run.')) {
return;
}
$error = new NotFoundException('Kaboom!');
ob_start();
ErrorHandler::handleException($error);
$result = ob_get_clean();
$this->assertPattern('/Kaboom!/', $result, 'message missing.');
}
/**
* test that methods declared in an ErrorHandler subclass are not converted
* into error400 when debug > 0
*
* @return void
*/
function testSubclassMethodsNotBeingConvertedToError() {
Configure::write('debug', 2);
$exception = new MissingWidgetThingException('Widget not found');
$ErrorHandler = new MyCustomErrorHandler($exception);
ob_start();
$ErrorHandler->render();
$result = ob_get_clean();
$this->assertEqual($result, 'widget thing is missing');
}
/**
* test that subclass methods are not converted when debug = 0
*
* @return void
*/
function testSubclassMethodsNotBeingConvertedDebug0() {
Configure::write('debug', 0);
$exception = new MissingWidgetThingException('Widget not found');
$ErrorHandler = new MyCustomErrorHandler($exception);
$this->assertEqual('missingWidgetThing', $ErrorHandler->method);
ob_start();
$ErrorHandler->render();
$result = ob_get_clean();
$this->assertEqual($result, 'widget thing is missing', 'Method declared in subclass converted to error400');
}
/**
* test that ErrorHandler subclasses properly convert framework errors.
*
* @return void
*/
function testSubclassConvertingFrameworkErrors() {
Configure::write('debug', 0);
$exception = new MissingControllerException('PostsController');
$ErrorHandler = new MyCustomErrorHandler($exception);
$this->assertEqual('error400', $ErrorHandler->method);
ob_start();
$ErrorHandler->render();
$result = ob_get_clean();
$this->assertPattern('/Not Found/', $result, 'Method declared in error handler not converted to error400. %s');
}
/**
* test things in the constructor.
*
* @return void
*/
function testConstruction() {
$exception = new NotFoundException('Page not found');
$ErrorHandler = new ErrorHandler($exception);
$this->assertType('CakeErrorController', $ErrorHandler->controller);
$this->assertEquals('error400', $ErrorHandler->method);
$this->assertEquals($exception, $ErrorHandler->error);
}
/**
* test that method gets coerced when debug = 0
*
* @return void
*/
function testErrorMethodCoercion() {
Configure::write('debug', 0);
$exception = new MissingActionException('Page not found');
$ErrorHandler = new ErrorHandler($exception);
$this->assertType('CakeErrorController', $ErrorHandler->controller);
$this->assertEquals('error400', $ErrorHandler->method);
$this->assertEquals($exception, $ErrorHandler->error);
}
/**
* test that unknown exception types with valid status codes are treated correctly.
*
* @return void
*/
function testUnknownExceptionTypeWithExceptionThatHasA400Code() {
$exception = new MissingWidgetThingException('coding fail.');
$ErrorHandler = new ErrorHandler($exception);
$ErrorHandler->controller->response = $this->getMock('CakeResponse', array('statusCode'));
$ErrorHandler->controller->response->expects($this->once())->method('statusCode')->with(404);
ob_start();
$ErrorHandler->render();
$results = ob_get_clean();
$this->assertFalse(method_exists($ErrorHandler, 'missingWidgetThing'), 'no method should exist.');
$this->assertEquals('error400', $ErrorHandler->method, 'incorrect method coercion.');
}
/**
* test that unknown exception types with valid status codes are treated correctly.
*
* @return void
*/
function testUnknownExceptionTypeWithNoCodeIsA500() {
$exception = new OutOfBoundsException('foul ball.');
$ErrorHandler = new ErrorHandler($exception);
$ErrorHandler->controller->response = $this->getMock('CakeResponse', array('statusCode'));
$ErrorHandler->controller->response->expects($this->once())->method('statusCode')->with(500);
ob_start();
$ErrorHandler->render();
$results = ob_get_clean();
$this->assertEquals('error500', $ErrorHandler->method, 'incorrect method coercion.');
}
/**
* testerror400 method
*
* @access public
* @return void
*/
function testerror400() {
App::build(array(
'views' => array(TEST_CAKE_CORE_INCLUDE_PATH . 'libs' . DS . 'view' . DS)
), true);
Router::reload();
$request = new CakeRequest('posts/view/1000', false);
Router::setRequestInfo($request);
$exception = new NotFoundException('Custom message');
$ErrorHandler = new ErrorHandler($exception);
$ErrorHandler->controller->response = $this->getMock('CakeResponse', array('statusCode'));
$ErrorHandler->controller->response->expects($this->once())->method('statusCode')->with(404);
ob_start();
$ErrorHandler->render();
$result = ob_get_clean();
$this->assertPattern('/<h2>Custom message<\/h2>/', $result);
$this->assertPattern("/<strong>'\/posts\/view\/1000'<\/strong>/", $result);
App::build();
}
/**
* test that error400 only modifies the messages on CakeExceptions.
*
* @return void
*/
function testerror400OnlyChangingCakeException() {
Configure::write('debug', 0);
$exception = new NotFoundException('Custom message');
$ErrorHandler = new ErrorHandler($exception);
ob_start();
$ErrorHandler->render();
$result = ob_get_clean();
$this->assertContains('Custom message', $result);
$exception = new MissingActionException(array('controller' => 'PostsController', 'action' => 'index'));
$ErrorHandler = new ErrorHandler($exception);
ob_start();
$ErrorHandler->render();
$result = ob_get_clean();
$this->assertContains('Not Found', $result);
}
/**
* test that error400 doesn't expose XSS
*
* @return void
*/
function testError400NoInjection() {
Router::reload();
$request = new CakeRequest('pages/<span id=333>pink</span></id><script>document.body.style.background = t=document.getElementById(333).innerHTML;window.alert(t);</script>', false);
Router::setRequestInfo($request);
$exception = new NotFoundException('Custom message');
$ErrorHandler = new ErrorHandler($exception);
ob_start();
$ErrorHandler->render();
$result = ob_get_clean();
$this->assertNoPattern('#<script>document#', $result);
$this->assertNoPattern('#alert\(t\);</script>#', $result);
}
/**
* testError500 method
*
* @access public
* @return void
*/
function testError500Message() {
$exception = new InternalErrorException('An Internal Error Has Occurred');
$ErrorHandler = new ErrorHandler($exception);
$ErrorHandler->controller->response = $this->getMock('CakeResponse', array('statusCode'));
$ErrorHandler->controller->response->expects($this->once())->method('statusCode')->with(500);
ob_start();
$ErrorHandler->render();
$result = ob_get_clean();
$this->assertPattern('/<h2>An Internal Error Has Occurred<\/h2>/', $result);
}
/**
* testMissingController method
*
* @access public
* @return void
*/
function testMissingController() {
$this->skipIf(defined('APP_CONTROLLER_EXISTS'), '%s Need a non-existent AppController');
$exception = new MissingControllerException(array('controller' => 'PostsController'));
$ErrorHandler = new ErrorHandler($exception);
ob_start();
$ErrorHandler->render();
$result = ob_get_clean();
$this->assertPattern('/<h2>Missing Controller<\/h2>/', $result);
$this->assertPattern('/<em>PostsController<\/em>/', $result);
$this->assertPattern('/BlueberryComponent/', $result);
}
/* TODO: Integration test that needs to be moved
ob_start();
$dispatcher = new Dispatcher('/blueberry/inexistent');
$result = ob_get_clean();
$this->assertPattern('/<h2>Missing Method in BlueberryController<\/h2>/', $result);
$this->assertPattern('/<em>BlueberryController::<\/em><em>inexistent\(\)<\/em>/', $result);
$this->assertNoPattern('/Location: (.*)\/users\/login/', $result);
$this->assertNoPattern('/Stopped with status: 0/', $result);
*/
/**
* Returns an array of tests to run for the various CakeException classes.
*
* @return void
*/
public static function testProvider() {
return array(
array(
new MissingActionException(array('controller' => 'PostsController', 'action' => 'index')),
array(
'/<h2>Missing Method in PostsController<\/h2>/',
'/<em>PostsController::<\/em><em>index\(\)<\/em>/'
),
404
),
array(
new PrivateActionException(array('controller' => 'PostsController' , 'action' => '_secretSauce')),
array(
'/<h2>Private Method in PostsController<\/h2>/',
'/<em>PostsController::<\/em><em>_secretSauce\(\)<\/em>/'
),
404
),
array(
new MissingTableException(array('table' => 'articles', 'class' => 'Article')),
array(
'/<h2>Missing Database Table<\/h2>/',
'/table <em>articles<\/em> for model <em>Article<\/em>/'
),
500
),
array(
new MissingDatabaseException(array('connection' => 'default')),
array(
'/<h2>Missing Database Connection<\/h2>/',
'/Confirm you have created the file/'
),
500
),
array(
new MissingViewException(array('file' => '/posts/about.ctp')),
array(
"/posts\/about.ctp/"
),
500
),
array(
new MissingLayoutException(array('file' => 'layouts/my_layout.ctp')),
array(
"/Missing Layout/",
"/layouts\/my_layout.ctp/"
),
500
),
array(
new MissingConnectionException(array('class' => 'Article')),
array(
'/<h2>Missing Database Connection<\/h2>/',
'/Article requires a database connection/'
),
500
),
array(
new MissingHelperFileException(array('file' => 'my_custom.php', 'class' => 'MyCustomHelper')),
array(
'/<h2>Missing Helper File<\/h2>/',
'/Create the class below in file:/',
'/(\/|\\\)my_custom.php/'
),
500
),
array(
new MissingHelperClassException(array('file' => 'my_custom.php', 'class' => 'MyCustomHelper')),
array(
'/<h2>Missing Helper Class<\/h2>/',
'/The helper class <em>MyCustomHelper<\/em> can not be found or does not exist./',
'/(\/|\\\)my_custom.php/',
),
500
),
array(
new MissingBehaviorFileException(array('file' => 'my_custom.php', 'class' => 'MyCustomBehavior')),
array(
'/<h2>Missing Behavior File<\/h2>/',
'/Create the class below in file:/',
'/(\/|\\\)my_custom.php/',
),
500
),
array(
new MissingBehaviorClassException(array('file' => 'my_custom.php', 'class' => 'MyCustomBehavior')),
array(
'/The behavior class <em>MyCustomBehavior<\/em> can not be found or does not exist./',
'/(\/|\\\)my_custom.php/'
),
500
),
array(
new MissingComponentFileException(array('file' => 'sidebox.php', 'class' => 'SideboxComponent')),
array(
'/<h2>Missing Component File<\/h2>/',
'/Create the class <em>SideboxComponent<\/em> in file:/',
'/(\/|\\\)sidebox.php/'
),
500
),
array(
new MissingComponentClassException(array('file' => 'sidebox.php', 'class' => 'SideboxComponent')),
array(
'/<h2>Missing Component Class<\/h2>/',
'/Create the class <em>SideboxComponent<\/em> in file:/',
'/(\/|\\\)sidebox.php/'
),
500
)
);
}
/**
* Test the various CakeException sub classes
*
* @dataProvider testProvider
* @return void
*/
function testCakeExceptionHandling($exception, $patterns, $code) {
$ErrorHandler = new ErrorHandler($exception);
$ErrorHandler->controller->response = $this->getMock('CakeResponse', array('statusCode'));
$ErrorHandler->controller->response->expects($this->once())
->method('statusCode')
->with($code);
ob_start();
$ErrorHandler->render();
$result = ob_get_clean();
foreach ($patterns as $pattern) {
$this->assertPattern($pattern, $result);
}
}
}

View file

@ -411,12 +411,12 @@ class Test7Behavior extends ModelBehavior{
}
/**
* BehaviorTest class
* BehaviorCollection class
*
* @package cake
* @subpackage cake.tests.cases.libs.model
*/
class BehaviorTest extends CakeTestCase {
class BehaviorCollectionTest extends CakeTestCase {
/**
* fixtures property
@ -1024,6 +1024,10 @@ class BehaviorTest extends CakeTestCase {
$result = $Apple->{'look for the remote'}('in the couch');
$expected = "Item.name = 'the remote' AND Location.name = 'the couch'";
$this->assertEqual($result, $expected);
$result = $Apple->{'look for THE REMOTE'}('in the couch');
$expected = "Item.name = 'THE REMOTE' AND Location.name = 'the couch'";
$this->assertEqual($result, $expected, 'Mapped method was lowercased.');
}
/**

Some files were not shown because too many files have changed in this diff Show more