Merge remote branch 'origin/2.0' into 2.0-class-loading

Conflicts:
	cake/libs/view/scaffolds/edit.ctp
	cake/libs/view/scaffolds/form.ctp
	cake/tests/test_app/plugins/test_plugin/views/tests/scaffold.edit.ctp
	cake/tests/test_app/plugins/test_plugin/views/tests/scaffold.form.ctp
	cake/tests/test_app/views/posts/scaffold.edit.ctp
	cake/tests/test_app/views/posts/scaffold.form.ctp
	lib/Cake/Error/ErrorHandler.php
	lib/Cake/Model/Behavior/TranslateBehavior.php
	lib/Cake/Model/Datasource/CakeSession.php
	lib/Cake/Routing/Router.php
	lib/Cake/TestSuite/TestManager.php
	lib/Cake/View/scaffolds/edit.ctp
	lib/Cake/tests/cases/console/shells/bake.test.php
	lib/Cake/tests/cases/libs/cake_log.test.php
	lib/Cake/tests/cases/libs/cake_request.test.php
	lib/Cake/tests/cases/libs/view/helpers/number.test.php
	lib/Cake/tests/test_app/plugins/test_plugin/views/tests/scaffold.edit.ctp
	lib/Cake/tests/test_app/views/posts/scaffold.edit.ctp
This commit is contained in:
José Lorenzo Rodríguez 2010-12-15 01:13:05 -04:30
commit 07e43bb0f8
122 changed files with 4822 additions and 2612 deletions

View file

@ -0,0 +1,251 @@
<?php
/**
* Paginator Component
*
* 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.controller.components
* @since CakePHP(tm) v 2.0
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
/**
* PaginatorComponent
*
* This component is used to handle automatic model data pagination
*
* @package cake
* @subpackage cake.cake.libs.controller.components
*
*/
class PaginatorComponent extends Component {
/**
* Pagination settings
*
* @var array
*/
public $settings = array();
/**
* 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()) {
$settings = array_merge(array('page' => 1, 'limit' => 20), (array)$settings);
$this->Controller = $collection->getController();
parent::__construct($collection, $settings);
}
/**
* Handles automatic pagination of model records.
*
* @param mixed $object Model to paginate (e.g: model instance, or 'Model', or 'Model.InnerModel')
* @param mixed $scope Conditions to use while paginating
* @param array $whitelist List of allowed options for paging
* @return array Model query results
*/
public function paginate($object = null, $scope = array(), $whitelist = array()) {
if (is_array($object)) {
$whitelist = $scope;
$scope = $object;
$object = null;
}
$assoc = null;
if (is_string($object)) {
$assoc = null;
if (strpos($object, '.') !== false) {
list($object, $assoc) = pluginSplit($object);
}
if ($assoc && isset($this->Controller->{$object}->{$assoc})) {
$object = $this->Controller->{$object}->{$assoc};
} elseif (
$assoc && isset($this->Controller->{$this->Controller->modelClass}) &&
isset($this->Controller->{$this->Controller->modelClass}->{$assoc}
)) {
$object = $this->Controller->{$this->Controller->modelClass}->{$assoc};
} elseif (isset($this->Controller->{$object})) {
$object = $this->Controller->{$object};
} elseif (
isset($this->Controller->{$this->Controller->modelClass}) && isset($this->Controller->{$this->Controller->modelClass}->{$object}
)) {
$object = $this->Controller->{$this->Controller->modelClass}->{$object};
}
} elseif (empty($object) || $object === null) {
if (isset($this->Controller->{$this->Controller->modelClass})) {
$object = $this->Controller->{$this->Controller->modelClass};
} else {
$className = null;
$name = $this->Controller->uses[0];
if (strpos($this->Controller->uses[0], '.') !== false) {
list($name, $className) = explode('.', $this->Controller->uses[0]);
}
if ($className) {
$object = $this->Controller->{$className};
} else {
$object = $this->Controller->{$name};
}
}
}
if (!is_object($object)) {
throw new MissingModelException($object);
}
$options = array_merge($this->Controller->request->params, $this->Controller->params['url'], $this->Controller->passedArgs);
if (isset($this->settings[$object->alias])) {
$defaults = $this->settings[$object->alias];
} else {
$defaults = $this->settings;
}
if (isset($options['show'])) {
$options['limit'] = $options['show'];
}
if (isset($options['sort'])) {
$direction = null;
if (isset($options['direction'])) {
$direction = strtolower($options['direction']);
}
if ($direction != 'asc' && $direction != 'desc') {
$direction = 'asc';
}
$options['order'] = array($options['sort'] => $direction);
}
if (!empty($options['order']) && is_array($options['order'])) {
$alias = $object->alias ;
$key = $field = key($options['order']);
if (strpos($key, '.') !== false) {
list($alias, $field) = explode('.', $key);
}
$value = $options['order'][$key];
unset($options['order'][$key]);
if ($object->hasField($field)) {
$options['order'][$alias . '.' . $field] = $value;
} elseif ($object->hasField($field, true)) {
$options['order'][$field] = $value;
} elseif (isset($object->{$alias}) && $object->{$alias}->hasField($field)) {
$options['order'][$alias . '.' . $field] = $value;
}
}
$vars = array('fields', 'order', 'limit', 'page', 'recursive');
$keys = array_keys($options);
$count = count($keys);
for ($i = 0; $i < $count; $i++) {
if (!in_array($keys[$i], $vars, true)) {
unset($options[$keys[$i]]);
}
if (empty($whitelist) && ($keys[$i] === 'fields' || $keys[$i] === 'recursive')) {
unset($options[$keys[$i]]);
} elseif (!empty($whitelist) && !in_array($keys[$i], $whitelist)) {
unset($options[$keys[$i]]);
}
}
$conditions = $fields = $order = $limit = $page = $recursive = null;
if (!isset($defaults['conditions'])) {
$defaults['conditions'] = array();
}
$type = 'all';
if (isset($defaults[0])) {
$type = $defaults[0];
unset($defaults[0]);
}
$options = array_merge(array('page' => 1, 'limit' => 20), $defaults, $options);
$options['limit'] = (int) $options['limit'];
if (empty($options['limit']) || $options['limit'] < 1) {
$options['limit'] = 1;
}
extract($options);
if (is_array($scope) && !empty($scope)) {
$conditions = array_merge($conditions, $scope);
} elseif (is_string($scope)) {
$conditions = array($conditions, $scope);
}
if ($recursive === null) {
$recursive = $object->recursive;
}
$extra = array_diff_key($defaults, compact(
'conditions', 'fields', 'order', 'limit', 'page', 'recursive'
));
if ($type !== 'all') {
$extra['type'] = $type;
}
if (method_exists($object, 'paginateCount')) {
$count = $object->paginateCount($conditions, $recursive, $extra);
} else {
$parameters = compact('conditions');
if ($recursive != $object->recursive) {
$parameters['recursive'] = $recursive;
}
$count = $object->find('count', array_merge($parameters, $extra));
}
$pageCount = intval(ceil($count / $limit));
if ($page === 'last' || $page >= $pageCount) {
$options['page'] = $page = $pageCount;
} elseif (intval($page) < 1) {
$options['page'] = $page = 1;
}
$page = $options['page'] = (integer)$page;
if (method_exists($object, 'paginate')) {
$results = $object->paginate(
$conditions, $fields, $order, $limit, $page, $recursive, $extra
);
} else {
$parameters = compact('conditions', 'fields', 'order', 'limit', 'page');
if ($recursive != $object->recursive) {
$parameters['recursive'] = $recursive;
}
$results = $object->find($type, array_merge($parameters, $extra));
}
$paging = array(
'page' => $page,
'current' => count($results),
'count' => $count,
'prevPage' => ($page > 1),
'nextPage' => ($count > ($page * $limit)),
'pageCount' => $pageCount,
'defaults' => array_merge(array('limit' => 20, 'step' => 1), $defaults),
'options' => $options
);
if (!isset($this->Controller->request['paging'])) {
$this->Controller->request['paging'] = array();
}
$this->Controller->request['paging'] = array_merge(
(array)$this->Controller->request['paging'],
array($object->alias => $paging)
);
if (!in_array('Paginator', $this->Controller->helpers) && !array_key_exists('Paginator', $this->Controller->helpers)) {
$this->Controller->helpers[] = 'Paginator';
}
return $results;
}
}

View file

@ -0,0 +1,68 @@
<?php
/**
* Basic authentication
*
* 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.http
* @since CakePHP(tm) v 2.0.0
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
/**
* Basic authentication
*
* @package cake
* @subpackage cake.cake.libs.http
*/
class BasicAuthentication {
/**
* Authentication
*
* @param HttpSocket $http
* @param array $authInfo
* @return void
* @see http://www.ietf.org/rfc/rfc2617.txt
*/
public static function authentication(HttpSocket $http, &$authInfo) {
if (isset($authInfo['user'], $authInfo['pass'])) {
$http->request['header']['Authorization'] = self::_generateHeader($authInfo['user'], $authInfo['pass']);
}
}
/**
* Proxy Authentication
*
* @param HttpSocket $http
* @param array $proxyInfo
* @return void
* @see http://www.ietf.org/rfc/rfc2617.txt
*/
public static function proxyAuthentication(HttpSocket $http, &$proxyInfo) {
if (isset($proxyInfo['user'], $proxyInfo['pass'])) {
$http->request['header']['Proxy-Authorization'] = self::_generateHeader($proxyInfo['user'], $proxyInfo['pass']);
}
}
/**
* Generate basic [proxy] authentication header
*
* @param string $user
* @param string $pass
* @return string
*/
protected static function _generateHeader($user, $pass) {
return 'Basic ' . base64_encode($user . ':' . $pass);
}
}

View file

@ -0,0 +1,106 @@
<?php
/**
* Digest authentication
*
* 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.http
* @since CakePHP(tm) v 2.0.0
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
/**
* Digest authentication
*
* @package cake
* @subpackage cake.cake.libs.http
*/
class DigestAuthentication {
/**
* Authentication
*
* @param HttpSocket $http
* @param array $authInfo
* @return void
* @link http://www.ietf.org/rfc/rfc2617.txt
*/
public static function authentication(HttpSocket $http, &$authInfo) {
if (isset($authInfo['user'], $authInfo['pass'])) {
if (!isset($authInfo['realm']) && !self::_getServerInformation($http, $authInfo)) {
return;
}
$http->request['header']['Authorization'] = self::_generateHeader($http, $authInfo);
}
}
/**
* Retrive information about the authetication
*
* @param HttpSocket $http
* @parma array $authInfo
* @return boolean
*/
protected static function _getServerInformation(HttpSocket $http, &$authInfo) {
$originalRequest = $http->request;
$http->configAuth(false);
$http->request($http->request);
$http->request = $originalRequest;
$http->configAuth('Digest', $authInfo);
if (empty($http->response['header']['WWW-Authenticate'])) {
return false;
}
preg_match_all('@(\w+)=(?:(?:")([^"]+)"|([^\s,$]+))@', $http->response['header']['WWW-Authenticate'], $matches, PREG_SET_ORDER);
foreach ($matches as $match) {
$authInfo[$match[1]] = $match[2];
}
if (!empty($authInfo['qop']) && empty($authInfo['nc'])) {
$authInfo['nc'] = 1;
}
return true;
}
/**
* Generate the header Authorization
*
* @param HttpSocket $http
* @param array $authInfo
* @return string
*/
protected static function _generateHeader(HttpSocket $http, &$authInfo) {
$a1 = md5($authInfo['user'] . ':' . $authInfo['realm'] . ':' . $authInfo['pass']);
$a2 = md5($http->request['method'] . ':' . $http->request['uri']['path']);
if (empty($authInfo['qop'])) {
$response = md5($a1 . ':' . $authInfo['nonce'] . ':' . $a2);
} else {
$authInfo['cnonce'] = uniqid();
$nc = sprintf('%08x', $authInfo['nc']++);
$response = md5($a1 . ':' . $authInfo['nonce'] . ':' . $nc . ':' . $authInfo['cnonce'] . ':auth:' . $a2);
}
$authHeader = 'Digest ';
$authHeader .= 'username="' . str_replace(array('\\', '"'), array('\\\\', '\\"'), $authInfo['user']) . '", ';
$authHeader .= 'realm="' . $authInfo['realm'] . '", ';
$authHeader .= 'nonce="' . $authInfo['nonce'] . '", ';
$authHeader .= 'uri="' . $http->request['uri']['path'] . '", ';
$authHeader .= 'response="' . $response . '"';
if (!empty($authInfo['opaque'])) {
$authHeader .= ', opaque="' . $authInfo['opaque'] . '"';
}
if (!empty($authInfo['qop'])) {
$authHeader .= ', qop="auth", nc=' . $nc . ', cnonce="' . $authInfo['cnonce'] . '"';
}
return $authHeader;
}
}

438
cake/libs/http_response.php Normal file
View file

@ -0,0 +1,438 @@
<?php
/**
* HTTP Response from HttpSocket.
*
* 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 2.0.0
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
class HttpResponse implements ArrayAccess {
/**
* Body content
*
* @var string
*/
public $body = '';
/**
* Headers
*
* @var array
*/
public $headers = array();
/**
* Cookies
*
* @var array
*/
public $cookies = array();
/**
* HTTP version
*
* @var string
*/
public $httpVersion = 'HTTP/1.1';
/**
* Response code
*
* @var integer
*/
public $code = 0;
/**
* Reason phrase
*
* @var string
*/
public $reasonPhrase = '';
/**
* Pure raw content
*
* @var string
*/
public $raw = '';
/**
* Contructor
*
*/
public function __construct($message = null) {
if ($message !== null) {
$this->parseResponse($message);
}
}
/**
* Body content
*
* @return string
*/
public function body() {
return (string)$this->body;
}
/**
* Get header in case insensitive
*
* @param string $name Header name
* @return mixed String if header exists or null
*/
public function getHeader($name, $headers = null) {
if (!is_array($headers)) {
$headers =& $this->headers;
}
if (isset($headers[$name])) {
return $headers[$name];
}
foreach ($headers as $key => $value) {
if (strcasecmp($key, $name) == 0) {
return $value;
}
}
return null;
}
/**
* If return is 200 (OK)
*
* @return boolean
*/
public function isOk() {
return $this->code == 200;
}
/**
* Parses the given message and breaks it down in parts.
*
* @param string $message Message to parse
* @return void
* @throw SocketException
*/
public function parseResponse($message) {
if (!is_string($message)) {
throw new SocketException(__('Invalid response.'));
}
if (!preg_match("/^(.+\r\n)(.*)(?<=\r\n)\r\n/Us", $message, $match)) {
throw new SocketException(__('Invalid HTTP response.'));
}
list(, $statusLine, $header) = $match;
$this->raw = $message;
$this->body = (string)substr($message, strlen($match[0]));
if (preg_match("/(.+) ([0-9]{3}) (.+)\r\n/DU", $statusLine, $match)) {
$this->httpVersion = $match[1];
$this->code = $match[2];
$this->reasonPhrase = $match[3];
}
$this->headers = $this->_parseHeader($header);
$transferEncoding = $this->getHeader('Transfer-Encoding');
$decoded = $this->_decodeBody($this->body, $transferEncoding);
$this->body = $decoded['body'];
if (!empty($decoded['header'])) {
$this->headers = $this->_parseHeader($this->_buildHeader($this->headers) . $this->_buildHeader($decoded['header']));
}
if (!empty($this->headers)) {
$this->cookies = $this->parseCookies($this->headers);
}
}
/**
* Generic function to decode a $body with a given $encoding. Returns either an array with the keys
* 'body' and 'header' or false on failure.
*
* @param string $body A string continaing the body to decode.
* @param mixed $encoding Can be false in case no encoding is being used, or a string representing the encoding.
* @return mixed Array of response headers and body or false.
*/
protected function _decodeBody($body, $encoding = 'chunked') {
if (!is_string($body)) {
return false;
}
if (empty($encoding)) {
return array('body' => $body, 'header' => false);
}
$decodeMethod = '_decode' . Inflector::camelize(str_replace('-', '_', $encoding)) . 'Body';
if (!is_callable(array(&$this, $decodeMethod))) {
return array('body' => $body, 'header' => false);
}
return $this->{$decodeMethod}($body);
}
/**
* Decodes a chunked message $body and returns either an array with the keys 'body' and 'header' or false as
* a result.
*
* @param string $body A string continaing the chunked body to decode.
* @return mixed Array of response headers and body or false.
* @throws SocketException
*/
protected function _decodeChunkedBody($body) {
if (!is_string($body)) {
return false;
}
$decodedBody = null;
$chunkLength = null;
while ($chunkLength !== 0) {
if (!preg_match("/^([0-9a-f]+) *(?:;(.+)=(.+))?\r\n/iU", $body, $match)) {
throw new SocketException(__('HttpSocket::_decodeChunkedBody - Could not parse malformed chunk.'));
}
$chunkSize = 0;
$hexLength = 0;
$chunkExtensionName = '';
$chunkExtensionValue = '';
if (isset($match[0])) {
$chunkSize = $match[0];
}
if (isset($match[1])) {
$hexLength = $match[1];
}
if (isset($match[2])) {
$chunkExtensionName = $match[2];
}
if (isset($match[3])) {
$chunkExtensionValue = $match[3];
}
$body = substr($body, strlen($chunkSize));
$chunkLength = hexdec($hexLength);
$chunk = substr($body, 0, $chunkLength);
if (!empty($chunkExtensionName)) {
/**
* @todo See if there are popular chunk extensions we should implement
*/
}
$decodedBody .= $chunk;
if ($chunkLength !== 0) {
$body = substr($body, $chunkLength + strlen("\r\n"));
}
}
$entityHeader = false;
if (!empty($body)) {
$entityHeader = $this->_parseHeader($body);
}
return array('body' => $decodedBody, 'header' => $entityHeader);
}
/**
* Parses an array based header.
*
* @param array $header Header as an indexed array (field => value)
* @return array Parsed header
*/
protected function _parseHeader($header) {
if (is_array($header)) {
return $header;
} elseif (!is_string($header)) {
return false;
}
preg_match_all("/(.+):(.+)(?:(?<![\t ])\r\n|\$)/Uis", $header, $matches, PREG_SET_ORDER);
$header = array();
foreach ($matches as $match) {
list(, $field, $value) = $match;
$value = trim($value);
$value = preg_replace("/[\t ]\r\n/", "\r\n", $value);
$field = $this->_unescapeToken($field);
if (!isset($header[$field])) {
$header[$field] = $value;
} else {
$header[$field] = array_merge((array)$header[$field], (array)$value);
}
}
return $header;
}
/**
* Parses cookies in response headers.
*
* @param array $header Header array containing one ore more 'Set-Cookie' headers.
* @return mixed Either false on no cookies, or an array of cookies recieved.
* @todo Make this 100% RFC 2965 confirm
*/
public function parseCookies($header) {
$cookieHeader = $this->getHeader('Set-Cookie', $header);
if (!$cookieHeader) {
return false;
}
$cookies = array();
foreach ((array)$cookieHeader as $cookie) {
if (strpos($cookie, '";"') !== false) {
$cookie = str_replace('";"', "{__cookie_replace__}", $cookie);
$parts = str_replace("{__cookie_replace__}", '";"', explode(';', $cookie));
} else {
$parts = preg_split('/\;[ \t]*/', $cookie);
}
list($name, $value) = explode('=', array_shift($parts), 2);
$cookies[$name] = compact('value');
foreach ($parts as $part) {
if (strpos($part, '=') !== false) {
list($key, $value) = explode('=', $part);
} else {
$key = $part;
$value = true;
}
$key = strtolower($key);
if (!isset($cookies[$name][$key])) {
$cookies[$name][$key] = $value;
}
}
}
return $cookies;
}
/**
* Unescapes a given $token according to RFC 2616 (HTTP 1.1 specs)
*
* @param string $token Token to unescape
* @param array $chars
* @return string Unescaped token
* @todo Test $chars parameter
*/
protected function _unescapeToken($token, $chars = null) {
$regex = '/"([' . implode('', $this->_tokenEscapeChars(true, $chars)) . '])"/';
$token = preg_replace($regex, '\\1', $token);
return $token;
}
/**
* Gets escape chars according to RFC 2616 (HTTP 1.1 specs).
*
* @param boolean $hex true to get them as HEX values, false otherwise
* @param array $chars
* @return array Escape chars
* @todo Test $chars parameter
*/
protected function _tokenEscapeChars($hex = true, $chars = null) {
if (!empty($chars)) {
$escape = $chars;
} else {
$escape = array('"', "(", ")", "<", ">", "@", ",", ";", ":", "\\", "/", "[", "]", "?", "=", "{", "}", " ");
for ($i = 0; $i <= 31; $i++) {
$escape[] = chr($i);
}
$escape[] = chr(127);
}
if ($hex == false) {
return $escape;
}
$regexChars = '';
foreach ($escape as $key => $char) {
$escape[$key] = '\\x' . str_pad(dechex(ord($char)), 2, '0', STR_PAD_LEFT);
}
return $escape;
}
/**
* ArrayAccess - Offset Exists
*
* @param mixed $offset
* @return boolean
*/
public function offsetExists($offset) {
return in_array($offset, array('raw', 'status', 'header', 'body', 'cookies'));
}
/**
* ArrayAccess - Offset Get
*
* @param mixed $offset
* @return mixed
*/
public function offsetGet($offset) {
switch ($offset) {
case 'raw':
$firstLineLength = strpos($this->raw, "\r\n") + 2;
if ($this->raw[$firstLineLength] === "\r") {
$header = null;
} else {
$header = substr($this->raw, $firstLineLength, strpos($this->raw, "\r\n\r\n") - $firstLineLength) . "\r\n";
}
return array(
'status-line' => $this->httpVersion . ' ' . $this->code . ' ' . $this->reasonPhrase . "\r\n",
'header' => $header,
'body' => $this->body,
'response' => $this->raw
);
case 'status':
return array(
'http-version' => $this->httpVersion,
'code' => $this->code,
'reason-phrase' => $this->reasonPhrase
);
case 'header':
return $this->headers;
case 'body':
return $this->body;
case 'cookies':
return $this->cookies;
}
return null;
}
/**
* ArrayAccess - 0ffset Set
*
* @param mixed $offset
* @param mixed $value
* @return void
*/
public function offsetSet($offset, $value) {
return;
}
/**
* ArrayAccess - Offset Unset
*
* @param mixed @offset
* @return void
*/
public function offsetUnset($offset) {
return;
}
/**
* Instance as string
*
* @return string
*/
public function __toString() {
return $this->body();
}
}

View file

