mirror of
https://github.com/kamilwylegala/cakephp2-php8.git
synced 2024-11-15 03:18:26 +00:00
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:
commit
07e43bb0f8
122 changed files with 4822 additions and 2612 deletions
251
cake/libs/controller/components/paginator.php
Normal file
251
cake/libs/controller/components/paginator.php
Normal 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;
|
||||
}
|
||||
}
|
68
cake/libs/http/basic_authentication.php
Normal file
68
cake/libs/http/basic_authentication.php
Normal 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);
|
||||
}
|
||||
|
||||
}
|
106
cake/libs/http/digest_authentication.php
Normal file
106
cake/libs/http/digest_authentication.php
Normal 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
438
cake/libs/http_response.php
Normal 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();
|
||||
}
|
||||
|
||||
}
|
|
@ -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) {
|
489
cake/tests/cases/libs/controller/components/paginator.test.php
Normal file
489
cake/tests/cases/libs/controller/components/paginator.test.php
Normal 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');
|
||||
}
|
||||
}
|
411
cake/tests/cases/libs/controller_test_case.test.php
Normal file
411
cake/tests/cases/libs/controller_test_case.test.php
Normal 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);
|
||||
}
|
||||
|
||||
}
|
66
cake/tests/cases/libs/http/basic_authentication.test.php
Normal file
66
cake/tests/cases/libs/http/basic_authentication.test.php
Normal 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=');
|
||||
}
|
||||
|
||||
}
|
197
cake/tests/cases/libs/http/digest_authentication.test.php
Normal file
197
cake/tests/cases/libs/http/digest_authentication.test.php
Normal 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']));
|
||||
}
|
||||
|
||||
}
|
509
cake/tests/cases/libs/http_response.test.php
Normal file
509
cake/tests/cases/libs/http_response.test.php
Normal 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);
|
||||
}
|
||||
|
||||
}
|
312
cake/tests/lib/controller_test_case.php
Normal file
312
cake/tests/lib/controller_test_case.php
Normal 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;
|
||||
}
|
||||
}
|
26
cake/tests/test_app/config/routes.php
Normal file
26
cake/tests/test_app/config/routes.php
Normal 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'));
|
|
@ -0,0 +1,3 @@
|
|||
Before the element.
|
||||
<?php echo $this->element('html_call'); ?>
|
||||
After the element.
|
3
cake/tests/test_app/views/elements/html_call.ctp
Normal file
3
cake/tests/test_app/views/elements/html_call.ctp
Normal file
|
@ -0,0 +1,3 @@
|
|||
<?php
|
||||
echo $this->Html->link('Test', 'http://example.com');
|
||||
?>
|
1
cake/tests/test_app/views/elements/type_check.ctp
Normal file
1
cake/tests/test_app/views/elements/type_check.ctp
Normal file
|
@ -0,0 +1 @@
|
|||
<?php echo gettype($form); ?>
|
1
cake/tests/test_app/views/layouts/json/default.ctp
Normal file
1
cake/tests/test_app/views/layouts/json/default.ctp
Normal file
|
@ -0,0 +1 @@
|
|||
<?php echo $content_for_layout; ?>
|
1
cake/tests/test_app/views/tests_apps/json/index.ctp
Normal file
1
cake/tests/test_app/views/tests_apps/json/index.ctp
Normal file
|
@ -0,0 +1 @@
|
|||
{"cakephp":"cool"}
|
|
@ -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();
|
||||
|
|
|
@ -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.'));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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__)
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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') {
|
||||
|
|
|
@ -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)
|
||||
));
|
||||
|
|
|
@ -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)
|
||||
));
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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'));
|
||||
|
|
|
@ -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'));
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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==.');
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
*
|
||||
|
|
|
@ -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
|
||||
));
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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])) {
|
||||
|
|
|
@ -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');
|
||||
|
|
|
@ -108,7 +108,7 @@ class ExceptionRenderer {
|
|||
}
|
||||
} elseif (!$methodExists) {
|
||||
$method = 'error500';
|
||||
if ($code >= 400) {
|
||||
if ($code >= 400 && $code < 500) {
|
||||
$method = 'error400';
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 { }
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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';
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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');
|
||||
|
||||
|
|
|
@ -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)
|
||||
*
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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';
|
||||
}
|
||||
|
|
|
@ -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');
|
||||
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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 === '\\';
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
));
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
|
|
|
@ -50,8 +50,8 @@ class ScaffoldView extends ThemeView {
|
|||
}
|
||||
}
|
||||
|
||||
if ($name === 'add') {
|
||||
$name = 'edit';
|
||||
if ($name === 'add' || $name == 'edit') {
|
||||
$name = 'form';
|
||||
}
|
||||
|
||||
$scaffoldAction = 'scaffold.' . $name;
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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'];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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() {
|
||||
|
|
|
@ -613,7 +613,7 @@ class CakeRequestTestCase extends CakeTestCase {
|
|||
/**
|
||||
* test __call expcetions
|
||||
*
|
||||
* @expectedException Exception
|
||||
* @expectedException CakeException
|
||||
* @return void
|
||||
*/
|
||||
function test__callExceptionOnUnknownMethod() {
|
||||
|
|
|
@ -55,7 +55,7 @@ class CakeResponseTestCase extends CakeTestCase {
|
|||
/**
|
||||
* Tests the statusCode method
|
||||
*
|
||||
* @expectedException OutOfRangeException
|
||||
* @expectedException CakeException
|
||||
*/
|
||||
public function testStatusCode() {
|
||||
$response = new CakeResponse();
|
||||
|
|
|
@ -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']);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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
|
||||
*
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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
|
||||
*
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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
|
||||
*
|
||||
|
|
|
@ -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>');
|
||||
}
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
||||
|
|
|
@ -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
Loading…
Reference in a new issue