@ -27,10 +27,15 @@
<div class="actions">
<h3><?php echo __('Actions'); ?></h3>
<ul>
<?php if ($this->action != 'add'):?>
<li><?php echo $this->Html->link(__('Delete'), array('action' => 'delete', $this->Form->value($modelClass.'.'.$primaryKey)), null, __('Are you sure you want to delete').' #' . $this->Form->value($modelClass.'.'.$primaryKey)); ?></li>
<?php if ($this->request->action != 'add'): ?>
<li><?php echo $this->Form->postLink(
__('Delete'),
array('action' => 'delete', $this->Form->value($modelClass . '.' . $primaryKey)),
null,
__('Are you sure you want to delete # %s?', $this->Form->value($modelClass . '.' . $primaryKey)));
?></li>
<?php endif;?>
<li><?php echo $this->Html->link(__('List').' '.$pluralHumanName, array('action' => 'index'));?></li>
<li><?php echo $this->Html->link(__('List') . ' ' . $pluralHumanName, array('action' => 'index'));?></li>
<?php
$done = array();
foreach ($associations as $_type => $_data) {

View file

@ -0,0 +1,489 @@
<?php
/**
* PaginatorComponentTest file
*
* Series of tests for paginator component.
*
* PHP 5
*
* CakePHP(tm) Tests <http://book.cakephp.org/view/1196/Testing>
* 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.cake.tests.cases.libs.controller.components
* @since CakePHP(tm) v 2.0
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
App::import('Controller', 'Controller', false);
App::import('Core', array('CakeRequest', 'CakeResponse'));
/**
* PaginatorTestController class
*
* @package cake
* @subpackage cake.tests.cases.libs.controller.components
*/
class PaginatorTestController extends Controller {
/**
* name property
*
* @var string 'PaginatorTest'
* @access public
*/
public $name = 'PaginatorTest';
/**
* uses property
*
* @var array
* @access public
*/
//public $uses = null;
/**
* components property
*
* @var array
* @access public
*/
public $components = array('Paginator');
}
/**
* PaginatorControllerPost class
*
* @package cake
* @subpackage cake.tests.cases.libs.controller.components
*/
class PaginatorControllerPost extends CakeTestModel {
/**
* name property
*
* @var string 'PaginatorControllerPost'
* @access public
*/
public $name = 'PaginatorControllerPost';
/**
* useTable property
*
* @var string 'posts'
* @access public
*/
public $useTable = 'posts';
/**
* invalidFields property
*
* @var array
* @access public
*/
public $invalidFields = array('name' => 'error_msg');
/**
* lastQuery property
*
* @var mixed null
* @access public
*/
public $lastQuery = null;
/**
* beforeFind method
*
* @param mixed $query
* @access public
* @return void
*/
function beforeFind($query) {
$this->lastQuery = $query;
}
/**
* find method
*
* @param mixed $type
* @param array $options
* @access public
* @return void
*/
function find($type, $options = array()) {
if ($type == 'popular') {
$conditions = array($this->name . '.' . $this->primaryKey .' > ' => '1');
$options = Set::merge($options, compact('conditions'));
return parent::find('all', $options);
}
return parent::find($type, $options);
}
}
/**
* ControllerPaginateModel class
*
* @package cake
* @subpackage cake.tests.cases.libs.controller.components
*/
class ControllerPaginateModel extends CakeTestModel {
/**
* name property
*
* @var string 'ControllerPaginateModel'
* @access public
*/
public $name = 'ControllerPaginateModel';
/**
* useTable property
*
* @var string 'comments'
* @access public
*/
public $useTable = 'comments';
/**
* paginate method
*
* @return void
*/
public function paginate($conditions, $fields, $order, $limit, $page, $recursive, $extra) {
$this->extra = $extra;
}
/**
* paginateCount
*
* @access public
* @return void
*/
function paginateCount($conditions, $recursive, $extra) {
$this->extraCount = $extra;
}
}
/**
* PaginatorControllerCommentclass
*
* @package cake
* @subpackage cake.tests.cases.libs.controller.components
*/
class PaginatorControllerComment extends CakeTestModel {
/**
* name property
*
* @var string 'Comment'
* @access public
*/
public $name = 'Comment';
/**
* useTable property
*
* @var string 'comments'
* @access public
*/
public $useTable = 'comments';
/**
* alias property
*
* @var string 'PaginatorControllerComment'
* @access public
*/
public $alias = 'PaginatorControllerComment';
}
class PaginatorTest extends CakeTestCase {
/**
* fixtures property
*
* @var array
* @access public
*/
public $fixtures = array('core.post', 'core.comment');
/**
* testPaginate method
*
* @access public
* @return void
*/
function testPaginate() {
$request = new CakeRequest('controller_posts/index');
$request->params['pass'] = $request->params['named'] = array();
$Controller = new PaginatorTestController($request);
$Controller->uses = array('PaginatorControllerPost', 'PaginatorControllerComment');
$Controller->passedArgs[] = '1';
$Controller->params['url'] = array();
$Controller->constructClasses();
$results = Set::extract($Controller->Paginator->paginate('PaginatorControllerPost'), '{n}.PaginatorControllerPost.id');
$this->assertEqual($results, array(1, 2, 3));
$results = Set::extract($Controller->Paginator->paginate('PaginatorControllerComment'), '{n}.PaginatorControllerComment.id');
$this->assertEqual($results, array(1, 2, 3, 4, 5, 6));
$Controller->modelClass = null;
$Controller->uses[0] = 'Plugin.PaginatorControllerPost';
$results = Set::extract($Controller->Paginator->paginate(), '{n}.PaginatorControllerPost.id');
$this->assertEqual($results, array(1, 2, 3));
$Controller->passedArgs = array('page' => '-1');
$results = Set::extract($Controller->Paginator->paginate('PaginatorControllerPost'), '{n}.PaginatorControllerPost.id');
$this->assertEqual($Controller->params['paging']['PaginatorControllerPost']['page'], 1);
$this->assertEqual($results, array(1, 2, 3));
$Controller->passedArgs = array('sort' => 'PaginatorControllerPost.id', 'direction' => 'asc');
$results = Set::extract($Controller->Paginator->paginate('PaginatorControllerPost'), '{n}.PaginatorControllerPost.id');
$this->assertEqual($Controller->params['paging']['PaginatorControllerPost']['page'], 1);
$this->assertEqual($results, array(1, 2, 3));
$Controller->passedArgs = array('sort' => 'PaginatorControllerPost.id', 'direction' => 'desc');
$results = Set::extract($Controller->Paginator->paginate('PaginatorControllerPost'), '{n}.PaginatorControllerPost.id');
$this->assertEqual($Controller->params['paging']['PaginatorControllerPost']['page'], 1);
$this->assertEqual($results, array(3, 2, 1));
$Controller->passedArgs = array('sort' => 'id', 'direction' => 'desc');
$results = Set::extract($Controller->Paginator->paginate('PaginatorControllerPost'), '{n}.PaginatorControllerPost.id');
$this->assertEqual($Controller->params['paging']['PaginatorControllerPost']['page'], 1);
$this->assertEqual($results, array(3, 2, 1));
$Controller->passedArgs = array('sort' => 'NotExisting.field', 'direction' => 'desc');
$results = Set::extract($Controller->Paginator->paginate('PaginatorControllerPost'), '{n}.PaginatorControllerPost.id');
$this->assertEqual($Controller->params['paging']['PaginatorControllerPost']['page'], 1, 'Invalid field in query %s');
$this->assertEqual($results, array(1, 2, 3));
$Controller->passedArgs = array('sort' => 'PaginatorControllerPost.author_id', 'direction' => 'allYourBase');
$results = Set::extract($Controller->Paginator->paginate('PaginatorControllerPost'), '{n}.PaginatorControllerPost.id');
$this->assertEqual($Controller->PaginatorControllerPost->lastQuery['order'][0], array('PaginatorControllerPost.author_id' => 'asc'));
$this->assertEqual($results, array(1, 3, 2));
$Controller->passedArgs = array('page' => '1 " onclick="alert(\'xss\');">');
$Controller->Paginator->settings = array('limit' => 1);
$Controller->Paginator->paginate('PaginatorControllerPost');
$this->assertIdentical($Controller->params['paging']['PaginatorControllerPost']['page'], 1, 'XSS exploit opened %s');
$this->assertIdentical($Controller->params['paging']['PaginatorControllerPost']['options']['page'], 1, 'XSS exploit opened %s');
$Controller->passedArgs = array();
$Controller->Paginator->settings = array('limit' => 0);
$Controller->Paginator->paginate('PaginatorControllerPost');
$this->assertIdentical($Controller->params['paging']['PaginatorControllerPost']['page'], 1);
$this->assertIdentical($Controller->params['paging']['PaginatorControllerPost']['pageCount'], 3);
$this->assertIdentical($Controller->params['paging']['PaginatorControllerPost']['prevPage'], false);
$this->assertIdentical($Controller->params['paging']['PaginatorControllerPost']['nextPage'], true);
$Controller->passedArgs = array();
$Controller->Paginator->settings = array('limit' => 'garbage!');
$Controller->Paginator->paginate('PaginatorControllerPost');
$this->assertIdentical($Controller->params['paging']['PaginatorControllerPost']['page'], 1);
$this->assertIdentical($Controller->params['paging']['PaginatorControllerPost']['pageCount'], 3);
$this->assertIdentical($Controller->params['paging']['PaginatorControllerPost']['prevPage'], false);
$this->assertIdentical($Controller->params['paging']['PaginatorControllerPost']['nextPage'], true);
$Controller->passedArgs = array();
$Controller->Paginator->settings = array('limit' => '-1');
$Controller->Paginator->paginate('PaginatorControllerPost');
$this->assertIdentical($Controller->params['paging']['PaginatorControllerPost']['page'], 1);
$this->assertIdentical($Controller->params['paging']['PaginatorControllerPost']['pageCount'], 3);
$this->assertIdentical($Controller->params['paging']['PaginatorControllerPost']['prevPage'], false);
$this->assertIdentical($Controller->params['paging']['PaginatorControllerPost']['nextPage'], true);
}
/**
* testPaginateExtraParams method
*
* @access public
* @return void
*/
function testPaginateExtraParams() {
$request = new CakeRequest('controller_posts/index');
$request->params['pass'] = $request->params['named'] = array();
$Controller = new PaginatorTestController($request);
$Controller->uses = array('PaginatorControllerPost', 'PaginatorControllerComment');
$Controller->passedArgs[] = '1';
$Controller->params['url'] = array();
$Controller->constructClasses();
$Controller->passedArgs = array('page' => '-1', 'contain' => array('PaginatorControllerComment'));
$result = $Controller->Paginator->paginate('PaginatorControllerPost');
$this->assertEqual($Controller->params['paging']['PaginatorControllerPost']['page'], 1);
$this->assertEqual(Set::extract($result, '{n}.PaginatorControllerPost.id'), array(1, 2, 3));
$this->assertTrue(!isset($Controller->PaginatorControllerPost->lastQuery['contain']));
$Controller->passedArgs = array('page' => '-1');
$Controller->Paginator->settings = array('PaginatorControllerPost' => array('contain' => array('PaginatorControllerComment')));
$result = $Controller->Paginator->paginate('PaginatorControllerPost');
$this->assertEqual($Controller->params['paging']['PaginatorControllerPost']['page'], 1);
$this->assertEqual(Set::extract($result, '{n}.PaginatorControllerPost.id'), array(1, 2, 3));
$this->assertTrue(isset($Controller->PaginatorControllerPost->lastQuery['contain']));
$Controller->Paginator->settings = array('PaginatorControllerPost' => array('popular', 'fields' => array('id', 'title')));
$result = $Controller->Paginator->paginate('PaginatorControllerPost');
$this->assertEqual(Set::extract($result, '{n}.PaginatorControllerPost.id'), array(2, 3));
$this->assertEqual($Controller->PaginatorControllerPost->lastQuery['conditions'], array('PaginatorControllerPost.id > ' => '1'));
$Controller->passedArgs = array('limit' => 12);
$Controller->Paginator->settings = array('limit' => 30);
$result = $Controller->Paginator->paginate('PaginatorControllerPost');
$paging = $Controller->params['paging']['PaginatorControllerPost'];
$this->assertEqual($Controller->PaginatorControllerPost->lastQuery['limit'], 12);
$this->assertEqual($paging['options']['limit'], 12);
$Controller = new PaginatorTestController($request);
$Controller->uses = array('ControllerPaginateModel');
$Controller->params['url'] = array();
$Controller->constructClasses();
$Controller->Paginator->settings = array(
'ControllerPaginateModel' => array('contain' => array('ControllerPaginateModel'), 'group' => 'Comment.author_id')
);
$result = $Controller->Paginator->paginate('ControllerPaginateModel');
$expected = array('contain' => array('ControllerPaginateModel'), 'group' => 'Comment.author_id');
$this->assertEqual($Controller->ControllerPaginateModel->extra, $expected);
$this->assertEqual($Controller->ControllerPaginateModel->extraCount, $expected);
$Controller->Paginator->settings = array(
'ControllerPaginateModel' => array('foo', 'contain' => array('ControllerPaginateModel'), 'group' => 'Comment.author_id')
);
$Controller->Paginator->paginate('ControllerPaginateModel');
$expected = array('contain' => array('ControllerPaginateModel'), 'group' => 'Comment.author_id', 'type' => 'foo');
$this->assertEqual($Controller->ControllerPaginateModel->extra, $expected);
$this->assertEqual($Controller->ControllerPaginateModel->extraCount, $expected);
}
/**
* testPaginatePassedArgs method
*
* @return void
*/
public function testPaginatePassedArgs() {
$request = new CakeRequest('controller_posts/index');
$request->params['pass'] = $request->params['named'] = array();
$Controller = new PaginatorTestController($request);
$Controller->uses = array('PaginatorControllerPost');
$Controller->passedArgs[] = array('1', '2', '3');
$Controller->params['url'] = array();
$Controller->constructClasses();
$Controller->Paginator->settings = array(
'fields' => array(),
'order' => '',
'limit' => 5,
'page' => 1,
'recursive' => -1
);
$conditions = array();
$Controller->Paginator->paginate('PaginatorControllerPost',$conditions);
$expected = array(
'fields' => array(),
'order' => '',
'limit' => 5,
'page' => 1,
'recursive' => -1,
'conditions' => array()
);
$this->assertEqual($Controller->params['paging']['PaginatorControllerPost']['options'],$expected);
}
/**
* Test that special paginate types are called and that the type param doesn't leak out into defaults or options.
*
* @return void
*/
function testPaginateSpecialType() {
$request = new CakeRequest('controller_posts/index');
$request->params['pass'] = $request->params['named'] = array();
$Controller = new PaginatorTestController($request);
$Controller->uses = array('PaginatorControllerPost', 'PaginatorControllerComment');
$Controller->passedArgs[] = '1';
$Controller->params['url'] = array();
$Controller->constructClasses();
$Controller->Paginator->settings = array('PaginatorControllerPost' => array('popular', 'fields' => array('id', 'title')));
$result = $Controller->Paginator->paginate('PaginatorControllerPost');
$this->assertEqual(Set::extract($result, '{n}.PaginatorControllerPost.id'), array(2, 3));
$this->assertEqual($Controller->PaginatorControllerPost->lastQuery['conditions'], array('PaginatorControllerPost.id > ' => '1'));
$this->assertFalse(isset($Controller->params['paging']['PaginatorControllerPost']['defaults'][0]));
$this->assertFalse(isset($Controller->params['paging']['PaginatorControllerPost']['options'][0]));
}
/**
* testDefaultPaginateParams method
*
* @access public
* @return void
*/
function testDefaultPaginateParams() {
$request = new CakeRequest('controller_posts/index');
$request->params['pass'] = $request->params['named'] = array();
$Controller = new PaginatorTestController($request);
$Controller->modelClass = 'PaginatorControllerPost';
$Controller->params['url'] = array();
$Controller->constructClasses();
$Controller->Paginator->settings = array('order' => 'PaginatorControllerPost.id DESC');
$results = Set::extract($Controller->Paginator->paginate('PaginatorControllerPost'), '{n}.PaginatorControllerPost.id');
$this->assertEqual($Controller->params['paging']['PaginatorControllerPost']['defaults']['order'], 'PaginatorControllerPost.id DESC');
$this->assertEqual($Controller->params['paging']['PaginatorControllerPost']['options']['order'], 'PaginatorControllerPost.id DESC');
$this->assertEqual($results, array(3, 2, 1));
}
/**
* test paginate() and virtualField interactions
*
* @return void
*/
function testPaginateOrderVirtualField() {
$request = new CakeRequest('controller_posts/index');
$request->params['pass'] = $request->params['named'] = array();
$Controller = new PaginatorTestController($request);
$Controller->uses = array('PaginatorControllerPost', 'PaginatorControllerComment');
$Controller->params['url'] = array();
$Controller->constructClasses();
$Controller->PaginatorControllerPost->virtualFields = array(
'offset_test' => 'PaginatorControllerPost.id + 1'
);
$Controller->Paginator->settings = array(
'fields' => array('id', 'title', 'offset_test'),
'order' => array('offset_test' => 'DESC')
);
$result = $Controller->Paginator->paginate('PaginatorControllerPost');
$this->assertEqual(Set::extract($result, '{n}.PaginatorControllerPost.offset_test'), array(4, 3, 2));
$Controller->passedArgs = array('sort' => 'offset_test', 'direction' => 'asc');
$result = $Controller->Paginator->paginate('PaginatorControllerPost');
$this->assertEqual(Set::extract($result, '{n}.PaginatorControllerPost.offset_test'), array(2, 3, 4));
}
/**
* Tests for missing models
*
* @expectedException MissingModelException
*/
function testPaginateMissingModel() {
$request = new CakeRequest('controller_posts/index');
$request->params['pass'] = $request->params['named'] = array();
$Controller = new PaginatorTestController($request);
$Controller->constructClasses();
$Controller->Paginator->paginate('MissingModel');
}
}

View file

@ -0,0 +1,411 @@
<?php
/**
* ControllerTestCaseTest file
*
* Test Case for ControllerTestCase class
*
* PHP version 5
*
* CakePHP : Rapid Development Framework (http://cakephp.org)
* Copyright 2006-2010, Cake Software Foundation, Inc.
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright 2006-2010, Cake Software Foundation, Inc.
* @link http://cakephp.org CakePHP Project
* @package cake
* @subpackage cake.cake.libs.
* @since CakePHP v 2.0
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
App::import('Controller', 'Controller', false);
require_once TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'lib' . DS . 'reporter' . DS . 'cake_html_reporter.php';
/**
* AppController class
*
* @package cake
* @subpackage cake.tests.cases.libs.controller
*/
if (!class_exists('AppController')) {
/**
* AppController class
*
* @package cake
* @subpackage cake.tests.cases.libs.controller
*/
class AppController extends Controller {
/**
* helpers property
*
* @var array
* @access public
*/
public $helpers = array('Html');
/**
* uses property
*
* @var array
* @access public
*/
public $uses = array('ControllerPost');
/**
* components property
*
* @var array
* @access public
*/
public $components = array('Cookie');
}
} elseif (!defined('APP_CONTROLLER_EXISTS')) {
define('APP_CONTROLLER_EXISTS', true);
}
/**
* PostsController class
*/
if (!class_exists('PostsController')) {
class PostsController extends AppController {
/**
* Components array
*
* @var array
*/
public $components = array(
'RequestHandler',
'Email',
'Auth'
);
}
}
/**
* Post model
*/
if (!class_exists('Post')) {
class Post extends CakeTestModel {
}
}
/**
* ControllerTestCaseTest
*
* @package cake
* @subpackage cake.tests.cases.libs
*/
class ControllerTestCaseTest extends CakeTestCase {
/**
* fixtures property
*
* @var array
* @access public
*/
public $fixtures = array('core.post');
/**
* reset environment.
*
* @return void
*/
function setUp() {
App::build(array(
'plugins' => array(TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'plugins' . DS),
'controllers' => array(TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'controllers' . DS),
'models' => array(TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'models' . DS),
'views' => array(TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'views' . DS)
));
$this->Case = new ControllerTestCase();
Router::reload();
}
/**
* teardown
*
* @return void
*/
function tearDown() {
$this->Case->controller = null;
App::build();
}
/**
* Test that ControllerTestCase::generate() creates mock objects correctly
*/
function testGenerate() {
$Posts = $this->Case->generate('Posts');
$this->Case->assertEquals($Posts->name, 'Posts');
$this->Case->assertEquals($Posts->modelClass, 'Post');
$this->Case->assertNull($Posts->response->send());
$Posts = $this->Case->generate('Posts', array(
'methods' => array(
'render'
)
));
$this->Case->assertNull($Posts->render('index'));
$Posts = $this->Case->generate('Posts', array(
'models' => array('Post'),
'components' => array('RequestHandler')
));
$this->Case->assertNull($Posts->Post->save(array()));
$this->Case->assertNull($Posts->Post->find('all'));
$this->Case->assertEquals($Posts->Post->useTable, 'posts');
$this->Case->assertNull($Posts->RequestHandler->isAjax());
$Posts = $this->Case->generate('Posts', array(
'models' => array(
'Post' => true
)
));
$this->Case->assertNull($Posts->Post->save(array()));
$this->Case->assertNull($Posts->Post->find('all'));
$Posts = $this->Case->generate('Posts', array(
'models' => array(
'Post' => array('save'),
)
));
$this->Case->assertNull($Posts->Post->save(array()));
$this->Case->assertIsA($Posts->Post->find('all'), 'array');
$Posts = $this->Case->generate('Posts', array(
'models' => array('Post'),
'components' => array(
'RequestHandler' => array('isPut'),
'Email' => array('send'),
'Session'
)
));
$Posts->RequestHandler->expects($this->once())
->method('isPut')
->will($this->returnValue(true));
$this->assertTrue($Posts->RequestHandler->isPut());
$Posts->Auth->Session->expects($this->any())
->method('write')
->will($this->returnValue('written!'));
$this->assertEquals($Posts->Auth->Session->write('something'), 'written!');
}
/**
* Tests testAction
*/
function testTestAction() {
$Controller = $this->Case->generate('TestsApps');
$this->Case->testAction('/tests_apps/index');
$this->Case->assertIsA($this->Case->controller->viewVars, 'array');
$this->Case->testAction('/tests_apps/set_action');
$results = $this->Case->controller->viewVars;
$expected = array(
'var' => 'string'
);
$this->Case->assertEquals($expected, $results);
$result = $this->Case->controller->response->body();
$this->Case->assertPattern('/This is the TestsAppsController index view/', $result);
$this->Case->testAction('/tests_apps/redirect_to');
$results = $this->Case->headers;
$expected = array(
'Location' => 'http://cakephp.org'
);
$this->Case->assertEquals($expected, $results);
}
/**
* Tests using loaded routes during tests
*/
function testUseRoutes() {
include TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'config' . DS . 'routes.php';
$controller = $this->Case->generate('TestsApps');
$controller->Components->load('RequestHandler');
$result = $this->Case->testAction('/tests_apps/index.json', array('return' => 'view'));
$result = json_decode($result, true);
$expected = array('cakephp' => 'cool');
$this->Case->assertEquals($result, $expected);
include TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'config' . DS . 'routes.php';
$result = $this->Case->testAction('/some_alias');
$this->Case->assertEquals($result, 5);
include TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'config' . DS . 'routes.php';
$this->Case->testAction('/redirect_me_now');
$result = $this->Case->headers['Location'];
$this->Case->assertEquals($result, 'http://cakephp.org');
include TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'config' . DS . 'routes.php';
$this->Case->testAction('/redirect_me');
$result = $this->Case->headers['Location'];
$this->Case->assertEquals($result, Router::url(array('controller' => 'tests_apps', 'action' => 'some_method'), true));
}
/**
* Tests not using loaded routes during tests
*/
function testSkipRoutes() {
include TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'config' . DS . 'routes.php';
$this->Case->loadRoutes = false;
$this->expectException('MissingActionException');
$result = $this->Case->testAction('/tests_apps/index.json', array('return' => 'view'));
}
/**
* Tests backwards compatibility with setting the return type
*/
function testBCSetReturn() {
$this->Case->autoMock = true;
$result = $this->Case->testAction('/tests_apps/some_method');
$this->Case->assertEquals($result, 5);
$data = array('var' => 'set');
$result = $this->Case->testAction('/tests_apps_posts/post_var', array(
'data' => $data,
'return' => 'vars'
));
$this->Case->assertEquals($result['data'], $data);
$result = $this->Case->testAction('/tests_apps/set_action', array(
'return' => 'view'
));
$this->Case->assertEquals($result, 'This is the TestsAppsController index view');
$result = $this->Case->testAction('/tests_apps/set_action', array(
'return' => 'contents'
));
$this->Case->assertPattern('/<html/', $result);
$this->Case->assertPattern('/This is the TestsAppsController index view/', $result);
$this->Case->assertPattern('/<\/html>/', $result);
}
/**
* Tests sending POST data to testAction
*/
function testTestActionPostData() {
$this->Case->autoMock = true;
$data = array(
'Post' => array(
'name' => 'Some Post'
)
);
$this->Case->testAction('/tests_apps_posts/post_var', array(
'data' => $data
));
$this->Case->assertEquals($this->Case->controller->viewVars['data'], $data);
$this->Case->assertEquals($this->Case->controller->data, $data);
$this->Case->testAction('/tests_apps_posts/post_var/named:param', array(
'data' => $data
));
$expected = array(
'named' => 'param'
);
$this->Case->assertEqual($this->Case->controller->request->named, $expected);
$this->Case->assertEquals($this->Case->controller->data, $data);
$result = $this->Case->testAction('/tests_apps_posts/post_var', array(
'return' => 'vars',
'method' => 'post',
'data' => array(
'name' => 'is jonas',
'pork' => 'and beans',
)
));
$this->assertEqual(array_keys($result['data']), array('name', 'pork'));
$result = $this->Case->testAction('/tests_apps_posts/add', array('return' => 'vars'));
$this->assertTrue(array_key_exists('posts', $result));
$this->assertEqual(count($result['posts']), 4);
}
/**
* Tests sending GET data to testAction
*/
function testTestActionGetData() {
$this->Case->autoMock = true;
$result = $this->Case->testAction('/tests_apps_posts/url_var', array(
'method' => 'get',
'data' => array(
'some' => 'var',
'lackof' => 'creativity'
)
));
$this->Case->assertEquals($this->Case->controller->request->query['some'], 'var');
$this->Case->assertEquals($this->Case->controller->request->query['lackof'], 'creativity');
$result = $this->Case->testAction('/tests_apps_posts/url_var/var1:value1/var2:val2', array(
'return' => 'vars',
'method' => 'get',
));
$this->assertTrue(isset($result['params']['url']['url']));
$this->assertEqual(array_keys($result['params']['named']), array('var1', 'var2'));
$result = $this->Case->testAction('/tests_apps_posts/url_var/gogo/val2', array(
'return' => 'vars',
'method' => 'get',
));
$this->assertEqual($result['params']['pass'], array('gogo', 'val2'));
$result = $this->Case->testAction('/tests_apps_posts/url_var', array(
'return' => 'vars',
'method' => 'get',
'data' => array(
'red' => 'health',
'blue' => 'mana'
)
));
$this->assertTrue(isset($result['params']['url']['red']));
$this->assertTrue(isset($result['params']['url']['blue']));
$this->assertTrue(isset($result['params']['url']['url']));
}
/**
* Tests autoMock ability
*/
function testAutoMock() {
$this->Case->autoMock = true;
$this->Case->testAction('/tests_apps/set_action');
$results = $this->Case->controller->viewVars;
$expected = array(
'var' => 'string'
);
$this->Case->assertEquals($expected, $results);
}
/**
* Test using testAction and not mocking
*/
function testNoMocking() {
$result = $this->Case->testAction('/tests_apps/some_method');
$this->Case->assertEquals($result, 5);
$data = array('var' => 'set');
$result = $this->Case->testAction('/tests_apps_posts/post_var', array(
'data' => $data,
'return' => 'vars'
));
$this->Case->assertEquals($result['data'], $data);
$result = $this->Case->testAction('/tests_apps/set_action', array(
'return' => 'view'
));
$this->Case->assertEquals($result, 'This is the TestsAppsController index view');
$result = $this->Case->testAction('/tests_apps/set_action', array(
'return' => 'contents'
));
$this->Case->assertPattern('/<html/', $result);
$this->Case->assertPattern('/This is the TestsAppsController index view/', $result);
$this->Case->assertPattern('/<\/html>/', $result);
}
}

View file

@ -0,0 +1,66 @@
<?php
/**
* BasicMethodTest file
*
* PHP 5
*
* CakePHP(tm) Tests <http://book.cakephp.org/view/1196/Testing>
* 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.tests.cases.libs.http
* @since CakePHP(tm) v 2.0.0
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
App::import('Core', 'HttpSocket');
App::import('Lib', 'http/BasicAuthentication');
/**
* BasicMethodTest class
*
* @package cake
* @subpackage cake.tests.cases.libs.http
*/
class BasicMethodTest extends CakeTestCase {
/**
* testAuthentication method
*
* @return void
*/
public function testAuthentication() {
$http = new HttpSocket();
$auth = array(
'method' => 'Basic',
'user' => 'mark',
'pass' => 'secret'
);
BasicAuthentication::authentication($http, $auth);
$this->assertEqual($http->request['header']['Authorization'], 'Basic bWFyazpzZWNyZXQ=');
}
/**
* testProxyAuthentication method
*
* @return void
*/
public function testProxyAuthentication() {
$http = new HttpSocket();
$proxy = array(
'method' => 'Basic',
'user' => 'mark',
'pass' => 'secret'
);
BasicAuthentication::proxyAuthentication($http, $proxy);
$this->assertEqual($http->request['header']['Proxy-Authorization'], 'Basic bWFyazpzZWNyZXQ=');
}
}

View file

@ -0,0 +1,197 @@
<?php
/**
* DigestAuthenticationTest file
*
* PHP 5
*
* CakePHP(tm) Tests <http://book.cakephp.org/view/1196/Testing>
* 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.tests.cases.libs.http
* @since CakePHP(tm) v 2.0.0
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
App::import('Core', 'HttpSocket');
App::import('Lib', 'http/DigestAuthentication');
class DigestHttpSocket extends HttpSocket {
/**
* nextHeader attribute
*
* @var string
*/
public $nextHeader = '';
/**
* request method
*
* @param mixed $request
* @return void
*/
public function request($request) {
if ($request === false) {
if (isset($this->response['header']['WWW-Authenticate'])) {
unset($this->response['header']['WWW-Authenticate']);
}
return;
}
$this->response['header']['WWW-Authenticate'] = $this->nextHeader;
}
}
/**
* DigestAuthenticationTest class
*
* @package cake
* @subpackage cake.tests.cases.libs.http
*/
class DigestAuthenticationTest extends CakeTestCase {
/**
* Socket property
*
* @var mixed null
*/
public $HttpSocket = null;
/**
* This function sets up a HttpSocket instance we are going to use for testing
*
* @return void
*/
public function setUp() {
$this->HttpSocket = new DigestHttpSocket();
$this->HttpSocket->request['method'] = 'GET';
$this->HttpSocket->request['uri']['path'] = '/';
}
/**
* We use this function to clean up after the test case was executed
*
* @return void
*/
function tearDown() {
unset($this->HttpSocket);
}
/**
* testBasic method
*
* @return void
*/
public function testBasic() {
$this->HttpSocket->nextHeader = 'Digest realm="The batcave",nonce="4cded326c6c51"';
$this->assertFalse(isset($this->HttpSocket->request['header']['Authorization']));
$auth = array('user' => 'admin', 'pass' => '1234');
DigestAuthentication::authentication($this->HttpSocket, $auth);
$this->assertTrue(isset($this->HttpSocket->request['header']['Authorization']));
$this->assertEqual($auth['realm'], 'The batcave');
$this->assertEqual($auth['nonce'], '4cded326c6c51');
}
/**
* testQop method
*
* @return void
*/
public function testQop() {
$this->HttpSocket->nextHeader = 'Digest realm="The batcave",nonce="4cded326c6c51"';
$auth = array('user' => 'admin', 'pass' => '1234');
DigestAuthentication::authentication($this->HttpSocket, $auth);
$expected = 'Digest username="admin", realm="The batcave", nonce="4cded326c6c51", uri="/", response="da7e2a46b471d77f70a9bb3698c8902b"';
$this->assertEqual($expected, $this->HttpSocket->request['header']['Authorization']);
$this->assertFalse(isset($auth['qop']));
$this->assertFalse(isset($auth['nc']));
$this->HttpSocket->nextHeader = 'Digest realm="The batcave",nonce="4cded326c6c51",qop="auth"';
$auth = array('user' => 'admin', 'pass' => '1234');
DigestAuthentication::authentication($this->HttpSocket, $auth);
$expected = '@Digest username="admin", realm="The batcave", nonce="4cded326c6c51", uri="/", response="[a-z0-9]{32}", qop="auth", nc=00000001, cnonce="[a-z0-9]+"@';
$this->assertPattern($expected, $this->HttpSocket->request['header']['Authorization']);
$this->assertEqual($auth['qop'], 'auth');
$this->assertEqual($auth['nc'], 2);
}
/**
* testOpaque method
*
* @return void
*/
public function testOpaque() {
$this->HttpSocket->nextHeader = 'Digest realm="The batcave",nonce="4cded326c6c51"';
$auth = array('user' => 'admin', 'pass' => '1234');
DigestAuthentication::authentication($this->HttpSocket, $auth);
$this->assertFalse(strpos($this->HttpSocket->request['header']['Authorization'], 'opaque="d8ea7aa61a1693024c4cc3a516f49b3c"'));
$this->HttpSocket->nextHeader = 'Digest realm="The batcave",nonce="4cded326c6c51",opaque="d8ea7aa61a1693024c4cc3a516f49b3c"';
$auth = array('user' => 'admin', 'pass' => '1234');
DigestAuthentication::authentication($this->HttpSocket, $auth);
$this->assertTrue(strpos($this->HttpSocket->request['header']['Authorization'], 'opaque="d8ea7aa61a1693024c4cc3a516f49b3c"') > 0);
}
/**
* testMultipleRequest method
*
* @return void
*/
public function testMultipleRequest() {
$this->HttpSocket->nextHeader = 'Digest realm="The batcave",nonce="4cded326c6c51",qop="auth"';
$auth = array('user' => 'admin', 'pass' => '1234');
DigestAuthentication::authentication($this->HttpSocket, $auth);
$this->assertTrue(strpos($this->HttpSocket->request['header']['Authorization'], 'nc=00000001') > 0);
$this->assertEqual($auth['nc'], 2);
DigestAuthentication::authentication($this->HttpSocket, $auth);
$this->assertTrue(strpos($this->HttpSocket->request['header']['Authorization'], 'nc=00000002') > 0);
$this->assertEqual($auth['nc'], 3);
$responsePos = strpos($this->HttpSocket->request['header']['Authorization'], 'response=');
$response = substr($this->HttpSocket->request['header']['Authorization'], $responsePos + 10, 32);
$this->HttpSocket->nextHeader = '';
DigestAuthentication::authentication($this->HttpSocket, $auth);
$this->assertTrue(strpos($this->HttpSocket->request['header']['Authorization'], 'nc=00000003') > 0);
$this->assertEqual($auth['nc'], 4);
$responsePos = strpos($this->HttpSocket->request['header']['Authorization'], 'response=');
$response2 = substr($this->HttpSocket->request['header']['Authorization'], $responsePos + 10, 32);
$this->assertNotEqual($response, $response2);
}
/**
* testPathChanged method
*
* @return void
*/
public function testPathChanged() {
$this->HttpSocket->nextHeader = 'Digest realm="The batcave",nonce="4cded326c6c51"';
$this->HttpSocket->request['uri']['path'] = '/admin';
$auth = array('user' => 'admin', 'pass' => '1234');
DigestAuthentication::authentication($this->HttpSocket, $auth);
$responsePos = strpos($this->HttpSocket->request['header']['Authorization'], 'response=');
$response = substr($this->HttpSocket->request['header']['Authorization'], $responsePos + 10, 32);
$this->assertNotEqual($response, 'da7e2a46b471d77f70a9bb3698c8902b');
}
/**
* testNoDigestResponse method
*
* @return void
*/
public function testNoDigestResponse() {
$this->HttpSocket->nextHeader = false;
$this->HttpSocket->request['uri']['path'] = '/admin';
$auth = array('user' => 'admin', 'pass' => '1234');
DigestAuthentication::authentication($this->HttpSocket, $auth);
$this->assertFalse(isset($this->HttpSocket->request['header']['Authorization']));
}
}

View file

@ -0,0 +1,509 @@
<?php
/**
* HttpSocketTest file
*
* PHP 5
*
* CakePHP(tm) Tests <http://book.cakephp.org/view/1196/Testing>
* 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.tests.cases.libs
* @since CakePHP(tm) v 1.2.0.4206
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
App::import('Core', 'HttpResponse');
/**
* TestHttpResponse class
*
* @package cake
* @subpackage cake.tests.cases.libs
*/
class TestHttpResponse extends HttpResponse {
/**
* Convenience method for testing protected method
*
* @param array $header Header as an indexed array (field => value)
* @return array Parsed header
*/
public function parseHeader($header) {
return parent::_parseHeader($header);
}
/**
* Convenience method for testing protected method
*
* @param string $body A string continaing the body to decode
* @param mixed $encoding Can be false in case no encoding is being used, or a string representing the encoding
* @return mixed Array or false
*/
public function decodeBody($body, $encoding = 'chunked') {
return parent::_decodeBody($body, $encoding);
}
/**
* Convenience method for testing protected method
*
* @param string $body A string continaing the chunked body to decode
* @return mixed Array or false
*/
public function decodeChunkedBody($body) {
return parent::_decodeChunkedBody($body);
}
/**
* Convenience method for testing protected method
*
* @param string $token Token to unescape
* @return string Unescaped token
*/
public function unescapeToken($token, $chars = null) {
return parent::_unescapeToken($token, $chars);
}
/**
* Convenience method for testing protected method
*
* @param boolean $hex true to get them as HEX values, false otherwise
* @return array Escape chars
*/
public function tokenEscapeChars($hex = true, $chars = null) {
return parent::_tokenEscapeChars($hex, $chars);
}
}
/**
* HttpResponseTest class
*
* @package cake
* @subpackage cake.tests.cases.libs
*/
class HttpResponseTest extends CakeTestCase {
/**
* This function sets up a HttpResponse
*
* @return void
*/
public function setUp() {
$this->HttpResponse = new TestHttpResponse();
}
/**
* testBody
*
* @return void
*/
public function testBody() {
$this->HttpResponse->body = 'testing';
$this->assertEqual($this->HttpResponse->body(), 'testing');
$this->HttpResponse->body = null;
$this->assertIdentical($this->HttpResponse->body(), '');
}
/**
* testToString
*
* @return void
*/
public function testToString() {
$this->HttpResponse->body = 'other test';
$this->assertEqual($this->HttpResponse->body(), 'other test');
$this->assertEqual((string)$this->HttpResponse, 'other test');
$this->assertTrue(strpos($this->HttpResponse, 'test') > 0);
$this->HttpResponse->body = null;
$this->assertEqual((string)$this->HttpResponse, '');
}
/**
* testGetHeadr
*
* @return void
*/
public function testGetHeader() {
$this->HttpResponse->headers = array(
'foo' => 'Bar',
'Some' => 'ok',
'HeAdEr' => 'value',
'content-Type' => 'text/plain'
);
$this->assertEqual($this->HttpResponse->getHeader('foo'), 'Bar');
$this->assertEqual($this->HttpResponse->getHeader('Foo'), 'Bar');
$this->assertEqual($this->HttpResponse->getHeader('FOO'), 'Bar');
$this->assertEqual($this->HttpResponse->getHeader('header'), 'value');
$this->assertEqual($this->HttpResponse->getHeader('Content-Type'), 'text/plain');
$this->assertIdentical($this->HttpResponse->getHeader(0), null);
$this->assertEqual($this->HttpResponse->getHeader('foo', false), 'Bar');
$this->assertEqual($this->HttpResponse->getHeader('foo', array('foo' => 'not from class')), 'not from class');
}
/**
* testIsOk
*
* @return void
*/
public function testIsOk() {
$this->HttpResponse->code = 0;
$this->assertFalse($this->HttpResponse->isOk());
$this->HttpResponse->code = -1;
$this->assertFalse($this->HttpResponse->isOk());
$this->HttpResponse->code = 201;
$this->assertFalse($this->HttpResponse->isOk());
$this->HttpResponse->code = 'what?';
$this->assertFalse($this->HttpResponse->isOk());
$this->HttpResponse->code = 200;
$this->assertTrue($this->HttpResponse->isOk());
}
/**
* Test that HttpSocket::parseHeader can take apart a given (and valid) $header string and turn it into an array.
*
* @return void
*/
public function testParseHeader() {
$r = $this->HttpResponse->parseHeader(array('foo' => 'Bar', 'fOO-bAr' => 'quux'));
$this->assertEquals($r, array('foo' => 'Bar', 'fOO-bAr' => 'quux'));
$r = $this->HttpResponse->parseHeader(true);
$this->assertEquals($r, false);
$header = "Host: cakephp.org\t\r\n";
$r = $this->HttpResponse->parseHeader($header);
$expected = array(
'Host' => 'cakephp.org'
);
$this->assertEquals($r, $expected);
$header = "Date:Sat, 07 Apr 2007 10:10:25 GMT\r\nX-Powered-By: PHP/5.1.2\r\n";
$r = $this->HttpResponse->parseHeader($header);
$expected = array(
'Date' => 'Sat, 07 Apr 2007 10:10:25 GMT',
'X-Powered-By' => 'PHP/5.1.2'
);
$this->assertEquals($r, $expected);
$header = "people: Jim,John\r\nfoo-LAND: Bar\r\ncAKe-PHP: rocks\r\n";
$r = $this->HttpResponse->parseHeader($header);
$expected = array(
'people' => 'Jim,John',
'foo-LAND' => 'Bar',
'cAKe-PHP' => 'rocks'
);
$this->assertEquals($r, $expected);
$header = "People: Jim,John,Tim\r\nPeople: Lisa,Tina,Chelsea\r\n";
$r = $this->HttpResponse->parseHeader($header);
$expected = array(
'People' => array('Jim,John,Tim', 'Lisa,Tina,Chelsea')
);
$this->assertEquals($r, $expected);
$header = "Multi-Line: I am a \r\nmulti line\t\r\nfield value.\r\nSingle-Line: I am not\r\n";
$r = $this->HttpResponse->parseHeader($header);
$expected = array(
'Multi-Line' => "I am a\r\nmulti line\r\nfield value.",
'Single-Line' => 'I am not'
);
$this->assertEquals($r, $expected);
$header = "Esc\"@\"ped: value\r\n";
$r = $this->HttpResponse->parseHeader($header);
$expected = array(
'Esc@ped' => 'value'
);
$this->assertEquals($r, $expected);
}
/**
* testParseResponse method
*
* @return void
*/
public function testParseResponse() {
$tests = array(
'simple-request' => array(
'response' => array(
'status-line' => "HTTP/1.x 200 OK\r\n",
'header' => "Date: Mon, 16 Apr 2007 04:14:16 GMT\r\nServer: CakeHttp Server\r\n",
'body' => "<h1>Hello World</h1>\r\n<p>It's good to be html</p>"
),
'expectations' => array(
'httpVersion' => 'HTTP/1.x',
'code' => 200,
'reasonPhrase' => 'OK',
'headers' => array('Date' => 'Mon, 16 Apr 2007 04:14:16 GMT', 'Server' => 'CakeHttp Server'),
'body' => "<h1>Hello World</h1>\r\n<p>It's good to be html</p>"
)
),
'no-header' => array(
'response' => array(
'status-line' => "HTTP/1.x 404 OK\r\n",
'header' => null
),
'expectations' => array(
'code' => 404,
'headers' => array()
)
)
);
$testResponse = array();
$expectations = array();
foreach ($tests as $name => $test) {
$testResponse = array_merge($testResponse, $test['response']);
$testResponse['response'] = $testResponse['status-line'] . $testResponse['header'] . "\r\n" . $testResponse['body'];
$this->HttpResponse->parseResponse($testResponse['response']);
$expectations = array_merge($expectations, $test['expectations']);
foreach ($expectations as $property => $expectedVal) {
$this->assertEquals($this->HttpResponse->{$property}, $expectedVal, 'Test "' . $name . '": response.' . $property . ' - %s');
}
foreach (array('status-line', 'header', 'body', 'response') as $field) {
$this->assertEquals($this->HttpResponse['raw'][$field], $testResponse[$field], 'Test response.raw.' . $field . ': %s');
}
}
}
/**
* data provider function for testInvalidParseResponseData
*
* @return array
*/
public static function invalidParseResponseDataProvider() {
return array(
array(array('foo' => 'bar')),
array(true),
array("HTTP Foo\r\nBar: La"),
array('HTTP/1.1 TEST ERROR')
);
}
/**
* testInvalidParseResponseData
*
* @dataProvider invalidParseResponseDataProvider
* @expectedException SocketException
* return void
*/
public function testInvalidParseResponseData($value) {
$this->HttpResponse->parseResponse($value);
}
/**
* testDecodeBody method
*
* @return void
*/
public function testDecodeBody() {
$r = $this->HttpResponse->decodeBody(true);
$this->assertEquals($r, false);
$r = $this->HttpResponse->decodeBody('Foobar', false);
$this->assertEquals($r, array('body' => 'Foobar', 'header' => false));
$encoding = 'chunked';
$sample = array(
'encoded' => "19\r\nThis is a chunked message\r\n0\r\n",
'decoded' => array('body' => "This is a chunked message", 'header' => false)
);
$r = $this->HttpResponse->decodeBody($sample['encoded'], $encoding);
$this->assertEquals($r, $sample['decoded']);
}
/**
* testDecodeFooCoded
*
* @return void
*/
public function testDecodeFooCoded() {
$r = $this->HttpResponse->decodeBody(true);
$this->assertEquals($r, false);
$r = $this->HttpResponse->decodeBody('Foobar', false);
$this->assertEquals($r, array('body' => 'Foobar', 'header' => false));
$encoding = 'foo-bar';
$sample = array(
'encoded' => '!Foobar!',
'decoded' => array('body' => '!Foobar!', 'header' => false),
);
$r = $this->HttpResponse->decodeBody($sample['encoded'], $encoding);
$this->assertEquals($r, $sample['decoded']);
}
/**
* testDecodeChunkedBody method
*
* @return void
*/
public function testDecodeChunkedBody() {
$r = $this->HttpResponse->decodeChunkedBody(true);
$this->assertEquals($r, false);
$encoded = "19\r\nThis is a chunked message\r\n0\r\n";
$decoded = "This is a chunked message";
$r = $this->HttpResponse->decodeChunkedBody($encoded);
$this->assertEquals($r['body'], $decoded);
$this->assertEquals($r['header'], false);
$encoded = "19 \r\nThis is a chunked message\r\n0\r\n";
$r = $this->HttpResponse->decodeChunkedBody($encoded);
$this->assertEquals($r['body'], $decoded);
$encoded = "19\r\nThis is a chunked message\r\nE\r\n\nThat is cool\n\r\n0\r\n";
$decoded = "This is a chunked message\nThat is cool\n";
$r = $this->HttpResponse->decodeChunkedBody($encoded);
$this->assertEquals($r['body'], $decoded);
$this->assertEquals($r['header'], false);
$encoded = "19\r\nThis is a chunked message\r\nE;foo-chunk=5\r\n\nThat is cool\n\r\n0\r\n";
$r = $this->HttpResponse->decodeChunkedBody($encoded);
$this->assertEquals($r['body'], $decoded);
$this->assertEquals($r['header'], false);
$encoded = "19\r\nThis is a chunked message\r\nE\r\n\nThat is cool\n\r\n0\r\nfoo-header: bar\r\ncake: PHP\r\n\r\n";
$r = $this->HttpResponse->decodeChunkedBody($encoded);
$this->assertEquals($r['body'], $decoded);
$this->assertEquals($r['header'], array('foo-header' => 'bar', 'cake' => 'PHP'));
$encoded = "19\r\nThis is a chunked message\r\nE\r\n\nThat is cool\n\r\n";
$this->expectError();
$r = $this->HttpResponse->decodeChunkedBody($encoded);
$this->assertEquals($r, false);
}
/**
* testParseCookies method
*
* @return void
*/
public function testParseCookies() {
$header = array(
'Set-Cookie' => array(
'foo=bar',
'people=jim,jack,johnny";";Path=/accounts',
'google=not=nice'
),
'Transfer-Encoding' => 'chunked',
'Date' => 'Sun, 18 Nov 2007 18:57:42 GMT',
);
$cookies = $this->HttpResponse->parseCookies($header);
$expected = array(
'foo' => array(
'value' => 'bar'
),
'people' => array(
'value' => 'jim,jack,johnny";"',
'path' => '/accounts',
),
'google' => array(
'value' => 'not=nice',
)
);
$this->assertEqual($cookies, $expected);
$header['Set-Cookie'][] = 'cakephp=great; Secure';
$expected['cakephp'] = array('value' => 'great', 'secure' => true);
$cookies = $this->HttpResponse->parseCookies($header);
$this->assertEqual($cookies, $expected);
$header['Set-Cookie'] = 'foo=bar';
unset($expected['people'], $expected['cakephp'], $expected['google']);
$cookies = $this->HttpResponse->parseCookies($header);
$this->assertEqual($cookies, $expected);
}
/**
* Test that escaped token strings are properly unescaped by HttpSocket::unescapeToken
*
* @return void
*/
public function testUnescapeToken() {
$this->assertEquals($this->HttpResponse->unescapeToken('Foo'), 'Foo');
$escape = $this->HttpResponse->tokenEscapeChars(false);
foreach ($escape as $char) {
$token = 'My-special-"' . $char . '"-Token';
$unescapedToken = $this->HttpResponse->unescapeToken($token);
$expectedToken = 'My-special-' . $char . '-Token';
$this->assertEquals($unescapedToken, $expectedToken, 'Test token unescaping for ASCII '.ord($char));
}
$token = 'Extreme-":"Token-" "-""""@"-test';
$escapedToken = $this->HttpResponse->unescapeToken($token);
$expectedToken = 'Extreme-:Token- -"@-test';
$this->assertEquals($expectedToken, $escapedToken);
}
/**
* testArrayAccess
*
* @return void
*/
public function testArrayAccess() {
$this->HttpResponse->httpVersion = 'HTTP/1.1';
$this->HttpResponse->code = 200;
$this->HttpResponse->reasonPhrase = 'OK';
$this->HttpResponse->headers = array(
'Server' => 'CakePHP',
'ContEnt-Type' => 'text/plain'
);
$this->HttpResponse->cookies = array(
'foo' => array('value' => 'bar'),
'bar' => array('value' => 'foo')
);
$this->HttpResponse->body = 'This is a test!';
$this->HttpResponse->raw = "HTTP/1.1 200 OK\r\nServer: CakePHP\r\nContEnt-Type: text/plain\r\n\r\nThis is a test!";
$expected1 = "HTTP/1.1 200 OK\r\n";
$this->assertEqual($this->HttpResponse['raw']['status-line'], $expected1);
$expected2 = "Server: CakePHP\r\nContEnt-Type: text/plain\r\n";
$this->assertEqual($this->HttpResponse['raw']['header'], $expected2);
$expected3 = 'This is a test!';
$this->assertEqual($this->HttpResponse['raw']['body'], $expected3);
$expected = $expected1 . $expected2 . "\r\n" . $expected3;
$this->assertEqual($this->HttpResponse['raw']['response'], $expected);
$expected = 'HTTP/1.1';
$this->assertEqual($this->HttpResponse['status']['http-version'], $expected);
$expected = 200;
$this->assertEqual($this->HttpResponse['status']['code'], $expected);
$expected = 'OK';
$this->assertEqual($this->HttpResponse['status']['reason-phrase'], $expected);
$expected = array(
'Server' => 'CakePHP',
'ContEnt-Type' => 'text/plain'
);
$this->assertEqual($this->HttpResponse['header'], $expected);
$expected = 'This is a test!';
$this->assertEqual($this->HttpResponse['body'], $expected);
$expected = array(
'foo' => array('value' => 'bar'),
'bar' => array('value' => 'foo')
);
$this->assertEqual($this->HttpResponse['cookies'], $expected);
$this->HttpResponse->raw = "HTTP/1.1 200 OK\r\n\r\nThis is a test!";
$this->assertIdentical($this->HttpResponse['raw']['header'], null);
}
}

View file

@ -0,0 +1,312 @@
<?php
/**
* ControllerTestCase file
*
* PHP 5
*
* CakePHP(tm) Tests <http://book.cakephp.org/view/1196/Testing>
* 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.cake.tests.libs
* @since CakePHP(tm) v 2.0
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
PHP_CodeCoverage_Filter::getInstance()->addFileToBlacklist(__FILE__, 'DEFAULT');
require_once CAKE . 'libs' . DS . 'dispatcher.php';
require_once CAKE_TESTS_LIB . 'cake_test_case.php';
App::import('Core', array('Router', 'CakeRequest', 'CakeResponse', 'Helper'));
/**
* ControllerTestDispatcher class
*
* @package cake
* @subpackage cake.cake.tests.lib
*/
class ControllerTestDispatcher extends Dispatcher {
/**
* The controller to use in the dispatch process
*
* @var Controller
*/
public $testController = null;
/**
* Use custom routes during tests
*
* @var boolean
*/
public $loadRoutes = true;
/**
* Returns the test controller
*
* @return Controller
*/
function _getController($request) {
if ($this->testController === null) {
$this->testController = parent::_getController($request);
}
$this->testController->helpers = array_merge(array('InterceptContent'), $this->testController->helpers);
$this->testController->setRequest($request);
$this->testController->response = $this->response;
return $this->testController;
}
/**
* Loads routes and resets if the test case dictates it should
*
* @return void
* @access private
*/
protected function __loadRoutes() {
parent::__loadRoutes();
if (!$this->loadRoutes) {
Router::reload();
}
}
}
/**
* InterceptContentHelper class
*
* @package cake
* @subpackage cake.cake.tests.lib
*/
class InterceptContentHelper extends Helper {
/**
* Intercepts and stores the contents of the view before the layout is rendered
*
* @param string $viewFile The view file
*/
function afterRender($viewFile) {
$this->_View->_viewNoLayout = $this->_View->output;
$this->_View->Helpers->unload('InterceptContent');
}
}
/**
* ControllerTestCase class
*
* @package cake
* @subpackage cake.cake.tests.lib
*/
class ControllerTestCase extends CakeTestCase {
/**
* The controller to test in testAction
*
* @var Controller
*/
public $controller = null;
/**
* Automatically mock controllers that aren't mocked
*
* @var boolean
*/
public $autoMock = false;
/**
* Use custom routes during tests
*
* @var boolean
*/
public $loadRoutes = true;
/**
* The resulting view vars of the last testAction call
*
* @var array
*/
public $vars = null;
/**
* The resulting rendered view of the last testAction call
*
* @var string
*/
public $view = null;
/**
* The resulting rendered layout+view of the last testAction call
*
* @var string
*/
public $contents = null;
/**
* The returned result of the dispatch (requestAction), if any
*
* @var string
*/
public $result = null;
/**
* The headers that would have been sent by the action
*
* @var string
*/
public $headers = null;
/**
* Used to enable calling ControllerTestCase::testAction() without the testing
* framework thinking that it's a test case
*
* @param string $name The name of the function
* @param array $arguments Array of arguments
* @return Function
*/
public function __call($name, $arguments) {
if ($name == 'testAction') {
return call_user_func_array(array($this, '_testAction'), $arguments);
}
}
/**
* Tests a controller action.
*
* ### Options:
* - `data` POST or GET data to pass
* - `method` POST or GET
*
* @param string $url The url to test
* @param array $options See options
*/
private function _testAction($url = '', $options = array()) {
$this->vars = $this->result = $this->view = $this->contents = $this->headers = null;
$options = array_merge(array(
'data' => array(),
'method' => 'POST',
'return' => 'result'
), $options);
if (strtoupper($options['method']) == 'GET') {
$_GET = $options['data'];
$_POST = array();
} else {
$_POST = array('data' => $options['data']);
$_GET = array();
}
$request = new CakeRequest($url);
$Dispatch = new ControllerTestDispatcher();
foreach (Router::$routes as $route) {
if (is_a($route, 'RedirectRoute')) {
$route->response = $this->getMock('CakeResponse', array('send'));
}
}
$Dispatch->loadRoutes = $this->loadRoutes;
$request = $Dispatch->parseParams($request);
if (!isset($request->params['controller'])) {
$this->headers = Router::currentRoute()->response->header();
return;
}
if ($this->controller !== null && Inflector::camelize($request->params['controller']) !== $this->controller->name) {
$this->controller = null;
}
if ($this->controller === null && $this->autoMock) {
$this->generate(Inflector::camelize($request->params['controller']));
}
$params = array();
if ($options['return'] == 'result') {
$params['return'] = 1;
$params['bare'] = 1;
$params['requested'] = 1;
}
$Dispatch->testController = $this->controller;
$Dispatch->response = $this->getMock('CakeResponse', array('send'));
$this->result = $Dispatch->dispatch($request, $params);
$this->controller = $Dispatch->testController;
if ($options['return'] != 'result') {
$this->vars = $this->controller->View->viewVars;
$this->view = $this->controller->View->_viewNoLayout;
$this->contents = $this->controller->response->body();
}
$this->headers = $Dispatch->response->header();
return $this->{$options['return']};
}
/**
* Generates a mocked controller and mocks any classes passed to `$mocks`. By
* default, `_stop()` is stubbed as is sending the response headers, so to not
* interfere with testing.
*
* ### Mocks:
* - `methods` Methods to mock on the controller. `_stop()` is mocked by default
* - `models` Models to mock. Models are added to the ClassRegistry so they any
* time they are instatiated the mock will be created. Pass as key value pairs
* with the value being specific methods on the model to mock. If `true` or
* no value is passed, the entire model will be mocked.
* - `components` Components to mock. Components are only mocked on this controller
* and not within each other (i.e., components on components)
*
* @param string $controller Controller name
* @param array $mocks List of classes and methods to mock
* @return Controller Mocked controller
*/
public function generate($controller, $mocks = array()) {
if (!class_exists($controller.'Controller') && App::import('Controller', $controller) === false) {
throw new MissingControllerException(array('controller' => $controller.'Controller'));
}
ClassRegistry::flush();
$mocks = array_merge_recursive(array(
'methods' => array('_stop'),
'models' => array(),
'components' => array()
), (array)$mocks);
$_controller = $this->getMock($controller.'Controller', $mocks['methods'], array(), '', false);
$_controller->name = $controller;
$_controller->__construct();
foreach ($mocks['models'] as $model => $methods) {
if (is_string($methods)) {
$model = $methods;
$methods = true;
}
if ($methods === true) {
$methods = array();
}
ClassRegistry::init($model);
$_model = $this->getMock($model, $methods, array(), '', false);
$_model->name = $model;
$_model->__construct();
ClassRegistry::removeObject($model);
ClassRegistry::addObject($model, $_model);
}
foreach ($mocks['components'] as $component => $methods) {
if (is_string($methods)) {
$component = $methods;
$methods = true;
}
if ($methods === true) {
$methods = array();
}
if (!App::import('Component', $component)) {
throw new MissingComponentFileException(array(
'file' => Inflector::underscore($component) . '.php',
'class' => $componentClass
));
}
$_component = $this->getMock($component.'Component', $methods, array(), '', false);
$_controller->Components->set($component, $_component);
}
$_controller->constructClasses();
$this->controller = $_controller;
return $this->controller;
}
}

View file

@ -0,0 +1,26 @@
<?php
/**
* Routes file
*
* Routes for test app
*
* PHP versions 4 and 5
*
* CakePHP : Rapid Development Framework (http://cakephp.org)
* Copyright 2006-2010, Cake Software Foundation, Inc.
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright 2006-2010, Cake Software Foundation, Inc.
* @link http://cakephp.org CakePHP Project
* @package cake
* @subpackage cake.tests.test_app.config
* @since CakePHP v 2.0
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
Router::parseExtensions('json');
Router::connect('/some_alias', array('controller' => 'tests_apps', 'action' => 'some_method'));
Router::redirect('/redirect_me_now', 'http://cakephp.org');
Router::redirect('/redirect_me', array('controller' => 'tests_apps', 'action' => 'some_method'));

View file

@ -0,0 +1,3 @@
Before the element.
<?php echo $this->element('html_call'); ?>
After the element.

View file

@ -0,0 +1,3 @@
<?php
echo $this->Html->link('Test', 'http://example.com');
?>

View file

@ -0,0 +1 @@
<?php echo gettype($form); ?>

View file

@ -0,0 +1 @@
<?php echo $content_for_layout; ?>

View file

@ -0,0 +1 @@
{"cakephp":"cool"}

View file

@ -69,7 +69,7 @@ class Cache {
* @param string $name Name of the configuration
* @param array $settings Optional associative array of settings passed to the engine
* @return array(engine, settings) on success, false on failure
* @throws Exception
* @throws CacheException
*/
public static function config($name = null, $settings = array()) {
if (is_array($name)) {
@ -116,10 +116,10 @@ class Cache {
return false;
}
$cacheClass = $class . 'Engine';
self::$_engines[$name] = new $cacheClass();
if (!self::$_engines[$name] instanceof CacheEngine) {
throw new Exception(__('Cache engines must use CacheEngine as a base class.'));
if (!is_subclass_of($cacheClass, 'CacheEngine')) {
throw new CacheException(__('Cache engines must use CacheEngine as a base class.'));
}
self::$_engines[$name] = new $cacheClass();
if (self::$_engines[$name]->init($config)) {
if (time() % self::$_engines[$name]->settings['probability'] === 0) {
self::$_engines[$name]->gc();

View file

@ -249,20 +249,20 @@ class FileEngine extends CacheEngine {
* Not implemented
*
* @return void
* @throws BadMethodCallException
* @throws CacheException
*/
public function decrement($key, $offset = 1) {
throw new BadMethodCallException(__('Files cannot be atomically decremented.'));
throw new CacheException(__('Files cannot be atomically decremented.'));
}
/**
* Not implemented
*
* @return void
* @throws BadMethodCallException
* @throws CacheException
*/
public function increment($key, $offset = 1) {
throw new BadMethodCallException(__('Files cannot be atomically incremented.'));
throw new CacheException(__('Files cannot be atomically incremented.'));
}
/**

View file

@ -148,11 +148,11 @@ class MemcacheEngine extends CacheEngine {
* @param integer $offset How much to increment
* @param integer $duration How long to cache the data, in seconds
* @return New incremented value, false otherwise
* @throws RuntimeException when you try to increment with compress = true
* @throws CacheException when you try to increment with compress = true
*/
public function increment($key, $offset = 1) {
if ($this->settings['compress']) {
throw new RuntimeException(
throw new CacheException(
__('Method increment() not implemented for compressed cache in %s', __CLASS__)
);
}
@ -166,11 +166,11 @@ class MemcacheEngine extends CacheEngine {
* @param integer $offset How much to substract
* @param integer $duration How long to cache the data, in seconds
* @return New decremented value, false otherwise
* @throws RuntimeException when you try to decrement with compress = true
* @throws CacheException when you try to decrement with compress = true
*/
public function decrement($key, $offset = 1) {
if ($this->settings['compress']) {
throw new RuntimeException(
throw new CacheException(
__('Method decrement() not implemented for compressed cache in %s', __CLASS__)
);
}

View file

@ -51,12 +51,12 @@ class PhpReader implements ConfigReaderInterface {
* @param string $key The identifier to read from. If the key has a . it will be treated
* as a plugin prefix.
* @return array Parsed configuration values.
* @throws RuntimeException when files don't exist or they don't contain `$config`.
* InvalidArgumentException when files contain '..' as this could lead to abusive reads.
* @throws ConfigureException when files don't exist or they don't contain `$config`.
* Or when files contain '..' as this could lead to abusive reads.
*/
public function read($key) {
if (strpos($key, '..') !== false) {
throw new InvalidArgumentException(__('Cannot load configuration files with ../ in them.'));
throw new ConfigureException(__('Cannot load configuration files with ../ in them.'));
}
list($plugin, $key) = pluginSplit($key);
@ -66,11 +66,11 @@ class PhpReader implements ConfigReaderInterface {
$file = $this->_path . $key . '.php';
}
if (!file_exists($file)) {
throw new RuntimeException(__('Could not load configuration file: ') . $file);
throw new ConfigureException(__('Could not load configuration file: ') . $file);
}
include $file;
if (!isset($config)) {
throw new RuntimeException(
throw new ConfigureException(
sprintf(__('No variable $config found in %s.php'), $file)
);
}

View file

@ -189,7 +189,7 @@ class BakeShell extends Shell {
} else {
$this->error(__('Bake All could not continue without a valid model'));
}
$this->_stop();
return $this->_stop();
}
/**

View file

@ -702,7 +702,7 @@ class ModelTask extends BakeTask {
protected function _generatePossibleKeys() {
$possible = array();
foreach ($this->_tables as $otherTable) {
$tempOtherModel = & new Model(array('table' => $otherTable, 'ds' => $this->connection));
$tempOtherModel = new Model(array('table' => $otherTable, 'ds' => $this->connection));
$modelFieldsTemp = $tempOtherModel->schema(true);
foreach ($modelFieldsTemp as $fieldName => $field) {
if ($field['type'] == 'integer' || $field['type'] == 'string') {

View file

@ -116,7 +116,7 @@ class ConsoleInputArgument {
return true;
}
if (!in_array($value, $this->_choices)) {
throw new InvalidArgumentException(sprintf(
throw new ConsoleException(sprintf(
__('"%s" is not a valid value for %s. Please use one of "%s"'),
$value, $this->_name, implode(', ', $this->_choices)
));

View file

@ -142,7 +142,7 @@ class ConsoleInputOption {
return true;
}
if (!in_array($value, $this->_choices)) {
throw new InvalidArgumentException(sprintf(
throw new ConsoleException(sprintf(
__('"%s" is not a valid value for --%s. Please use one of "%s"'),
$value, $this->_name, implode(', ', $this->_choices)
));

View file

@ -460,7 +460,7 @@ class ConsoleOptionParser {
}
foreach ($this->_args as $i => $arg) {
if ($arg->isRequired() && !isset($args[$i]) && empty($params['help'])) {
throw new RuntimeException(
throw new ConsoleException(
__('Missing required arguments. %s is required.', $arg->name())
);
}
@ -555,7 +555,7 @@ class ConsoleOptionParser {
*/
protected function _parseOption($name, $params) {
if (!isset($this->_options[$name])) {
throw new InvalidArgumentException(__('Unknown option `%s`', $name));
throw new ConsoleException(__('Unknown option `%s`', $name));
}
$option = $this->_options[$name];
$isBoolean = $option->isBoolean();
@ -589,7 +589,7 @@ class ConsoleOptionParser {
}
$next = count($args);
if (!isset($this->_args[$next])) {
throw new InvalidArgumentException(__('Too many arguments.'));
throw new ConsoleException(__('Too many arguments.'));
}
if ($this->_args[$next]->validChoice($argument)) {

View file

@ -102,7 +102,7 @@ class ShellDispatcher {
protected function _initEnvironment() {
if (!$this->__bootstrap()) {
$message = "Unable to load CakePHP core.\nMake sure " . DS . 'cake' . DS . 'libs exists in ' . CAKE_CORE_INCLUDE_PATH;
throw new RuntimeException($message);
throw new CakeException($message);
}
if (!isset($this->args[0]) || !isset($this->params['working'])) {
@ -110,7 +110,7 @@ class ShellDispatcher {
"Please make sure that " . DIRECTORY_SEPARATOR . "cake" . DIRECTORY_SEPARATOR . "console is in your system path,\n" .
"and check the cookbook for the correct usage of this command.\n" .
"(http://book.cakephp.org/)";
throw new RuntimeException($message);
throw new CakeException($message);
}
$this->shiftArgs();

View file

@ -25,13 +25,9 @@
}
public function <?php echo $admin ?>view($id = null) {
if (!$id) {
<?php if ($wannaUseSession): ?>
$this->Session->setFlash(__('Invalid <?php echo strtolower($singularHumanName) ?>'));
$this->redirect(array('action' => 'index'));
<?php else: ?>
$this->flash(__('Invalid <?php echo strtolower($singularHumanName); ?>'), array('action' => 'index'));
<?php endif; ?>
$this-><?php echo $currentModelName; ?>->id = $id;
if (!$this-><?php echo $currentModelName; ?>->exists()) {
throw new NotFoundException(__('Invalid <?php echo strtolower($singularHumanName); ?>'));
}
$this->set('<?php echo $singularName; ?>', $this-><?php echo $currentModelName; ?>->read(null, $id));
}
@ -72,15 +68,11 @@
<?php $compact = array(); ?>
public function <?php echo $admin; ?>edit($id = null) {
if (!$id && empty($this->request->data)) {
<?php if ($wannaUseSession): ?>
$this->Session->setFlash(__('Invalid <?php echo strtolower($singularHumanName); ?>'));
$this->redirect(array('action' => 'index'));
<?php else: ?>
$this->flash(__('Invalid <?php echo strtolower($singularHumanName); ?>'), array('action' => 'index'));
<?php endif; ?>
$this-><?php echo $currentModelName; ?>->id = $id;
if (!$this-><?php echo $currentModelName; ?>->exists()) {
throw new NotFoundException(__('Invalid <?php echo strtolower($singularHumanName); ?>'));
}
if ($this->request->is('post')) {
if ($this->request->is('post') || $this->request->is('put')) {
if ($this-><?php echo $currentModelName; ?>->save($this->request->data)) {
<?php if ($wannaUseSession): ?>
$this->Session->setFlash(__('The <?php echo strtolower($singularHumanName); ?> has been saved'));
@ -93,8 +85,7 @@
$this->Session->setFlash(__('The <?php echo strtolower($singularHumanName); ?> could not be saved. Please, try again.'));
<?php endif; ?>
}
}
if (!$this->request->is('post')) {
} else {
$this->data = $this-><?php echo $currentModelName; ?>->read(null, $id);
}
<?php
@ -118,15 +109,11 @@
if (!$this->request->is('post')) {
throw new MethodNotAllowedException();
}
if (!$id) {
<?php if ($wannaUseSession): ?>
$this->Session->setFlash(__('Invalid id for <?php echo strtolower($singularHumanName); ?>'));
$this->redirect(array('action'=>'index'));
<?php else: ?>
$this->flash(__('Invalid <?php echo strtolower($singularHumanName); ?>'), array('action' => 'index'));
<?php endif; ?>
$this-><?php echo $currentModelName; ?>->id = $id;
if (!$this-><?php echo $currentModelName; ?>->exists()) {
throw new NotFoundException(__('Invalid <?php echo strtolower($singularHumanName); ?>'));
}
if ($this-><?php echo $currentModelName; ?>->delete($id)) {
if ($this-><?php echo $currentModelName; ?>->delete()) {
<?php if ($wannaUseSession): ?>
$this->Session->setFlash(__('<?php echo ucfirst(strtolower($singularHumanName)); ?> deleted'));
$this->redirect(array('action'=>'index'));

View file

@ -26,7 +26,7 @@ class CakeErrorController extends AppController {
function __construct() {
parent::__construct();
$this->_set(Router::getPaths());
$this->request = $this->params = Router::getRequest(false);
$this->request = Router::getRequest(false);
$this->constructClasses();
$this->Components->trigger('initialize', array(&$this));
$this->_set(array('cacheAction' => false, 'viewPath' => 'errors'));

View file

@ -58,7 +58,7 @@ class AclComponent extends Component {
/**
* Constructor. Will return an instance of the correct ACL class as defined in `Configure::read('Acl.classname')`
*
* @throws Exception when Acl.classname could not be loaded.
* @throws CakeException when Acl.classname could not be loaded.
*/
public function __construct(ComponentCollection $collection, $settings = array()) {
parent::__construct($collection, $settings);
@ -68,7 +68,7 @@ class AclComponent extends Component {
list($plugin, $name) = pluginSplit($name);
$name .= 'Component';
} else {
throw new Exception(__('Could not find %s.', $name));
throw new CakeException(__('Could not find %s.', $name));
}
}
$this->adapter($name);
@ -84,7 +84,7 @@ class AclComponent extends Component {
*
* @param mixed $adapter Instance of AclBase or a string name of the class to use. (optional)
* @return mixed either null, or instance of AclBase
* @throws Exception when the given class is not an AclBase
* @throws CakeException when the given class is not an AclBase
*/
public function adapter($adapter = null) {
if ($adapter) {
@ -92,7 +92,7 @@ class AclComponent extends Component {
$adapter = new $adapter();
}
if (!$adapter instanceof AclInterface) {
throw new Exception(__('AclComponent adapters must implement AclInterface'));
throw new CakeException(__('AclComponent adapters must implement AclInterface'));
}
$this->_Instance = $adapter;
$this->_Instance->initialize($this);

View file

@ -193,7 +193,7 @@ class CookieComponent extends Component {
/**
* Write a value to the $_COOKIE[$key];
*
* Optional [Name.], reguired key, optional $value, optional $encrypt, optional $expires
* Optional [Name.], required key, optional $value, optional $encrypt, optional $expires
* $this->Cookie->write('[Name.]key, $value);
*
* By default all values are encrypted.
@ -222,7 +222,6 @@ class CookieComponent extends Component {
if (strpos($name, '.') === false) {
$this->_values[$name] = $value;
$this->_write("[$name]", $value);
} else {
$names = explode('.', $name, 2);
if (!isset($this->_values[$names[0]])) {
@ -238,7 +237,7 @@ class CookieComponent extends Component {
/**
* Read the value of the $_COOKIE[$key];
*
* Optional [Name.], reguired key
* Optional [Name.], required key
* $this->Cookie->read(Name.key);
*
* @param mixed $key Key of the value to be obtained. If none specified, obtain map key => values
@ -252,7 +251,7 @@ class CookieComponent extends Component {
if (is_null($key)) {
return $this->_values;
}
if (strpos($key, '.') !== false) {
$names = explode('.', $key, 2);
$key = $names[0];
@ -270,7 +269,7 @@ class CookieComponent extends Component {
/**
* Delete a cookie value
*
* Optional [Name.], reguired key
* Optional [Name.], required key
* $this->Cookie->read('Name.key);
*
* You must use this method before any output is sent to the browser.
@ -348,11 +347,11 @@ class CookieComponent extends Component {
return $this->_expires;
}
$this->_reset = $this->_expires;
if ($expires == 0) {
return $this->_expires = 0;
}
if (is_integer($expires) || is_numeric($expires)) {
return $this->_expires = $now + intval($expires);
}
@ -433,7 +432,7 @@ class CookieComponent extends Component {
$decrypted = array();
$type = $this->_type;
foreach ($values as $name => $value) {
foreach ((array)$values as $name => $value) {
if (is_array($value)) {
foreach ($value as $key => $val) {
$pos = strpos($val, 'Q2FrZQ==.');

View file

@ -97,6 +97,15 @@ class EmailComponent extends Component {
*/
public $bcc = array();
/**
* The date to put in the Date: header. This should be a date
* conformant with the RFC2822 standard. Leave null, to have
* today's date generated.
*
* @var string
*/
var $date = null;
/**
* The subject of the email
*
@ -148,6 +157,18 @@ class EmailComponent extends Component {
*/
public $lineLength = 70;
/**
* Line feed character(s) to be used when sending using mail() function
* If null PHP_EOL is used.
* RFC2822 requires it to be CRLF but some Unix
* mail transfer agents replace LF by CRLF automatically
* (which leads to doubling CR if CRLF is used).
*
* @var string
* @access public
*/
var $lineFeed = null;
/**
* @deprecated see lineLength
*/
@ -261,6 +282,9 @@ class EmailComponent extends Component {
* it be handled by sendmail (or similar) or a string
* to completely override the Message-ID.
*
* If you are sending Email from a shell, be sure to set this value. As you
* could encounter delivery issues if you do not.
*
* @var mixed
* @access public
*/
@ -412,6 +436,7 @@ class EmailComponent extends Component {
$this->bcc = array();
$this->subject = null;
$this->additionalParams = null;
$this->date = null;
$this->smtpError = null;
$this->attachments = array();
$this->htmlMessage = null;
@ -576,6 +601,12 @@ class EmailComponent extends Component {
}
}
$date = $this->date;
if ($date == false) {
$date = date(DATE_RFC2822);
}
$headers['Date'] = $date;
$headers['X-Mailer'] = $this->xMailer;
if (!empty($this->headers)) {
@ -790,8 +821,13 @@ class EmailComponent extends Component {
* @access private
*/
function _mail() {
$header = implode("\r\n", $this->_header);
$message = implode("\r\n", $this->_message);
if ($this->lineFeed === null) {
$lineFeed = PHP_EOL;
} else {
$lineFeed = $this->lineFeed;
}
$header = implode($lineFeed, $this->_header);
$message = implode($lineFeed, $this->_message);
if (is_array($this->to)) {
$to = implode(', ', array_map(array($this, '_formatAddress'), $this->to));
} else {
@ -861,7 +897,7 @@ class EmailComponent extends Component {
}
if (!is_array($this->to)) {
$tos = array($this->to);
$tos = array_map('trim', explode(',', $this->to));
} else {
$tos = $this->to;
}

View file

@ -619,15 +619,11 @@ class SecurityComponent extends Component {
}
unset($check['_Token']);
$locked = str_rot13($locked);
if (preg_match('/(\A|;|{|})O\:[0-9]+/', $locked)) {
return false;
}
$locked = explode('|', $locked);
$lockedFields = array();
$fields = Set::flatten($check);
$fieldList = array_keys($fields);
$locked = unserialize($locked);
$multi = array();
foreach ($fieldList as $i => $key) {

View file

@ -32,17 +32,6 @@ App::uses('CakeSession', 'Model/Datasource');
*/
class SessionComponent extends Component {
/**
* Constructor automatically starts the session.
*
* @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()) {
parent::__construct($collection, $settings);
CakeSession::start();
}
/**
* Get / Set the userAgent
*

View file

@ -74,7 +74,7 @@ class ComponentCollection extends ObjectCollection {
App::uses($componentClass, 'Controller/Component');
if (!class_exists($componentClass)) {
if (!class_exists($componentClass)) {
throw new MissingComponentFileException(array(
throw new MissingComponentClassException(array(
'file' => Inflector::underscore($component) . '.php',
'class' => $componentClass
));

View file

@ -94,26 +94,6 @@ class Controller extends Object {
*/
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',
* similar to the keys in the second parameter of Model::find().
*
* Pagination defaults can also be supplied in a model-by-model basis by using
* the name of the model as a key for a pagination array:
*
* {{{
* public $paginate = array(
* 'Post' => array(...),
* 'Comment' => array(...)
* );
* }}}
*
* @var array
* @link http://book.cakephp.org/view/1231/Pagination
*/
public $paginate = array('limit' => 20, 'page' => 1, 'maxLimit' => 100);
/**
* The name of the views subfolder containing views for this controller.
*
@ -315,7 +295,7 @@ class Controller extends Object {
$this->Components = new ComponentCollection();
if ($request instanceof CakeRequest) {
$this->_setRequest($request);
$this->setRequest($request);
}
$this->getResponse();
parent::__construct();
@ -356,6 +336,8 @@ class Controller extends Object {
return isset($this->request->params['action']) ? $this->request->params['action'] : '';
case 'params':
return $this->request;
case 'paginate':
return $this->Components->load('Paginator')->settings;
}
return null;
}
@ -376,6 +358,8 @@ class Controller extends Object {
return $this->request->params['action'] = $value;
case 'params':
return $this->request->params = $value;
case 'paginate':
return $this->Components->load('Paginator')->settings = $value;
}
return $this->{$name} = $value;
}
@ -387,7 +371,7 @@ class Controller extends Object {
* @param CakeRequest $request
* @return void
*/
protected function _setRequest(CakeRequest $request) {
public function setRequest(CakeRequest $request) {
$this->request = $request;
$this->plugin = isset($request->params['plugin']) ? $request->params['plugin'] : null;
@ -434,17 +418,23 @@ class Controller extends Object {
$this->uses = array_flip($this->uses);
array_unshift($this->uses, $plugin . $this->modelClass);
}
} elseif ($this->uses !== null || $this->uses !== false) {
$this->_mergeVars(array('uses'), 'AppController', false);
} elseif (
($this->uses !== null || $this->uses !== false) &&
is_array($this->uses) && !empty($appVars['uses'])
) {
$this->uses = array_merge($this->uses, array_diff($appVars['uses'], $this->uses));
}
$this->_mergeVars($merge, 'AppController', true);
}
if ($pluginController && $pluginName != null) {
$merge = array('components', 'helpers');
if ($this->uses !== null || $this->uses !== false) {
$this->_mergeVars(array('uses'), $pluginController, false);
$appVars = get_class_vars($pluginController);
if (
($this->uses !== null || $this->uses !== false) &&
is_array($this->uses) && !empty($appVars['uses'])
) {
$this->uses = array_merge($this->uses, array_diff($appVars['uses'], $this->uses));
}
$this->_mergeVars($merge, $pluginController);
}
@ -948,201 +938,10 @@ class Controller extends Object {
* @param array $whitelist List of allowed options for paging
* @return array Model query results
* @link http://book.cakephp.org/view/1232/Controller-Setup
* @deprecated Use PaginatorComponent instead
*/
public function paginate($object = null, $scope = array(), $whitelist = array()) {
if (is_array($object)) {
$whitelist = $scope;
$scope = $object;
$object = null;
}
$assoc = null;
if (is_string($object)) {
$assoc = null;
if (strpos($object, '.') !== false) {
list($object, $assoc) = pluginSplit($object);
}
if ($assoc && isset($this->{$object}->{$assoc})) {
$object = $this->{$object}->{$assoc};
} elseif (
$assoc && isset($this->{$this->modelClass}) &&
isset($this->{$this->modelClass}->{$assoc}
)) {
$object = $this->{$this->modelClass}->{$assoc};
} elseif (isset($this->{$object})) {
$object = $this->{$object};
} elseif (
isset($this->{$this->modelClass}) && isset($this->{$this->modelClass}->{$object}
)) {
$object = $this->{$this->modelClass}->{$object};
}
} elseif (empty($object) || $object === null) {
if (isset($this->{$this->modelClass})) {
$object = $this->{$this->modelClass};
} else {
$className = null;
$name = $this->uses[0];
if (strpos($this->uses[0], '.') !== false) {
list($name, $className) = explode('.', $this->uses[0]);
}
if ($className) {
$object = $this->{$className};
} else {
$object = $this->{$name};
}
}
}
if (!is_object($object)) {
trigger_error(sprintf(
__('Controller::paginate() - can\'t find model %1$s in controller %2$sController'), $object, $this->name
), E_USER_WARNING);
return array();
}
$options = array_merge($this->request->params, $this->request->query, $this->passedArgs);
if (isset($this->paginate[$object->alias])) {
$defaults = $this->paginate[$object->alias];
} else {
$defaults = $this->paginate;
}
if (isset($options['show'])) {
$options['limit'] = $options['show'];
}
if (isset($options['sort'])) {
$direction = null;
if (isset($options['direction'])) {
$direction = strtolower($options['direction']);
}
if ($direction != 'asc' && $direction != 'desc') {
$direction = 'asc';
}
$options['order'] = array($options['sort'] => $direction);
}
if (!empty($options['order']) && is_array($options['order'])) {
$alias = $object->alias ;
$key = $field = key($options['order']);
if (strpos($key, '.') !== false) {
list($alias, $field) = explode('.', $key);
}
$value = $options['order'][$key];
unset($options['order'][$key]);
if ($object->hasField($field)) {
$options['order'][$alias . '.' . $field] = $value;
} elseif ($object->hasField($field, true)) {
$options['order'][$field] = $value;
} elseif (isset($object->{$alias}) && $object->{$alias}->hasField($field)) {
$options['order'][$alias . '.' . $field] = $value;
}
}
$vars = array('fields', 'order', 'limit', 'page', 'recursive');
$keys = array_keys($options);
$count = count($keys);
for ($i = 0; $i < $count; $i++) {
if (!in_array($keys[$i], $vars, true)) {
unset($options[$keys[$i]]);
}
if (empty($whitelist) && ($keys[$i] === 'fields' || $keys[$i] === 'recursive')) {
unset($options[$keys[$i]]);
} elseif (!empty($whitelist) && !in_array($keys[$i], $whitelist)) {
unset($options[$keys[$i]]);
}
}
$conditions = $fields = $order = $limit = $page = $recursive = null;
if (!isset($defaults['conditions'])) {
$defaults['conditions'] = array();
}
$type = 'all';
if (isset($defaults[0])) {
$type = $defaults[0];
unset($defaults[0]);
}
$options = array_merge(array('page' => 1, 'limit' => 20, 'maxLimit' => 100), $defaults, $options);
$options['limit'] = min((int)$options['limit'], $options['maxLimit']);
if (empty($options['limit']) || $options['limit'] < 1) {
$options['limit'] = 1;
}
extract($options);
if (is_array($scope) && !empty($scope)) {
$conditions = array_merge($conditions, $scope);
} elseif (is_string($scope)) {
$conditions = array($conditions, $scope);
}
if ($recursive === null) {
$recursive = $object->recursive;
}
$extra = array_diff_key($defaults, compact(
'conditions', 'fields', 'order', 'limit', 'page', 'recursive'
));
if ($type !== 'all') {
$extra['type'] = $type;
}
if (method_exists($object, 'paginateCount')) {
$count = $object->paginateCount($conditions, $recursive, $extra);
} else {
$parameters = compact('conditions');
if ($recursive != $object->recursive) {
$parameters['recursive'] = $recursive;
}
$count = $object->find('count', array_merge($parameters, $extra));
}
$pageCount = intval(ceil($count / $limit));
if ($page === 'last' || $page >= $pageCount) {
$options['page'] = $page = $pageCount;
} elseif (intval($page) < 1) {
$options['page'] = $page = 1;
}
$page = $options['page'] = (int)$page;
if (method_exists($object, 'paginate')) {
$results = $object->paginate(
$conditions, $fields, $order, $limit, $page, $recursive, $extra
);
} else {
$parameters = compact('conditions', 'fields', 'order', 'limit', 'page');
if ($recursive != $object->recursive) {
$parameters['recursive'] = $recursive;
}
$results = $object->find($type, array_merge($parameters, $extra));
}
$paging = array(
'page' => $page,
'current' => count($results),
'count' => $count,
'prevPage' => ($page > 1),
'nextPage' => ($count > ($page * $limit)),
'pageCount' => $pageCount,
'defaults' => array_merge(array('limit' => 20, 'step' => 1), $defaults),
'options' => $options
);
if (!isset($this->request->params['paging'])) {
$this->request->params['paging'] = array();
}
$this->request->params['paging'] = array_merge(
(array)$this->request->params['paging'],
array($object->alias => $paging)
);
if (!in_array('Paginator', $this->helpers) && !array_key_exists('Paginator', $this->helpers)) {
$this->helpers[] = 'Paginator';
}
return $results;
return $this->Components->load('Paginator', $this->paginate)->paginate($object, $scope, $whitelist);
}
/**

View file

@ -172,15 +172,14 @@ class Scaffold {
*/
protected function _scaffoldView(CakeRequest $request) {
if ($this->controller->_beforeScaffold('view')) {
$message = __(sprintf("No id set for %s::view()", Inflector::humanize($this->modelKey)));
if (isset($request->params['pass'][0])) {
$this->ScaffoldModel->id = $request->params['pass'][0];
} else {
return $this->_sendMessage($message);
}
if (!$this->ScaffoldModel->exists()) {
throw new NotFoundException(__('Invalid %s', Inflector::humanize($this->modelKey)));
}
$this->ScaffoldModel->recursive = 1;
$this->controller->request->data = $this->controller->data = $this->ScaffoldModel->read();
$this->controller->request->data = $this->ScaffoldModel->read();
$this->controller->set(
Inflector::variable($this->controller->modelClass), $this->request->data
);
@ -245,10 +244,8 @@ class Scaffold {
if (isset($request->params['pass'][0])) {
$this->ScaffoldModel->id = $request['pass'][0];
}
if (!$this->ScaffoldModel->exists()) {
$message = __(sprintf("Invalid id for %s::edit()", Inflector::humanize($this->modelKey)));
return $this->_sendMessage($message);
throw new NotFoundException(__('Invalid %s', Inflector::humanize($this->modelKey)));
}
}
@ -260,7 +257,9 @@ class Scaffold {
if ($this->ScaffoldModel->save($request->data)) {
if ($this->controller->_afterScaffoldSave($action)) {
$message = __(
sprintf('The %1$s has been %2$s', Inflector::humanize($this->modelKey), $success)
'The %1$s has been %2$s',
Inflector::humanize($this->modelKey),
$success
);
return $this->_sendMessage($message);
} else {
@ -306,25 +305,26 @@ class Scaffold {
*/
protected function _scaffoldDelete(CakeRequest $request) {
if ($this->controller->_beforeScaffold('delete')) {
$message = __(
sprintf("No id set for %s::delete()", Inflector::humanize($this->modelKey))
);
if (!$request->is('post')) {
throw new MethodNotAllowedException();
}
$id = false;
if (isset($request->params['pass'][0])) {
$id = $request->params['pass'][0];
} else {
return $this->_sendMessage($message);
}
if ($this->ScaffoldModel->delete($id)) {
$message = __(
sprintf('The %1$s with id: %2$d has been deleted.', Inflector::humanize($this->modelClass), $id)
);
$this->ScaffoldModel->id = $id;
if (!$this->ScaffoldModel->exists()) {
throw new NotFoundException(__('Invalid %s', Inflector::humanize($this->modelClass)));
}
if ($this->ScaffoldModel->delete()) {
$message = __('The %1$s with id: %2$d has been deleted.', Inflector::humanize($this->modelClass), $id);
return $this->_sendMessage($message);
} else {
$message = __(sprintf(
'There was an error deleting the %1$s with id: %2$d',
Inflector::humanize($this->modelClass), $id
));
$message = __(
'There was an error deleting the %1$s with id: %2$d',
Inflector::humanize($this->modelClass),
$id
);
return $this->_sendMessage($message);
}
} elseif ($this->controller->_scaffoldError('delete') === false) {

View file

@ -325,7 +325,7 @@ class Configure {
* @param string $key name of configuration resource to load.
* @param string $config Name of the configured reader to use to read the resource identfied by $key.
* @return mixed false if file not found, void if load successful.
* @throws Exception Will throw any exceptions the reader raises.
* @throws ConfigureException Will throw any exceptions the reader raises.
*/
public static function load($key, $config = 'default') {
if (!isset(self::$_readers[$config])) {

View file

@ -110,7 +110,12 @@ class ErrorHandler {
public static function handleException(Exception $exception) {
$config = Configure::read('Exception');
if (!empty($config['log'])) {
CakeLog::write(LOG_ERR, '[' . get_class($exception) . '] ' . $exception->getMessage());
$message = sprintf("[%s] %s\n%s",
get_class($exception),
$exception->getMessage(),
$exception->getTraceAsString()
);
CakeLog::write(LOG_ERR, $message);
}
if ($config['renderer'] !== 'ExceptionRenderer') {
App::uses($config['renderer'], 'Error');

View file

@ -108,7 +108,7 @@ class ExceptionRenderer {
}
} elseif (!$methodExists) {
$method = 'error500';
if ($code >= 400) {
if ($code >= 400 && $code < 500) {
$method = 'error400';
}
}

View file

@ -19,12 +19,21 @@
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
/**
* Parent class for all of the HTTP related exceptions in CakePHP.
* All HTTP status/error related exceptions should extend this class so
* catch blocks can be specifically typed.
*
* @package cake.libs
*/
class HttpException extends RuntimeException { }
/**
* Represents an HTTP 400 error.
*
* @package cake.libs
*/
class BadRequestException extends RuntimeException {
class BadRequestException extends HttpException {
/**
* Constructor
*
@ -44,7 +53,7 @@ class BadRequestException extends RuntimeException {
*
* @package cake.libs
*/
class UnauthorizedException extends RuntimeException {
class UnauthorizedException extends HttpException {
/**
* Constructor
*
@ -64,7 +73,7 @@ class UnauthorizedException extends RuntimeException {
*
* @package cake.libs
*/
class ForbiddenException extends RuntimeException {
class ForbiddenException extends HttpException {
/**
* Constructor
*
@ -84,7 +93,7 @@ class ForbiddenException extends RuntimeException {
*
* @package cake.libs
*/
class NotFoundException extends RuntimeException {
class NotFoundException extends HttpException {
/**
* Constructor
*
@ -104,7 +113,7 @@ class NotFoundException extends RuntimeException {
*
* @package cake.libs
*/
class MethodNotAllowedException extends RuntimeException {
class MethodNotAllowedException extends HttpException {
/**
* Constructor
*
@ -124,7 +133,7 @@ class MethodNotAllowedException extends RuntimeException {
*
* @package cake.libs
*/
class InternalErrorException extends CakeException {
class InternalErrorException extends HttpException {
/**
* Constructor
*
@ -378,4 +387,70 @@ class MissingTableException extends CakeException {
*/
class MissingModelException extends CakeException {
protected $_messageTemplate = 'Model %s could not be found.';
}
}
/**
* Exception class for Cache. This exception will be thrown from Cache when it
* encounters an error.
*
* @package cake.libs
*/
class CacheException extends CakeException { }
/**
* Exception class for Router. This exception will be thrown from Router when it
* encounters an error.
*
* @package cake.libs
*/
class RouterException extends CakeException { }
/**
* Exception class for CakeLog. This exception will be thrown from CakeLog when it
* encounters an error.
*
* @package cake.libs
*/
class CakeLogException extends CakeException { }
/**
* Exception class for CakeSession. This exception will be thrown from CakeSession when it
* encounters an error.
*
* @package cake.libs
*/
class CakeSessionException extends CakeException { }
/**
* Exception class for Configure. This exception will be thrown from Configure when it
* encounters an error.
*
* @package cake.libs
*/
class ConfigureException extends CakeException { }
/**
* Exception class for Socket. This exception will be thrown from CakeSocket, HttpSocket and HttpResponse when it
* encounters an error.
*
* @package cake.libs
*/
class SocketException extends CakeException { }
/**
* Exception class for Xml. This exception will be thrown from Xml when it
* encounters an error.
*
* @package cake.libs
*/
class XmlException extends CakeException { }
/**
* Exception class for Console libraries. This exception will be thrown from Console library
* classes when they encounter an error.
*
* @package cake.libs
*/
class ConsoleException extends CakeException { }

View file

@ -97,18 +97,18 @@ class CakeLog {
* @param string $key The keyname for this logger, used to remove the logger later.
* @param array $config Array of configuration information for the logger
* @return boolean success of configuration.
* @throws Exception
* @throws CakeLogException
*/
public static function config($key, $config) {
if (empty($config['engine'])) {
throw new Exception(__('Missing logger classname'));
throw new CakeLogException(__('Missing logger classname'));
}
$loggerName = $config['engine'];
unset($config['engine']);
$className = self::_getLogger($loggerName);
$logger = new $className($config);
if (!$logger instanceof CakeLogInterface) {
throw new Exception(sprintf(
throw new CakeLogException(sprintf(
__('logger class %s does not implement a write method.'), $loggerName
));
}
@ -128,7 +128,7 @@ class CakeLog {
App::uses($loggerName, $plugin . 'Log/Engine');
if (!class_exists($loggerName)) {
throw new Exception(__('Could not load class %s', $loggerName));
throw new CakeLogException(__('Could not load class %s', $loggerName));
}
return $loggerName;
}

View file

@ -43,7 +43,7 @@ class AclBehavior extends ModelBehavior {
* @param mixed $config
* @return void
*/
public function setup(&$model, $config = array()) {
public function setup($model, $config = array()) {
if (is_string($config)) {
$config = array('type' => $config);
}
@ -67,7 +67,7 @@ class AclBehavior extends ModelBehavior {
* @return array
* @link http://book.cakephp.org/view/1322/node
*/
public function node(&$model, $ref = null) {
public function node($model, $ref = null) {
$type = $this->__typeMaps[$this->settings[$model->name]['type']];
if (empty($ref)) {
$ref = array('model' => $model->name, 'foreign_key' => $model->id);
@ -81,7 +81,7 @@ class AclBehavior extends ModelBehavior {
* @param boolean $created True if this is a new record
* @return void
*/
public function afterSave(&$model, $created) {
public function afterSave($model, $created) {
$type = $this->__typeMaps[$this->settings[$model->name]['type']];
$parent = $model->parentNode();
if (!empty($parent)) {
@ -105,7 +105,7 @@ class AclBehavior extends ModelBehavior {
*
* @return void
*/
public function afterDelete(&$model) {
public function afterDelete($model) {
$type = $this->__typeMaps[$this->settings[$model->name]['type']];
$node = Set::extract($this->node($model), "0.{$type}.id");
if (!empty($node)) {

View file

@ -63,7 +63,7 @@ class ContainableBehavior extends ModelBehavior {
* @param object $Model Model using the behavior
* @param array $settings Settings to override for model.
*/
public function setup(&$Model, $settings = array()) {
public function setup($Model, $settings = array()) {
if (!isset($this->settings[$Model->alias])) {
$this->settings[$Model->alias] = array('recursive' => true, 'notices' => true, 'autoFields' => true);
}
@ -94,9 +94,12 @@ class ContainableBehavior extends ModelBehavior {
* @param array $query Query parameters as set by cake
* @return array
*/
public function beforeFind(&$Model, $query) {
public function beforeFind($Model, $query) {
$reset = (isset($query['reset']) ? $query['reset'] : true);
$noContain = ((isset($this->runtime[$Model->alias]['contain']) && empty($this->runtime[$Model->alias]['contain'])) || (isset($query['contain']) && empty($query['contain'])));
$noContain = (
(isset($this->runtime[$Model->alias]['contain']) && empty($this->runtime[$Model->alias]['contain'])) ||
(isset($query['contain']) && empty($query['contain']))
);
$contain = array();
if (isset($this->runtime[$Model->alias]['contain'])) {
$contain = $this->runtime[$Model->alias]['contain'];
@ -105,7 +108,10 @@ class ContainableBehavior extends ModelBehavior {
if (isset($query['contain'])) {
$contain = array_merge($contain, (array)$query['contain']);
}
if ($noContain || !$contain || in_array($contain, array(null, false), true) || (isset($contain[0]) && $contain[0] === null)) {
if (
$noContain || !$contain || in_array($contain, array(null, false), true) ||
(isset($contain[0]) && $contain[0] === null)
) {
if ($noContain) {
$query['recursive'] = -1;
}
@ -177,6 +183,7 @@ class ContainableBehavior extends ModelBehavior {
$autoFields = ($this->settings[$Model->alias]['autoFields']
&& !in_array($Model->findQueryType, array('list', 'count'))
&& !empty($query['fields']));
if (!$autoFields) {
return $query;
}
@ -225,7 +232,7 @@ class ContainableBehavior extends ModelBehavior {
* @param array $results Results of the find operation
* @param bool $primary true if this is the primary model that issued the find operation, false otherwise
*/
public function afterFind(&$Model, $results, $primary) {
public function afterFind($Model, $results, $primary) {
if (!empty($Model->__backContainableAssociation)) {
foreach ($Model->__backContainableAssociation as $relation => $bindings) {
$Model->{$relation} = $bindings;
@ -242,7 +249,7 @@ class ContainableBehavior extends ModelBehavior {
* @return void
* @link http://book.cakephp.org/view/1323/Containable#Using-Containable-1324
*/
public function contain(&$Model) {
public function contain($Model) {
$args = func_get_args();
$contain = call_user_func_array('am', array_slice($args, 1));
$this->runtime[$Model->alias]['contain'] = $contain;
@ -256,7 +263,7 @@ class ContainableBehavior extends ModelBehavior {
* @param object $Model Model on which to reset bindings
* @return void
*/
public function resetBindings(&$Model) {
public function resetBindings($Model) {
if (!empty($Model->__backOriginalAssociation)) {
$Model->__backAssociation = $Model->__backOriginalAssociation;
unset($Model->__backOriginalAssociation);
@ -264,7 +271,7 @@ class ContainableBehavior extends ModelBehavior {
$Model->resetAssociations();
if (!empty($Model->__backInnerAssociation)) {
$assocs = $Model->__backInnerAssociation;
unset($Model->__backInnerAssociation);
$Model->__backInnerAssociation = array();
foreach ($assocs as $currentModel) {
$this->resetBindings($Model->$currentModel);
}
@ -280,7 +287,7 @@ class ContainableBehavior extends ModelBehavior {
* @param bool $throwErrors Wether unexisting bindings show throw errors
* @return array Containments
*/
public function containments(&$Model, $contain, $containments = array(), $throwErrors = null) {
public function containments($Model, $contain, $containments = array(), $throwErrors = null) {
$options = array('className', 'joinTable', 'with', 'foreignKey', 'associationForeignKey', 'conditions', 'fields', 'order', 'limit', 'offset', 'unique', 'finderQuery', 'deleteQuery', 'insertQuery');
$keep = array();
$depth = array();
@ -383,7 +390,7 @@ class ContainableBehavior extends ModelBehavior {
* @param mixed $fields If array, fields to initially load, if false use $Model as primary model
* @return array Fields
*/
public function fieldDependencies(&$Model, $map, $fields = array()) {
public function fieldDependencies($Model, $map, $fields = array()) {
if ($fields === false) {
foreach ($map as $parent => $children) {
foreach ($children as $type => $bindings) {

View file

@ -18,7 +18,7 @@
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
App::uses('I18n', 'Core');
App::uses('I18n', 'I18n');
/**
* Translate behavior
@ -53,7 +53,7 @@ class TranslateBehavior extends ModelBehavior {
* @param array $config Array of configuration information.
* @return mixed
*/
public function setup(&$model, $config = array()) {
public function setup($model, $config = array()) {
$db = ConnectionManager::getDataSource($model->useDbConfig);
if (!$db->connected) {
trigger_error(
@ -75,7 +75,7 @@ class TranslateBehavior extends ModelBehavior {
* @param Model $model Model being detached.
* @return void
*/
public function cleanup(&$model) {
public function cleanup($model) {
$this->unbindTranslation($model);
unset($this->settings[$model->alias]);
unset($this->runtime[$model->alias]);
@ -88,7 +88,7 @@ class TranslateBehavior extends ModelBehavior {
* @param array $query Array of Query parameters.
* @return array Modified query
*/
public function beforeFind(&$model, $query) {
public function beforeFind($model, $query) {
$this->runtime[$model->alias]['virtualFields'] = $model->virtualFields;
$locale = $this->_getLocale($model);
if (empty($locale)) {
@ -198,7 +198,7 @@ class TranslateBehavior extends ModelBehavior {
* @param boolean $primary Did the find originate on $model.
* @return array Modified results
*/
public function afterFind(&$model, $results, $primary) {
public function afterFind($model, $results, $primary) {
$model->virtualFields = $this->runtime[$model->alias]['virtualFields'];
$this->runtime[$model->alias]['virtualFields'] = $this->runtime[$model->alias]['fields'] = array();
$locale = $this->_getLocale($model);
@ -244,7 +244,7 @@ class TranslateBehavior extends ModelBehavior {
* @param Model $model Model invalidFields was called on.
* @return boolean
*/
public function beforeValidate(&$model) {
public function beforeValidate($model) {
$locale = $this->_getLocale($model);
if (empty($locale)) {
return true;
@ -278,7 +278,7 @@ class TranslateBehavior extends ModelBehavior {
* @param boolean $created Whether or not the save created a record.
* @return void
*/
public function afterSave(&$model, $created) {
public function afterSave($model, $created) {
if (!isset($this->runtime[$model->alias]['beforeSave'])) {
return true;
}
@ -286,7 +286,7 @@ class TranslateBehavior extends ModelBehavior {
$tempData = $this->runtime[$model->alias]['beforeSave'];
unset($this->runtime[$model->alias]['beforeSave']);
$conditions = array('model' => $model->alias, 'foreign_key' => $model->id);
$RuntimeModel =& $this->translateModel($model);
$RuntimeModel = $this->translateModel($model);
foreach ($tempData as $field => $value) {
unset($conditions['content']);
@ -321,8 +321,8 @@ class TranslateBehavior extends ModelBehavior {
* @param Model $model Model the callback was run on.
* @return void
*/
public function afterDelete(&$model) {
$RuntimeModel =& $this->translateModel($model);
public function afterDelete($model) {
$RuntimeModel = $this->translateModel($model);
$conditions = array('model' => $model->alias, 'foreign_key' => $model->id);
$RuntimeModel->deleteAll($conditions);
}
@ -333,9 +333,9 @@ class TranslateBehavior extends ModelBehavior {
* @param Model $model Model the locale needs to be set/get on.
* @return mixed string or false
*/
protected function _getLocale(&$model) {
protected function _getLocale($model) {
if (!isset($model->locale) || is_null($model->locale)) {
$I18n =& I18n::getInstance();
$I18n = I18n::getInstance();
$I18n->l10n->get(Configure::read('Config.language'));
$model->locale = $I18n->l10n->locale;
}
@ -352,7 +352,7 @@ class TranslateBehavior extends ModelBehavior {
* @param Model $model Model to get a translatemodel for.
* @return object
*/
public function &translateModel(&$model) {
public function translateModel($model) {
if (!isset($this->runtime[$model->alias]['model'])) {
if (!isset($model->translateModel) || empty($model->translateModel)) {
$className = 'I18nModel';
@ -379,12 +379,12 @@ class TranslateBehavior extends ModelBehavior {
* @param boolean $reset
* @return bool
*/
function bindTranslation(&$model, $fields, $reset = true) {
function bindTranslation($model, $fields, $reset = true) {
if (is_string($fields)) {
$fields = array($fields);
}
$associations = array();
$RuntimeModel =& $this->translateModel($model);
$RuntimeModel = $this->translateModel($model);
$default = array('className' => $RuntimeModel->alias, 'foreignKey' => 'foreign_key');
foreach ($fields as $key => $value) {
@ -452,7 +452,7 @@ class TranslateBehavior extends ModelBehavior {
* unbind all original translations
* @return bool
*/
function unbindTranslation(&$model, $fields = null) {
function unbindTranslation($model, $fields = null) {
if (empty($fields) && empty($this->settings[$model->alias])) {
return false;
}
@ -463,7 +463,7 @@ class TranslateBehavior extends ModelBehavior {
if (is_string($fields)) {
$fields = array($fields);
}
$RuntimeModel =& $this->translateModel($model);
$RuntimeModel = $this->translateModel($model);
$associations = array();
foreach ($fields as $key => $value) {
@ -498,15 +498,13 @@ class TranslateBehavior extends ModelBehavior {
return true;
}
}
if (!defined('CAKEPHP_UNIT_TEST_EXECUTION')) {
/**
* @package cake
* @subpackage cake.cake.libs.model.behaviors
*/
class I18nModel extends AppModel {
public $name = 'I18nModel';
public $useTable = 'i18n';
public $displayField = 'field';
}
class I18nModel extends AppModel {
public $name = 'I18nModel';
public $useTable = 'i18n';
public $displayField = 'field';
}

View file

@ -57,7 +57,7 @@ class TreeBehavior extends ModelBehavior {
* @param array $config array of configuration settings.
* @return void
*/
public function setup(&$Model, $config = array()) {
public function setup($Model, $config = array()) {
if (!is_array($config)) {
$config = array('type' => $config);
}
@ -82,7 +82,7 @@ class TreeBehavior extends ModelBehavior {
* @param boolean $created indicates whether the node just saved was created or updated
* @return boolean true on success, false on failure
*/
public function afterSave(&$Model, $created) {
public function afterSave($Model, $created) {
extract($this->settings[$Model->alias]);
if ($created) {
if ((isset($Model->data[$Model->alias][$parent])) && $Model->data[$Model->alias][$parent]) {
@ -102,7 +102,7 @@ class TreeBehavior extends ModelBehavior {
* @param AppModel $Model Model instance
* @return boolean true to continue, false to abort the delete
*/
public function beforeDelete(&$Model) {
public function beforeDelete($Model, $cascade = true) {
extract($this->settings[$Model->alias]);
list($name, $data) = array($Model->alias, $Model->read());
$data = $data[$name];
@ -134,7 +134,7 @@ class TreeBehavior extends ModelBehavior {
* @param AppModel $Model Model instance
* @return boolean true to continue, false to abort the save
*/
public function beforeSave(&$Model) {
public function beforeSave($Model) {
extract($this->settings[$Model->alias]);
$this->_addToWhitelist($Model, array($left, $right));
@ -204,7 +204,7 @@ class TreeBehavior extends ModelBehavior {
* @return integer number of child nodes
* @link http://book.cakephp.org/view/1347/Counting-children
*/
public function childCount(&$Model, $id = null, $direct = false) {
public function childCount($Model, $id = null, $direct = false) {
if (is_array($id)) {
extract (array_merge(array('id' => null), $id));
}
@ -250,7 +250,7 @@ class TreeBehavior extends ModelBehavior {
* @return array Array of child nodes
* @link http://book.cakephp.org/view/1346/Children
*/
public function children(&$Model, $id = null, $direct = false, $fields = null, $order = null, $limit = null, $page = 1, $recursive = null) {
public function children($Model, $id = null, $direct = false, $fields = null, $order = null, $limit = null, $page = 1, $recursive = null) {
if (is_array($id)) {
extract (array_merge(array('id' => null), $id));
}
@ -307,7 +307,7 @@ class TreeBehavior extends ModelBehavior {
* @return array An associative array of records, where the id is the key, and the display field is the value
* @link http://book.cakephp.org/view/1348/generatetreelist
*/
public function generateTreeList(&$Model, $conditions = null, $keyPath = null, $valuePath = null, $spacer = '_', $recursive = null) {
public function generateTreeList($Model, $conditions = null, $keyPath = null, $valuePath = null, $spacer = '_', $recursive = null) {
$overrideRecursive = $recursive;
extract($this->settings[$Model->alias]);
if (!is_null($overrideRecursive)) {
@ -362,7 +362,7 @@ class TreeBehavior extends ModelBehavior {
* @return array Array of data for the parent node
* @link http://book.cakephp.org/view/1349/getparentnode
*/
public function getParentNode(&$Model, $id = null, $fields = null, $recursive = null) {
public function getParentNode($Model, $id = null, $fields = null, $recursive = null) {
if (is_array($id)) {
extract (array_merge(array('id' => null), $id));
}
@ -395,7 +395,7 @@ class TreeBehavior extends ModelBehavior {
* @return array Array of nodes from top most parent to current node
* @link http://book.cakephp.org/view/1350/getpath
*/
public function getPath(&$Model, $id = null, $fields = null, $recursive = null) {
public function getPath($Model, $id = null, $fields = null, $recursive = null) {
if (is_array($id)) {
extract (array_merge(array('id' => null), $id));
}
@ -432,7 +432,7 @@ class TreeBehavior extends ModelBehavior {
* @return boolean true on success, false on failure
* @link http://book.cakephp.org/view/1352/moveDown
*/
public function moveDown(&$Model, $id = null, $number = 1) {
public function moveDown($Model, $id = null, $number = 1) {
if (is_array($id)) {
extract (array_merge(array('id' => null), $id));
}
@ -490,7 +490,7 @@ class TreeBehavior extends ModelBehavior {
* @return boolean true on success, false on failure
* @link http://book.cakephp.org/view/1353/moveUp
*/
public function moveUp(&$Model, $id = null, $number = 1) {
public function moveUp($Model, $id = null, $number = 1) {
if (is_array($id)) {
extract (array_merge(array('id' => null), $id));
}
@ -554,7 +554,7 @@ class TreeBehavior extends ModelBehavior {
* @return boolean true on success, false on failure
* @link http://book.cakephp.org/view/1628/Recover
*/
public function recover(&$Model, $mode = 'parent', $missingParentAction = null) {
public function recover($Model, $mode = 'parent', $missingParentAction = null) {
if (is_array($mode)) {
extract (array_merge(array('mode' => 'parent'), $mode));
}
@ -634,7 +634,7 @@ class TreeBehavior extends ModelBehavior {
* @link http://book.cakephp.org/view/1355/reorder
* @link http://book.cakephp.org/view/1629/Reorder
*/
function reorder(&$Model, $options = array()) {
function reorder($Model, $options = array()) {
$options = array_merge(array('id' => null, 'field' => $Model->displayField, 'order' => 'ASC', 'verify' => true), $options);
extract($options);
if ($verify && !$this->verify($Model)) {
@ -673,7 +673,7 @@ class TreeBehavior extends ModelBehavior {
* @return boolean true on success, false on failure
* @link http://book.cakephp.org/view/1354/removeFromTree
*/
public function removeFromTree(&$Model, $id = null, $delete = false) {
public function removeFromTree($Model, $id = null, $delete = false) {
if (is_array($id)) {
extract (array_merge(array('id' => null), $id));
}
@ -744,7 +744,7 @@ class TreeBehavior extends ModelBehavior {
* [incorrect left/right index,node id], message)
* @link http://book.cakephp.org/view/1630/Verify
*/
public function verify(&$Model) {
public function verify($Model) {
extract($this->settings[$Model->alias]);
if (!$Model->find('count', array('conditions' => $scope))) {
return true;
@ -815,7 +815,7 @@ class TreeBehavior extends ModelBehavior {
* @param mixed $parentId
* @return boolean true on success, false on failure
*/
protected function _setParent(&$Model, $parentId = null, $created = false) {
protected function _setParent($Model, $parentId = null, $created = false) {
extract($this->settings[$Model->alias]);
list($node) = array_values($Model->find('first', array(
'conditions' => array($scope, $Model->escapeField() => $Model->id),
@ -938,7 +938,7 @@ class TreeBehavior extends ModelBehavior {
* @param string $field
* @access private
*/
function __sync(&$Model, $shift, $dir = '+', $conditions = array(), $created = false, $field = 'both') {
function __sync($Model, $shift, $dir = '+', $conditions = array(), $created = false, $field = 'both') {
$ModelRecursive = $Model->recursive;
extract($this->settings[$Model->alias]);
$Model->recursive = $recursive;

View file

@ -225,43 +225,6 @@ class BehaviorCollection extends ObjectCollection {
return array('unhandled');
}
/**
* Dispatches a behavior callback on all attached behavior objects
*
* @param model $model
* @param string $callback
* @param array $params
* @param array $options
* @return mixed
*/
public function trigger(&$model, $callback, $params = array(), $options = array()) {
if (empty($this->_enabled)) {
return true;
}
$options = array_merge(
array('break' => false, 'breakOn' => array(null, false), 'modParams' => false),
$options
);
foreach ($this->_enabled as $name) {
$result = call_user_func_array(
array(&$this->_loaded[$name], $callback),
array_merge(array(&$model), $params)
);
if (
$options['break'] && ($result === $options['breakOn'] ||
(is_array($options['breakOn']) && in_array($result, $options['breakOn'], true)))
) {
return $result;
} elseif ($options['modParams'] && is_array($result)) {
$params[0] = $result;
}
}
if ($options['modParams'] && isset($params[0])) {
return $params[0];
}
return true;
}
/**
* Gets the method list for attached behaviors, i.e. all public, non-callback methods
*
@ -271,4 +234,4 @@ class BehaviorCollection extends ObjectCollection {
return $this->__methods;
}
}
}

View file

@ -24,6 +24,7 @@
*/
App::uses('Set', 'Utility');
App::uses('Security', 'Utility');
/**
* Session class for Cake.
@ -99,13 +100,6 @@ class CakeSession {
*/
public static $sessionTime = false;
/**
* Keeps track of keys to watch for writes on
*
* @var array
*/
public static $watchKeys = array();
/**
* Current Session id
*
@ -149,14 +143,8 @@ class CakeSession {
if (($checkAgent === true || $checkAgent === null) && env('HTTP_USER_AGENT') != null) {
self::$_userAgent = md5(env('HTTP_USER_AGENT') . Configure::read('Security.salt'));
}
if ($start === true) {
self::_setPath($base);
self::_setHost(env('HTTP_HOST'));
}
if (isset($_SESSION) || $start === true) {
self::start();
}
self::_setPath($base);
self::_setHost(env('HTTP_HOST'));
}
/**
@ -230,6 +218,9 @@ class CakeSession {
* @return boolean True if variable is there
*/
public static function check($name = null) {
if (!self::started() && !self::start()) {
return false;
}
if (empty($name)) {
return false;
}
@ -262,9 +253,6 @@ class CakeSession {
*/
public static function delete($name) {
if (self::check($name)) {
if (in_array($name, self::$watchKeys)) {
trigger_error(__('Deleting session key {%s}', $name), E_USER_NOTICE);
}
self::__overwrite($_SESSION, Set::remove($_SESSION, $name));
return (self::check($name) == false);
}
@ -373,6 +361,9 @@ class CakeSession {
* @return mixed The value of the session variable
*/
public static function read($name = null) {
if (!self::started() && !self::start()) {
return false;
}
if (is_null($name)) {
return self::__returnSessionVars();
}
@ -392,9 +383,8 @@ class CakeSession {
* Returns all session variables.
*
* @return mixed Full $_SESSION array, or false on error.
* @access private
*/
function __returnSessionVars() {
private static function __returnSessionVars() {
if (!empty($_SESSION)) {
return $_SESSION;
}
@ -402,41 +392,6 @@ class CakeSession {
return false;
}
/**
* Tells Session to write a notification when a certain session path or subpath is written to
*
* @param mixed $var The variable path to watch
* @return void
*/
public static function watch($var) {
if (empty($var)) {
return false;
}
if (!in_array($var, self::$watchKeys, true)) {
self::$watchKeys[] = $var;
}
}
/**
* Tells Session to stop watching a given key path
*
* @param mixed $var The variable path to watch
* @return void
*/
public static function ignore($var) {
if (!in_array($var, self::$watchKeys)) {
debug("NOT");
return;
}
foreach (self::$watchKeys as $i => $key) {
if ($key == $var) {
unset(self::$watchKeys[$i]);
self::$watchKeys = array_values(self::$watchKeys);
return;
}
}
}
/**
* Writes value to given session variable name.
*
@ -445,6 +400,9 @@ class CakeSession {
* @return boolean True if the write was successful, false if the write failed
*/
public static function write($name, $value = null) {
if (!self::started() && !self::start()) {
return false;
}
if (empty($name)) {
return false;
}
@ -453,9 +411,6 @@ class CakeSession {
$write = array($name => $value);
}
foreach ($write as $key => $val) {
if (in_array($key, self::$watchKeys)) {
trigger_error(__('Writing session key {%s}: %s', $key, Debugger::exportVar($val)), E_USER_NOTICE);
}
self::__overwrite($_SESSION, Set::insert($_SESSION, $key, $val));
if (Set::classicExtract($_SESSION, $key) !== $val) {
return false;
@ -494,7 +449,7 @@ class CakeSession {
* Sessions can be configured with a few shortcut names as well as have any number of ini settings declared.
*
* @return void
* @throws Exception Throws exceptions when ini_set() fails.
* @throws CakeSessionException Throws exceptions when ini_set() fails.
*/
protected static function _configureSession() {
$sessionConfig = Configure::read('Session');
@ -526,7 +481,7 @@ class CakeSession {
if (!empty($sessionConfig['ini']) && is_array($sessionConfig['ini'])) {
foreach ($sessionConfig['ini'] as $setting => $value) {
if (ini_set($setting, $value) === false) {
throw new Exception(sprintf(
throw new CakeSessionException(sprintf(
__('Unable to configure the session, setting %s failed.'),
$setting
));
@ -561,13 +516,13 @@ class CakeSession {
list($plugin, $class) = pluginSplit($handler, true);
App::uses($class, $plugin . 'Model/Datasource/Session');
if (!class_exists($class)) {
throw new Exception(__('Could not load %s to handle the session.', $class));
throw new CakeSessionException(__('Could not load %s to handle the session.', $class));
}
$handler = new $class();
if ($handler instanceof CakeSessionHandlerInterface) {
return $handler;
}
throw new Exception(__('Chosen SessionHandler does not implement CakeSessionHandlerInterface it cannot be used with an engine key.'));
throw new CakeSessionException(__('Chosen SessionHandler does not implement CakeSessionHandlerInterface it cannot be used with an engine key.'));
}
/**
@ -670,6 +625,10 @@ class CakeSession {
* @return void
*/
protected static function _checkValid() {
if (!self::started() && !self::start()) {
self::$valid = false;
return false;
}
if ($config = self::read('Config')) {
$sessionConfig = Configure::read('Session');

View file

@ -384,7 +384,7 @@ class DataSource extends Object {
}
/**
* Returns the ID generated from the previous INSERT operation.
* Returns the number of rows returned by last operation.
*
* @param unknown_type $source
* @return integer Number of rows returned by last operation
@ -394,7 +394,7 @@ class DataSource extends Object {
}
/**
* Returns the ID generated from the previous INSERT operation.
* Returns the number of rows affected by last query.
*
* @param unknown_type $source
* @return integer Number of rows affected by last query.
@ -413,6 +413,7 @@ class DataSource extends Object {
public function enabled() {
return true;
}
/**
* Returns true if the DataSource supports the given interface (method)
*

View file

@ -682,7 +682,7 @@ class DboSource extends DataSource {
return $return;
}
$data = trim($data);
if (preg_match('/^[\w-]+(\.[\w-]+)*$/', $data)) { // string, string.string
if (preg_match('/^[\w-]+(?:\.[^ \*]*)*$/', $data)) { // string, string.string
if (strpos($data, '.') === false) { // string
return $this->cacheMethod(__FUNCTION__, $cacheKey, $this->startQuote . $data . $this->endQuote);
}

View file

@ -331,7 +331,13 @@ class Model extends Object {
* @var array
* @access private
*/
private $__backAssociation = array();
public $__backAssociation = array();
public $__backInnerAssociation = array();
public $__backOriginalAssociation = array();
public $__backContainableAssociation = array();
/**
* The ID of the model record that was last inserted.
@ -1315,8 +1321,8 @@ class Model extends Object {
}
if ($options['callbacks'] === true || $options['callbacks'] === 'before') {
$result = $this->Behaviors->trigger($this, 'beforeSave', array($options), array(
'break' => true, 'breakOn' => false
$result = $this->Behaviors->trigger('beforeSave', array(&$this, $options), array(
'break' => true, 'breakOn' => array(false, null)
));
if (!$result || !$this->beforeSave($options)) {
$this->whitelist = $_whitelist;
@ -1399,7 +1405,7 @@ class Model extends Object {
$success = $this->data;
}
if ($options['callbacks'] === true || $options['callbacks'] === 'after') {
$this->Behaviors->trigger($this, 'afterSave', array($created, $options));
$this->Behaviors->trigger('afterSave', array(&$this, $created, $options));
$this->afterSave($created);
}
if (!empty($this->data)) {
@ -1845,13 +1851,15 @@ class Model extends Object {
$id = $this->id;
if ($this->beforeDelete($cascade)) {
$filters = $this->Behaviors->trigger($this, 'beforeDelete', array($cascade), array(
'break' => true, 'breakOn' => false
));
$filters = $this->Behaviors->trigger(
'beforeDelete',
array(&$this, $cascade),
array('break' => true, 'breakOn' => array(false, null))
);
if (!$filters || !$this->exists()) {
return false;
}
$db =& ConnectionManager::getDataSource($this->useDbConfig);
$db = ConnectionManager::getDataSource($this->useDbConfig);
$this->_deleteDependent($id, $cascade);
$this->_deleteLinks($id);
@ -1868,7 +1876,7 @@ class Model extends Object {
if (!empty($this->belongsTo)) {
$this->updateCounterCache($keys[$this->alias]);
}
$this->Behaviors->trigger($this, 'afterDelete');
$this->Behaviors->trigger('afterDelete', array(&$this));
$this->afterDelete();
$this->_clearCache();
$this->id = false;
@ -2132,9 +2140,12 @@ class Model extends Object {
$query['order'] = array($query['order']);
if ($query['callbacks'] === true || $query['callbacks'] === 'before') {
$return = $this->Behaviors->trigger($this, 'beforeFind', array($query), array(
'break' => true, 'breakOn' => false, 'modParams' => true
));
$return = $this->Behaviors->trigger(
'beforeFind',
array(&$this, $query),
array('break' => true, 'breakOn' => array(false, null), 'modParams' => 1)
);
$query = (is_array($return)) ? $return : $query;
if ($return === false) {
@ -2397,7 +2408,11 @@ class Model extends Object {
* @access private
*/
function __filterResults($results, $primary = true) {
$return = $this->Behaviors->trigger($this, 'afterFind', array($results, $primary), array('modParams' => true));
$return = $this->Behaviors->trigger(
'afterFind',
array(&$this, $results, $primary),
array('modParams' => 1)
);
if ($return !== true) {
$results = $return;
}
@ -2522,9 +2537,8 @@ class Model extends Object {
function invalidFields($options = array()) {
if (
!$this->Behaviors->trigger(
$this,
'beforeValidate',
array($options),
array(&$this, $options),
array('break' => true, 'breakOn' => false)
) ||
$this->beforeValidate($options) === false

View file

@ -80,10 +80,13 @@ class ModelBehavior extends Object {
*
* @param object $model Model using this behavior
* @param array $queryData Data used to execute this query, i.e. conditions, order, etc.
* @return mixed False if the operation should abort. An array will replace the value of $query.
* @return mixed False or null will abort the operation. You can return an array to replace the
* $query that will be eventually run.
* @access public
*/
public function beforeFind($model, $query) { }
public function beforeFind($model, $query) {
return true;
}
/**
* After find callback. Can be used to modify any results returned by find and findAll.
@ -100,10 +103,12 @@ class ModelBehavior extends Object {
* Before validate callback
*
* @param object $model Model using this behavior
* @return mixed False if the operation should abort. Any other result will continue.
* @return mixed False or null will abort the operation. Any other result will continue.
* @access public
*/
public function beforeValidate($model) { }
public function beforeValidate($model) {
return true;
}
/**
* Before save callback
@ -112,7 +117,9 @@ class ModelBehavior extends Object {
* @return mixed False if the operation should abort. Any other result will continue.
* @access public
*/
public function beforeSave($model) { }
public function beforeSave($model) {
return true;
}
/**
* After save callback
@ -120,7 +127,9 @@ class ModelBehavior extends Object {
* @param object $model Model using this behavior
* @param boolean $created True if this save created a new record
*/
public function afterSave($model, $created) { }
public function afterSave($model, $created) {
return true;
}
/**
* Before delete callback
@ -130,7 +139,9 @@ class ModelBehavior extends Object {
* @return mixed False if the operation should abort. Any other result will continue.
* @access public
*/
public function beforeDelete($model, $cascade = true) { }
public function beforeDelete($model, $cascade = true) {
return true;
}
/**
* After delete callback

View file

@ -426,7 +426,7 @@ class CakeRequest implements ArrayAccess {
$type = strtolower(substr($name, 2));
return $this->is($type);
}
throw new BadMethodCallException(sprintf('Method %s does not exist', $name));
throw new CakeException(__('Method %s does not exist', $name));
}
/**

View file

@ -448,13 +448,14 @@ class CakeResponse {
*
* @param integer $code
* @return integer current status code
* @throws CakeException When an unknown status code is reached.
*/
public function statusCode($code = null) {
if (is_null($code)) {
return $this->_status;
}
if (!isset($this->_statusCodes[$code])) {
throw new OutOfRangeException(__('Unknown status code'));
throw new CakeException(__('Unknown status code'));
}
return $this->_status = $code;
}

View file

@ -100,6 +100,7 @@ class CakeSocket {
* Connect the socket to the given host and port.
*
* @return boolean Success
* @throws SocketException
*/
public function connect() {
if ($this->connection != null) {
@ -112,7 +113,6 @@ class CakeSocket {
}
if ($this->config['persistent'] == true) {
$tmp = null;
$this->connection = @pfsockopen($scheme.$this->config['host'], $this->config['port'], $errNum, $errStr, $this->config['timeout']);
} else {
$this->connection = @fsockopen($scheme.$this->config['host'], $this->config['port'], $errNum, $errStr, $this->config['timeout']);
@ -120,6 +120,7 @@ class CakeSocket {
if (!empty($errNum) || !empty($errStr)) {
$this->setLastError($errStr, $errNum);
throw new SocketException($errStr, $errNum);
}
$this->connected = is_resource($this->connection);
@ -137,9 +138,8 @@ class CakeSocket {
public function host() {
if (Validation::ip($this->config['host'])) {
return gethostbyaddr($this->config['host']);
} else {
return gethostbyaddr($this->address());
}
return gethostbyaddr($this->address());
}
/**
@ -150,9 +150,8 @@ class CakeSocket {
public function address() {
if (Validation::ip($this->config['host'])) {
return $this->config['host'];
} else {
return gethostbyname($this->config['host']);
}
return gethostbyname($this->config['host']);
}
/**
@ -163,9 +162,8 @@ class CakeSocket {
public function addresses() {
if (Validation::ip($this->config['host'])) {
return array($this->config['host']);
} else {
return gethostbynamel($this->config['host']);
}
return gethostbynamel($this->config['host']);
}
/**
@ -176,9 +174,8 @@ class CakeSocket {
public function lastError() {
if (!empty($this->lastError)) {
return $this->lastError['num'] . ': ' . $this->lastError['str'];
} else {
return null;
}
return null;
}
/**
@ -186,6 +183,7 @@ class CakeSocket {
*
* @param integer $errNum Error code
* @param string $errStr Error string
* @return void
*/
public function setLastError($errNum, $errStr) {
$this->lastError = array('num' => $errNum, 'str' => $errStr);
@ -229,17 +227,8 @@ class CakeSocket {
return false;
}
return $buffer;
} else {
return false;
}
}
/**
* Abort socket operation.
*
* @return boolean Success
*/
public function abort() {
return false;
}
/**
@ -272,6 +261,7 @@ class CakeSocket {
/**
* Resets the state of this Socket instance to it's initial state (before Object::__construct got executed)
*
* @param array $state Array with key and values to reset
* @return boolean True on success
*/
public function reset($state = null) {

View file

@ -31,29 +31,19 @@ App::uses('Router', 'Routing');
*/
class HttpSocket extends CakeSocket {
/**
* Object description
*
* @var string
* @access public
*/
public $description = 'HTTP-based DataSource Interface';
/**
* When one activates the $quirksMode by setting it to true, all checks meant to
* enforce RFC 2616 (HTTP/1.1 specs).
* will be disabled and additional measures to deal with non-standard responses will be enabled.
*
* @var boolean
* @access public
*/
public $quirksMode = false;
/**
* The default values to use for a request
* Contain information about the last request (read only)
*
* @var array
* @access public
*/
public $request = array(
'method' => 'GET',
@ -67,11 +57,6 @@ class HttpSocket extends CakeSocket {
'query' => null,
'fragment' => null
),
'auth' => array(
'method' => 'Basic',
'user' => null,
'pass' => null
),
'version' => '1.1',
'body' => '',
'line' => null,
@ -84,33 +69,23 @@ class HttpSocket extends CakeSocket {
);
/**
* The default structure for storing the response
*
* @var array
* @access public
*/
public $response = array(
'raw' => array(
'status-line' => null,
'header' => null,
'body' => null,
'response' => null
),
'status' => array(
'http-version' => null,
'code' => null,
'reason-phrase' => null
),
'header' => array(),
'body' => '',
'cookies' => array()
);
/**
* Default configuration settings for the HttpSocket
* Contain information about the last response (read only)
*
* @var array
*/
public $response = null;
/**
* Response classname
*
* @var string
*/
public $responseClass = 'HttpResponse';
/**
* Configuration settings for the HttpSocket and the requests
*
* @var array
* @access public
*/
public $config = array(
'persistent' => false,
@ -124,22 +99,30 @@ class HttpSocket extends CakeSocket {
'host' => 'localhost',
'port' => 80
),
'auth' => array(
'method' => 'Basic',
'user' => null,
'pass' => null
),
'cookies' => array()
)
);
/**
* String that represents a line break.
* Authentication settings
*
* @var string
* @access public
* @var array
*/
public $lineBreak = "\r\n";
protected $_auth = array();
/**
* Proxy settings
*
* @var array
*/
protected $_proxy = array();
/**
* Resource to receive the content of request
*
* @var mixed
*/
protected $_contentResource = null;
/**
* Build an HTTP Socket using the specified configuration.
@ -175,12 +158,72 @@ class HttpSocket extends CakeSocket {
parent::__construct($this->config);
}
/**
* Set authentication settings
*
* @param string $method Authentication method (ie. Basic, Digest). If empty, disable authentication
* @param mixed $user Username for authentication. Can be an array with settings to authentication class
* @param string $pass Password for authentication
* @return void
*/
public function configAuth($method, $user = null, $pass = null) {
if (empty($method)) {
$this->_auth = array();
return;
}
if (is_array($user)) {
$this->_auth = array($method => $user);
return;
}
$this->_auth = array($method => compact('user', 'pass'));
}
/**
* Set proxy settings
*
* @param mixed $host Proxy host. Can be an array with settings to authentication class
* @param integer $port Port. Default 3128.
* @param string $method Proxy method (ie, Basic, Digest). If empty, disable proxy authentication
* @param string $user Username if your proxy need authentication
* @param string $pass Password to proxy authentication
* @return void
*/
public function configProxy($host, $port = 3128, $method = null, $user = null, $pass = null) {
if (empty($host)) {
$this->_proxy = array();
return;
}
if (is_array($host)) {
$this->_proxy = $host + array('host' => null);
return;
}
$this->_proxy = compact('host', 'port', 'method', 'user', 'pass');
}
/**
* Set the resource to receive the request content. This resource must support fwrite.
*
* @param mixed $resource Resource or false to disable the resource use
* @return void
* @throw SocketException
*/
public function setContentResource($resource) {
if ($resource === false) {
$this->_contentResource = null;
return;
}
if (!is_resource($resource)) {
throw new SocketException(__('Invalid resource.'));
}
$this->_contentResource = $resource;
}
/**
* Issue the specified request. HttpSocket::get() and HttpSocket::post() wrap this
* method and provide a more granular interface.
*
* @param mixed $request Either an URI string, or an array defining host/uri
* @return mixed false on error, request body on success
* @return mixed false on error, HttpResponse on success
*/
public function request($request = array()) {
$this->reset(false);
@ -195,10 +238,6 @@ class HttpSocket extends CakeSocket {
$request['uri'] = null;
}
$uri = $this->_parseUri($request['uri']);
$hadAuth = false;
if (is_array($uri) && array_key_exists('user', $uri)) {
$hadAuth = true;
}
if (!isset($uri['host'])) {
$host = $this->config['host'];
}
@ -208,25 +247,33 @@ class HttpSocket extends CakeSocket {
}
$request['uri'] = $this->url($request['uri']);
$request['uri'] = $this->_parseUri($request['uri'], true);
$this->request = Set::merge($this->request, $this->config['request'], $request);
$this->request = Set::merge($this->request, array_diff_key($this->config['request'], array('cookies' => true)), $request);
if (!$hadAuth && !empty($this->config['request']['auth']['user'])) {
$this->request['uri']['user'] = $this->config['request']['auth']['user'];
$this->request['uri']['pass'] = $this->config['request']['auth']['pass'];
}
$this->_configUri($this->request['uri']);
$Host = $this->request['uri']['host'];
if (!empty($this->config['request']['cookies'][$Host])) {
if (!isset($this->request['cookies'])) {
$this->request['cookies'] = array();
}
if (!isset($request['cookies'])) {
$request['cookies'] = array();
}
$this->request['cookies'] = array_merge($this->request['cookies'], $this->config['request']['cookies'][$Host], $request['cookies']);
}
if (isset($host)) {
$this->config['host'] = $host;
}
$this->_setProxy();
$this->request['proxy'] = $this->_proxy;
$cookies = null;
if (is_array($this->request['header'])) {
$this->request['header'] = $this->_parseHeader($this->request['header']);
if (!empty($this->request['cookies'])) {
$cookies = $this->buildCookies($this->request['cookies']);
}
$Host = $this->request['uri']['host'];
$schema = '';
$port = 0;
if (isset($this->request['uri']['schema'])) {
@ -245,12 +292,11 @@ class HttpSocket extends CakeSocket {
$this->request['header'] = array_merge(compact('Host'), $this->request['header']);
}
if (isset($this->request['auth']['user']) && isset($this->request['auth']['pass'])) {
$this->request['header']['Authorization'] = $this->request['auth']['method'] . " " . base64_encode($this->request['auth']['user'] . ":" . $this->request['auth']['pass']);
}
if (isset($this->request['uri']['user']) && isset($this->request['uri']['pass'])) {
$this->request['header']['Authorization'] = $this->request['auth']['method'] . " " . base64_encode($this->request['uri']['user'] . ":" . $this->request['uri']['pass']);
if (isset($this->request['uri']['user'], $this->request['uri']['pass'])) {
$this->configAuth('Basic', $this->request['uri']['user'], $this->request['uri']['pass']);
}
$this->_setAuth();
$this->request['auth'] = $this->_auth;
if (is_array($this->request['body'])) {
$this->request['body'] = $this->_httpSerialize($this->request['body']);
@ -275,9 +321,10 @@ class HttpSocket extends CakeSocket {
}
if ($this->quirksMode === false && $this->request['line'] === false) {
return $this->response = false;
return false;
}
$this->request['raw'] = '';
if ($this->request['line'] !== false) {
$this->request['raw'] = $this->request['line'];
}
@ -291,20 +338,46 @@ class HttpSocket extends CakeSocket {
$this->write($this->request['raw']);
$response = null;
$inHeader = true;
while ($data = $this->read()) {
$response .= $data;
if ($this->_contentResource) {
if ($inHeader) {
$response .= $data;
$pos = strpos($response, "\r\n\r\n");
if ($pos !== false) {
$pos += 4;
$data = substr($response, $pos);
fwrite($this->_contentResource, $data);
$response = substr($response, 0, $pos);
$inHeader = false;
}
} else {
fwrite($this->_contentResource, $data);
fflush($this->_contentResource);
}
} else {
$response .= $data;
}
}
if ($connectionType == 'close') {
if ($connectionType === 'close') {
$this->disconnect();
}
$this->response = $this->_parseResponse($response);
if (!empty($this->response['cookies'])) {
$this->config['request']['cookies'] = array_merge($this->config['request']['cookies'], $this->response['cookies']);
if (!App::import('Lib', $this->responseClass)) {
throw new SocketException(__('Class %s not found.', $this->responseClass));
}
$responseClass = $this->responseClass;
$this->response = new $responseClass($response);
if (!empty($this->response->cookies)) {
if (!isset($this->config['request']['cookies'][$Host])) {
$this->config['request']['cookies'][$Host] = array();
}
$this->config['request']['cookies'][$Host] = array_merge($this->config['request']['cookies'][$Host], $this->response->cookies);
}
return $this->response['body'];
return $this->response;
}
/**
@ -394,7 +467,7 @@ class HttpSocket extends CakeSocket {
}
/**
* Normalizes urls into a $uriTemplate. If no template is provided
* Normalizes urls into a $uriTemplate. If no template is provided
* a default one will be used. Will generate the url using the
* current config information.
*
@ -426,10 +499,10 @@ class HttpSocket extends CakeSocket {
}
if (is_string($url)) {
if ($url{0} == '/') {
$url = $this->config['request']['uri']['host'].':'.$this->config['request']['uri']['port'] . $url;
$url = $this->config['request']['uri']['host'] . ':' . $this->config['request']['uri']['port'] . $url;
}
if (!preg_match('/^.+:\/\/|\*|^\//', $url)) {
$url = $this->config['request']['uri']['scheme'].'://'.$url;
$url = $this->config['request']['uri']['scheme'] . '://' . $url;
}
} elseif (!is_array($url) && !empty($url)) {
return false;
@ -449,159 +522,57 @@ class HttpSocket extends CakeSocket {
}
/**
* Parses the given message and breaks it down in parts.
* Set authentication in request
*
* @param string $message Message to parse
* @return array Parsed message (with indexed elements such as raw, status, header, body)
* @return void
* @throws SocketException
*/
protected function _parseResponse($message) {
if (is_array($message)) {
return $message;
} elseif (!is_string($message)) {
return false;
protected function _setAuth() {
if (empty($this->_auth)) {
return;
}
static $responseTemplate;
if (empty($responseTemplate)) {
$classVars = get_class_vars(__CLASS__);
$responseTemplate = $classVars['response'];
$method = key($this->_auth);
$authClass = Inflector::camelize($method) . 'Authentication';
if (!App::import('Lib', 'http/' . $authClass)) {
throw new SocketException(__('Unknown authentication method.'));
}
$response = $responseTemplate;
if (!preg_match("/^(.+\r\n)(.*)(?<=\r\n)\r\n/Us", $message, $match)) {
return false;
if (!method_exists($authClass, 'authentication')) {
throw new SocketException(sprintf(__('The %s do not support authentication.'), $authClass));
}
list($null, $response['raw']['status-line'], $response['raw']['header']) = $match;
$response['raw']['response'] = $message;
$response['raw']['body'] = substr($message, strlen($match[0]));
if (preg_match("/(.+) ([0-9]{3}) (.+)\r\n/DU", $response['raw']['status-line'], $match)) {
$response['status']['http-version'] = $match[1];
$response['status']['code'] = (int)$match[2];
$response['status']['reason-phrase'] = $match[3];
}
$response['header'] = $this->_parseHeader($response['raw']['header']);
$transferEncoding = null;
if (isset($response['header']['Transfer-Encoding'])) {
$transferEncoding = $response['header']['Transfer-Encoding'];
}
$decoded = $this->_decodeBody($response['raw']['body'], $transferEncoding);
$response['body'] = $decoded['body'];
if (!empty($decoded['header'])) {
$response['header'] = $this->_parseHeader($this->_buildHeader($response['header']).$this->_buildHeader($decoded['header']));
}
if (!empty($response['header'])) {
$response['cookies'] = $this->parseCookies($response['header']);
}
foreach ($response['raw'] as $field => $val) {
if ($val === '') {
$response['raw'][$field] = null;
}
}
return $response;
call_user_func("$authClass::authentication", $this, &$this->_auth[$method]);
}
/**
* Generic function to decode a $body with a given $encoding. Returns either an array with the keys
* 'body' and 'header' or false on failure.
* Set the proxy configuration and authentication
*
* @param string $body A string continaing the body to decode.
* @param mixed $encoding Can be false in case no encoding is being used, or a string representing the encoding.
* @return mixed Array of response headers and body or false.
* @return void
* @throws SocketException
*/
protected function _decodeBody($body, $encoding = 'chunked') {
if (!is_string($body)) {
return false;
protected function _setProxy() {
if (empty($this->_proxy) || !isset($this->_proxy['host'], $this->_proxy['port'])) {
return;
}
if (empty($encoding)) {
return array('body' => $body, 'header' => false);
$this->config['host'] = $this->_proxy['host'];
$this->config['port'] = $this->_proxy['port'];
if (empty($this->_proxy['method']) || !isset($this->_proxy['user'], $this->_proxy['pass'])) {
return;
}
$decodeMethod = '_decode'.Inflector::camelize(str_replace('-', '_', $encoding)).'Body';
if (!is_callable(array(&$this, $decodeMethod))) {
if (!$this->quirksMode) {
trigger_error(__('HttpSocket::_decodeBody - Unknown encoding: %s. Activate quirks mode to surpress error.', h($encoding)), E_USER_WARNING);
}
return array('body' => $body, 'header' => false);
$authClass = Inflector::camelize($this->_proxy['method']) . 'Authentication';
if (!App::import('Lib', 'http/' . $authClass)) {
throw new SocketException(__('Unknown authentication method for proxy.'));
}
return $this->{$decodeMethod}($body);
}
/**
* Decodes a chunked message $body and returns either an array with the keys 'body' and 'header' or false as
* a result.
*
* @param string $body A string continaing the chunked body to decode.
* @return mixed Array of response headers and body or false.
*/
protected function _decodeChunkedBody($body) {
if (!is_string($body)) {
return false;
if (!method_exists($authClass, 'proxyAuthentication')) {
throw new SocketException(sprintf(__('The %s do not support proxy authentication.'), $authClass));
}
$decodedBody = null;
$chunkLength = null;
while ($chunkLength !== 0) {
if (!preg_match("/^([0-9a-f]+) *(?:;(.+)=(.+))?\r\n/iU", $body, $match)) {
if (!$this->quirksMode) {
trigger_error(__('HttpSocket::_decodeChunkedBody - Could not parse malformed chunk. Activate quirks mode to do this.'), E_USER_WARNING);
return false;
}
break;
}
$chunkSize = 0;
$hexLength = 0;
$chunkExtensionName = '';
$chunkExtensionValue = '';
if (isset($match[0])) {
$chunkSize = $match[0];
}
if (isset($match[1])) {
$hexLength = $match[1];
}
if (isset($match[2])) {
$chunkExtensionName = $match[2];
}
if (isset($match[3])) {
$chunkExtensionValue = $match[3];
}
$body = substr($body, strlen($chunkSize));
$chunkLength = hexdec($hexLength);
$chunk = substr($body, 0, $chunkLength);
if (!empty($chunkExtensionName)) {
/**
* @todo See if there are popular chunk extensions we should implement
*/
}
$decodedBody .= $chunk;
if ($chunkLength !== 0) {
$body = substr($body, $chunkLength+strlen("\r\n"));
}
}
$entityHeader = false;
if (!empty($body)) {
$entityHeader = $this->_parseHeader($body);
}
return array('body' => $decodedBody, 'header' => $entityHeader);
call_user_func("$authClass::proxyAuthentication", $this, &$this->_proxy);
}
/**
* Parses and sets the specified URI into current request configuration.
*
* @param mixed $uri URI, See HttpSocket::_parseUri()
* @return array Current configuration settings
* @return boolean If uri has merged in config
*/
protected function _configUri($uri = null) {
if (empty($uri)) {
@ -619,19 +590,18 @@ class HttpSocket extends CakeSocket {
}
$config = array(
'request' => array(
'uri' => array_intersect_key($uri, $this->config['request']['uri']),
'auth' => array_intersect_key($uri, $this->config['request']['auth'])
'uri' => array_intersect_key($uri, $this->config['request']['uri'])
)
);
$this->config = Set::merge($this->config, $config);
$this->config = Set::merge($this->config, array_intersect_key($this->config['request']['uri'], $this->config));
return $this->config;
return true;
}
/**
* Takes a $uri array and turns it into a fully qualified URL string
*
* @param mixed $uri Either A $uri array, or a request string. Will use $this->config if left empty.
* @param mixed $uri Either A $uri array, or a request string. Will use $this->config if left empty.
* @param string $uriTemplate The Uri template/format to use.
* @return mixed A fully qualified URL formated according to $uriTemplate, or false on failure
*/
@ -665,7 +635,7 @@ class HttpSocket extends CakeSocket {
$uriTemplate = str_replace(':%port', null, $uriTemplate);
}
foreach ($uri as $property => $value) {
$uriTemplate = str_replace('%'.$property, $value, $uriTemplate);
$uriTemplate = str_replace('%' . $property, $value, $uriTemplate);
}
if ($uriTemplate === '/*') {
@ -740,7 +710,7 @@ class HttpSocket extends CakeSocket {
* - ?key[subKey]=value
* - ?key[]=value1&key[]=value2
*
* A leading '?' mark in $query is optional and does not effect the outcome of this function.
* A leading '?' mark in $query is optional and does not effect the outcome of this function.
* For the complete capabilities of this implementation take a look at HttpSocketTest::testparseQuery()
*
* @param mixed $query A query string to parse into an array or an array to return directly "as is"
@ -803,6 +773,7 @@ class HttpSocket extends CakeSocket {
* @param array $request Needs to contain a 'uri' key. Should also contain a 'method' key, otherwise defaults to GET.
* @param string $versionToken The version token to use, defaults to HTTP/1.1
* @return string Request line
* @throws SocketException
*/
protected function _buildRequestLine($request = array(), $versionToken = 'HTTP/1.1') {
$asteriskMethods = array('OPTIONS');
@ -810,8 +781,7 @@ class HttpSocket extends CakeSocket {
if (is_string($request)) {
$isValid = preg_match("/(.+) (.+) (.+)\r\n/U", $request, $match);
if (!$this->quirksMode && (!$isValid || ($match[2] == '*' && !in_array($match[3], $asteriskMethods)))) {
trigger_error(__('HttpSocket::_buildRequestLine - Passed an invalid request line string. Activate quirks mode to do this.'), E_USER_WARNING);
return false;
throw new SocketException(__('HttpSocket::_buildRequestLine - Passed an invalid request line string. Activate quirks mode to do this.'));
}
return $request;
} elseif (!is_array($request)) {
@ -822,13 +792,16 @@ class HttpSocket extends CakeSocket {
$request['uri'] = $this->_parseUri($request['uri']);
$request = array_merge(array('method' => 'GET'), $request);
$request['uri'] = $this->_buildUri($request['uri'], '/%path?%query');
if (!empty($this->_proxy['host'])) {
$request['uri'] = $this->_buildUri($request['uri'], '%scheme://%host:%port/%path?%query');
} else {
$request['uri'] = $this->_buildUri($request['uri'], '/%path?%query');
}
if (!$this->quirksMode && $request['uri'] === '*' && !in_array($request['method'], $asteriskMethods)) {
trigger_error(__('HttpSocket::_buildRequestLine - The "*" asterisk character is only allowed for the following methods: %s. Activate quirks mode to work outside of HTTP/1.1 specs.', implode(',', $asteriskMethods)), E_USER_WARNING);
return false;
throw new SocketException(__('HttpSocket::_buildRequestLine - The "*" asterisk character is only allowed for the following methods: %s. Activate quirks mode to work outside of HTTP/1.1 specs.', implode(',', $asteriskMethods)));
}
return $request['method'].' '.$request['uri'].' '.$versionToken.$this->lineBreak;
return $request['method'] . ' ' . $request['uri'] . ' ' . $versionToken . "\r\n";
}
/**
@ -851,6 +824,7 @@ class HttpSocket extends CakeSocket {
* Builds the header.
*
* @param array $header Header to build
* @param string $mode
* @return string Header built from array
*/
protected function _buildHeader($header, $mode = 'standard') {
@ -860,6 +834,17 @@ class HttpSocket extends CakeSocket {
return false;
}
$fieldsInHeader = array();
foreach ($header as $key => $value) {
$lowKey = strtolower($key);
if (array_key_exists($lowKey, $fieldsInHeader)) {
$header[$fieldsInHeader[$lowKey]] = $value;
unset($header[$key]);
} else {
$fieldsInHeader[$lowKey] = $key;
}
}
$returnHeader = '';
foreach ($header as $field => $contents) {
if (is_array($contents) && $mode == 'standard') {
@ -869,144 +854,37 @@ class HttpSocket extends CakeSocket {
$contents = preg_replace("/\r\n(?![\t ])/", "\r\n ", $content);
$field = $this->_escapeToken($field);
$returnHeader .= $field.': '.$contents.$this->lineBreak;
$returnHeader .= $field . ': ' . $contents . "\r\n";
}
}
return $returnHeader;
}
/**
* Parses an array based header.
*
* @param array $header Header as an indexed array (field => value)
* @return array Parsed header
*/
protected function _parseHeader($header) {
if (is_array($header)) {
foreach ($header as $field => $value) {
unset($header[$field]);
$field = strtolower($field);
preg_match_all('/(?:^|(?<=-))[a-z]/U', $field, $offsets, PREG_OFFSET_CAPTURE);
foreach ($offsets[0] as $offset) {
$field = substr_replace($field, strtoupper($offset[0]), $offset[1], 1);
}
$header[$field] = $value;
}
return $header;
} elseif (!is_string($header)) {
return false;
}
preg_match_all("/(.+):(.+)(?:(?<![\t ])" . $this->lineBreak . "|\$)/Uis", $header, $matches, PREG_SET_ORDER);
$header = array();
foreach ($matches as $match) {
list(, $field, $value) = $match;
$value = trim($value);
$value = preg_replace("/[\t ]\r\n/", "\r\n", $value);
$field = $this->_unescapeToken($field);
$field = strtolower($field);
preg_match_all('/(?:^|(?<=-))[a-z]/U', $field, $offsets, PREG_OFFSET_CAPTURE);
foreach ($offsets[0] as $offset) {
$field = substr_replace($field, strtoupper($offset[0]), $offset[1], 1);
}
if (!isset($header[$field])) {
$header[$field] = $value;
} else {
$header[$field] = array_merge((array)$header[$field], (array)$value);
}
}
return $header;
}
/**
* Parses cookies in response headers.
*
* @param array $header Header array containing one ore more 'Set-Cookie' headers.
* @return mixed Either false on no cookies, or an array of cookies recieved.
* @access public
* @todo Make this 100% RFC 2965 confirm
*/
function parseCookies($header) {
if (!isset($header['Set-Cookie'])) {
return false;
}
$cookies = array();
foreach ((array)$header['Set-Cookie'] as $cookie) {
if (strpos($cookie, '";"') !== false) {
$cookie = str_replace('";"', "{__cookie_replace__}", $cookie);
$parts = str_replace("{__cookie_replace__}", '";"', explode(';', $cookie));
} else {
$parts = preg_split('/\;[ \t]*/', $cookie);
}
list($name, $value) = explode('=', array_shift($parts), 2);
$cookies[$name] = compact('value');
foreach ($parts as $part) {
if (strpos($part, '=') !== false) {
list($key, $value) = explode('=', $part);
} else {
$key = $part;
$value = true;
}
$key = strtolower($key);
if (!isset($cookies[$name][$key])) {
$cookies[$name][$key] = $value;
}
}
}
return $cookies;
}
/**
* Builds cookie headers for a request.
*
* @param array $cookies Array of cookies to send with the request.
* @return string Cookie header string to be sent with the request.
* @access public
* @todo Refactor token escape mechanism to be configurable
*/
function buildCookies($cookies) {
public function buildCookies($cookies) {
$header = array();
foreach ($cookies as $name => $cookie) {
$header[] = $name.'='.$this->_escapeToken($cookie['value'], array(';'));
$header[] = $name . '=' . $this->_escapeToken($cookie['value'], array(';'));
}
$header = $this->_buildHeader(array('Cookie' => implode('; ', $header)), 'pragmatic');
return $header;
}
/**
* Unescapes a given $token according to RFC 2616 (HTTP 1.1 specs)
*
* @param string $token Token to unescape
* @return string Unescaped token
* @access protected
* @todo Test $chars parameter
*/
function _unescapeToken($token, $chars = null) {
$regex = '/"(['.join('', $this->_tokenEscapeChars(true, $chars)).'])"/';
$token = preg_replace($regex, '\\1', $token);
return $token;
return $this->_buildHeader(array('Cookie' => implode('; ', $header)), 'pragmatic');
}
/**
* Escapes a given $token according to RFC 2616 (HTTP 1.1 specs)
*
* @param string $token Token to escape
* @param array $chars
* @return string Escaped token
* @access protected
* @todo Test $chars parameter
*/
function _escapeToken($token, $chars = null) {
$regex = '/(['.join('', $this->_tokenEscapeChars(true, $chars)).'])/';
protected function _escapeToken($token, $chars = null) {
$regex = '/([' . implode('', $this->_tokenEscapeChars(true, $chars)) . '])/';
$token = preg_replace($regex, '"\\1"', $token);
return $token;
}
@ -1015,11 +893,11 @@ class HttpSocket extends CakeSocket {
* Gets escape chars according to RFC 2616 (HTTP 1.1 specs).
*
* @param boolean $hex true to get them as HEX values, false otherwise
* @param array $chars
* @return array Escape chars
* @access protected
* @todo Test $chars parameter
*/
function _tokenEscapeChars($hex = true, $chars = null) {
protected function _tokenEscapeChars($hex = true, $chars = null) {
if (!empty($chars)) {
$escape = $chars;
} else {
@ -1035,7 +913,7 @@ class HttpSocket extends CakeSocket {
}
$regexChars = '';
foreach ($escape as $key => $char) {
$escape[$key] = '\\x'.str_pad(dechex(ord($char)), 2, '0', STR_PAD_LEFT);
$escape[$key] = '\\x' . str_pad(dechex(ord($char)), 2, '0', STR_PAD_LEFT);
}
return $escape;
}
@ -1052,7 +930,7 @@ class HttpSocket extends CakeSocket {
if (empty($initalState)) {
$initalState = get_class_vars(__CLASS__);
}
if ($full == false) {
if (!$full) {
$this->request = $initalState['request'];
$this->response = $initalState['response'];
return true;

View file

@ -102,8 +102,8 @@ class Dispatcher {
return;
}
$request = $this->parseParams($request, $additionalParams);
$controller = $this->_getController($request);
$this->request = $this->parseParams($request, $additionalParams);
$controller = $this->_getController($this->request);
if (!is_object($controller)) {
Router::setRequestInfo($request);
@ -201,7 +201,7 @@ class Dispatcher {
if (count(Router::$routes) > 0) {
$namedExpressions = Router::getNamedExpressions();
extract($namedExpressions);
include CONFIGS . 'routes.php';
$this->__loadRoutes();
}
$params = Router::parse($request->url);
@ -253,6 +253,16 @@ class Dispatcher {
return false;
}
/**
* Loads route configuration
*
* @return void
* @access protected
*/
protected function __loadRoutes() {
include CONFIGS . 'routes.php';
}
/**
* Outputs cached dispatch view cache
*
@ -315,7 +325,8 @@ class Dispatcher {
$this->_stop();
}
$controller = null;
$ext = array_pop(explode('.', $url));
$pathSegments = explode('.', $url);
$ext = array_pop($pathSegments);
$parts = explode('/', $url);
$assetFile = null;

View file

@ -343,7 +343,13 @@ class CakeRoute {
if (!empty($params['named']) && is_array($params['named'])) {
$named = array();
foreach ($params['named'] as $key => $value) {
$named[] = $key . $separator . $value;
if (is_array($value)) {
foreach ($value as $namedKey => $namedValue) {
$named[] = $key . "[$namedKey]" . $separator . $namedValue;
}
} else {
$named[] = $key . $separator . $value;
}
}
$params['pass'] = $params['pass'] . '/' . implode('/', $named);
}

View file

@ -226,7 +226,7 @@ class Router {
* shifted into the passed arguments. As well as supplying patterns for routing parameters.
* @see routes
* @return array Array of routes
* @throws Exception
* @throws RouterException
*/
public static function connect($route, $defaults = array(), $options = array()) {
foreach (self::$_prefixes as $prefix) {
@ -246,13 +246,15 @@ class Router {
$routeClass = 'CakeRoute';
if (isset($options['routeClass'])) {
$routeClass = $options['routeClass'];
if (!is_subclass_of($routeClass, 'CakeRoute')) {
throw new RouterException(__('Route classes must extend CakeRoute'));
}
unset($options['routeClass']);
if ($routeClass == 'RedirectRoute' && isset($defaults['redirect'])) {
$defaults = $defaults['redirect'];
}
}
$Route = new $routeClass($route, $defaults, $options);
if (!$Route instanceof CakeRoute) {
throw new Exception(__('Route classes must extend CakeRoute'));
}
self::$routes[] =& $Route;
self::$routes[] = new $routeClass($route, $defaults, $options);
return self::$routes;
}
@ -285,9 +287,12 @@ class Router {
* @see routes
* @return array Array of routes
*/
public static function redirect($route, $url, $options) {
public static function redirect($route, $url, $options = array()) {
App::uses('RedirectRoute', 'Routing/Route');
$options['routeClass'] = 'RedirectRoute';
if (is_string($url)) {
$url = array('redirect' => $url);
}
return self::connect($route, $url, $options);
}
@ -938,8 +943,15 @@ class Router {
}
if (!empty($named)) {
foreach ($named as $name => $value) {
$output .= '/' . $name . self::$named['separator'] . $value;
foreach ($named as $name => $value) {
if (is_array($value)) {
$flattend = Set::flatten($value, '][');
foreach ($flattend as $namedKey => $namedValue) {
$output .= '/' . $name . "[$namedKey]" . self::$named['separator'] . $namedValue;
}
} else {
$output .= '/' . $name . self::$named['separator'] . $value;
}
}
}
return $output;
@ -1203,7 +1215,22 @@ class Router {
if ($passIt) {
$pass[] = $param;
} else {
$named[$key] = $val;
if (preg_match_all('/\[([A-Za-z0-9_-]+)?\]/', $key, $matches, PREG_SET_ORDER)) {
$matches = array_reverse($matches);
$key = array_shift(explode('[', $key));
$arr = $val;
foreach ($matches as $match) {
if (empty($match[1])) {
$arr = array($arr);
} else {
$arr = array(
$match[1] => $arr
);
}
}
$val = $arr;
}
$named = array_merge_recursive($named, array($key => $val));
}
} else {
$pass[] = $param;

View file

@ -62,7 +62,7 @@ class CakeHtmlReporter extends CakeBaseReporter {
*/
public function paintTestMenu() {
$cases = $this->baseUrl() . '?show=cases';
$plugins = App::objects('plugin');
$plugins = App::objects('plugin', null, false);
sort($plugins);
include CAKE_TESTS_LIB . 'templates' . DS . 'menu.php';
}

View file

@ -26,6 +26,7 @@ PHP_CodeCoverage_Filter::getInstance()->addFileToBlacklist(__FILE__, 'DEFAULT');
App::uses('CakeTestSuite', 'TestSuite');
App::uses('CakeTestCase', 'TestSuite');
App::uses('ControllerTestCase', 'TestSuite');
App::uses('CakeFixtureManager', 'TestSuite/Fixture');
App::uses('CakeTestModel', 'TestSuite/Fixture');

View file

@ -232,7 +232,7 @@ class Debugger {
* @param array $context Context
* @return boolean true if error was handled
*/
public function showError($code, $description, $file = null, $line = null, $context = null) {
public static function showError($code, $description, $file = null, $line = null, $context = null) {
$_this = Debugger::getInstance();
if (empty($file)) {

View file

@ -88,7 +88,6 @@ class File {
* @param string $path Path to file
* @param boolean $create Create file if it does not exist (if true)
* @param integer $mode Mode to apply to the folder holding the file
* @access private
*/
function __construct($path, $create = false, $mode = 0755) {
$this->Folder = new Folder(dirname($path), $create, $mode);
@ -102,7 +101,6 @@ class File {
/**
* Closes the current file if it is opened
*
* @access private
*/
function __destruct() {
$this->close();
@ -212,7 +210,7 @@ class File {
* @param string $data Data to prepare for writing.
* @return string The with converted line endings.
*/
public function prepare($data, $forceWindows = false) {
public static function prepare($data, $forceWindows = false) {
$lineBreak = "\n";
if (DIRECTORY_SEPARATOR == '\\' || $forceWindows === true) {
$lineBreak = "\r\n";

View file

@ -240,10 +240,8 @@ class Folder {
*
* @param string $path Path to check
* @return boolean true if windows path, false otherwise
* @access public
* @static
*/
function isWindowsPath($path) {
public static function isWindowsPath($path) {
return (preg_match('/^[A-Z]:\\\\/i', $path) || substr($path, 0, 2) == '\\\\');
}
@ -252,10 +250,8 @@ class Folder {
*
* @param string $path Path to check
* @return bool true if path is absolute.
* @access public
* @static
*/
function isAbsolute($path) {
public static function isAbsolute($path) {
return !empty($path) && ($path[0] === '/' || preg_match('/^[A-Z]:\\\\/i', $path) || substr($path, 0, 2) == '\\\\');
}
@ -264,10 +260,8 @@ class Folder {
*
* @param string $path Path to check
* @return string Set of slashes ("\\" or "/")
* @access public
* @static
*/
function normalizePath($path) {
public static function normalizePath($path) {
return Folder::correctSlashFor($path);
}
@ -276,10 +270,8 @@ class Folder {
*
* @param string $path Path to check
* @return string Set of slashes ("\\" or "/")
* @access public
* @static
*/
function correctSlashFor($path) {
public static function correctSlashFor($path) {
return (Folder::isWindowsPath($path)) ? '\\' : '/';
}
@ -288,10 +280,8 @@ class Folder {
*
* @param string $path Path to check
* @return string Path with ending slash
* @access public
* @static
*/
function slashTerm($path) {
public static function slashTerm($path) {
if (Folder::isSlashTerm($path)) {
return $path;
}
@ -304,10 +294,8 @@ class Folder {
* @param string $path Path
* @param string $element Element to and at end of path
* @return string Combined path
* @access public
* @static
*/
function addPathElement($path, $element) {
public static function addPathElement($path, $element) {
return rtrim($path, DS) . DS . $element;
}
@ -755,10 +743,8 @@ class Folder {
*
* @param string $path Path to check
* @return boolean true if path ends with slash, false otherwise
* @access public
* @static
*/
function isSlashTerm($path) {
public static function isSlashTerm($path) {
$lastChar = $path[strlen($path) - 1];
return $lastChar === '/' || $lastChar === '\\';
}

View file

@ -60,25 +60,43 @@ abstract class ObjectCollection {
* ### Options
*
* - `breakOn` Set to the value or values you want the callback propagation to stop on.
* Defaults to `false`
* - `break` Set to true to enabled breaking. Defaults to `false`.
* Can either be a scalar value, or an array of values to break on. Defaults to `false`.
*
* - `break` Set to true to enabled breaking. When a trigger is broken, the last returned value
* will be returned. If used in combination with `collectReturn` the collected results will be returned.
* 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.
* objects. Defaults to false.
*
* - `modParams` Allows each object the callback gets called on to modify the parameters to the next object.
* Setting modParams to an integer value will allow you to modify the parameter with that index.
* Any non-null value will modify the parameter index indicated.
* Defaults to false.
*
*
* @param string $callback Method to fire on all the objects. Its assumed all the objects implement
* the method you are calling.
* @param array $params Array of parameters for the triggered callback.
* @param array $options Array of options.
* @return mixed true.
* @return mixed Either the last result or all results if collectReturn is on.
* @throws CakeException when modParams is used with an index that does not exist.
*/
public function trigger($callback, $params = array(), $options = array()) {
if (empty($this->_enabled)) {
return true;
}
$options = array_merge(
array('break' => false, 'breakOn' => false, 'collectReturn' => false, 'triggerDisabled' => false),
array(
'break' => false,
'breakOn' => false,
'collectReturn' => false,
'triggerDisabled' => false,
'modParams' => false
),
$options
);
$collected = array();
@ -86,19 +104,27 @@ abstract class ObjectCollection {
if ($options['triggerDisabled'] === true) {
$list = array_keys($this->_loaded);
}
if ($options['modParams'] !== false && !isset($params[$options['modParams']])) {
throw new CakeException(__('Cannot use modParams with indexes that do not exist.'));
}
foreach ($list as $name) {
$result = call_user_func_array(array(&$this->_loaded[$name], $callback), $params);
$result = call_user_func_array(array($this->_loaded[$name], $callback), $params);
if ($options['collectReturn'] === true) {
$collected[] = $result;
}
if (
$options['break'] && ($result === $options['breakOn'] ||
$options['break'] && ($result === $options['breakOn'] ||
(is_array($options['breakOn']) && in_array($result, $options['breakOn'], true)))
) {
return ($options['collectReturn'] === true) ? $collected : $result;
return $result;
} elseif ($options['modParams'] !== false && is_array($result)) {
$params[$options['modParams']] = $result;
}
}
return $options['collectReturn'] ? $collected : true;
if ($options['modParams'] !== false) {
return $params[$options['modParams']];
}
return $options['collectReturn'] ? $collected : $result;
}
/**
@ -195,6 +221,20 @@ abstract class ObjectCollection {
$this->_enabled = array_values(array_diff($this->_enabled, (array)$name));
}
/**
* Adds or overwrites an instatiated object to the collection
*
* @param string $name Name of the object
* @param Object $object The object to use
*/
public function set($name = null, $object = null) {
if (!empty($name) && !empty($object)) {
list($plugin, $name) = pluginSplit($name);
$this->_loaded[$name] = $object;
}
return $this->_loaded;
}
/**
* Normalizes an object array, creates an array that makes lazy loading
* easier

View file

@ -1019,7 +1019,7 @@ class Set {
* @param string $key
* @return array
*/
private function __flatten($results, $key = null) {
private static function __flatten($results, $key = null) {
$stack = array();
foreach ($results as $k => $r) {
$id = $k;
@ -1044,6 +1044,10 @@ class Set {
* @return array Sorted array of data
*/
public static function sort($data, $path, $dir) {
$originalKeys = array_keys($data);
if (is_numeric(implode('', $originalKeys))) {
$data = array_values($data);
}
$result = Set::__flatten(Set::extract($data, $path));
list($keys, $values) = array(Set::extract($result, '{n}.id'), Set::extract($result, '{n}.value'));
@ -1055,7 +1059,6 @@ class Set {
}
array_multisort($values, $dir, $keys, $dir);
$sorted = array();
$keys = array_unique($keys);
foreach ($keys as $k) {

View file

@ -414,7 +414,8 @@ class Validation {
if (is_array($check)) {
return self::extension(array_shift($check), $extensions);
}
$extension = strtolower(array_pop(explode('.', $check)));
$pathSegments = explode('.', $check);
$extension = strtolower(array_pop($pathSegments));
foreach ($extensions as $value) {
if ($extension == strtolower($value)) {
return true;
@ -430,7 +431,7 @@ class Validation {
* @param string $ipVersion The IP Protocol version to validate against
* @return boolean Success
*/
public function ip($check, $type = 'both') {
public static function ip($check, $type = 'both') {
$type = strtolower($type);
$flags = array();
if ($type === 'ipv4' || $type === 'both') {
@ -667,12 +668,12 @@ class Validation {
*/
public static function url($check, $strict = false) {
self::__populateIp();
$validChars = '([' . preg_quote('!"$&\'()*+,-.@_:;=~') . '\/0-9a-z]|(%[0-9a-f]{2}))';
$validChars = '([' . preg_quote('!"$&\'()*+,-.@_:;=~') . '\/0-9a-z\p{L}\p{N}]|(%[0-9a-f]{2}))';
$regex = '/^(?:(?:https?|ftps?|file|news|gopher):\/\/)' . (!empty($strict) ? '' : '?') .
'(?:' . self::$__pattern['IPv4'] . '|' . self::$__pattern['hostname'] . ')(?::[1-9][0-9]{0,3})?' .
'(?:' . self::$__pattern['IPv4'] . '|\[' . self::$__pattern['IPv6'] . '\]|' . self::$__pattern['hostname'] . ')(?::[1-9][0-9]{0,4})?' .
'(?:\/?|\/' . $validChars . '*)?' .
'(?:\?' . $validChars . '*)?' .
'(?:#' . $validChars . '*)?$/i';
'(?:#' . $validChars . '*)?$/iu';
return self::_check($check, $regex);
}
@ -700,6 +701,18 @@ class Validation {
return call_user_func_array(array($object, $method), array($check, $args));
}
/**
* Checks that a value is a valid uuid - http://tools.ietf.org/html/rfc4122
*
* @param string $check Value to check
* @return boolean Success
* @access public
*/
public static function uuid($check) {
$regex = '/^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/i';
return self::_check($check, $regex);
}
/**
* Attempts to pass unhandled Validation locales to a class starting with $classPrefix
* and ending with Validation. For example $classPrefix = 'nl', the class would be

View file

@ -73,7 +73,7 @@ class Xml {
* @param mixed $input XML string, a path to a file, an URL or an array
* @param array $options The options to use
* @return object SimpleXMLElement or DOMDocument
* @throws Exception
* @throws XmlException
*/
public static function build($input, $options = array()) {
if (!is_array($options)) {
@ -101,9 +101,9 @@ class Xml {
$dom->load($input);
return $dom;
} elseif (!is_string($input)) {
throw new Exception(__('Invalid input.'));
throw new XmlException(__('Invalid input.'));
}
throw new Exception(__('XML cannot be read.'));
throw new XmlException(__('XML cannot be read.'));
}
/**
@ -141,14 +141,15 @@ class Xml {
* @param array $input Array with data
* @param array $options The options to use
* @return object SimpleXMLElement or DOMDocument
* @throws XmlException
*/
public static function fromArray($input, $options = array()) {
if (!is_array($input) || count($input) !== 1) {
throw new Exception(__('Invalid input.'));
throw new XmlException(__('Invalid input.'));
}
$key = key($input);
if (is_integer($key)) {
throw new Exception(__('The key of input must be alphanumeric'));
throw new XmlException(__('The key of input must be alphanumeric'));
}
if (!is_array($options)) {
@ -181,7 +182,7 @@ class Xml {
* @param string $format Either 'attribute' or 'tags'. This determines where nested keys go.
* @return void
*/
protected function _fromArray(&$dom, &$node, &$data, $format) {
protected static function _fromArray(&$dom, &$node, &$data, $format) {
if (empty($data) || !is_array($data)) {
return;
}
@ -212,7 +213,7 @@ class Xml {
}
} else {
if ($key[0] === '@') {
throw new Exception(__('Invalid array'));
throw new XmlException(__('Invalid array'));
}
if (array_keys($value) === range(0, count($value) - 1)) { // List
foreach ($value as $item) {
@ -225,7 +226,7 @@ class Xml {
}
}
} else {
throw new Exception(__('Invalid array'));
throw new XmlException(__('Invalid array'));
}
}
}
@ -236,7 +237,7 @@ class Xml {
* @param array $data Array with informations to create childs
* @return void
*/
private function __createChild($data) {
private static function __createChild($data) {
extract($data);
$childNS = $childValue = null;
if (is_array($value)) {
@ -270,13 +271,14 @@ class Xml {
*
* @param object $obj SimpleXMLElement, DOMDocument or DOMNode instance
* @return array Array representation of the XML structure.
* @throws XmlException
*/
public static function toArray($obj) {
if ($obj instanceof DOMNode) {
$obj = simplexml_import_dom($obj);
}
if (!($obj instanceof SimpleXMLElement)) {
throw new Exception(__('The input is not instance of SimpleXMLElement, DOMDocument or DOMNode.'));
throw new XmlException(__('The input is not instance of SimpleXMLElement, DOMDocument or DOMNode.'));
}
$result = array();
$namespaces = array_merge(array('' => ''), $obj->getNamespaces(true));

View file

@ -403,7 +403,7 @@ class FormHelper extends AppHelper {
$fields += $locked;
$fields = Security::hash(serialize($fields) . Configure::read('Security.salt'));
$locked = str_rot13(serialize(array_keys($locked)));
$locked = implode(array_keys($locked), '|');
$out = $this->hidden('_Token.fields', array(
'value' => urlencode($fields . ':' . $locked),
@ -542,7 +542,8 @@ class FormHelper extends AppHelper {
if ($text === null) {
if (strpos($fieldName, '.') !== false) {
$text = array_pop(explode('.', $fieldName));
$fieldElements = explode('.', $fieldName);
$text = array_pop($fieldElements);
} else {
$text = $fieldName;
}
@ -1135,14 +1136,15 @@ class FormHelper extends AppHelper {
* The first argument to an input type should always be the fieldname, in `Model.field` format.
* The second argument should always be an array of attributes for the input.
*
* @param string $method Method name / input type to make.
* @param string $method Method name / input type to make.
* @param array $params Parameters for the method call
* @return string Formatted input method.
* @throws CakeException When there are no params for the method call.
*/
public function __call($method, $params) {
$options = array();
if (empty($params)) {
throw new Exception(__('Missing field name for FormHelper::%s', $method));
throw new CakeException(__('Missing field name for FormHelper::%s', $method));
}
if (isset($params[1])) {
$options = $params[1];

View file

@ -838,7 +838,7 @@ class HtmlHelper extends AppHelper {
/**
* Internal function to build a nested list (UL/OL) out of an associative array.
*
* @param array $list Set of elements to list
* @param array $items Set of elements to list
* @param array $options Additional HTML attributes of the list (ol/ul) tag
* @param array $itemOptions Additional HTML attributes of the list item (LI) tag
* @param string $tag Type of list tag to use (ol/ul)

View file

@ -158,20 +158,6 @@ class JsHelper extends AppHelper {
trigger_error(__('JsHelper:: Missing Method %s is undefined', $method), E_USER_WARNING);
}
/**
* Workaround for Object::Object() existing. Since Object::object exists, it does not
* fall into call__ and is not passed onto the engine helper. See JsBaseEngineHelper::object() for
* more information on this method.
*
* @param mixed $data Data to convert into JSON
* @param array $options Options to use for encoding JSON. See JsBaseEngineHelper::object() for more details.
* @return string encoded JSON
* @deprecated Remove when support for PHP4 and Object::object are removed.
*/
public function object($data = array(), $options = array()) {
return $this->{$this->__engineName}->object($data, $options);
}
/**
* Overwrite inherited Helper::value()
* See JsBaseEngineHelper::value() for more information on this method.
@ -206,7 +192,6 @@ class JsHelper extends AppHelper {
*/
public function writeBuffer($options = array()) {
$domReady = $this->request->is('ajax');
// $domReady = isset($this->params['isAjax']) ? !$this->params['isAjax'] : true;
$defaults = array(
'onDomReady' => $domReady, 'inline' => true,
'cache' => false, 'clear' => true, 'safe' => true

View file

@ -89,7 +89,7 @@ class PaginatorHelper extends AppHelper {
*
* @param View $View the view object the helper is attached to.
* @param array $settings Array of settings.
* @return void
* @throws CakeException When the AjaxProvider helper does not implement a link method.
*/
function __construct(View $View, $settings = array()) {
parent::__construct($View, $settings);
@ -99,7 +99,7 @@ class PaginatorHelper extends AppHelper {
App::uses($ajaxProvider . 'Helper', 'View/Helper');
$classname = $ajaxProvider . 'Helper';
if (!method_exists($classname, 'link')) {
throw new Exception(sprintf(
throw new CakeException(sprintf(
__('%s does not implement a link() method, it is incompatible with PaginatorHelper'), $classname
));
}

View file

@ -32,19 +32,6 @@ App::uses('CakeSession', 'Model/Datasource');
*/
class SessionHelper extends AppHelper {
/**
* Constructor. Starts the session if it has not already been started
*
* @param View $view View instance for this helper
* @param array $settings Settings for the helper.
* @return void
*/
public function __construct(View $view, $settings = array()) {
parent::__construct($view, $settings);
if (!CakeSession::started()) {
CakeSession::start();
}
}
/**
* Used to read a session values set in a controller for a key or return values for all keys.
*

View file

@ -50,8 +50,8 @@ class ScaffoldView extends ThemeView {
}
}
if ($name === 'add') {
$name = 'edit';
if ($name === 'add' || $name == 'edit') {
$name = 'form';
}
$scaffoldAction = 'scaffold.' . $name;

View file

@ -385,6 +385,7 @@ class View extends Object {
* @param string $layout Layout to use
* @param string $file Custom filename for view
* @return string Rendered Element
* @throws CakeException if there is an error in the view.
*/
public function render($action = null, $layout = null, $file = null) {
if ($this->hasRendered) {
@ -409,7 +410,7 @@ class View extends Object {
$layout = $this->layout;
}
if ($this->output === false) {
throw new RuntimeException(__("Error in view %s, got no content.", $viewFileName));
throw new CakeException(__("Error in view %s, got no content.", $viewFileName));
}
if ($layout && $this->autoLayout) {
$this->output = $this->renderLayout($this->output, $layout);
@ -428,6 +429,7 @@ class View extends Object {
*
* @param string $content_for_layout Content to render in a view, wrapped by the surrounding layout.
* @return mixed Rendered output, or false on error
* @throws CakeException if there is an error in the view.
*/
public function renderLayout($content_for_layout, $layout = null) {
$layoutFileName = $this->_getLayoutFileName($layout);
@ -451,7 +453,7 @@ class View extends Object {
$this->output = $this->_render($layoutFileName);
if ($this->output === false) {
throw new RuntimeException(__("Error in layout %s, got no content.", $layoutFileName));
throw new CakeException(__("Error in layout %s, got no content.", $layoutFileName));
}
$this->Helpers->trigger('afterLayout', array($layoutFileName));

View file

@ -33,33 +33,37 @@ foreach (${$pluralVar} as ${$singularVar}):
if ($i++ % 2 == 0) {
$class = ' class="altrow"';
}
echo "\n";
echo "\t<tr{$class}>\n";
echo "<tr{$class}>";
foreach ($scaffoldFields as $_field) {
$isKey = false;
if (!empty($associations['belongsTo'])) {
foreach ($associations['belongsTo'] as $_alias => $_details) {
if ($_field === $_details['foreignKey']) {
$isKey = true;
echo "\t\t<td>\n\t\t\t" . $this->Html->link(${$singularVar}[$_alias][$_details['displayField']], array('controller' => $_details['controller'], 'action' => 'view', ${$singularVar}[$_alias][$_details['primaryKey']])) . "\n\t\t</td>\n";
echo "<td>" . $this->Html->link(${$singularVar}[$_alias][$_details['displayField']], array('controller' => $_details['controller'], 'action' => 'view', ${$singularVar}[$_alias][$_details['primaryKey']])) . "</td>";
break;
}
}
}
if ($isKey !== true) {
echo "\t\t<td>" . h(${$singularVar}[$modelClass][$_field]) . "</td>\n";
echo "<td>" . h(${$singularVar}[$modelClass][$_field]) . "</td>";
}
}
echo "\t\t<td class=\"actions\">\n";
echo "\t\t\t" . $this->Html->link(__('View'), array('action' => 'view', ${$singularVar}[$modelClass][$primaryKey])) . "\n";
echo "\t\t\t" . $this->Html->link(__('Edit'), array('action' => 'edit', ${$singularVar}[$modelClass][$primaryKey])) . "\n";
echo "\t\t\t" . $this->Html->link(__('Delete'), array('action' => 'delete', ${$singularVar}[$modelClass][$primaryKey]), null, __('Are you sure you want to delete').' #' . ${$singularVar}[$modelClass][$primaryKey]) . "\n";
echo "\t\t</td>\n";
echo "\t</tr>\n";
echo '<td class="actions">';
echo $this->Html->link(__('View'), array('action' => 'view', ${$singularVar}[$modelClass][$primaryKey]));
echo $this->Html->link(__('Edit'), array('action' => 'edit', ${$singularVar}[$modelClass][$primaryKey]));
echo $this->Form->postLink(
__('Delete'),
array('action' => 'delete', ${$singularVar}[$modelClass][$primaryKey]),
null,
__('Are you sure you want to delete').' #' . ${$singularVar}[$modelClass][$primaryKey]
);
echo '</td>';
echo '</tr>';
endforeach;
echo "\n";
?>
</table>
<p><?php
@ -68,9 +72,9 @@ echo "\n";
));
?></p>
<div class="paging">
<?php echo "\t" . $this->Paginator->prev('<< ' . __('previous'), array(), null, array('class' => 'disabled')) . "\n";?>
| <?php echo $this->Paginator->numbers() . "\n"?>
<?php echo "\t ". $this->Paginator->next(__('next') .' >>', array(), null, array('class' => 'disabled')) . "\n";?>
<?php echo $this->Paginator->prev('<< ' . __('previous'), array(), null, array('class' => 'disabled')); ?>
| <?php echo $this->Paginator->numbers(); ?>
<?php echo $this->Paginator->next(__('next') .' >>', array(), null, array('class' => 'disabled')); ?>
</div>
</div>
<div class="actions">
@ -82,8 +86,8 @@ echo "\n";
foreach ($associations as $_type => $_data) {
foreach ($_data as $_alias => $_details) {
if ($_details['controller'] != $this->name && !in_array($_details['controller'], $done)) {
echo "\t\t<li>" . $this->Html->link(__('List %s', Inflector::humanize($_details['controller'])), array('controller' => $_details['controller'], 'action' => 'index')) . "</li>\n";
echo "\t\t<li>" . $this->Html->link(__('New %s', Inflector::humanize(Inflector::underscore($_alias))), array('controller' => $_details['controller'], 'action' => 'add')) . "</li>\n";
echo "<li>" . $this->Html->link(__('List %s', Inflector::humanize($_details['controller'])), array('controller' => $_details['controller'], 'action' => 'index')) . "</li>";
echo "<li>" . $this->Html->link(__('New %s', Inflector::humanize(Inflector::underscore($_alias))), array('controller' => $_details['controller'], 'action' => 'add')) . "</li>";
$done[] = $_details['controller'];
}
}

View file

@ -116,10 +116,9 @@ TEXT;
$template = $html;
if (php_sapi_name() == 'cli') {
$template = $text;
} else {
if ($showHtml === null) {
$showHtml = true;
}
}
if ($showHtml === null) {
$showHtml = true;
}
$var = print_r($var, true);
if ($showHtml) {

View file

@ -230,7 +230,7 @@ class ConsoleOptionParserTest extends CakeTestCase {
/**
* test parsing options that do not exist.
*
* @expectedException InvalidArgumentException
* @expectedException ConsoleException
*/
function testOptionThatDoesNotExist() {
$parser = new ConsoleOptionParser('test', false);
@ -242,7 +242,7 @@ class ConsoleOptionParserTest extends CakeTestCase {
/**
* test that options with choices enforce them.
*
* @expectedException InvalidArgumentException
* @expectedException ConsoleException
* @return void
*/
function testOptionWithChoices() {
@ -297,7 +297,7 @@ class ConsoleOptionParserTest extends CakeTestCase {
/**
* test parsing arguments.
*
* @expectedException InvalidArgumentException
* @expectedException ConsoleException
* @return void
*/
function testParseArgumentTooMany() {
@ -315,7 +315,7 @@ class ConsoleOptionParserTest extends CakeTestCase {
/**
* test that when there are not enough arguments an exception is raised
*
* @expectedException RuntimeException
* @expectedException ConsoleException
* @return void
*/
function testPositionalArgNotEnough() {
@ -329,7 +329,7 @@ class ConsoleOptionParserTest extends CakeTestCase {
/**
* test that arguments with choices enforce them.
*
* @expectedException InvalidArgumentException
* @expectedException ConsoleException
* @return void
*/
function testPositionalArgWithChoices() {

View file

@ -118,25 +118,4 @@ class TaskCollectionTest extends CakeTestCase {
$this->assertEquals(array('Extract'), $result, 'loaded tasks is wrong');
}
/**
* test normalizeObjectArray
*
* @return void
*/
function testnormalizeObjectArray() {
$tasks = array(
'Html',
'Foo.Bar' => array('one', 'two'),
'Something',
'Banana.Apple' => array('foo' => 'bar')
);
$result = TaskCollection::normalizeObjectArray($tasks);
$expected = array(
'Html' => array('class' => 'Html', 'settings' => array()),
'Bar' => array('class' => 'Foo.Bar', 'settings' => array('one', 'two')),
'Something' => array('class' => 'Something', 'settings' => array()),
'Apple' => array('class' => 'Banana.Apple', 'settings' => array('foo' => 'bar')),
);
$this->assertEquals($expected, $result);
}
}

View file

@ -94,12 +94,11 @@ class BakeShellTest extends CakeTestCase {
$this->Shell->Controller->expects($this->once())->method('bake')->will($this->returnValue(true));
$this->Shell->View->expects($this->once())->method('execute');
$this->Shell->expects($this->at(1))->method('out')->with('Bake All');
$this->Shell->expects($this->at(3))->method('out')->with('User Model was baked.');
$this->Shell->expects($this->once())->method('_stop');
$this->Shell->expects($this->at(0))->method('out')->with('Bake All');
$this->Shell->expects($this->at(5))->method('out')->with('<success>Bake All complete</success>');
$this->Shell->expects($this->at(7))->method('out')->with('User Views were baked.');
$this->Shell->expects($this->at(8))->method('out')->with('Bake All complete');
$this->Shell->connection = '';
$this->Shell->params = array();
$this->Shell->args = array('User');
$this->Shell->all();

View file

@ -334,7 +334,7 @@ class ControllerTaskTest extends CakeTestCase {
$this->assertContains("\$this->set('bakeArticles', \$this->paginate());", $result);
$this->assertContains('function view($id = null)', $result);
$this->assertContains("\$this->Session->setFlash(__('Invalid bake article'));", $result);
$this->assertContains("throw new NotFoundException(__('Invalid bake article'));", $result);
$this->assertContains("\$this->set('bakeArticle', \$this->BakeArticle->read(null, \$id)", $result);
$this->assertContains('function add()', $result);
@ -346,7 +346,7 @@ class ControllerTaskTest extends CakeTestCase {
$this->assertContains("\$this->Session->setFlash(__('The bake article could not be saved. Please, try again.'));", $result);
$this->assertContains('function delete($id = null)', $result);
$this->assertContains('if ($this->BakeArticle->delete($id))', $result);
$this->assertContains('if ($this->BakeArticle->delete())', $result);
$this->assertContains("\$this->Session->setFlash(__('Bake article deleted'));", $result);
$result = $this->Task->bakeActions('BakeArticles', 'admin_', true);
@ -376,7 +376,7 @@ class ControllerTaskTest extends CakeTestCase {
$this->assertContains("\$this->set('bakeArticles', \$this->paginate());", $result);
$this->assertContains('function view($id = null)', $result);
$this->assertContains("\$this->flash(__('Invalid bake article'), array('action' => 'index'))", $result);
$this->assertContains("throw new NotFoundException(__('Invalid bake article'));", $result);
$this->assertContains("\$this->set('bakeArticle', \$this->BakeArticle->read(null, \$id)", $result);
$this->assertContains('function add()', $result);
@ -390,7 +390,7 @@ class ControllerTaskTest extends CakeTestCase {
$this->assertContains("\$this->set(compact('bakeTags'))", $result);
$this->assertContains('function delete($id = null)', $result);
$this->assertContains('if ($this->BakeArticle->delete($id))', $result);
$this->assertContains('if ($this->BakeArticle->delete())', $result);
$this->assertContains("\$this->flash(__('Bake article deleted'), array('action' => 'index'))", $result);
}

View file

@ -39,7 +39,7 @@ class AllBehaviorsTest extends PHPUnit_Framework_TestSuite {
$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');
$suite->addTestFile($path . 'containable.test.php');
$suite->addTestFile($path . 'translate.test.php');
$suite->addTestFile($path . 'tree.test.php');
return $suite;

View file

@ -49,6 +49,7 @@ class AllLibsTest extends PHPUnit_Framework_TestSuite {
$suite->addTestFile(CORE_TEST_CASES . DS . 'libs' . DS . 'set.test.php');
$suite->addTestFile(CORE_TEST_CASES . DS . 'libs' . DS . 'string.test.php');
$suite->addTestFile(CORE_TEST_CASES . DS . 'libs' . DS . 'validation.test.php');
$suite->addTestFile(CORE_TEST_CASES . DS . 'libs' . DS . 'object_collection.test.php');
return $suite;
}
}

View file

@ -34,10 +34,12 @@ class AllSocketTest extends PHPUnit_Framework_TestSuite {
* @return void
*/
public static function suite() {
$suite = new PHPUnit_Framework_TestSuite('All Socket related class tests');
$suite = new CakeTestSuite('All Socket related class tests');
$suite->addTestFile(CORE_TEST_CASES . DS . 'libs' . DS . 'cake_socket.test.php');
$suite->addTestFile(CORE_TEST_CASES . DS . 'libs' . DS . 'http_socket.test.php');
$suite->addTestFile(CORE_TEST_CASES . DS . 'libs' . DS . 'http_response.test.php');
$suite->addTestDirectory(CORE_TEST_CASES . DS . 'libs' . DS . 'http');
return $suite;
}
}

View file

@ -40,6 +40,7 @@ class AllTestSuiteTest extends PHPUnit_Framework_TestSuite {
$suite->addTestFile(CORE_TEST_CASES . DS . 'libs' . DS . 'cake_test_case.test.php');
$suite->addTestFile(CORE_TEST_CASES . DS . 'libs' . DS . 'cake_test_fixture.test.php');
$suite->addTestFile(CORE_TEST_CASES . DS . 'libs' . DS . 'html_coverage_report.test.php');
$suite->addTestFile(CORE_TEST_CASES . DS . 'libs' . DS . 'controller_test_case.test.php');
return $suite;
}
}

View file

@ -71,7 +71,7 @@ class CakeLogTest extends CakeTestCase {
/**
* test all the errors from failed logger imports
*
* @expectedException Exception
* @expectedException CakeLogException
* @return void
*/
function testImportingLoggerFailure() {
@ -81,7 +81,7 @@ class CakeLogTest extends CakeTestCase {
/**
* test that loggers have to implement the correct interface.
*
* @expectedException Exception
* @expectedException CakeLogException
* @return void
*/
function testNotImplementingInterface() {

View file

@ -613,7 +613,7 @@ class CakeRequestTestCase extends CakeTestCase {
/**
* test __call expcetions
*
* @expectedException Exception
* @expectedException CakeException
* @return void
*/
function test__callExceptionOnUnknownMethod() {

View file

@ -55,7 +55,7 @@ class CakeResponseTestCase extends CakeTestCase {
/**
* Tests the statusCode method
*
* @expectedException OutOfRangeException
* @expectedException CakeException
*/
public function testStatusCode() {
$response = new CakeResponse();

View file

@ -87,7 +87,6 @@ class CakeSessionTest extends CakeTestCase {
'ini' => array(),
));
TestCakeSession::init();
TestCakeSession::$watchKeys = array();
}
/**
@ -135,10 +134,10 @@ class CakeSessionTest extends CakeTestCase {
*/
function testSessionPath() {
TestCakeSession::init('/index.php');
$this->assertEqual('/', TestCakeSession::$path);
$this->assertEquals(TestCakeSession::$path, '/');
TestCakeSession::init('/sub_dir/index.php');
$this->assertEqual('/sub_dir/', TestCakeSession::$path);
$this->assertEquals(TestCakeSession::$path, '/sub_dir/');
}
/**
@ -149,7 +148,7 @@ class CakeSessionTest extends CakeTestCase {
*/
function testCakeSessionPathEmpty() {
TestCakeSession::init('');
$this->assertEqual('/', TestCakeSession::$path, 'Session path is empty, with "" as $base needs to be / %s');
$this->assertEquals(TestCakeSession::$path, '/', 'Session path is empty, with "" as $base needs to be /');
}
/**
@ -160,7 +159,7 @@ class CakeSessionTest extends CakeTestCase {
*/
function testCakeSessionPathContainsQuestion() {
TestCakeSession::init('/index.php?');
$this->assertEqual('/', TestCakeSession::$path);
$this->assertEquals(TestCakeSession::$path, '/');
}
/**
@ -172,7 +171,7 @@ class CakeSessionTest extends CakeTestCase {
function testSetHost() {
TestCakeSession::init();
TestCakeSession::setHost('cakephp.org');
$this->assertEqual('cakephp.org', TestCakeSession::$host);
$this->assertEquals(TestCakeSession::$host, 'cakephp.org');
}
/**
@ -184,7 +183,7 @@ class CakeSessionTest extends CakeTestCase {
function testSetHostWithPort() {
TestCakeSession::init();
TestCakeSession::setHost('cakephp.org:443');
$this->assertEqual('cakephp.org', TestCakeSession::$host);
$this->assertEquals(TestCakeSession::$host, 'cakephp.org');
}
/**
@ -237,14 +236,14 @@ class CakeSessionTest extends CakeTestCase {
function testSimpleRead() {
TestCakeSession::write('testing', '1,2,3');
$result = TestCakeSession::read('testing');
$this->assertEqual($result, '1,2,3');
$this->assertEquals('1,2,3', $result);
TestCakeSession::write('testing', array('1' => 'one', '2' => 'two','3' => 'three'));
$result = TestCakeSession::read('testing.1');
$this->assertEqual($result, 'one');
$this->assertEquals('one', $result);
$result = TestCakeSession::read('testing');
$this->assertEqual($result, array('1' => 'one', '2' => 'two', '3' => 'three'));
$this->assertEquals(array('1' => 'one', '2' => 'two', '3' => 'three'), $result);
$result = TestCakeSession::read();
$this->assertTrue(isset($result['testing']));
@ -253,7 +252,7 @@ class CakeSessionTest extends CakeTestCase {
TestCakeSession::write('This.is.a.deep.array.my.friend', 'value');
$result = TestCakeSession::read('This.is.a.deep.array.my.friend');
$this->assertEqual('value', $result);
$this->assertEquals($result, 'value');
}
/**
@ -304,13 +303,15 @@ class CakeSessionTest extends CakeTestCase {
* @return void
*/
function testId() {
$expected = session_id();
TestCakeSession::destroy();
$result = TestCakeSession::id();
$this->assertEqual($result, $expected);
$expected = session_id();
$this->assertEquals($expected, $result);
TestCakeSession::id('MySessionId');
$result = TestCakeSession::id();
$this->assertEqual($result, 'MySessionId');
$this->assertEquals('MySessionId', $result);
}
/**
@ -320,10 +321,9 @@ class CakeSessionTest extends CakeTestCase {
* @return void
*/
function testStarted() {
$this->assertTrue(TestCakeSession::started());
unset($_SESSION);
$_SESSION = null;
$this->assertFalse(TestCakeSession::started());
$this->assertTrue(TestCakeSession::start());
$this->assertTrue(TestCakeSession::started());
@ -338,11 +338,11 @@ class CakeSessionTest extends CakeTestCase {
function testError() {
TestCakeSession::read('Does.not.exist');
$result = TestCakeSession::error();
$this->assertEqual($result, "Does.not.exist doesn't exist");
$this->assertEquals("Does.not.exist doesn't exist", $result);
TestCakeSession::delete('Failing.delete');
$result = TestCakeSession::error();
$this->assertEqual($result, "Failing.delete doesn't exist");
$this->assertEquals("Failing.delete doesn't exist", $result);
}
/**
@ -363,47 +363,6 @@ class CakeSessionTest extends CakeTestCase {
$this->assertFalse(TestCakeSession::check('Clearing'));
}
/**
* testWatchVar method
*
* @expectedException Exception
* @access public
* @return void
*/
function testWatchVarWrite() {
$this->assertFalse(TestCakeSession::watch(null));
TestCakeSession::write('Watching', "I'm watching you");
TestCakeSession::watch('Watching');
TestCakeSession::write('Watching', 'They found us!');
}
/**
* undocumented function
*
* @expectedException Exception
* @return void
*/
function testWatchVarDelete() {
TestCakeSession::watch('Watching');
TestCakeSession::delete('Watching');
$this->assertFalse(TestCakeSession::watch('Invalid.key'));
}
/**
* testIgnore method
*
* @access public
* @return void
*/
function testIgnore() {
TestCakeSession::write('Watching', "I'm watching you");
TestCakeSession::watch('Watching');
TestCakeSession::ignore('Watching');
$this->assertTrue(TestCakeSession::write('Watching', 'They found us!'));
}
/**
* testDestroy method
*
@ -447,7 +406,7 @@ class CakeSessionTest extends CakeTestCase {
*/
function testCheckKeyWithSpaces() {
$this->assertTrue(TestCakeSession::write('Session Test', "test"));
$this->assertEqual(TestCakeSession::check('Session Test'), 'test');
$this->assertEquals('test', TestCakeSession::check('Session Test'));
TestCakeSession::delete('Session Test');
$this->assertTrue(TestCakeSession::write('Session Test.Test Case', "test"));
@ -475,7 +434,7 @@ class CakeSessionTest extends CakeTestCase {
$this->assertTrue($result);
$result = TestCakeSession::read($key);
$this->assertEqual($result, 'haxored');
$this->assertEquals('haxored', $result);
}
/**
@ -486,17 +445,17 @@ class CakeSessionTest extends CakeTestCase {
*/
function testReadingSavedEmpty() {
TestCakeSession::write('SessionTestCase', 0);
$this->assertEqual(TestCakeSession::read('SessionTestCase'), 0);
$this->assertEquals(0, TestCakeSession::read('SessionTestCase'));
TestCakeSession::write('SessionTestCase', '0');
$this->assertEqual(TestCakeSession::read('SessionTestCase'), '0');
$this->assertEquals('0', TestCakeSession::read('SessionTestCase'));
$this->assertFalse(TestCakeSession::read('SessionTestCase') === 0);
TestCakeSession::write('SessionTestCase', false);
$this->assertFalse(TestCakeSession::read('SessionTestCase'));
TestCakeSession::write('SessionTestCase', null);
$this->assertEqual(TestCakeSession::read('SessionTestCase'), null);
$this->assertEquals(null, TestCakeSession::read('SessionTestCase'));
}
/**
@ -540,24 +499,24 @@ class CakeSessionTest extends CakeTestCase {
TestCakeSession::start();
TestCakeSession::write('SessionTestCase', 0);
$this->assertEqual(TestCakeSession::read('SessionTestCase'), 0);
$this->assertEquals(0, TestCakeSession::read('SessionTestCase'));
TestCakeSession::write('SessionTestCase', '0');
$this->assertEqual(TestCakeSession::read('SessionTestCase'), '0');
$this->assertEquals('0', TestCakeSession::read('SessionTestCase'));
$this->assertFalse(TestCakeSession::read('SessionTestCase') === 0);
TestCakeSession::write('SessionTestCase', false);
$this->assertFalse(TestCakeSession::read('SessionTestCase'));
TestCakeSession::write('SessionTestCase', null);
$this->assertEqual(TestCakeSession::read('SessionTestCase'), null);
$this->assertEquals(null, TestCakeSession::read('SessionTestCase'));
TestCakeSession::write('SessionTestCase', 'This is a Test');
$this->assertEqual(TestCakeSession::read('SessionTestCase'), 'This is a Test');
$this->assertEquals('This is a Test', TestCakeSession::read('SessionTestCase'));
TestCakeSession::write('SessionTestCase', 'This is a Test');
TestCakeSession::write('SessionTestCase', 'This was updated');
$this->assertEqual(TestCakeSession::read('SessionTestCase'), 'This was updated');
$this->assertEquals('This was updated', TestCakeSession::read('SessionTestCase'));
TestCakeSession::destroy();
$this->assertNull(TestCakeSession::read('SessionTestCase'));
@ -622,24 +581,24 @@ class CakeSessionTest extends CakeTestCase {
TestCakeSession::destroy();
TestCakeSession::write('SessionTestCase', 0);
$this->assertEqual(TestCakeSession::read('SessionTestCase'), 0);
$this->assertEquals(0, TestCakeSession::read('SessionTestCase'));
TestCakeSession::write('SessionTestCase', '0');
$this->assertEqual(TestCakeSession::read('SessionTestCase'), '0');
$this->assertEquals('0', TestCakeSession::read('SessionTestCase'));
$this->assertFalse(TestCakeSession::read('SessionTestCase') === 0);
TestCakeSession::write('SessionTestCase', false);
$this->assertFalse(TestCakeSession::read('SessionTestCase'));
TestCakeSession::write('SessionTestCase', null);
$this->assertEqual(TestCakeSession::read('SessionTestCase'), null);
$this->assertEquals(null, TestCakeSession::read('SessionTestCase'));
TestCakeSession::write('SessionTestCase', 'This is a Test');
$this->assertEqual(TestCakeSession::read('SessionTestCase'), 'This is a Test');
$this->assertEquals('This is a Test', TestCakeSession::read('SessionTestCase'));
TestCakeSession::write('SessionTestCase', 'This is a Test');
TestCakeSession::write('SessionTestCase', 'This was updated');
$this->assertEqual(TestCakeSession::read('SessionTestCase'), 'This was updated');
$this->assertEquals('This was updated', TestCakeSession::read('SessionTestCase'));
TestCakeSession::destroy();
$this->assertNull(TestCakeSession::read('SessionTestCase'));
@ -685,23 +644,23 @@ class CakeSessionTest extends CakeTestCase {
TestCakeSession::start();
TestCakeSession::write('SessionTestCase', 0);
$this->assertEqual(TestCakeSession::read('SessionTestCase'), 0);
$this->assertEquals(0, TestCakeSession::read('SessionTestCase'));
TestCakeSession::write('SessionTestCase', '0');
$this->assertEqual(TestCakeSession::read('SessionTestCase'), '0');
$this->assertEquals('0', TestCakeSession::read('SessionTestCase'));
$this->assertFalse(TestCakeSession::read('SessionTestCase') === 0);
TestCakeSession::write('SessionTestCase', false);
$this->assertFalse(TestCakeSession::read('SessionTestCase'));
TestCakeSession::write('SessionTestCase', null);
$this->assertEqual(TestCakeSession::read('SessionTestCase'), null);
$this->assertEquals(null, TestCakeSession::read('SessionTestCase'));
TestCakeSession::write('SessionTestCase', 'This is a Test');
$this->assertEqual(TestCakeSession::read('SessionTestCase'), 'This is a Test');
$this->assertEquals('This is a Test', TestCakeSession::read('SessionTestCase'));
TestCakeSession::write('SessionTestCase', 'Some additional data');
$this->assertEqual(TestCakeSession::read('SessionTestCase'), 'Some additional data');
$this->assertEquals('Some additional data', TestCakeSession::read('SessionTestCase'));
TestCakeSession::destroy();
$this->assertNull(TestCakeSession::read('SessionTestCase'));
@ -727,21 +686,21 @@ class CakeSessionTest extends CakeTestCase {
TestCakeSession::destroy();
TestCakeSession::write('Test', 'some value');
$this->assertEqual(CakeSession::$sessionTime, time() + $timeoutSeconds);
$this->assertEqual($_SESSION['Config']['countdown'], 10);
$this->assertEqual($_SESSION['Config']['time'], CakeSession::$sessionTime);
$this->assertEqual(CakeSession::$time, time());
$this->assertEqual($_SESSION['Config']['time'], time() + $timeoutSeconds);
$this->assertEquals(time() + $timeoutSeconds, CakeSession::$sessionTime);
$this->assertEquals(10, $_SESSION['Config']['countdown']);
$this->assertEquals(CakeSession::$sessionTime, $_SESSION['Config']['time']);
$this->assertEquals(time(), CakeSession::$time);
$this->assertEquals(time() + $timeoutSeconds, $_SESSION['Config']['time']);
Configure::write('Session.harden', true);
TestCakeSession::destroy();
TestCakeSession::write('Test', 'some value');
$this->assertEqual(CakeSession::$sessionTime, time() + $timeoutSeconds);
$this->assertEqual($_SESSION['Config']['countdown'], 10);
$this->assertEqual($_SESSION['Config']['time'], CakeSession::$sessionTime);
$this->assertEqual(CakeSession::$time, time());
$this->assertEqual($_SESSION['Config']['time'], CakeSession::$time + $timeoutSeconds);
$this->assertEquals(time() + $timeoutSeconds, CakeSession::$sessionTime);
$this->assertEquals(10, $_SESSION['Config']['countdown']);
$this->assertEquals(CakeSession::$sessionTime, $_SESSION['Config']['time']);
$this->assertEquals(time(), CakeSession::$time);
$this->assertEquals(CakeSession::$time + $timeoutSeconds, $_SESSION['Config']['time']);
}
}

View file

@ -102,6 +102,30 @@ class CakeSocketTest extends CakeTestCase {
$this->assertTrue($this->Socket->connected);
}
/**
* data provider function for testInvalidConnection
*
* @return array
*/
public static function invalidConnections() {
return array(
array(array('host' => 'invalid.host')),
array(array('host' => '127.0.0.1', 'port' => '70000'))
);
}
/**
* testInvalidConnection method
*
* @dataProvider invalidConnections
* @expectedException SocketException
* return void
*/
public function testInvalidConnection($data) {
$this->Socket->config = array_merge($this->Socket->config, $data);
$this->Socket->connect();
}
/**
* testSocketHost method
*

View file

@ -44,7 +44,7 @@ class PhpReaderTest extends CakeTestCase {
/**
* Test an exception is thrown by reading files that don't exist.
*
* @expectedException RuntimeException
* @expectedException ConfigureException
* @return void
*/
function testReadWithNonExistantFile() {
@ -66,7 +66,7 @@ class PhpReaderTest extends CakeTestCase {
/**
* test reading keys with ../ doesn't work
*
* @expectedException InvalidArgumentException
* @expectedException ConfigureException
* @return void
*/
function testReadWithDots() {

View file

@ -120,162 +120,6 @@ class ComponentCollectionTest extends CakeTestCase {
$this->assertEquals(array('Security'), $result, 'enabled components is wrong');
}
/**
* creates mock classes for testing
*
* @return void
*/
protected function _makeMockClasses() {
if (!class_exists('TriggerMockCookieComponent')) {
$this->getMock('CookieComponent', array(), array(), 'TriggerMockCookieComponent', false);
$this->getMock('SecurityComponent', array(), array(), 'TriggerMockSecurityComponent', false);
}
}
/**
* test triggering callbacks.
*
* @return void
*/
function testTrigger() {
$controller = null;
$this->_makeMockClasses();
$this->Components->load('TriggerMockCookie');
$this->Components->load('TriggerMockSecurity');
$this->Components->TriggerMockCookie->expects($this->once())->method('startup')
->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.
*
* @return void
*/
function testTriggerWithDisabledComponents() {
$controller = null;
$this->_makeMockClasses();
$this->Components->load('TriggerMockCookie');
$this->Components->load('TriggerMockSecurity');
$this->Components->TriggerMockCookie->expects($this->once())->method('startup')
->with($controller);
$this->Components->TriggerMockSecurity->expects($this->never())->method('startup');
$this->mockObjects[] = $this->Components->TriggerMockCookie;
$this->mockObjects[] = $this->Components->TriggerMockSecurity;
$this->Components->disable('TriggerMockSecurity');
$this->assertTrue($this->Components->trigger('startup', array(&$controller)));
}
/**
* test that the collectReturn option works.
*
* @return void
*/
function testTriggerWithCollectReturn() {
$controller = null;
$this->_makeMockClasses();
$this->Components->load('TriggerMockCookie');
$this->Components->load('TriggerMockSecurity');
$this->Components->TriggerMockCookie->expects($this->once())->method('startup')
->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(
array('one', 'two'),
array('three', 'four')
);
$this->assertEquals($expected, $result);
}
/**
* test that trigger with break & breakOn works.
*
* @return void
*/
function testTriggerWithBreak() {
$controller = null;
$this->_makeMockClasses();
$this->Components->load('TriggerMockCookie');
$this->Components->load('TriggerMockSecurity');
$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',
array(&$controller),
array('break' => true, 'breakOn' => false)
);
$this->assertFalse($result);
}
/**
* test normalizeObjectArray
*
* @return void
*/
function testnormalizeObjectArray() {
$components = array(
'Html',
'Foo.Bar' => array('one', 'two'),
'Something',
'Banana.Apple' => array('foo' => 'bar')
);
$result = ComponentCollection::normalizeObjectArray($components);
$expected = array(
'Html' => array('class' => 'Html', 'settings' => array()),
'Bar' => array('class' => 'Foo.Bar', 'settings' => array('one', 'two')),
'Something' => array('class' => 'Something', 'settings' => array()),
'Apple' => array('class' => 'Banana.Apple', 'settings' => array('foo' => 'bar')),
);
$this->assertEquals($expected, $result);
}
/**
* test getting the controller out of the collection
*

View file

@ -219,7 +219,7 @@ class AclComponentTest extends CakeTestCase {
* test that construtor throws an exception when Acl.classname is a
* non-existant class
*
* @expectedException Exception
* @expectedException CakeException
* @return void
*/
function testConstrutorException() {
@ -244,7 +244,7 @@ class AclComponentTest extends CakeTestCase {
/**
* test that adapter() whines when the class is not an AclBase
*
* @expectedException Exception
* @expectedException CakeException
* @return void
*/
function testAdapterException() {

View file

@ -461,6 +461,19 @@ class CookieComponentTest extends CakeTestCase {
unset($_COOKIE['CakeTestCookie']);
}
/**
* test that no error is issued for non array data.
*
* @return void
*/
function testNoErrorOnNonArrayData() {
$this->Cookie->destroy();
$_COOKIE['CakeTestCookie'] = 'kaboom';
$this->assertNull($this->Cookie->read('value'));
}
/**
* encrypt method
*

View file

@ -268,7 +268,7 @@ class EmailComponentTest extends CakeTestCase {
* @return void
*/
function testSmtpConfig() {
if ($this->skipIf(!@fsockopen('localhost', 25), '%s No SMTP server running on localhost')) {
if ($this->skipIf(!@fsockopen('localhost', 25, $err, $errstr, .01), '%s No SMTP server running on localhost')) {
return;
}
$this->Controller->EmailTest->delivery = 'smtp';
@ -295,7 +295,7 @@ class EmailComponentTest extends CakeTestCase {
* @return void
*/
function testBadSmtpSend() {
if ($this->skipIf(!@fsockopen('localhost', 25), '%s No SMTP server running on localhost')) {
if ($this->skipIf(!@fsockopen('localhost', 25, $err, $errstr, .01), '%s No SMTP server running on localhost')) {
return;
}
$this->Controller->EmailTest->smtpOptions['host'] = 'blah';
@ -310,7 +310,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, $err, $errstr, .01), '%s No SMTP server running on localhost')) {
return;
}
@ -359,7 +359,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, $err, $errstr, .01), '%s No SMTP server running on localhost')) {
return;
}
@ -416,7 +416,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, $err, $errstr, .01), '%s No SMTP server running on localhost')) {
return;
}
$this->Controller->EmailTest->reset();
@ -465,7 +465,7 @@ TEMPDOC;
* @return void
*/
function testAuthenticatedSmtpSend() {
if ($this->skipIf(!@fsockopen('localhost', 25), '%s No SMTP server running on localhost')) {
if ($this->skipIf(!@fsockopen('localhost', 25, $err, $errstr, .01), '%s No SMTP server running on localhost')) {
return;
}
@ -501,6 +501,7 @@ TEMPDOC;
$this->Controller->EmailTest->delivery = 'debug';
$this->Controller->EmailTest->messageId = false;
$date = date(DATE_RFC2822);
$message = <<<MSGBLOC
<pre>To: postmaster@localhost
From: noreply@example.com
@ -509,6 +510,7 @@ Header:
From: noreply@example.com
Reply-To: noreply@example.com
Date: $date
X-Mailer: CakePHP Email Component
Content-Type: {CONTENTTYPE}
Content-Transfer-Encoding: 7bitParameters:
@ -552,6 +554,7 @@ MSGBLOC;
$this->Controller->EmailTest->delivery = 'debug';
$this->Controller->EmailTest->messageId = false;
$date = date(DATE_RFC2822);
$header = <<<HEADBLOC
To: postmaster@localhost
From: noreply@example.com
@ -560,6 +563,7 @@ Header:
From: noreply@example.com
Reply-To: noreply@example.com
Date: $date
X-Mailer: CakePHP Email Component
Content-Type: {CONTENTTYPE}
Content-Transfer-Encoding: 7bitParameters:
@ -633,22 +637,30 @@ HTMLBLOC;
$expect = '<pre>' . str_replace('{CONTENTTYPE}', 'text/html; charset=UTF-8', $header) . $html . '</pre>';
$this->assertTrue($this->Controller->EmailTest->send('This is the body of the message', 'default', 'thin'));
$this->assertEqual($this->Controller->Session->read('Message.email.message'), $this->__osFix($expect));
}
return;
/**
* test that elements used in email templates get helpers.
*
* @return void
*/
function testTemplateNestedElements() {
$this->Controller->EmailTest->to = 'postmaster@localhost';
$this->Controller->EmailTest->from = 'noreply@example.com';
$this->Controller->EmailTest->subject = 'Cake SMTP test';
$this->Controller->EmailTest->replyTo = 'noreply@example.com';
$text = <<<TEXTBLOC
$this->Controller->EmailTest->delivery = 'debug';
$this->Controller->EmailTest->messageId = false;
$this->Controller->EmailTest->layout = 'default';
$this->Controller->EmailTest->template = 'nested_element';
$this->Controller->EmailTest->sendAs = 'html';
$this->Controller->helpers = array('Html');
This element has some text that is just too wide to comply with email
standards.
This is the body of the message
This email was sent using the CakePHP Framework, http://cakephp.org.
TEXTBLOC;
$this->Controller->EmailTest->sendAs = 'text';
$expect = '<pre>' . str_replace('{CONTENTTYPE}', 'text/plain; charset=UTF-8', $header) . $text . "\n" . '</pre>';
$this->assertTrue($this->Controller->EmailTest->send('This is the body of the message', 'wide', 'default'));
$this->assertEqual($this->Controller->Session->read('Message.email.message'), $this->__osFix($expect));
$this->Controller->EmailTest->send();
$result = $this->Controller->Session->read('Message.email.message');
$this->assertPattern('/Test/', $result);
$this->assertPattern('/http\:\/\/example\.com/', $result);
}
/**
@ -658,7 +670,7 @@ TEXTBLOC;
* @return void
*/
function testSmtpSendSocket() {
if ($this->skipIf(!@fsockopen('localhost', 25), '%s No SMTP server running on localhost')) {
if ($this->skipIf(!@fsockopen('localhost', 25, $err, $errstr, .01), '%s No SMTP server running on localhost')) {
return;
}
@ -697,6 +709,7 @@ TEXTBLOC;
$this->assertPattern('/Subject: Cake Debug Test\n/', $result);
$this->assertPattern('/Reply-To: noreply@example.com\n/', $result);
$this->assertPattern('/From: noreply@example.com\n/', $result);
$this->assertPattern('/Date: ' . preg_quote(date(DATE_RFC2822)) . '\n/', $result);
$this->assertPattern('/X-Mailer: CakePHP Email Component\n/', $result);
$this->assertPattern('/Content-Type: text\/plain; charset=UTF-8\n/', $result);
$this->assertPattern('/Content-Transfer-Encoding: 7bitParameters:\n/', $result);
@ -724,6 +737,7 @@ TEXTBLOC;
$this->assertPattern('/Subject: Cake Debug Test\n/', $result);
$this->assertPattern('/Reply-To: noreply@example.com\n/', $result);
$this->assertPattern('/From: noreply@example.com\n/', $result);
$this->assertPattern('/Date: ' . preg_quote(date(DATE_RFC2822)) . '\n/', $result);
$this->assertPattern('/X-Mailer: CakePHP Email Component\n/', $result);
$this->assertPattern('/Content-Type: text\/plain; charset=UTF-8\n/', $result);
$this->assertPattern('/Content-Transfer-Encoding: 7bitParameters:\n/', $result);
@ -857,7 +871,24 @@ HTMLBLOC;
$this->assertPattern('/First line\n/', $result);
$this->assertPattern('/Second line\n/', $result);
$this->assertPattern('/Third line\n/', $result);
}
/**
* test setting a custom date.
*
* @return void
*/
function testDateProperty() {
$this->Controller->EmailTest->to = 'postmaster@localhost';
$this->Controller->EmailTest->from = 'noreply@example.com';
$this->Controller->EmailTest->subject = 'Cake Debug Test';
$this->Controller->EmailTest->date = 'Today!';
$this->Controller->EmailTest->template = null;
$this->Controller->EmailTest->delivery = 'debug';
$this->assertTrue($this->Controller->EmailTest->send('test message'));
$result = $this->Controller->Session->read('Message.email.message');
$this->assertPattern('/Date: Today!\n/', $result);
}
/**
@ -1051,6 +1082,7 @@ HTMLBLOC;
$this->Controller->EmailTest->return = 'test.return@example.com';
$this->Controller->EmailTest->cc = array('cc1@example.com', 'cc2@example.com');
$this->Controller->EmailTest->bcc = array('bcc1@example.com', 'bcc2@example.com');
$this->Controller->EmailTest->date = 'Today!';
$this->Controller->EmailTest->subject = 'Test subject';
$this->Controller->EmailTest->additionalParams = 'X-additional-header';
$this->Controller->EmailTest->delivery = 'smtp';
@ -1072,6 +1104,7 @@ HTMLBLOC;
$this->assertNull($this->Controller->EmailTest->return);
$this->assertIdentical($this->Controller->EmailTest->cc, array());
$this->assertIdentical($this->Controller->EmailTest->bcc, array());
$this->assertNull($this->Controller->EmailTest->date);
$this->assertNull($this->Controller->EmailTest->subject);
$this->assertNull($this->Controller->EmailTest->additionalParams);
$this->assertIdentical($this->Controller->EmailTest->getHeaders(), array());
@ -1200,10 +1233,10 @@ HTMLBLOC;
$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

@ -578,9 +578,9 @@ DIGEST;
*/
function testValidatePost() {
$this->Controller->Security->startup($this->Controller);
$key = $this->Controller->request->params['_Token']['key'];
$fields = 'a5475372b40f6e3ccbf9f8af191f20e1642fd877%3An%3A1%3A%7Bv%3A0%3B';
$fields .= 'f%3A11%3A%22Zbqry.inyvq%22%3B%7D';
$fields = 'a5475372b40f6e3ccbf9f8af191f20e1642fd877%3AModel.valid';
$this->Controller->request->data = array(
'Model' => array('username' => 'nate', 'password' => 'foo', 'valid' => '0'),
@ -597,8 +597,7 @@ DIGEST;
function testValidatePostFormHacking() {
$this->Controller->Security->startup($this->Controller);
$key = $this->Controller->params['_Token']['key'];
$fields = 'a5475372b40f6e3ccbf9f8af191f20e1642fd877%3An%3A1%3A%7Bv%3A0%3B';
$fields .= 'f%3A11%3A%22Zbqry.inyvq%22%3B%7D';
$fields = 'a5475372b40f6e3ccbf9f8af191f20e1642fd877%3AModel.valid';
$this->Controller->request->data = array(
'Model' => array('username' => 'nate', 'password' => 'foo', 'valid' => '0'),
@ -639,8 +638,9 @@ DIGEST;
*/
function testValidatePostArray() {
$this->Controller->Security->startup($this->Controller);
$key = $this->Controller->request->params['_Token']['key'];
$fields = 'f7d573650a295b94e0938d32b323fde775e5f32b%3An%3A0%3A%7B%7D';
$fields = 'f7d573650a295b94e0938d32b323fde775e5f32b%3A';
$this->Controller->request->data = array(
'Model' => array('multi_field' => array('1', '3')),
@ -657,8 +657,9 @@ DIGEST;
*/
function testValidatePostNoModel() {
$this->Controller->Security->startup($this->Controller);
$key = $this->Controller->request->params['_Token']['key'];
$fields = '540ac9c60d323c22bafe997b72c0790f39a8bdef%3An%3A0%3A%7B%7D';
$fields = '540ac9c60d323c22bafe997b72c0790f39a8bdef%3A';
$this->Controller->request->data = array(
'anything' => 'some_data',
@ -677,8 +678,9 @@ DIGEST;
*/
function testValidatePostSimple() {
$this->Controller->Security->startup($this->Controller);
$key = $this->Controller->request->params['_Token']['key'];
$fields = '69f493434187b867ea14b901fdf58b55d27c935d%3An%3A0%3A%7B%7D';
$fields = '69f493434187b867ea14b901fdf58b55d27c935d%3A';
$this->Controller->request->data = $data = array(
'Model' => array('username' => '', 'password' => ''),
@ -697,9 +699,9 @@ DIGEST;
*/
function testValidatePostComplex() {
$this->Controller->Security->startup($this->Controller);
$key = $this->Controller->request->params['_Token']['key'];
$fields = 'c9118120e680a7201b543f562e5301006ccfcbe2%3An%3A2%3A%7Bv%3A0%3Bf%3A14%3A%';
$fields .= '22Nqqerffrf.0.vq%22%3Bv%3A1%3Bf%3A14%3A%22Nqqerffrf.1.vq%22%3B%7D';
$fields = 'c9118120e680a7201b543f562e5301006ccfcbe2%3AAddresses.0.id%7CAddresses.1.id';
$this->Controller->request->data = array(
'Addresses' => array(
@ -725,8 +727,9 @@ DIGEST;
*/
function testValidatePostMultipleSelect() {
$this->Controller->Security->startup($this->Controller);
$key = $this->Controller->request->params['_Token']['key'];
$fields = '422cde416475abc171568be690a98cad20e66079%3An%3A0%3A%7B%7D';
$fields = '422cde416475abc171568be690a98cad20e66079%3A';
$this->Controller->request->data = array(
'Tag' => array('Tag' => array(1, 2)),
@ -749,7 +752,7 @@ DIGEST;
$result = $this->Controller->Security->validatePost($this->Controller);
$this->assertTrue($result);
$fields = '19464422eafe977ee729c59222af07f983010c5f%3An%3A0%3A%7B%7D';
$fields = '19464422eafe977ee729c59222af07f983010c5f%3A';
$this->Controller->request->data = array(
'User.password' => 'bar', 'User.name' => 'foo', 'User.is_valid' => '1',
'Tag' => array('Tag' => array(1)), '_Token' => compact('key', 'fields'),
@ -770,8 +773,7 @@ DIGEST;
function testValidatePostCheckbox() {
$this->Controller->Security->startup($this->Controller);
$key = $this->Controller->request->params['_Token']['key'];
$fields = 'a5475372b40f6e3ccbf9f8af191f20e1642fd877%3An%3A1%3A%7Bv%3A0%';
$fields .= '3Bf%3A11%3A%22Zbqry.inyvq%22%3B%7D';
$fields = 'a5475372b40f6e3ccbf9f8af191f20e1642fd877%3AModel.valid';
$this->Controller->request->data = array(
'Model' => array('username' => '', 'password' => '', 'valid' => '0'),
@ -781,7 +783,7 @@ DIGEST;
$result = $this->Controller->Security->validatePost($this->Controller);
$this->assertTrue($result);
$fields = '874439ca69f89b4c4a5f50fb9c36ff56a28f5d42%3An%3A0%3A%7B%7D';
$fields = '874439ca69f89b4c4a5f50fb9c36ff56a28f5d42%3A';
$this->Controller->request->data = array(
'Model' => array('username' => '', 'password' => '', 'valid' => '0'),
@ -814,8 +816,8 @@ DIGEST;
function testValidatePostHidden() {
$this->Controller->Security->startup($this->Controller);
$key = $this->Controller->request->params['_Token']['key'];
$fields = '51ccd8cb0997c7b3d4523ecde5a109318405ef8c%3An%3A2%3A%7Bv%3A0%3Bf%3A12%3A';
$fields .= '%22Zbqry.uvqqra%22%3Bv%3A1%3Bf%3A18%3A%22Zbqry.bgure_uvqqra%22%3B%7D';
$fields = '51ccd8cb0997c7b3d4523ecde5a109318405ef8c%3AModel.hidden%7CModel.other_hidden';
$fields .= '';
$this->Controller->request->data = array(
'Model' => array(
@ -838,8 +840,7 @@ DIGEST;
$this->Controller->Security->disabledFields = array('Model.username', 'Model.password');
$this->Controller->Security->startup($this->Controller);
$key = $this->Controller->request->params['_Token']['key'];
$fields = 'ef1082968c449397bcd849f963636864383278b1%3An%3A1%3A%7Bv%';
$fields .= '3A0%3Bf%3A12%3A%22Zbqry.uvqqra%22%3B%7D';
$fields = 'ef1082968c449397bcd849f963636864383278b1%3AModel.hidden';
$this->Controller->request->data = array(
'Model' => array(
@ -861,9 +862,7 @@ DIGEST;
function testValidateHiddenMultipleModel() {
$this->Controller->Security->startup($this->Controller);
$key = $this->Controller->request->params['_Token']['key'];
$fields = 'a2d01072dc4660eea9d15007025f35a7a5b58e18%3An%3A3%3A%7Bv%3A0%3Bf%3A11';
$fields .= '%3A%22Zbqry.inyvq%22%3Bv%3A1%3Bf%3A12%3A%22Zbqry2.inyvq%22%3Bv%3A2%';
$fields .= '3Bf%3A12%3A%22Zbqry3.inyvq%22%3B%7D';
$fields = 'a2d01072dc4660eea9d15007025f35a7a5b58e18%3AModel.valid%7CModel2.valid%7CModel3.valid';
$this->Controller->request->data = array(
'Model' => array('username' => '', 'password' => '', 'valid' => '0'),
@ -884,9 +883,8 @@ DIGEST;
function testValidateHasManyModel() {
$this->Controller->Security->startup($this->Controller);
$key = $this->Controller->request->params['_Token']['key'];
$fields = '51e3b55a6edd82020b3f29c9ae200e14bbeb7ee5%3An%3A4%3A%7Bv%3A0%3Bf%3A14%3A%2';
$fields .= '2Zbqry.0.uvqqra%22%3Bv%3A1%3Bf%3A13%3A%22Zbqry.0.inyvq%22%3Bv%3A2%3Bf%3';
$fields .= 'A14%3A%22Zbqry.1.uvqqra%22%3Bv%3A3%3Bf%3A13%3A%22Zbqry.1.inyvq%22%3B%7D';
$fields = '51e3b55a6edd82020b3f29c9ae200e14bbeb7ee5%3AModel.0.hidden%7CModel.0.valid';
$fields .= '%7CModel.1.hidden%7CModel.1.valid';
$this->Controller->request->data = array(
'Model' => array(
@ -915,9 +913,8 @@ DIGEST;
function testValidateHasManyRecordsPass() {
$this->Controller->Security->startup($this->Controller);
$key = $this->Controller->request->params['_Token']['key'];
$fields = '7a203edb3d345bbf38fe0dccae960da8842e11d7%3An%3A4%3A%7Bv%3A0%3Bf%3A12%3A%2';
$fields .= '2Nqqerff.0.vq%22%3Bv%3A1%3Bf%3A17%3A%22Nqqerff.0.cevznel%22%3Bv%3A2%3Bf%';
$fields .= '3A12%3A%22Nqqerff.1.vq%22%3Bv%3A3%3Bf%3A17%3A%22Nqqerff.1.cevznel%22%3B%7D';
$fields = '7a203edb3d345bbf38fe0dccae960da8842e11d7%3AAddress.0.id%7CAddress.0.primary%7C';
$fields .= 'Address.1.id%7CAddress.1.primary';
$this->Controller->request->data = array(
'Address' => array(
@ -960,9 +957,8 @@ DIGEST;
function testValidateHasManyRecordsFail() {
$this->Controller->Security->startup($this->Controller);
$key = $this->Controller->request->params['_Token']['key'];
$fields = '7a203edb3d345bbf38fe0dccae960da8842e11d7%3An%3A4%3A%7Bv%3A0%3Bf%3A12%3A%2';
$fields .= '2Nqqerff.0.vq%22%3Bv%3A1%3Bf%3A17%3A%22Nqqerff.0.cevznel%22%3Bv%3A2%3Bf%';
$fields .= '3A12%3A%22Nqqerff.1.vq%22%3Bv%3A3%3Bf%3A17%3A%22Nqqerff.1.cevznel%22%3B%7D';
$fields = '7a203edb3d345bbf38fe0dccae960da8842e11d7%3AAddress.0.id%7CAddress.0.primary%7C';
$fields .= 'Address.1.id%7CAddress.1.primary';
$this->Controller->request->data = array(
'Address' => array(

View file

@ -143,6 +143,7 @@ class SessionComponentTest extends CakeTestCase {
*/
function testSessionIdConsistentAcrossRequestAction() {
$Session = new SessionComponent($this->ComponentCollection);
$Session->check('Test');
$this->assertTrue(isset($_SESSION));
$Object = new Object();
@ -287,6 +288,7 @@ class SessionComponentTest extends CakeTestCase {
function testSessionId() {
unset($_SESSION);
$Session = new SessionComponent($this->ComponentCollection);
$Session->check('test');
$this->assertEquals(session_id(), $Session->id());
}

View file

@ -223,50 +223,6 @@ class ControllerAlias extends CakeTestModel {
public $useTable = 'posts';
}
/**
* ControllerPaginateModel class
*
* @package cake
* @subpackage cake.tests.cases.libs.controller
*/
class ControllerPaginateModel extends CakeTestModel {
/**
* name property
*
* @var string
* @access public
*/
public $name = 'ControllerPaginateModel';
/**
* useTable property
*
* @var string'
* @access public
*/
public $useTable = 'comments';
/**
* paginate method
*
* @return void
*/
public function paginate($conditions, $fields, $order, $limit, $page, $recursive, $extra) {
$this->extra = $extra;
}
/**
* paginateCount
*
* @access public
* @return void
*/
function paginateCount($conditions, $recursive, $extra) {
$this->extraCount = $extra;
}
}
/**
* NameTest class
*
@ -598,350 +554,6 @@ class ControllerTest extends CakeTestCase {
Configure::write('Cache.disable', true);
}
/**
* testPaginate method
*
* @access public
* @return void
*/
function testPaginate() {
$request = new CakeRequest('controller_posts/index');
$request->params['pass'] = $request->params['named'] = array();
$Controller = new Controller($request);
$Controller->uses = array('ControllerPost', 'ControllerComment');
$Controller->passedArgs[] = '1';
$Controller->params['url'] = array();
$Controller->constructClasses();
$results = Set::extract($Controller->paginate('ControllerPost'), '{n}.ControllerPost.id');
$this->assertEqual($results, array(1, 2, 3));
$results = Set::extract($Controller->paginate('ControllerComment'), '{n}.ControllerComment.id');
$this->assertEqual($results, array(1, 2, 3, 4, 5, 6));
$Controller->modelClass = null;
$Controller->uses[0] = 'Plugin.ControllerPost';
$results = Set::extract($Controller->paginate(), '{n}.ControllerPost.id');
$this->assertEqual($results, array(1, 2, 3));
$Controller->passedArgs = array('page' => '-1');
$results = Set::extract($Controller->paginate('ControllerPost'), '{n}.ControllerPost.id');
$this->assertEqual($Controller->params['paging']['ControllerPost']['page'], 1);
$this->assertEqual($results, array(1, 2, 3));
$Controller->passedArgs = array('sort' => 'ControllerPost.id', 'direction' => 'asc');
$results = Set::extract($Controller->paginate('ControllerPost'), '{n}.ControllerPost.id');
$this->assertEqual($Controller->params['paging']['ControllerPost']['page'], 1);
$this->assertEqual($results, array(1, 2, 3));
$Controller->passedArgs = array('sort' => 'ControllerPost.id', 'direction' => 'desc');
$results = Set::extract($Controller->paginate('ControllerPost'), '{n}.ControllerPost.id');
$this->assertEqual($Controller->params['paging']['ControllerPost']['page'], 1);
$this->assertEqual($results, array(3, 2, 1));
$Controller->passedArgs = array('sort' => 'id', 'direction' => 'desc');
$results = Set::extract($Controller->paginate('ControllerPost'), '{n}.ControllerPost.id');
$this->assertEqual($Controller->params['paging']['ControllerPost']['page'], 1);
$this->assertEqual($results, array(3, 2, 1));
$Controller->passedArgs = array('sort' => 'NotExisting.field', 'direction' => 'desc');
$results = Set::extract($Controller->paginate('ControllerPost'), '{n}.ControllerPost.id');
$this->assertEqual($Controller->params['paging']['ControllerPost']['page'], 1, 'Invalid field in query %s');
$this->assertEqual($results, array(1, 2, 3));
$Controller->passedArgs = array('sort' => 'ControllerPost.author_id', 'direction' => 'allYourBase');
$results = Set::extract($Controller->paginate('ControllerPost'), '{n}.ControllerPost.id');
$this->assertEqual($Controller->ControllerPost->lastQuery['order'][0], array('ControllerPost.author_id' => 'asc'));
$this->assertEqual($results, array(1, 3, 2));
$Controller->passedArgs = array('page' => '1 " onclick="alert(\'xss\');">');
$Controller->paginate = array('limit' => 1);
$Controller->paginate('ControllerPost');
$this->assertIdentical($Controller->params['paging']['ControllerPost']['page'], 1, 'XSS exploit opened %s');
$this->assertIdentical($Controller->params['paging']['ControllerPost']['options']['page'], 1, 'XSS exploit opened %s');
$Controller->passedArgs = array();
$Controller->paginate = array('limit' => 0);
$Controller->paginate('ControllerPost');
$this->assertIdentical($Controller->params['paging']['ControllerPost']['page'], 1);
$this->assertIdentical($Controller->params['paging']['ControllerPost']['pageCount'], 3);
$this->assertIdentical($Controller->params['paging']['ControllerPost']['prevPage'], false);
$this->assertIdentical($Controller->params['paging']['ControllerPost']['nextPage'], true);
$Controller->passedArgs = array();
$Controller->paginate = array('limit' => 'garbage!');
$Controller->paginate('ControllerPost');
$this->assertIdentical($Controller->params['paging']['ControllerPost']['page'], 1);
$this->assertIdentical($Controller->params['paging']['ControllerPost']['pageCount'], 3);
$this->assertIdentical($Controller->params['paging']['ControllerPost']['prevPage'], false);
$this->assertIdentical($Controller->params['paging']['ControllerPost']['nextPage'], true);
$Controller->passedArgs = array();
$Controller->paginate = array('limit' => '-1');
$Controller->paginate('ControllerPost');
$this->assertIdentical($Controller->params['paging']['ControllerPost']['page'], 1);
$this->assertIdentical($Controller->params['paging']['ControllerPost']['pageCount'], 3);
$this->assertIdentical($Controller->params['paging']['ControllerPost']['prevPage'], false);
$this->assertIdentical($Controller->params['paging']['ControllerPost']['nextPage'], true);
}
/**
* testPaginateExtraParams method
*
* @access public
* @return void
*/
function testPaginateExtraParams() {
$request = new CakeRequest('controller_posts/index');
$request->params['pass'] = $request->params['named'] = array();
$Controller = new Controller($request);
$Controller->uses = array('ControllerPost', 'ControllerComment');
$Controller->passedArgs[] = '1';
$Controller->params['url'] = array();
$Controller->constructClasses();
$Controller->passedArgs = array('page' => '-1', 'contain' => array('ControllerComment'));
$result = $Controller->paginate('ControllerPost');
$this->assertEqual($Controller->params['paging']['ControllerPost']['page'], 1);
$this->assertEqual(Set::extract($result, '{n}.ControllerPost.id'), array(1, 2, 3));
$this->assertTrue(!isset($Controller->ControllerPost->lastQuery['contain']));
$Controller->passedArgs = array('page' => '-1');
$Controller->paginate = array('ControllerPost' => array('contain' => array('ControllerComment')));
$result = $Controller->paginate('ControllerPost');
$this->assertEqual($Controller->params['paging']['ControllerPost']['page'], 1);
$this->assertEqual(Set::extract($result, '{n}.ControllerPost.id'), array(1, 2, 3));
$this->assertTrue(isset($Controller->ControllerPost->lastQuery['contain']));
$Controller->paginate = array('ControllerPost' => array('popular', 'fields' => array('id', 'title')));
$result = $Controller->paginate('ControllerPost');
$this->assertEqual(Set::extract($result, '{n}.ControllerPost.id'), array(2, 3));
$this->assertEqual($Controller->ControllerPost->lastQuery['conditions'], array('ControllerPost.id > ' => '1'));
$Controller->passedArgs = array('limit' => 12);
$Controller->paginate = array('limit' => 30);
$result = $Controller->paginate('ControllerPost');
$paging = $Controller->params['paging']['ControllerPost'];
$this->assertEqual($Controller->ControllerPost->lastQuery['limit'], 12);
$this->assertEqual($paging['options']['limit'], 12);
$Controller = new Controller($request);
$Controller->uses = array('ControllerPaginateModel');
$Controller->params['url'] = array();
$Controller->constructClasses();
$Controller->paginate = array(
'ControllerPaginateModel' => array('contain' => array('ControllerPaginateModel'), 'group' => 'Comment.author_id')
);
$result = $Controller->paginate('ControllerPaginateModel');
$expected = array('contain' => array('ControllerPaginateModel'), 'group' => 'Comment.author_id');
$this->assertEqual($Controller->ControllerPaginateModel->extra, $expected);
$this->assertEqual($Controller->ControllerPaginateModel->extraCount, $expected);
$Controller->paginate = array(
'ControllerPaginateModel' => array('foo', 'contain' => array('ControllerPaginateModel'), 'group' => 'Comment.author_id')
);
$Controller->paginate('ControllerPaginateModel');
$expected = array('contain' => array('ControllerPaginateModel'), 'group' => 'Comment.author_id', 'type' => 'foo');
$this->assertEqual($Controller->ControllerPaginateModel->extra, $expected);
$this->assertEqual($Controller->ControllerPaginateModel->extraCount, $expected);
}
/**
* testPaginateMaxLimit
*
* @return void
* @access public
*/
function testPaginateMaxLimit() {
$request = new CakeRequest('controller_posts/index');
$request->params['pass'] = $request->params['named'] = array();
$Controller = new Controller($request);
$Controller->uses = array('ControllerPost', 'ControllerComment');
$Controller->passedArgs[] = '1';
$Controller->params['url'] = array();
$Controller->constructClasses();
$Controller->passedArgs = array('contain' => array('ControllerComment'), 'limit' => '1000');
$result = $Controller->paginate('ControllerPost');
$this->assertEqual($Controller->params['paging']['ControllerPost']['options']['limit'], 100);
$Controller->passedArgs = array('contain' => array('ControllerComment'), 'limit' => '1000', 'maxLimit' => 1000);
$result = $Controller->paginate('ControllerPost');
$this->assertEqual($Controller->params['paging']['ControllerPost']['options']['limit'], 100);
$Controller->passedArgs = array('contain' => array('ControllerComment'), 'limit' => '10');
$result = $Controller->paginate('ControllerPost');
$this->assertEqual($Controller->params['paging']['ControllerPost']['options']['limit'], 10);
$Controller->passedArgs = array('contain' => array('ControllerComment'), 'limit' => '1000');
$Controller->paginate = array('maxLimit' => 2000);
$result = $Controller->paginate('ControllerPost');
$this->assertEqual($Controller->params['paging']['ControllerPost']['options']['limit'], 1000);
$Controller->passedArgs = array('contain' => array('ControllerComment'), 'limit' => '5000');
$result = $Controller->paginate('ControllerPost');
$this->assertEqual($Controller->params['paging']['ControllerPost']['options']['limit'], 2000);
}
/**
* testPaginateFieldsDouble method
*
* @return void
* @access public
*/
function testPaginateFieldsDouble(){
$request = new CakeRequest('controller_posts/index');
$Controller = new Controller($request);
$Controller->uses = array('ControllerPost');
$Controller->request = $this->getMock('CakeRequest');
$Controller->request->params['url'] = array();
$Controller->constructClasses();
$Controller->paginate = array(
'fields' => array(
'ControllerPost.id',
'radians(180.0) as floatvalue'
),
'order' => array('ControllerPost.created'=>'DESC'),
'limit' => 1,
'page' => 1,
'recursive' => -1
);
$conditions = array();
$result = $Controller->paginate('ControllerPost',$conditions);
$expected = array(
array(
'ControllerPost' => array(
'id' => 3,
),
0 => array(
'floatvalue' => '3.14159265358979',
),
),
);
$this->assertEqual($result, $expected);
}
/**
* testPaginatePassedArgs method
*
* @return void
*/
public function testPaginatePassedArgs() {
$request = new CakeRequest('controller_posts/index');
$request->params['pass'] = $request->params['named'] = array();
$Controller = new Controller($request);
$Controller->uses = array('ControllerPost');
$Controller->passedArgs[] = array('1', '2', '3');
$Controller->params['url'] = array();
$Controller->constructClasses();
$Controller->paginate = array(
'fields' => array(),
'order' => '',
'limit' => 5,
'page' => 1,
'recursive' => -1
);
$conditions = array();
$Controller->paginate('ControllerPost',$conditions);
$expected = array(
'fields' => array(),
'order' => '',
'limit' => 5,
'maxLimit' => 100,
'page' => 1,
'recursive' => -1,
'conditions' => array()
);
$this->assertEqual($Controller->params['paging']['ControllerPost']['options'],$expected);
}
/**
* Test that special paginate types are called and that the type param doesn't leak out into defaults or options.
*
* @return void
*/
function testPaginateSpecialType() {
$request = new CakeRequest('controller_posts/index');
$request->params['pass'] = $request->params['named'] = array();
$Controller = new Controller($request);
$Controller->uses = array('ControllerPost', 'ControllerComment');
$Controller->passedArgs[] = '1';
$Controller->params['url'] = array();
$Controller->constructClasses();
$Controller->paginate = array('ControllerPost' => array('popular', 'fields' => array('id', 'title')));
$result = $Controller->paginate('ControllerPost');
$this->assertEqual(Set::extract($result, '{n}.ControllerPost.id'), array(2, 3));
$this->assertEqual($Controller->ControllerPost->lastQuery['conditions'], array('ControllerPost.id > ' => '1'));
$this->assertFalse(isset($Controller->params['paging']['ControllerPost']['defaults'][0]));
$this->assertFalse(isset($Controller->params['paging']['ControllerPost']['options'][0]));
}
/**
* testDefaultPaginateParams method
*
* @access public
* @return void
*/
function testDefaultPaginateParams() {
$request = new CakeRequest('controller_posts/index');
$request->params['pass'] = $request->params['named'] = array();
$Controller = new Controller($request);
$Controller->modelClass = 'ControllerPost';
$Controller->params['url'] = array();
$Controller->paginate = array('order' => 'ControllerPost.id DESC');
$Controller->constructClasses();
$results = Set::extract($Controller->paginate('ControllerPost'), '{n}.ControllerPost.id');
$this->assertEqual($Controller->params['paging']['ControllerPost']['defaults']['order'], 'ControllerPost.id DESC');
$this->assertEqual($Controller->params['paging']['ControllerPost']['options']['order'], 'ControllerPost.id DESC');
$this->assertEqual($results, array(3, 2, 1));
}
/**
* test paginate() and virtualField interactions
*
* @return void
*/
function testPaginateOrderVirtualField() {
$request = new CakeRequest('controller_posts/index');
$request->params['pass'] = $request->params['named'] = array();
$Controller = new Controller($request);
$Controller->uses = array('ControllerPost', 'ControllerComment');
$Controller->params['url'] = array();
$Controller->constructClasses();
$Controller->ControllerPost->virtualFields = array(
'offset_test' => 'ControllerPost.id + 1'
);
$Controller->paginate = array(
'fields' => array('id', 'title', 'offset_test'),
'order' => array('offset_test' => 'DESC')
);
$result = $Controller->paginate('ControllerPost');
$this->assertEqual(Set::extract($result, '{n}.ControllerPost.offset_test'), array(4, 3, 2));
$Controller->passedArgs = array('sort' => 'offset_test', 'direction' => 'asc');
$result = $Controller->paginate('ControllerPost');
$this->assertEqual(Set::extract($result, '{n}.ControllerPost.offset_test'), array(2, 3, 4));
}
/**
* testFlash method
*
@ -1284,10 +896,12 @@ class ControllerTest extends CakeTestCase {
? array_merge($appVars['uses'], $testVars['uses'])
: $testVars['uses'];
$this->assertEqual(count(array_diff($TestController->helpers, $helpers)), 0);
$this->assertEqual(count(array_diff_key($TestController->helpers, array_flip($helpers))), 0);
$this->assertEqual(count(array_diff($TestController->uses, $uses)), 0);
$this->assertEqual(count(array_diff_assoc(Set::normalize($TestController->components), Set::normalize($components))), 0);
$expected = array('ControllerComment', 'ControllerAlias', 'ControllerPost');
$this->assertEquals($expected, $TestController->uses, '$uses was merged incorrectly, AppController models should be last.');
$TestController = new AnotherTestController($request);
$TestController->constructClasses();
@ -1647,4 +1261,33 @@ class ControllerTest extends CakeTestCase {
$this->assertType('SecurityComponent', $Controller->Security);
$this->assertType('ControllerComment', $Controller->ControllerComment);
}
/**
* test that using Controller::paginate() falls back to PaginatorComponent
*
* @return void
*/
function testPaginateBackwardsCompatibility() {
$request = new CakeRequest('controller_posts/index');
$request->params['pass'] = $request->params['named'] = array();
$Controller = new Controller($request);
$Controller->uses = array('ControllerPost', 'ControllerComment');
$Controller->passedArgs[] = '1';
$Controller->params['url'] = array();
$Controller->constructClasses();
$this->assertEqual($Controller->paginate, array('page' => 1, 'limit' => 20));
$results = Set::extract($Controller->paginate('ControllerPost'), '{n}.ControllerPost.id');
$this->assertEqual($results, array(1, 2, 3));
$Controller->passedArgs = array();
$Controller->paginate = array('limit' => '-1');
$this->assertEqual($Controller->paginate, array('limit' => '-1'));
$Controller->paginate('ControllerPost');
$this->assertIdentical($Controller->params['paging']['ControllerPost']['page'], 1);
$this->assertIdentical($Controller->params['paging']['ControllerPost']['pageCount'], 3);
$this->assertIdentical($Controller->params['paging']['ControllerPost']['prevPage'], false);
$this->assertIdentical($Controller->params['paging']['ControllerPost']['nextPage'], true);
}
}

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