This commit is contained in:
planardothum 2012-11-13 19:50:38 -05:00
commit d1a591bd44
213 changed files with 11037 additions and 3108 deletions

View file

@ -1,11 +1,5 @@
<?php
/**
* This is i18n Schema file
*
* Use it to configure database for i18n
*
* PHP 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
*
@ -19,15 +13,16 @@
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
// @codingStandardsIgnoreStart
/*
/**
*
* Using the Schema command line utility
*
* Use it to configure database for i18n
*
* cake schema run create i18n
*/
class i18nSchema extends CakeSchema {
// @codingStandardsIgnoreStart
class I18nSchema extends CakeSchema {
// @codingStandardsIgnoreEnd
public $name = 'i18n';

View file

@ -232,17 +232,16 @@
//date_default_timezone_set('UTC');
/**
* Pick the caching engine to use. If APC is enabled use it.
* If running via cli - apc is disabled by default. ensure it's available and enabled in this case
* Configure the cache handlers that CakePHP will use for internal
* metadata like class maps, and model schema.
*
* By default File is used, but for improved performance you should use APC.
*
* Note: 'default' and other application caches should be configured in app/Config/bootstrap.php.
* Please check the comments in boostrap.php for more info on the cache engines available
* and their setttings.
*/
$engine = 'File';
if (extension_loaded('apc') && function_exists('apc_dec') && (php_sapi_name() !== 'cli' || ini_get('apc.enable_cli'))) {
$engine = 'Apc';
}
// In development mode, caches should expire quickly.
$duration = '+999 days';

View file

@ -17,17 +17,21 @@
# @license MIT License (http://www.opensource.org/licenses/mit-license.php)
#
################################################################################
LIB=$(cd -P -- "$(dirname -- "$0")" && pwd -P) && LIB=$LIB/$(basename -- "$0")
while [ -h "$LIB" ]; do
DIR=$(dirname -- "$LIB")
SYM=$(readlink "$LIB")
LIB=$(cd "$DIR" && cd $(dirname -- "$SYM") && pwd)/$(basename -- "$SYM")
done
# Canonicalize by following every symlink of the given name recursively
canonicalize() {
NAME=$1
while [ -h "$NAME" ]; do
DIR=$(dirname -- "$NAME")
SYM=$(readlink "$NAME")
NAME=$(cd "$DIR" && cd $(dirname -- "$SYM") && pwd)/$(basename -- "$SYM")
done
echo "$NAME"
}
LIB=$(dirname -- "$LIB")/
APP=$(dirname $(cd $(dirname $0) && pwd))
CONSOLE=$(dirname $(canonicalize "$0"))
APP=$(dirname "$CONSOLE")
exec php -q "$LIB"cake.php -working "$APP" "$@"
exec php -q $CONSOLE/cake.php -working "$APP" "$@"
exit;

View file

@ -15,7 +15,7 @@
* @since CakePHP(tm) v 0.10.0.1076
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
if (Configure::read('debug') == 0):
if (!Configure::read('debug')):
throw new NotFoundException();
endif;
App::uses('Debugger', 'Utility');
@ -116,7 +116,7 @@ if (isset($filePresent)):
endif;
?>
</p>
<?php endif;?>
<?php endif; ?>
<?php
App::uses('Validation', 'Utility');
if (!Validation::alphaNumeric('cakephp')) {
@ -127,6 +127,23 @@ if (isset($filePresent)):
echo '</span></p>';
}
?>
<p>
<?php
if (CakePlugin::loaded('DebugKit')):
echo '<span class="notice success">';
echo __d('cake_dev', 'DebugKit plugin is present');
echo '</span>';
else:
echo '<span class="notice">';
echo __d('cake_dev', 'DebugKit is not installed. It will help you inspect and debug different aspects of your application.');
echo '<br/>';
echo __d('cake_dev', 'You can install it from %s', $this->Html->link('github', 'https://github.com/cakephp/debug_kit'));
echo '</span>';
endif;
?>
</p>
<h3><?php echo __d('cake_dev', 'Editing this Page'); ?></h3>
<p>
<?php
@ -156,6 +173,20 @@ You can also add some CSS styles for your pages at: APP/webroot/css.');
?>
</p>
<h3><?php echo __d('cake_dev', 'Official Plugins'); ?></h3>
<p>
<ul>
<li>
<?php echo $this->Html->link('DebugKit', 'https://github.com/cakephp/debug_kit') ?>:
<?php echo __d('cake_dev', 'provides a debugging toolbar and enhanced debugging tools for CakePHP applications.'); ?>
</li>
<li>
<?php echo $this->Html->link('Localized', 'https://github.com/cakephp/localized') ?>:
<?php echo __d('cake_dev', 'contains various localized validation classes and translations for specific countries'); ?>
</li>
</ul>
</p>
<h3><?php echo __d('cake_dev', 'More about Cake'); ?></h3>
<p>
<?php echo __d('cake_dev', 'CakePHP is a rapid development framework for PHP which uses commonly known design patterns like Active Record, Association Data Mapping, Front Controller and MVC.'); ?>
@ -175,8 +206,8 @@ You can also add some CSS styles for your pages at: APP/webroot/css.');
<ul><li><?php echo __d('cake_dev', 'Quick Reference'); ?></li></ul></li>
<li><a href="http://bakery.cakephp.org"><?php echo __d('cake_dev', 'The Bakery'); ?> </a>
<ul><li><?php echo __d('cake_dev', 'Everything CakePHP'); ?></li></ul></li>
<li><a href="http://live.cakephp.org"><?php echo __d('cake_dev', 'The Show'); ?> </a>
<ul><li><?php echo __d('cake_dev', 'The Show is a live and archived internet radio broadcast CakePHP-related topics and answer questions live via IRC, Skype, and telephone.'); ?></li></ul></li>
<li><a href="http://plugins.cakephp.org"><?php echo __d('cake_dev', 'CakePHP plugins repo'); ?> </a>
<ul><li><?php echo __d('cake_dev', 'A comprehensive list of all CakePHP plugins created by the community'); ?></li></ul></li>
<li><a href="http://groups.google.com/group/cake-php"><?php echo __d('cake_dev', 'CakePHP Google Group'); ?> </a>
<ul><li><?php echo __d('cake_dev', 'Community mailing list'); ?></li></ul></li>
<li><a href="irc://irc.freenode.net/cakephp">irc.freenode.net #cakephp</a>

View file

@ -70,6 +70,11 @@ if (!defined('WWW_ROOT')) {
define('WWW_ROOT', dirname(__FILE__) . DS);
}
// for built-in server
if (php_sapi_name() == 'cli-server') {
$_SERVER['PHP_SELF'] = '/' . basename(__FILE__);
}
if (!defined('CAKE_CORE_INCLUDE_PATH')) {
if (function_exists('ini_set')) {
ini_set('include_path', ROOT . DS . 'lib' . PATH_SEPARATOR . ini_get('include_path'));
@ -89,4 +94,4 @@ if (!empty($failed)) {
App::uses('Dispatcher', 'Routing');
$Dispatcher = new Dispatcher();
$Dispatcher->dispatch(new CakeRequest(), new CakeResponse(array('charset' => Configure::read('App.encoding'))));
$Dispatcher->dispatch(new CakeRequest(), new CakeResponse());

View file

@ -103,7 +103,7 @@ class Cache {
* - `path` Used by FileCache. Path to where cachefiles should be saved.
* - `lock` Used by FileCache. Should files be locked before writing to them?
* - `user` Used by Xcache. Username for XCache
* - `password` Used by Xcache. Password for XCache
* - `password` Used by Xcache/Redis. Password for XCache/Redis
*
* @see app/Config/core.php for configuration settings
* @param string $name Name of the configuration
@ -366,7 +366,7 @@ class Cache {
}
$key = self::$_engines[$config]->key($key);
if (!$key || !is_integer($offset) || $offset < 0) {
if (!$key || !is_int($offset) || $offset < 0) {
return false;
}
$success = self::$_engines[$config]->increment($settings['prefix'] . $key, $offset);
@ -394,7 +394,7 @@ class Cache {
}
$key = self::$_engines[$config]->key($key);
if (!$key || !is_integer($offset) || $offset < 0) {
if (!$key || !is_int($offset) || $offset < 0) {
return false;
}
$success = self::$_engines[$config]->decrement($settings['prefix'] . $key, $offset);

View file

@ -61,9 +61,8 @@ class ApcEngine extends CacheEngine {
* @return boolean True if the data was successfully cached, false on failure
*/
public function write($key, $value, $duration) {
if ($duration == 0) {
$expires = 0;
} else {
if ($duration) {
$expires = time() + $duration;
}
apc_store($key . '_expires', $expires, $duration);

View file

@ -62,6 +62,7 @@ class RedisEngine extends CacheEngine {
'prefix' => null,
'server' => '127.0.0.1',
'port' => 6379,
'password' => false,
'timeout' => 0,
'persistent' => true
), $settings)
@ -87,6 +88,9 @@ class RedisEngine extends CacheEngine {
} catch (RedisException $e) {
return false;
}
if ($return && $this->settings['password']) {
$return = $this->_Redis->auth($this->settings['password']);
}
return $return;
}

3920
lib/Cake/Config/cacert.pem Normal file

File diff suppressed because it is too large Load diff

View file

@ -173,8 +173,10 @@ class IniReader implements ConfigReaderInterface {
public function dump($filename, $data) {
$result = array();
foreach ($data as $key => $value) {
$isSection = false;
if ($key[0] != '[') {
$result[] = "[$key]";
$isSection = true;
}
if (is_array($value)) {
$keyValues = Hash::flatten($value, '.');
@ -182,8 +184,11 @@ class IniReader implements ConfigReaderInterface {
$result[] = "$k = " . $this->_value($v);
}
}
if ($isSection) {
$result[] = '';
}
$contents = join("\n", $result);
}
$contents = trim(implode("\n", $result));
if (substr($filename, -4) !== '.ini') {
$filename .= '.ini';

View file

@ -598,7 +598,7 @@ class AclShell extends AppShell {
* @return array Variables
*/
protected function _dataVars($type = null) {
if ($type == null) {
if (!$type) {
$type = $this->args[0];
}
$vars = array();

View file

@ -73,12 +73,13 @@ class ApiShell extends AppShell {
$path = $this->paths['core'];
}
if (count($this->args) == 1) {
$file = $type;
$class = Inflector::camelize($type);
} elseif (count($this->args) > 1) {
$count = count($this->args);
if ($count > 1) {
$file = Inflector::underscore($this->args[1]);
$class = Inflector::camelize($this->args[1]);
} elseif ($count) {
$file = $type;
$class = Inflector::camelize($type);
}
$objects = App::objects('class', $path);
if (in_array($class, $objects)) {

View file

@ -182,7 +182,7 @@ class ConsoleShell extends AppShell {
$this->out(" - {$model}");
}
break;
case (preg_match("/^(\w+) bind (\w+) (\w+)/", $command, $tmp) == true):
case preg_match("/^(\w+) bind (\w+) (\w+)/", $command, $tmp):
foreach ($tmp as $data) {
$data = strip_tags($data);
$data = str_replace($this->badCommandChars, "", $data);
@ -200,7 +200,7 @@ class ConsoleShell extends AppShell {
$this->out(__d('cake_console', "Please verify you are using valid models and association types"));
}
break;
case (preg_match("/^(\w+) unbind (\w+) (\w+)/", $command, $tmp) == true):
case preg_match("/^(\w+) unbind (\w+) (\w+)/", $command, $tmp):
foreach ($tmp as $data) {
$data = strip_tags($data);
$data = str_replace($this->badCommandChars, "", $data);
@ -298,7 +298,7 @@ class ConsoleShell extends AppShell {
$this->out(__d('cake_console', 'Saved record for %s', $modelToSave));
}
break;
case (preg_match("/^(\w+) columns/", $command, $tmp) == true):
case preg_match("/^(\w+) columns/", $command, $tmp):
$modelToCheck = strip_tags(str_replace($this->badCommandChars, "", $tmp[1]));
if ($this->_isValidModel($modelToCheck)) {
@ -315,22 +315,22 @@ class ConsoleShell extends AppShell {
$this->out(__d('cake_console', "Please verify that you selected a valid model"));
}
break;
case (preg_match("/^routes\s+reload/i", $command, $tmp) == true):
case preg_match("/^routes\s+reload/i", $command, $tmp):
if (!$this->_loadRoutes()) {
$this->err(__d('cake_console', "There was an error loading the routes config. Please check that the file exists and is free of parse errors."));
break;
}
$this->out(__d('cake_console', "Routes configuration reloaded, %d routes connected", count(Router::$routes)));
break;
case (preg_match("/^routes\s+show/i", $command, $tmp) == true):
case preg_match("/^routes\s+show/i", $command, $tmp):
$this->out(print_r(Hash::combine(Router::$routes, '{n}.template', '{n}.defaults'), true));
break;
case (preg_match("/^route\s+(\(.*\))$/i", $command, $tmp) == true):
case preg_match("/^route\s+(\(.*\))$/i", $command, $tmp):
if ($url = eval('return array' . $tmp[1] . ';')) {
$this->out(Router::url($url));
}
break;
case (preg_match("/^route\s+(.*)/i", $command, $tmp) == true):
case preg_match("/^route\s+(.*)/i", $command, $tmp):
$this->out(var_export(Router::parse($tmp[1]), true));
break;
default:

View file

@ -89,6 +89,7 @@ class SchemaShell extends AppShell {
$name = $plugin;
}
}
$name = Inflector::classify($name);
$this->Schema = new CakeSchema(compact('name', 'path', 'file', 'connection', 'plugin'));
}
@ -120,7 +121,9 @@ class SchemaShell extends AppShell {
$this->out(__d('cake_console', 'Generating Schema...'));
$options = array();
if ($this->params['force']) {
$options = array('models' => false);
$options['models'] = false;
} elseif (!empty($this->params['models'])) {
$options['models'] = String::tokenize($this->params['models']);
}
$snapshot = false;
@ -459,6 +462,10 @@ class SchemaShell extends AppShell {
'short' => 's',
'help' => __d('cake_console', 'Snapshot number to use/make.')
);
$models = array(
'short' => 'm',
'help' => __d('cake_console', 'Specify models as comma separated list.'),
);
$dry = array(
'help' => __d('cake_console', 'Perform a dry run on create and update commands. Queries will be output instead of run.'),
'boolean' => true
@ -484,7 +491,7 @@ class SchemaShell extends AppShell {
))->addSubcommand('generate', array(
'help' => __d('cake_console', 'Reads from --connection and writes to --path. Generate snapshots with -s'),
'parser' => array(
'options' => compact('plugin', 'path', 'file', 'name', 'connection', 'snapshot', 'force'),
'options' => compact('plugin', 'path', 'file', 'name', 'connection', 'snapshot', 'force', 'models'),
'arguments' => array(
'snapshot' => array('help' => __d('cake_console', 'Generate a snapshot.'))
)

View file

@ -0,0 +1,167 @@
<?php
/**
* built-in Server Shell
*
* PHP 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @since CakePHP(tm) v 2.3.0
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
App::uses('AppShell', 'Console/Command');
/**
* built-in Server Shell
*
* @package Cake.Console.Command
*/
class ServerShell extends AppShell {
/**
* Default ServerHost
*/
const DEFAULT_HOST = 'localhost';
/**
* Default ListenPort
*/
const DEFAULT_PORT = 80;
/**
* server host
*
* @var string
*/
protected $_host = null;
/**
* listen port
*
* @var string
*/
protected $_port = null;
/**
* document root
*
* @var string
*/
protected $_documentRoot = null;
/**
* Override initialize of the Shell
*
* @return void
*/
public function initialize() {
$this->_host = self::DEFAULT_HOST;
$this->_port = self::DEFAULT_PORT;
$this->_documentRoot = WWW_ROOT;
}
/**
* Starts up the Shell and displays the welcome message.
* Allows for checking and configuring prior to command or main execution
*
* Override this method if you want to remove the welcome information,
* or otherwise modify the pre-command flow.
*
* @return void
* @link http://book.cakephp.org/2.0/en/console-and-shells.html#Shell::startup
*/
public function startup() {
if (!empty($this->params['host'])) {
$this->_host = $this->params['host'];
}
if (!empty($this->params['port'])) {
$this->_port = $this->params['port'];
}
if (!empty($this->params['document_root'])) {
$this->_documentRoot = $this->params['document_root'];
}
// for windows
if (substr($this->_documentRoot, -1, 1) == DIRECTORY_SEPARATOR) {
$this->_documentRoot = substr($this->_documentRoot, 0, strlen($this->_documentRoot) - 1);
}
if (preg_match("/^([a-z]:)[\\\]+(.+)$/i", $this->_documentRoot, $m)) {
$this->_documentRoot = $m[1] . '\\' . $m[2];
}
parent::startup();
}
/**
* Displays a header for the shell
*
* @return void
*/
protected function _welcome() {
$this->out();
$this->out(__d('cake_console', '<info>Welcome to CakePHP %s Console</info>', 'v' . Configure::version()));
$this->hr();
$this->out(__d('cake_console', 'App : %s', APP_DIR));
$this->out(__d('cake_console', 'Path: %s', APP));
$this->out(__d('cake_console', 'DocumentRoot: %s', $this->_documentRoot));
$this->hr();
}
/**
* Override main() to handle action
*
* @return void
*/
public function main() {
if (version_compare(PHP_VERSION, '5.4.0') < 0) {
$this->out(__d('cake_console', '<warning>This command is available on PHP5.4 or above</warning>'));
return;
}
$command = sprintf("php -S %s:%d -t %s",
$this->_host,
$this->_port,
$this->_documentRoot
);
$port = ($this->_port == self::DEFAULT_PORT) ? '' : ':' . $this->_port;
$this->out(__d('cake_console', 'built-in server is running in http://%s%s/', $this->_host, $port));
$ret = system($command);
}
/**
* Get and configure the optionparser.
*
* @return ConsoleOptionParser
*/
public function getOptionParser() {
$parser = parent::getOptionParser();
$parser->addOption('host', array(
'short' => 'H',
'help' => __d('cake_console', 'ServerHost')
));
$parser->addOption('port', array(
'short' => 'p',
'help' => __d('cake_console', 'ListenPort')
));
$parser->addOption('document_root', array(
'short' => 'd',
'help' => __d('cake_console', 'DocumentRoot')
));
$parser->description(array(
__d('cake_console', 'PHP Built-in Server for CakePHP'),
__d('cake_console', '<warning>[WARN] Don\'t use this at the production environment</warning>'),
));
return $parser;
}
}

View file

@ -349,7 +349,7 @@ class ControllerTask extends BakeTask {
public function doHelpers() {
return $this->_doPropertyChoices(
__d('cake_console', "Would you like this controller to use other helpers\nbesides HtmlHelper and FormHelper?"),
__d('cake_console', "Please provide a comma separated list of the other\nhelper names you'd like to use.\nExample: 'Ajax, Javascript, Time'")
__d('cake_console', "Please provide a comma separated list of the other\nhelper names you'd like to use.\nExample: 'Text, Js, Time'")
);
}
@ -395,7 +395,7 @@ class ControllerTask extends BakeTask {
}
$this->__tables = $this->Model->getAllTables($useDbConfig);
if ($this->interactive == true) {
if ($this->interactive) {
$this->out(__d('cake_console', 'Possible Controllers based on your current database:'));
$this->hr();
$this->_controllerNames = array();
@ -419,20 +419,20 @@ class ControllerTask extends BakeTask {
$controllers = $this->listAll($useDbConfig);
$enteredController = '';
while ($enteredController == '') {
while (!$enteredController) {
$enteredController = $this->in(__d('cake_console', "Enter a number from the list above,\ntype in the name of another controller, or 'q' to exit"), null, 'q');
if ($enteredController === 'q') {
$this->out(__d('cake_console', 'Exit'));
return $this->_stop();
}
if ($enteredController == '' || intval($enteredController) > count($controllers)) {
if (!$enteredController || intval($enteredController) > count($controllers)) {
$this->err(__d('cake_console', "The Controller name you supplied was empty,\nor the number you selected was not an option. Please try again."));
$enteredController = '';
}
}
if (intval($enteredController) > 0 && intval($enteredController) <= count($controllers) ) {
if (intval($enteredController) > 0 && intval($enteredController) <= count($controllers)) {
$controllerName = $controllers[intval($enteredController) - 1];
} else {
$controllerName = Inflector::camelize($enteredController);

View file

@ -92,10 +92,10 @@ class DbConfigTask extends AppShell {
$done = false;
$dbConfigs = array();
while ($done == false) {
while (!$done) {
$name = '';
while ($name == '') {
while (!$name) {
$name = $this->in(__d('cake_console', "Name:"), null, 'default');
if (preg_match('/[^a-z0-9_]/i', $name)) {
$name = '';
@ -116,12 +116,12 @@ class DbConfigTask extends AppShell {
}
$host = '';
while ($host == '') {
while (!$host) {
$host = $this->in(__d('cake_console', 'Database Host:'), null, 'localhost');
}
$port = '';
while ($port == '') {
while (!$port) {
$port = $this->in(__d('cake_console', 'Port?'), null, 'n');
}
@ -130,16 +130,16 @@ class DbConfigTask extends AppShell {
}
$login = '';
while ($login == '') {
while (!$login) {
$login = $this->in(__d('cake_console', 'User:'), null, 'root');
}
$password = '';
$blankPassword = false;
while ($password == '' && $blankPassword == false) {
while (!$password && !$blankPassword) {
$password = $this->in(__d('cake_console', 'Password:'));
if ($password == '') {
if (!$password) {
$blank = $this->in(__d('cake_console', 'The password you supplied was empty. Use an empty password?'), array('y', 'n'), 'n');
if ($blank == 'y') {
$blankPassword = true;
@ -148,12 +148,12 @@ class DbConfigTask extends AppShell {
}
$database = '';
while ($database == '') {
while (!$database) {
$database = $this->in(__d('cake_console', 'Database Name:'), null, 'cake');
}
$prefix = '';
while ($prefix == '') {
while (!$prefix) {
$prefix = $this->in(__d('cake_console', 'Table Prefix?'), null, 'n');
}
if (strtolower($prefix) == 'n') {
@ -161,7 +161,7 @@ class DbConfigTask extends AppShell {
}
$encoding = '';
while ($encoding == '') {
while (!$encoding) {
$encoding = $this->in(__d('cake_console', 'Table encoding?'), null, 'n');
}
if (strtolower($encoding) == 'n') {
@ -170,7 +170,7 @@ class DbConfigTask extends AppShell {
$schema = '';
if ($datasource == 'postgres') {
while ($schema == '') {
while (!$schema) {
$schema = $this->in(__d('cake_console', 'Table schema?'), null, 'n');
}
}
@ -180,7 +180,7 @@ class DbConfigTask extends AppShell {
$config = compact('name', 'datasource', 'persistent', 'host', 'login', 'password', 'database', 'prefix', 'encoding', 'port', 'schema');
while ($this->_verify($config) == false) {
while (!$this->_verify($config)) {
$this->_interactive();
}
@ -277,11 +277,7 @@ class DbConfigTask extends AppShell {
$info['port'] = null;
}
if ($info['persistent'] === false) {
$info['persistent'] = 'false';
} else {
$info['persistent'] = ($info['persistent'] == true) ? 'true' : 'false';
}
$info['persistent'] = var_export((bool)$info['persistent'], true);
$oldConfigs[] = array(
'name' => $configName,

View file

@ -391,7 +391,7 @@ class ExtractTask extends AppShell {
$position = $count;
$depth = 0;
while ($depth == 0) {
while (!$depth) {
if ($this->_tokens[$position] == '(') {
$depth++;
} elseif ($this->_tokens[$position] == ')') {
@ -480,7 +480,7 @@ class ExtractTask extends AppShell {
}
$dims = Hash::dimensions($rules);
if ($dims == 1 || ($dims == 2 && isset($rules['message']))) {
if ($dims === 1 || ($dims === 2 && isset($rules['message']))) {
$rules = array($rules);
}
@ -523,7 +523,7 @@ class ExtractTask extends AppShell {
$occurrences[] = $file . ':' . implode(';', $lines);
}
$occurrences = implode("\n#: ", $occurrences);
$header = '#: ' . str_replace($paths, '', $occurrences) . "\n";
$header = '#: ' . str_replace(DS, '/', str_replace($paths, '', $occurrences)) . "\n";
if ($plural === false) {
$sentence = "msgid \"{$msgid}\"\n";
@ -591,7 +591,7 @@ class ExtractTask extends AppShell {
);
if (strtoupper($response) === 'N') {
$response = '';
while ($response == '') {
while (!$response) {
$response = $this->in(__d('cake_console', "What would you like to name this file?"), null, 'new_' . $filename);
$File = new File($this->_output . $response);
$filename = $response;

View file

@ -472,16 +472,14 @@ class ModelTask extends BakeTask {
}
if ($choice != $defaultChoice) {
$validate[$validatorName] = $choice;
if (is_numeric($choice) && isset($this->_validations[$choice])) {
$validate[$validatorName] = $this->_validations[$choice];
} else {
$validate[$validatorName] = $choice;
}
}
if ($this->interactive == true && $choice != $defaultChoice) {
$anotherValidator = $this->in(__d('cake_console', 'Would you like to add another validation rule?'), array('y', 'n'), 'n');
} else {
$anotherValidator = 'n';
if ($this->interactive && $choice != $defaultChoice) {
$anotherValidator = $this->in(__d('cake_console', 'Would you like to add another validation rule?'), array('y', 'n'), 'n');
}
}
return $validate;
@ -583,7 +581,7 @@ class ModelTask extends BakeTask {
$pattern = '/_' . preg_quote($model->table, '/') . '|' . preg_quote($model->table, '/') . '_/';
$possibleJoinTable = preg_match($pattern, $otherTable);
if ($possibleJoinTable == true) {
if ($possibleJoinTable) {
continue;
}
foreach ($modelFieldsTemp as $fieldName => $field) {
@ -688,7 +686,7 @@ class ModelTask extends BakeTask {
$prompt = __d('cake_console', 'Would you like to define some additional model associations?');
$wannaDoMoreAssoc = $this->in($prompt, array('y', 'n'), 'n');
$possibleKeys = $this->_generatePossibleKeys();
while (strtolower($wannaDoMoreAssoc) == 'y') {
while (strtolower($wannaDoMoreAssoc) === 'y') {
$assocs = array('belongsTo', 'hasOne', 'hasMany', 'hasAndBelongsToMany');
$this->out(__d('cake_console', 'What is the association type?'));
$assocType = intval($this->inOptions($assocs, __d('cake_console', 'Enter a number')));
@ -698,9 +696,9 @@ class ModelTask extends BakeTask {
$this->hr();
$alias = $this->in(__d('cake_console', 'What is the alias for this association?'));
$className = $this->in(__d('cake_console', 'What className will %s use?', $alias), null, $alias );
$className = $this->in(__d('cake_console', 'What className will %s use?', $alias), null, $alias);
if ($assocType == 0) {
if ($assocType === 0) {
if (!empty($possibleKeys[$model->table])) {
$showKeys = $possibleKeys[$model->table];
} else {
@ -733,7 +731,7 @@ class ModelTask extends BakeTask {
if (!isset($foreignKey)) {
$foreignKey = $this->in(__d('cake_console', 'What is the foreignKey? Specify your own.'), null, $suggestedForeignKey);
}
if ($assocType == 3) {
if ($assocType === 3) {
$associationForeignKey = $this->in(__d('cake_console', 'What is the associationForeignKey?'), null, $this->_modelKey($model->name));
$joinTable = $this->in(__d('cake_console', 'What is the joinTable?'));
}
@ -743,7 +741,7 @@ class ModelTask extends BakeTask {
$associations[$assocs[$assocType]][$i]['alias'] = $alias;
$associations[$assocs[$assocType]][$i]['className'] = $className;
$associations[$assocs[$assocType]][$i]['foreignKey'] = $foreignKey;
if ($assocType == 3) {
if ($assocType === 3) {
$associations[$assocs[$assocType]][$i]['associationForeignKey'] = $associationForeignKey;
$associations[$assocs[$assocType]][$i]['joinTable'] = $joinTable;
}
@ -780,7 +778,7 @@ class ModelTask extends BakeTask {
*/
public function bake($name, $data = array()) {
if (is_object($name)) {
if ($data == false) {
if (!$data) {
$data = array();
$data['associations'] = $this->doAssociations($name);
$data['validate'] = $this->doValidation($name);
@ -935,7 +933,7 @@ class ModelTask extends BakeTask {
$enteredModel = '';
while ($enteredModel == '') {
while (!$enteredModel) {
$enteredModel = $this->in(__d('cake_console', "Enter a number from the list above,\n" .
"type in the name of another model, or 'q' to exit"), null, 'q');
@ -944,18 +942,17 @@ class ModelTask extends BakeTask {
$this->_stop();
}
if ($enteredModel == '' || intval($enteredModel) > count($this->_modelNames)) {
if (!$enteredModel || intval($enteredModel) > count($this->_modelNames)) {
$this->err(__d('cake_console', "The model name you supplied was empty,\n" .
"or the number you selected was not an option. Please try again."));
$enteredModel = '';
}
}
if (intval($enteredModel) > 0 && intval($enteredModel) <= count($this->_modelNames)) {
$currentModelName = $this->_modelNames[intval($enteredModel) - 1];
} else {
$currentModelName = $enteredModel;
return $this->_modelNames[intval($enteredModel) - 1];
}
return $currentModelName;
return $enteredModel;
}
/**

View file

@ -66,7 +66,7 @@ class ProjectTask extends AppShell {
}
$response = false;
while ($response == false && is_dir($project) === true && file_exists($project . 'Config' . 'core.php')) {
while (!$response && is_dir($project) === true && file_exists($project . 'Config' . 'core.php')) {
$prompt = __d('cake_console', '<warning>A project already exists in this location:</warning> %s Overwrite?', $project);
$response = $this->in($prompt, array('y', 'n'), 'n');
if (strtolower($response) === 'n') {
@ -92,6 +92,13 @@ class ProjectTask extends AppShell {
$success = false;
}
if ($this->cachePrefix($path)) {
$this->out(__d('cake_console', ' * Cache prefix set'));
} else {
$this->err(__d('cake_console', 'The cache prefix was <error>NOT</error> set'));
$success = false;
}
if ($this->consolePath($path) === true) {
$this->out(__d('cake_console', ' * app/Console/cake.php path set.'));
} else {
@ -284,6 +291,23 @@ class ProjectTask extends AppShell {
return false;
}
/**
* Writes cache prefix using app's name
*
* @param string $dir Path to project
* @return boolean Success
*/
public function cachePrefix($dir) {
$app = basename($dir);
$File = new File($dir . 'Config' . DS . 'core.php');
$contents = $File->read();
if (preg_match('/(\$prefix = \'myapp_\';)/', $contents, $match)) {
$result = str_replace($match[0], '$prefix = \'' . $app . '_\';', $contents);
return $File->write($result);
}
return false;
}
/**
* Generates and writes CAKE_CORE_INCLUDE_PATH
*
@ -325,10 +349,7 @@ class ProjectTask extends AppShell {
if (!file_put_contents($filename, $result)) {
return false;
}
if ($count == 0) {
return false;
}
return true;
return (bool)$count;
}
/**
@ -363,7 +384,7 @@ class ProjectTask extends AppShell {
$admin = '';
$prefixes = Configure::read('Routing.prefixes');
if (!empty($prefixes)) {
if (count($prefixes) == 1) {
if (count($prefixes) === 1) {
return $prefixes[0] . '_';
}
if ($this->interactive) {
@ -385,7 +406,7 @@ class ProjectTask extends AppShell {
$this->out(__d('cake_console', 'You need to enable Configure::write(\'Routing.prefixes\',array(\'admin\')) in /app/Config/core.php to use prefix routing.'));
$this->out(__d('cake_console', 'What would you like the prefix route to be?'));
$this->out(__d('cake_console', 'Example: www.example.com/admin/controller'));
while ($admin == '') {
while (!$admin) {
$admin = $this->in(__d('cake_console', 'Enter a routing prefix:'), null, 'admin');
}
if ($this->cakeAdmin($admin) !== true) {

View file

@ -123,7 +123,7 @@ class TemplateTask extends AppShell {
$data = array($one => $two);
}
if ($data == null) {
if (!$data) {
return false;
}
$this->templateVars = $data + $this->templateVars;
@ -166,7 +166,7 @@ class TemplateTask extends AppShell {
* @return string returns the path to the selected theme.
*/
public function getThemePath() {
if (count($this->templatePaths) == 1) {
if (count($this->templatePaths) === 1) {
$paths = array_values($this->templatePaths);
return $paths[0];
}

View file

@ -83,15 +83,16 @@ class TestTask extends BakeTask {
*/
public function execute() {
parent::execute();
if (empty($this->args)) {
$count = count($this->args);
if (!$count) {
$this->_interactive();
}
if (count($this->args) == 1) {
if ($count === 1) {
$this->_interactive($this->args[0]);
}
if (count($this->args) > 1) {
if ($count > 1) {
$type = Inflector::classify($this->args[0]);
if ($this->bake($type, $this->args[1])) {
$this->out('<success>Done</success>');
@ -334,7 +335,7 @@ class TestTask extends BakeTask {
* @param string $type The type the class having a test
* generated for is in.
* @return array Array of (class, type)
* @throws CakeException On invalid typename
* @throws CakeException on invalid types.
*/
public function getBaseType($type) {
if (empty($this->baseTypes[$type])) {

View file

@ -316,9 +316,9 @@ class ViewTask extends BakeTask {
*/
public function customAction() {
$action = '';
while ($action == '') {
while (!$action) {
$action = $this->in(__d('cake_console', 'Action Name? (use lowercase_underscored function name)'));
if ($action == '') {
if (!$action) {
$this->out(__d('cake_console', 'The action name you supplied was empty. Please try again.'));
}
}

View file

@ -81,7 +81,7 @@ class ConsoleErrorHandler {
$message = __d('cake_console', '%s in [%s, line %s]', $description, $file, $line);
$stderr->write(__d('cake_console', "<error>%s Error:</error> %s\n", $name, $message));
if (Configure::read('debug') == 0) {
if (!Configure::read('debug')) {
CakeLog::write($log, $message);
}

View file

@ -154,7 +154,7 @@ class Shell extends Object {
* @link http://book.cakephp.org/2.0/en/console-and-shells.html#Shell
*/
public function __construct($stdout = null, $stderr = null, $stdin = null) {
if ($this->name == null) {
if (!$this->name) {
$this->name = Inflector::camelize(str_replace(array('Shell', 'Task'), '', get_class($this)));
}
$this->Tasks = new TaskCollection($this);
@ -162,13 +162,13 @@ class Shell extends Object {
$this->stdout = $stdout;
$this->stderr = $stderr;
$this->stdin = $stdin;
if ($this->stdout == null) {
if (!$this->stdout) {
$this->stdout = new ConsoleOutput('php://stdout');
}
if ($this->stderr == null) {
if (!$this->stderr) {
$this->stderr = new ConsoleOutput('php://stderr');
}
if ($this->stdin == null) {
if (!$this->stdin) {
$this->stdin = new ConsoleInput('php://stdin');
}
$this->_useLogger();
@ -325,7 +325,7 @@ class Shell extends Object {
*/
public function dispatchShell() {
$args = func_get_args();
if (is_string($args[0]) && count($args) == 1) {
if (is_string($args[0]) && count($args) === 1) {
$args = explode(' ', $args[0]);
}

View file

@ -276,7 +276,11 @@ class ShellDispatcher {
if (isset($params['working'])) {
$params['working'] = trim($params['working']);
}
if (!empty($params['working']) && (!isset($this->args[0]) || isset($this->args[0]) && $this->args[0]{0} !== '.')) {
if (!empty($params['working']) && (!isset($this->args[0]) || isset($this->args[0]) && $this->args[0][0] !== '.')) {
if ($params['working'][0] === '.') {
$params['working'] = realpath($params['working']);
}
if (empty($this->params['app']) && $params['working'] != $params['root']) {
$params['root'] = dirname($params['working']);
$params['app'] = basename($params['working']);

View file

@ -36,11 +36,11 @@
* @return void
*/
public function <?php echo $admin ?>view($id = null) {
$this-><?php echo $currentModelName; ?>->id = $id;
if (!$this-><?php echo $currentModelName; ?>->exists()) {
if (!$this-><?php echo $currentModelName; ?>->exists($id)) {
throw new NotFoundException(__('Invalid <?php echo strtolower($singularHumanName); ?>'));
}
$this->set('<?php echo $singularName; ?>', $this-><?php echo $currentModelName; ?>->read(null, $id));
$options = array('conditions' => array('<?php echo $currentModelName; ?>.' . $this-><?php echo $currentModelName; ?>->primaryKey => $id));
$this->set('<?php echo $singularName; ?>', $this-><?php echo $currentModelName; ?>->find('first', $options));
}
<?php $compact = array(); ?>
@ -91,8 +91,7 @@
* @return void
*/
public function <?php echo $admin; ?>edit($id = null) {
$this-><?php echo $currentModelName; ?>->id = $id;
if (!$this-><?php echo $currentModelName; ?>->exists()) {
if (!$this-><?php echo $currentModelName; ?>->exists($id)) {
throw new NotFoundException(__('Invalid <?php echo strtolower($singularHumanName); ?>'));
}
if ($this->request->is('post') || $this->request->is('put')) {
@ -109,7 +108,8 @@
<?php endif; ?>
}
} else {
$this->request->data = $this-><?php echo $currentModelName; ?>->read(null, $id);
$options = array('conditions' => array('<?php echo $currentModelName; ?>.' . $this-><?php echo $currentModelName; ?>->primaryKey => $id));
$this->request->data = $this-><?php echo $currentModelName; ?>->find('first', $options);
}
<?php
foreach (array('belongsTo', 'hasAndBelongsToMany') as $assoc):
@ -131,19 +131,17 @@
/**
* <?php echo $admin ?>delete method
*
* @throws MethodNotAllowedException
* @throws NotFoundException
* @throws MethodNotAllowedException
* @param string $id
* @return void
*/
public function <?php echo $admin; ?>delete($id = null) {
if (!$this->request->is('post')) {
throw new MethodNotAllowedException();
}
$this-><?php echo $currentModelName; ?>->id = $id;
if (!$this-><?php echo $currentModelName; ?>->exists()) {
throw new NotFoundException(__('Invalid <?php echo strtolower($singularHumanName); ?>'));
}
$this->request->onlyAllow('post', 'delete');
if ($this-><?php echo $currentModelName; ?>->delete()) {
<?php if ($wannaUseSession): ?>
$this->Session->setFlash(__('<?php echo ucfirst(strtolower($singularHumanName)); ?> deleted'));

View file

@ -26,8 +26,7 @@
<th class="actions"><?php echo "<?php echo __('Actions'); ?>"; ?></th>
</tr>
<?php
echo "<?php
foreach (\${$pluralVar} as \${$singularVar}): ?>\n";
echo "<?php foreach (\${$pluralVar} as \${$singularVar}): ?>\n";
echo "\t<tr>\n";
foreach ($fields as $field) {
$isKey = false;
@ -62,7 +61,6 @@
));
?>"; ?>
</p>
<div class="paging">
<?php
echo "<?php\n";

View file

@ -293,18 +293,20 @@
*/
/**
* Pick the caching engine to use. If APC is enabled use it.
* If running via cli - apc is disabled by default. ensure it's available and enabled in this case
* Configure the cache handlers that CakePHP will use for internal
* metadata like class maps, and model schema.
*
* By default File is used, but for improved performance you should use APC.
*
* Note: 'default' and other application caches should be configured in app/Config/bootstrap.php.
* Please check the comments in boostrap.php for more info on the cache engines available
* and their setttings.
*/
$engine = 'File';
if (extension_loaded('apc') && function_exists('apc_dec') && (php_sapi_name() !== 'cli' || ini_get('apc.enable_cli'))) {
$engine = 'Apc';
}
// In development mode, caches should expire quickly.
$duration = '+999 days';
if (Configure::read('debug') >= 1) {
if (Configure::read('debug') > 0) {
$duration = '+10 seconds';
}

View file

@ -17,17 +17,21 @@
# @license MIT License (http://www.opensource.org/licenses/mit-license.php)
#
################################################################################
LIB=$(cd -P -- "$(dirname -- "$0")" && pwd -P) && LIB=$LIB/$(basename -- "$0")
while [ -h "$LIB" ]; do
DIR=$(dirname -- "$LIB")
SYM=$(readlink "$LIB")
LIB=$(cd "$DIR" && cd $(dirname -- "$SYM") && pwd)/$(basename -- "$SYM")
done
# Canonicalize by following every symlink of the given name recursively
canonicalize() {
NAME=$1
while [ -h "$NAME" ]; do
DIR=$(dirname -- "$NAME")
SYM=$(readlink "$NAME")
NAME=$(cd "$DIR" && cd $(dirname -- "$SYM") && pwd)/$(basename -- "$SYM")
done
echo "$NAME"
}
LIB=$(dirname -- "$LIB")/
APP=`pwd`
CONSOLE=$(dirname $(canonicalize "$0"))
APP=$(dirname "$CONSOLE")
exec php -q "$LIB"cake.php -working "$APP" "$@"
exec php -q $CONSOLE/cake.php -working "$APP" "$@"
exit;

View file

@ -18,6 +18,7 @@
* @since CakePHP(tm) v 0.2.9
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
App::uses('AppController', 'Controller');
/**
* Static content controller

View file

@ -25,7 +25,7 @@
); ?>
</p>
<?php
if (Configure::read('debug') > 0 ):
if (Configure::read('debug') > 0):
echo $this->element('exception_stack_trace');
endif;
?>

View file

@ -22,7 +22,7 @@
<?php echo __d('cake', 'An Internal Error Has Occurred.'); ?>
</p>
<?php
if (Configure::read('debug') > 0 ):
if (Configure::read('debug') > 0):
echo $this->element('exception_stack_trace');
endif;
?>

View file

@ -16,7 +16,7 @@
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<?php echo $this->Html->charset(); ?>

View file

@ -16,7 +16,7 @@
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<?php echo $this->Html->charset(); ?>

View file

@ -16,7 +16,7 @@
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<?php echo $this->Html->charset(); ?>

View file

@ -15,7 +15,7 @@
* @since CakePHP(tm) v 0.10.0.1076
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
if (Configure::read('debug') == 0):
if (!Configure::read('debug')):
throw new NotFoundException();
endif;
App::uses('Debugger', 'Utility');
@ -127,11 +127,28 @@ if (isset($filePresent)):
echo '</span></p>';
}
?>
<p>
<?php
if (CakePlugin::loaded('DebugKit')):
echo '<span class="notice success">';
echo __d('cake_dev', 'DebugKit plugin is present');
echo '</span>';
else:
echo '<span class="notice">';
echo __d('cake_dev', 'DebugKit is not installed. It will help you inspect and debug different aspects of your application.');
echo '<br/>';
echo __d('cake_dev', 'You can install it from %s', $this->Html->link('github', 'https://github.com/cakephp/debug_kit'));
echo '</span>';
endif;
?>
</p>
<h3><?php echo __d('cake_dev', 'Editing this Page'); ?></h3>
<p>
<?php
echo __d('cake_dev', 'To change the content of this page, create: APP/View/Pages/home.ctp.<br />
To change its layout, create: APP/View/Layouts/default.ctp.<br />
echo __d('cake_dev', 'To change the content of this page, edit: APP/View/Pages/home.ctp.<br />
To change its layout, edit: APP/View/Layouts/default.ctp.<br />
You can also add some CSS styles for your pages at: APP/webroot/css.');
?>
</p>
@ -156,6 +173,20 @@ You can also add some CSS styles for your pages at: APP/webroot/css.');
?>
</p>
<h3><?php echo __d('cake_dev', 'Official Plugins'); ?></h3>
<p>
<ul>
<li>
<?php echo $this->Html->link('DebugKit', 'https://github.com/cakephp/debug_kit') ?>:
<?php echo __d('cake_dev', 'provides a debugging toolbar and enhanced debugging tools for CakePHP applications.'); ?>
</li>
<li>
<?php echo $this->Html->link('Localized', 'https://github.com/cakephp/localized') ?>:
<?php echo __d('cake_dev', 'contains various localized validation classes and translations for specific countries'); ?>
</li>
</ul>
</p>
<h3><?php echo __d('cake_dev', 'More about Cake'); ?></h3>
<p>
<?php echo __d('cake_dev', 'CakePHP is a rapid development framework for PHP which uses commonly known design patterns like Active Record, Association Data Mapping, Front Controller and MVC.'); ?>
@ -175,8 +206,8 @@ You can also add some CSS styles for your pages at: APP/webroot/css.');
<ul><li><?php echo __d('cake_dev', 'Quick Reference'); ?></li></ul></li>
<li><a href="http://bakery.cakephp.org"><?php echo __d('cake_dev', 'The Bakery'); ?> </a>
<ul><li><?php echo __d('cake_dev', 'Everything CakePHP'); ?></li></ul></li>
<li><a href="http://live.cakephp.org"><?php echo __d('cake_dev', 'The Show'); ?> </a>
<ul><li><?php echo __d('cake_dev', 'The Show is a live and archived internet radio broadcast CakePHP-related topics and answer questions live via IRC, Skype, and telephone.'); ?></li></ul></li>
<li><a href="http://plugins.cakephp.org"><?php echo __d('cake_dev', 'CakePHP plugins repo'); ?> </a>
<ul><li><?php echo __d('cake_dev', 'A comprehensive list of all CakePHP plugins created by the community'); ?></li></ul></li>
<li><a href="http://groups.google.com/group/cake-php"><?php echo __d('cake_dev', 'CakePHP Google Group'); ?> </a>
<ul><li><?php echo __d('cake_dev', 'Community mailing list'); ?></li></ul></li>
<li><a href="irc://irc.freenode.net/cakephp">irc.freenode.net #cakephp</a>

View file

@ -72,6 +72,11 @@ if (!defined('WWW_ROOT')) {
define('WWW_ROOT', dirname(__FILE__) . DS);
}
// for built-in server
if (php_sapi_name() == 'cli-server') {
$_SERVER['PHP_SELF'] = '/' . basename(__FILE__);
}
if (!defined('CAKE_CORE_INCLUDE_PATH')) {
if (function_exists('ini_set')) {
ini_set('include_path', ROOT . DS . 'lib' . PATH_SEPARATOR . ini_get('include_path'));
@ -93,5 +98,5 @@ App::uses('Dispatcher', 'Routing');
$Dispatcher = new Dispatcher();
$Dispatcher->dispatch(
new CakeRequest(),
new CakeResponse(array('charset' => Configure::read('App.encoding')))
new CakeResponse()
);

View file

@ -86,7 +86,7 @@ if (!empty($failed)) {
}
if (Configure::read('debug') < 1) {
die(__d('cake_dev', 'Debug setting does not allow access to this url.'));
exit(__d('cake_dev', 'Debug setting does not allow access to this url.'));
}
require_once CAKE . 'TestSuite' . DS . 'CakeTestSuiteDispatcher.php';

View file

@ -17,17 +17,21 @@
# @license MIT License (http://www.opensource.org/licenses/mit-license.php)
#
################################################################################
LIB=$(cd -P -- "$(dirname -- "$0")" && pwd -P) && LIB=$LIB/$(basename -- "$0")
while [ -h "$LIB" ]; do
DIR=$(dirname -- "$LIB")
SYM=$(readlink "$LIB")
LIB=$(cd "$DIR" && cd $(dirname -- "$SYM") && pwd)/$(basename -- "$SYM")
done
# Canonicalize by following every symlink of the given name recursively
canonicalize() {
NAME=$1
while [ -h "$NAME" ]; do
DIR=$(dirname -- "$NAME")
SYM=$(readlink "$NAME")
NAME=$(cd "$DIR" && cd $(dirname -- "$SYM") && pwd)/$(basename -- "$SYM")
done
echo "$NAME"
}
LIB=$(dirname -- "$LIB")/
CONSOLE=$(dirname $(canonicalize "$0"))
APP=`pwd`
exec php -q "$LIB"cake.php -working "$APP" "$@"
exec php -q $CONSOLE/cake.php -working "$APP" "$@"
exit;

View file

@ -71,18 +71,4 @@ class CakeErrorController extends AppController {
$this->_set(array('cacheAction' => false, 'viewPath' => 'Errors'));
}
/**
* Escapes the viewVars.
*
* @return void
*/
public function beforeRender() {
parent::beforeRender();
foreach ($this->viewVars as $key => $value) {
if (!is_object($value)) {
$this->viewVars[$key] = h($value);
}
}
}
}

View file

@ -91,7 +91,7 @@ class IniAcl extends Object implements AclInterface {
* @return boolean Success
*/
public function check($aro, $aco, $action = null) {
if ($this->config == null) {
if (!$this->config) {
$this->config = $this->readConfigFile(APP . 'Config' . DS . 'acl.ini.php');
}
$aclConfig = $this->config;

View file

@ -170,11 +170,11 @@ class PhpAcl extends Object implements AclInterface {
foreach ($path as $depth => $node) {
foreach ($prioritizedAros as $aros) {
if (!empty($node['allow'])) {
$allow = $allow || count(array_intersect($node['allow'], $aros)) > 0;
$allow = $allow || count(array_intersect($node['allow'], $aros));
}
if (!empty($node['deny'])) {
$allow = $allow && count(array_intersect($node['deny'], $aros)) == 0;
$allow = $allow && !count(array_intersect($node['deny'], $aros));
}
}
}

View file

@ -66,19 +66,28 @@ abstract class BaseAuthenticate {
/**
* Find a user record using the standard options.
*
* @param string $username The username/identifier.
* @param string $password The unhashed password.
* The $conditions parameter can be a (string)username or an array containing conditions for Model::find('first'). If
* the password field is not included in the conditions the password will be returned.
*
* @param Mixed $conditions The username/identifier, or an array of find conditions.
* @param Mixed $password The password, only use if passing as $conditions = 'username'.
* @return Mixed Either false on failure, or an array of user data.
*/
protected function _findUser($username, $password) {
protected function _findUser($conditions, $password = null) {
$userModel = $this->settings['userModel'];
list($plugin, $model) = pluginSplit($userModel);
$fields = $this->settings['fields'];
if (!is_array($conditions)) {
if (!$password) {
return false;
}
$username = $conditions;
$conditions = array(
$model . '.' . $fields['username'] => $username,
$model . '.' . $fields['password'] => $this->_password($password),
);
}
if (!empty($this->settings['scope'])) {
$conditions = array_merge($conditions, $this->settings['scope']);
}
@ -91,7 +100,12 @@ abstract class BaseAuthenticate {
return false;
}
$user = $result[$model];
if (
isset($conditions[$model . '.' . $fields['password']]) ||
isset($conditions[$fields['password']])
) {
unset($user[$fields['password']]);
}
unset($result[$model]);
return array_merge($user, $result);
}

View file

@ -0,0 +1,78 @@
<?php
/**
* PHP 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* Redistributions of the files must retain the above copyright notice.
*
* @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
App::uses('FormAuthenticate', 'Controller/Component/Auth');
/**
* An authentication adapter for AuthComponent. Provides the ability to authenticate using POST data using Blowfish
* hashing. Can be used by configuring AuthComponent to use it via the AuthComponent::$authenticate setting.
*
* {{{
* $this->Auth->authenticate = array(
* 'Blowfish' => array(
* 'scope' => array('User.active' => 1)
* )
* )
* }}}
*
* When configuring BlowfishAuthenticate you can pass in settings to which fields, model and additional conditions
* are used. See FormAuthenticate::$settings for more information.
*
* For inital password hashing/creation see Security::hash(). Other than how the password is initally hashed,
* BlowfishAuthenticate works exactly the same way as FormAuthenticate.
*
* @package Cake.Controller.Component.Auth
* @since CakePHP(tm) v 2.3
* @see AuthComponent::$authenticate
*/
class BlowfishAuthenticate extends FormAuthenticate {
/**
* Authenticates the identity contained in a request. Will use the `settings.userModel`, and `settings.fields`
* to find POST data that is used to find a matching record in the`settings.userModel`. Will return false if
* there is no post data, either username or password is missing, or if the scope conditions have not been met.
*
* @param CakeRequest $request The request that contains login information.
* @param CakeResponse $response Unused response object.
* @return mixed False on login failure. An array of User data on success.
*/
public function authenticate(CakeRequest $request, CakeResponse $response) {
$userModel = $this->settings['userModel'];
list($plugin, $model) = pluginSplit($userModel);
$fields = $this->settings['fields'];
if (!$this->_checkFields($request, $model, $fields)) {
return false;
}
$user = $this->_findUser(
array(
$model . '.' . $fields['username'] => $request->data[$model][$fields['username']],
)
);
if (!$user) {
return false;
}
$password = Security::hash(
$request->data[$model][$fields['password']],
'blowfish',
$user[$fields['password']]
);
if ($password === $user[$fields['password']]) {
unset($user[$fields['password']]);
return $user;
}
return false;
}
}

View file

@ -138,7 +138,7 @@ class DigestAuthenticate extends BaseAuthenticate {
if (empty($digest)) {
return false;
}
$user = $this->_findUser($digest['username'], null);
$user = $this->_findUser($digest['username']);
if (empty($user)) {
return false;
}
@ -157,7 +157,7 @@ class DigestAuthenticate extends BaseAuthenticate {
* @param string $password Unused password, digest doesn't require passwords.
* @return Mixed Either false on failure, or an array of user data.
*/
protected function _findUser($username, $password) {
protected function _findUser($username, $password = null) {
$userModel = $this->settings['userModel'];
list($plugin, $model) = pluginSplit($userModel);
$fields = $this->settings['fields'];

View file

@ -36,6 +36,27 @@ App::uses('BaseAuthenticate', 'Controller/Component/Auth');
*/
class FormAuthenticate extends BaseAuthenticate {
/**
* Checks the fields to ensure they are supplied.
*
* @param CakeRequest $request The request that contains login information.
* @param string $model The model used for login verification.
* @param array $fields The fields to be checked.
* @return boolean False if the fields have not been supplied. True if they exist.
*/
protected function _checkFields(CakeRequest $request, $model, $fields) {
if (empty($request->data[$model])) {
return false;
}
if (
empty($request->data[$model][$fields['username']]) ||
empty($request->data[$model][$fields['password']])
) {
return false;
}
return true;
}
/**
* Authenticates the identity contained in a request. Will use the `settings.userModel`, and `settings.fields`
* to find POST data that is used to find a matching record in the `settings.userModel`. Will return false if
@ -50,13 +71,7 @@ class FormAuthenticate extends BaseAuthenticate {
list($plugin, $model) = pluginSplit($userModel);
$fields = $this->settings['fields'];
if (empty($request->data[$model])) {
return false;
}
if (
empty($request->data[$model][$fields['username']]) ||
empty($request->data[$model][$fields['password']])
) {
if (!$this->_checkFields($request, $model, $fields)) {
return false;
}
return $this->_findUser(

View file

@ -211,6 +211,15 @@ class AuthComponent extends Component {
*/
public $authError = null;
/**
* Controls handling of unauthorized access. By default unauthorized user is
* redirected to the referrer url or AuthComponent::$loginAction or '/'.
* If set to false a ForbiddenException exception is thrown instead of redirecting.
*
* @var boolean
*/
public $unauthorizedRedirect = true;
/**
* Controller actions for which user validation is not required.
*
@ -289,13 +298,7 @@ class AuthComponent extends Component {
$url = Router::normalize($url);
$loginAction = Router::normalize($this->loginAction);
$allowedActions = $this->allowedActions;
$isAllowed = (
$this->allowedActions == array('*') ||
in_array($action, array_map('strtolower', $allowedActions))
);
if ($loginAction != $url && $isAllowed) {
if ($loginAction != $url && in_array($action, array_map('strtolower', $this->allowedActions))) {
return true;
}
@ -306,27 +309,43 @@ class AuthComponent extends Component {
}
}
return true;
} else {
}
if (!$this->_getUser()) {
if (!$request->is('ajax')) {
$this->flash($this->authError);
$this->Session->write('Auth.redirect', $request->here());
$controller->redirect($loginAction);
return false;
} elseif (!empty($this->ajaxLogin)) {
}
if (!empty($this->ajaxLogin)) {
$controller->viewPath = 'Elements';
echo $controller->render($this->ajaxLogin, $this->RequestHandler->ajaxLayout);
$this->_stop();
return false;
} else {
}
$controller->redirect(null, 403);
}
}
}
if (empty($this->authorize) || $this->isAuthorized($this->user())) {
return true;
}
return $this->_unauthorized($controller);
}
/**
* Handle unauthorized access attempt
*
* @param Controller $controller A reference to the controller object
* @return boolean Returns false
* @throws ForbiddenException
*/
protected function _unauthorized(Controller $controller) {
if (!$this->unauthorizedRedirect) {
throw new ForbiddenException($this->authError);
}
$this->flash($this->authError);
$default = '/';
if (!empty($this->loginRedirect)) {
@ -366,7 +385,8 @@ class AuthComponent extends Component {
public function isAuthorized($user = null, $request = null) {
if (empty($user) && !$this->user()) {
return false;
} elseif (empty($user)) {
}
if (empty($user)) {
$user = $this->user();
}
if (empty($request)) {
@ -434,13 +454,13 @@ class AuthComponent extends Component {
$args = func_get_args();
if (empty($args) || $action === null) {
$this->allowedActions = $this->_methods;
} else {
return;
}
if (isset($args[0]) && is_array($args[0])) {
$args = $args[0];
}
$this->allowedActions = array_merge($this->allowedActions, $args);
}
}
/**
* Removes items from the list of allowed/no authentication required actions.
@ -460,7 +480,8 @@ class AuthComponent extends Component {
$args = func_get_args();
if (empty($args) || $action === null) {
$this->allowedActions = array();
} else {
return;
}
if (isset($args[0]) && is_array($args[0])) {
$args = $args[0];
}
@ -472,7 +493,6 @@ class AuthComponent extends Component {
}
$this->allowedActions = array_values($this->allowedActions);
}
}
/**
* Maps action names to CRUD operations. Used for controller-based authentication. Make sure

View file

@ -177,7 +177,7 @@ class CookieComponent extends Component {
if ($controller && isset($controller->response)) {
$this->_response = $controller->response;
} else {
$this->_response = new CakeResponse(array('charset' => Configure::read('App.encoding')));
$this->_response = new CakeResponse();
}
}
@ -278,6 +278,19 @@ class CookieComponent extends Component {
return $this->_values[$this->name][$key];
}
/**
* Returns true if given variable is set in cookie.
*
* @param string $var Variable name to check for
* @return boolean True if variable is there
*/
public function check($key = null) {
if (empty($key)) {
return false;
}
return $this->read($key) !== null;
}
/**
* Delete a cookie value
*
@ -378,11 +391,11 @@ class CookieComponent extends Component {
}
$this->_reset = $this->_expires;
if ($expires == 0) {
if (!$expires) {
return $this->_expires = 0;
}
if (is_integer($expires) || is_numeric($expires)) {
if (is_int($expires) || is_numeric($expires)) {
return $this->_expires = $now + intval($expires);
}
return $this->_expires = strtotime($expires, $now);
@ -504,7 +517,7 @@ class CookieComponent extends Component {
$first = substr($string, 0, 1);
if ($first === '{' || $first === '[') {
$ret = json_decode($string, true);
return ($ret != null) ? $ret : $string;
return ($ret) ? $ret : $string;
}
$array = array();
foreach (explode(',', $string) as $pair) {

View file

@ -316,7 +316,7 @@ class EmailComponent extends Component {
foreach ($this->headers as $key => $value) {
$headers['X-' . $key] = $value;
}
if ($this->date != false) {
if ($this->date) {
$headers['Date'] = $this->date;
}
$lib->setHeaders($headers);

View file

@ -16,6 +16,7 @@
* @since CakePHP(tm) v 2.0
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
App::uses('Component', 'Controller');
App::uses('Hash', 'Utility');
/**
@ -50,6 +51,20 @@ App::uses('Hash', 'Utility');
*
* This would allow you to have different pagination settings for `Comment` and `Post` models.
*
* #### Paginating with custom finders
*
* You can paginate with any find type defined on your model using the `findType` option.
*
* {{{
* $this->Paginator->settings = array(
* 'Post' => array(
* 'findType' => 'popular'
* )
* );
* }}}
*
* Would paginate using the `find('popular')` method.
*
* @package Cake.Controller.Component
* @link http://book.cakephp.org/2.0/en/core-libraries/components/pagination.html
*/
@ -152,6 +167,12 @@ class PaginatorComponent extends Component {
$extra = array_diff_key($options, compact(
'conditions', 'fields', 'order', 'limit', 'page', 'recursive'
));
if (!empty($extra['findType'])) {
$type = $extra['findType'];
unset($extra['findType']);
}
if ($type !== 'all') {
$extra['type'] = $type;
}
@ -228,36 +249,34 @@ class PaginatorComponent extends Component {
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};
return $this->Controller->{$object}->{$assoc};
}
} elseif (empty($object) || $object === null) {
if ($assoc && isset($this->Controller->{$this->Controller->modelClass}->{$assoc})) {
return $this->Controller->{$this->Controller->modelClass}->{$assoc};
}
if (isset($this->Controller->{$object})) {
return $this->Controller->{$object};
}
if (isset($this->Controller->{$this->Controller->modelClass}->{$object})) {
return $this->Controller->{$this->Controller->modelClass}->{$object};
}
}
if (empty($object) || $object === null) {
if (isset($this->Controller->{$this->Controller->modelClass})) {
$object = $this->Controller->{$this->Controller->modelClass};
} else {
return $this->Controller->{$this->Controller->modelClass};
}
$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};
}
return $this->Controller->{$className};
}
return $this->Controller->{$name};
}
return $object;
}
@ -299,10 +318,9 @@ class PaginatorComponent extends Component {
* @return array An array of pagination defaults for a model, or the general settings.
*/
public function getDefaults($alias) {
$defaults = $this->settings;
if (isset($this->settings[$alias])) {
$defaults = $this->settings[$alias];
} else {
$defaults = $this->settings;
}
return array_merge(
array('page' => 1, 'limit' => 20, 'maxLimit' => 100, 'paramType' => 'named'),
@ -323,13 +341,13 @@ class PaginatorComponent extends Component {
* @param array $whitelist The list of columns that can be used for sorting. If empty all keys are allowed.
* @return array An array of options with sort + direction removed and replaced with order if possible.
*/
public function validateSort($object, $options, $whitelist = array()) {
public function validateSort(Model $object, array $options, array $whitelist = array()) {
if (isset($options['sort'])) {
$direction = null;
if (isset($options['direction'])) {
$direction = strtolower($options['direction']);
}
if ($direction != 'asc' && $direction != 'desc') {
if (!in_array($direction, array('asc', 'desc'))) {
$direction = 'asc';
}
$options['order'] = array($options['sort'] => $direction);
@ -371,7 +389,7 @@ class PaginatorComponent extends Component {
* @param array $options An array of options with a limit key to be checked.
* @return array An array of options for pagination
*/
public function checkLimit($options) {
public function checkLimit(array $options) {
$options['limit'] = (int)$options['limit'];
if (empty($options['limit']) || $options['limit'] < 1) {
$options['limit'] = 1;

View file

@ -19,6 +19,7 @@
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
App::uses('Component', 'Controller');
App::uses('Xml', 'Utility');
/**
@ -88,6 +89,17 @@ class RequestHandlerComponent extends Component {
'json' => array('json_decode', true)
);
/**
* A mapping between type and viewClass
* By default only JSON and XML are mapped, use RequestHandlerComponent::viewClassMap()
*
* @var array
*/
protected $_viewClassMap = array(
'json' => 'Json',
'xml' => 'Xml'
);
/**
* Constructor. Parses the accepted content types accepted by the client using HTTP_ACCEPT
*
@ -95,8 +107,7 @@ class RequestHandlerComponent extends Component {
* @param array $settings Array of settings.
*/
public function __construct(ComponentCollection $collection, $settings = array()) {
$default = array('checkHttpCache' => true);
parent::__construct($collection, $settings + $default);
parent::__construct($collection, $settings + array('checkHttpCache' => true));
$this->addInputType('xml', array(array($this, 'convertXml')));
$Controller = $collection->getController();
@ -111,11 +122,10 @@ class RequestHandlerComponent extends Component {
* and the requested mime-types, RequestHandler::$ext is set to that value.
*
* @param Controller $controller A reference to the controller
* @param array $settings Array of settings to _set().
* @return void
* @see Router::parseExtensions()
*/
public function initialize(Controller $controller, $settings = array()) {
public function initialize(Controller $controller) {
if (isset($this->request->params['ext'])) {
$this->ext = $this->request->params['ext'];
}
@ -123,7 +133,9 @@ class RequestHandlerComponent extends Component {
$this->_setExtension();
}
$this->params = $controller->params;
$this->_set($settings);
if (!empty($this->settings['viewClassMap'])) {
$this->viewClassMap($this->settings['viewClassMap']);
}
}
/**
@ -145,11 +157,13 @@ class RequestHandlerComponent extends Component {
$extensions = Router::extensions();
$preferred = array_shift($accept);
$preferredTypes = $this->response->mapType($preferred);
if (!in_array('xhtml', $preferredTypes) && !in_array('html', $preferredTypes)) {
$similarTypes = array_intersect($extensions, $preferredTypes);
if (count($similarTypes) === 1 && !in_array('xhtml', $preferredTypes) && !in_array('html', $preferredTypes)) {
if (count($similarTypes) === 1) {
$this->ext = array_shift($similarTypes);
}
}
}
/**
* The startup method of the RequestHandler enables several automatic behaviors
@ -256,8 +270,7 @@ class RequestHandlerComponent extends Component {
* @return boolean false if the render process should be aborted
**/
public function beforeRender(Controller $controller) {
$shouldCheck = $this->settings['checkHttpCache'];
if ($shouldCheck && $this->response->checkNotModified($this->request)) {
if ($this->settings['checkHttpCache'] && $this->response->checkNotModified($this->request)) {
return false;
}
}
@ -382,13 +395,11 @@ class RequestHandlerComponent extends Component {
* Gets Prototype version if call is Ajax, otherwise empty string.
* The Prototype library sets a special "Prototype version" HTTP header.
*
* @return string Prototype version of component making Ajax call
* @return string|boolean When Ajax the prototype version of component making the call otherwise false
*/
public function getAjaxVersion() {
if (env('HTTP_X_PROTOTYPE_VERSION') != null) {
return env('HTTP_X_PROTOTYPE_VERSION');
}
return false;
$httpX = env('HTTP_X_PROTOTYPE_VERSION');
return ($httpX === null) ? false : $httpX;
}
/**
@ -454,9 +465,10 @@ class RequestHandlerComponent extends Component {
public function accepts($type = null) {
$accepted = $this->request->accepts();
if ($type == null) {
if (!$type) {
return $this->mapType($accepted);
} elseif (is_array($type)) {
}
if (is_array($type)) {
foreach ($type as $t) {
$t = $this->mapAlias($t);
if (in_array($t, $accepted)) {
@ -464,9 +476,9 @@ class RequestHandlerComponent extends Component {
}
}
return false;
} elseif (is_string($type)) {
$type = $this->mapAlias($type);
return in_array($type, $accepted);
}
if (is_string($type)) {
return in_array($this->mapAlias($type), $accepted);
}
return false;
}
@ -483,18 +495,20 @@ class RequestHandlerComponent extends Component {
if (!$this->request->is('post') && !$this->request->is('put')) {
return null;
}
list($contentType) = explode(';', env('CONTENT_TYPE'));
if ($type == null) {
return $this->mapType($contentType);
} elseif (is_array($type)) {
if (is_array($type)) {
foreach ($type as $t) {
if ($this->requestedWith($t)) {
return $t;
}
}
return false;
} elseif (is_string($type)) {
}
list($contentType) = explode(';', env('CONTENT_TYPE'));
if (!$type) {
return $this->mapType($contentType);
}
if (is_string($type)) {
return ($type == $this->mapType($contentType));
}
}
@ -522,10 +536,9 @@ class RequestHandlerComponent extends Component {
if (empty($acceptRaw)) {
return $this->ext;
}
$accepts = array_shift($acceptRaw);
$accepts = $this->mapType($accepts);
$accepts = $this->mapType(array_shift($acceptRaw));
if ($type == null) {
if (!$type) {
if (empty($this->ext) && !empty($accepts)) {
return $accepts[0];
}
@ -582,18 +595,27 @@ class RequestHandlerComponent extends Component {
}
$controller->ext = '.ctp';
$pluginDot = null;
$viewClassMap = $this->viewClassMap();
if (array_key_exists($type, $viewClassMap)) {
list($pluginDot, $viewClass) = pluginSplit($viewClassMap[$type], true);
} else {
$viewClass = Inflector::classify($type);
}
$viewName = $viewClass . 'View';
if (!class_exists($viewName)) {
App::uses($viewName, 'View');
App::uses($viewName, $pluginDot . 'View');
}
if (class_exists($viewName)) {
$controller->viewClass = $viewClass;
} elseif (empty($this->_renderType)) {
$controller->viewPath .= DS . $type;
} else {
$remove = preg_replace("/([\/\\\\]{$this->_renderType})$/", DS . $type, $controller->viewPath);
$controller->viewPath = $remove;
$controller->viewPath = preg_replace(
"/([\/\\\\]{$this->_renderType})$/",
DS . $type,
$controller->viewPath
);
}
$this->_renderType = $type;
$controller->layoutPath = $type;
@ -603,12 +625,8 @@ class RequestHandlerComponent extends Component {
}
$helper = ucfirst($type);
$isAdded = (
in_array($helper, $controller->helpers) ||
array_key_exists($helper, $controller->helpers)
);
if (!$isAdded) {
if (!in_array($helper, $controller->helpers) && empty($controller->helpers[$helper])) {
App::uses('AppHelper', 'View/Helper');
App::uses($helper . 'Helper', 'View/Helper');
if (class_exists($helper . 'Helper')) {
@ -634,30 +652,28 @@ class RequestHandlerComponent extends Component {
$defaults = array('index' => null, 'charset' => null, 'attachment' => false);
$options = $options + $defaults;
$cType = $type;
if (strpos($type, '/') === false) {
$cType = $this->response->getMimeType($type);
if ($cType === false) {
return false;
}
if (is_array($cType) && isset($cType[$options['index']])) {
$cType = $cType[$options['index']];
}
if (is_array($cType)) {
if (isset($cType[$options['index']])) {
$cType = $cType[$options['index']];
}
if ($this->prefers($cType)) {
$cType = $this->prefers($cType);
} else {
$cType = $cType[0];
}
}
} else {
$cType = $type;
}
if ($cType != null) {
if (!$type) {
return false;
}
if (empty($this->request->params['requested'])) {
$this->response->type($cType);
}
if (!empty($options['charset'])) {
$this->response->charset($options['charset']);
}
@ -666,8 +682,6 @@ class RequestHandlerComponent extends Component {
}
return true;
}
return false;
}
/**
* Returns the current response type (Content-type header), or null if not alias exists
@ -729,4 +743,25 @@ class RequestHandlerComponent extends Component {
$this->_inputTypeMap[$type] = $handler;
}
/**
* Getter/setter for viewClassMap
*
* @param array|string $type The type string or array with format `array('type' => 'viewClass')` to map one or more
* @param array $viewClass The viewClass to be used for the type without `View` appended
* @return array]string Returns viewClass when only string $type is set, else array with viewClassMap
*/
public function viewClassMap($type = null, $viewClass = null) {
if (!$viewClass && is_string($type) && isset($this->_viewClassMap[$type])) {
return $this->_viewClassMap[$type];
}
if (is_string($type)) {
$this->_viewClassMap[$type] = $viewClass;
} elseif (is_array($type)) {
foreach ($type as $key => $value) {
$this->viewClassMap($key, $value);
}
}
return $this->_viewClassMap;
}
}

View file

@ -129,6 +129,13 @@ class SecurityComponent extends Component {
*/
public $unlockedFields = array();
/**
* Actions to exclude from any security checks
*
* @var array
*/
public $unlockedActions = array();
/**
* Whether to validate POST data. Set to false to disable for data coming from 3rd party
* services, etc.
@ -218,13 +225,11 @@ class SecurityComponent extends Component {
$controller->request->params['requested'] != 1
);
if ($isPost && $isNotRequestAction && $this->validatePost) {
if ($this->_validatePost($controller) === false) {
if (!in_array($this->_action, (array)$this->unlockedActions) && $isPost && $isNotRequestAction) {
if ($this->validatePost && $this->_validatePost($controller) === false) {
return $this->blackHole($controller, 'auth');
}
}
if ($isPost && $isNotRequestAction && $this->csrfCheck) {
if ($this->_validateCsrf($controller) === false) {
if ($this->csrfCheck && $this->_validateCsrf($controller) === false) {
return $this->blackHole($controller, 'csrf');
}
}
@ -309,11 +314,10 @@ class SecurityComponent extends Component {
* @throws BadRequestException
*/
public function blackHole(Controller $controller, $error = '') {
if ($this->blackHoleCallback == null) {
if (!$this->blackHoleCallback) {
throw new BadRequestException(__d('cake_dev', 'The request has been black-holed'));
} else {
return $this->_callback($controller, $this->blackHoleCallback, array($error));
}
return $this->_callback($controller, $this->blackHoleCallback, array($error));
}
/**
@ -385,7 +389,7 @@ class SecurityComponent extends Component {
$requireAuth = $this->requireAuth;
if (in_array($this->request->params['action'], $requireAuth) || $this->requireAuth == array('*')) {
if (!isset($controller->request->data['_Token'] )) {
if (!isset($controller->request->data['_Token'])) {
if (!$this->blackHole($controller, 'auth')) {
return null;
}
@ -489,7 +493,7 @@ class SecurityComponent extends Component {
$fieldList += $lockedFields;
$unlocked = implode('|', $unlocked);
$check = Security::hash(serialize($fieldList) . $unlocked . Configure::read('Security.salt'));
$check = Security::hash(serialize($fieldList) . $unlocked . Configure::read('Security.salt'), 'sha1');
return ($token === $check);
}
@ -588,11 +592,10 @@ class SecurityComponent extends Component {
* @throws BadRequestException When a the blackholeCallback is not callable.
*/
protected function _callback(Controller $controller, $method, $params = array()) {
if (is_callable(array($controller, $method))) {
return call_user_func_array(array(&$controller, $method), empty($params) ? null : $params);
} else {
if (!is_callable(array($controller, $method))) {
throw new BadRequestException(__d('cake_dev', 'The request has been black-holed'));
}
return call_user_func_array(array(&$controller, $method), empty($params) ? null : $params);
}
}

View file

@ -319,7 +319,7 @@ class Controller extends Object implements CakeEventListener {
$this->name = substr(get_class($this), 0, -10);
}
if ($this->viewPath == null) {
if (!$this->viewPath) {
$this->viewPath = $this->name;
}
@ -454,7 +454,7 @@ class Controller extends Object implements CakeEventListener {
$this->passedArgs = array_merge($request->params['pass'], $request->params['named']);
}
if (array_key_exists('return', $request->params) && $request->params['return'] == 1) {
if (!empty($request->params['return']) && $request->params['return'] == 1) {
$this->autoRender = false;
}
if (!empty($request->params['bare'])) {
@ -966,15 +966,16 @@ class Controller extends Object implements CakeEventListener {
* @link http://book.cakephp.org/2.0/en/controllers.html#Controller::referer
*/
public function referer($default = null, $local = false) {
if ($this->request) {
if (!$this->request) {
return '/';
}
$referer = $this->request->referer($local);
if ($referer == '/' && $default != null) {
if ($referer == '/' && $default) {
return Router::url($default, true);
}
return $referer;
}
return '/';
}
/**
* Forces the user's browser not to cache the results of the current request.
@ -1061,7 +1062,7 @@ class Controller extends Object implements CakeEventListener {
$cond[$key] = $value;
}
}
if ($bool != null && strtoupper($bool) != 'AND') {
if ($bool && strtoupper($bool) != 'AND') {
$cond = array($bool => $cond);
}
return $cond;

View file

@ -146,7 +146,7 @@ class Scaffold {
$this->controller->viewClass = 'Scaffold';
}
$this->_validSession = (
isset($this->controller->Session) && $this->controller->Session->valid() != false
isset($this->controller->Session) && $this->controller->Session->valid()
);
$this->_scaffold($request);
}

View file

@ -607,7 +607,7 @@ class App {
extract($parent, EXTR_OVERWRITE);
}
if ($name == null && $file == null) {
if (!$name && !$file) {
return false;
}

View file

@ -170,6 +170,19 @@ class Configure {
return Hash::get(self::$_values, $var);
}
/**
* Returns true if given variable is set in Configure.
*
* @param string $var Variable name to check for
* @return boolean True if variable is there
*/
public static function check($var = null) {
if (empty($var)) {
return false;
}
return Hash::get(self::$_values, $var) !== null;
}
/**
* Used to delete a variable from Configure.
*
@ -306,10 +319,10 @@ class Configure {
public static function dump($key, $config = 'default', $keys = array()) {
$reader = self::_getReader($config);
if (!$reader) {
throw new ConfigureException(__d('cake', 'There is no "%s" adapter.', $config));
throw new ConfigureException(__d('cake_dev', 'There is no "%s" adapter.', $config));
}
if (!method_exists($reader, 'dump')) {
throw new ConfigureException(__d('cake', 'The "%s" adapter, does not have a dump() method.', $config));
throw new ConfigureException(__d('cake_dev', 'The "%s" adapter, does not have a dump() method.', $config));
}
$values = self::$_values;
if (!empty($keys) && is_array($keys)) {

View file

@ -102,10 +102,7 @@ class ExceptionRenderer {
if ($exception instanceof CakeException && !$methodExists) {
$method = '_cakeError';
if (empty($template)) {
$template = 'error500';
}
if ($template == 'internalError') {
if (empty($template) || $template == 'internalError') {
$template = 'error500';
}
} elseif ($exception instanceof PDOException) {
@ -119,14 +116,13 @@ class ExceptionRenderer {
}
}
if (Configure::read('debug') == 0) {
if ($method == '_cakeError') {
$isNotDebug = !Configure::read('debug');
if ($isNotDebug && $method == '_cakeError') {
$method = 'error400';
}
if ($code == 500) {
if ($isNotDebug && $code == 500) {
$method = 'error500';
}
}
$this->template = $template;
$this->method = $method;
$this->error = $exception;
@ -147,7 +143,12 @@ class ExceptionRenderer {
if (!$request = Router::getRequest(true)) {
$request = new CakeRequest();
}
$response = new CakeResponse(array('charset' => Configure::read('App.encoding')));
$response = new CakeResponse();
if (method_exists($exception, 'responseHeader')) {
$response->header($exception->responseHeader());
}
try {
$controller = new CakeErrorController($request, $response);
} catch (Exception $e) {
@ -183,7 +184,7 @@ class ExceptionRenderer {
$this->controller->set(array(
'code' => $code,
'url' => h($url),
'name' => $error->getMessage(),
'name' => h($error->getMessage()),
'error' => $error,
'_serialize' => array('code', 'url', 'name')
));
@ -199,13 +200,13 @@ class ExceptionRenderer {
*/
public function error400($error) {
$message = $error->getMessage();
if (Configure::read('debug') == 0 && $error instanceof CakeException) {
if (!Configure::read('debug') && $error instanceof CakeException) {
$message = __d('cake', 'Not Found');
}
$url = $this->controller->request->here();
$this->controller->response->statusCode($error->getCode());
$this->controller->set(array(
'name' => $message,
'name' => h($message),
'url' => h($url),
'error' => $error,
'_serialize' => array('name', 'url')
@ -221,14 +222,14 @@ class ExceptionRenderer {
*/
public function error500($error) {
$message = $error->getMessage();
if (Configure::read('debug') == 0) {
if (!Configure::read('debug')) {
$message = __d('cake', 'An Internal Error Has Occurred.');
}
$url = $this->controller->request->here();
$code = ($error->getCode() > 500 && $error->getCode() < 506) ? $error->getCode() : 500;
$this->controller->response->statusCode($code);
$this->controller->set(array(
'name' => $message,
'name' => h($message),
'message' => h($url),
'error' => $error,
'_serialize' => array('name', 'message')
@ -249,7 +250,7 @@ class ExceptionRenderer {
$this->controller->set(array(
'code' => $code,
'url' => h($url),
'name' => $error->getMessage(),
'name' => h($error->getMessage()),
'error' => $error,
'_serialize' => array('code', 'url', 'name', 'error')
));

View file

@ -18,6 +18,43 @@
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
/**
* Base class that all Exceptions extend.
*
* @package Cake.Error
*/
class CakeBaseException extends RuntimeException {
/**
* Array of headers to be passed to CakeResponse::header()
*
* @var array
*/
protected $_responseHeaders = null;
/**
* Get/set the response header to be used
*
* See also CakeResponse::header()
*
* @param string|array $header. An array of header strings or a single header string
* - an associative array of "header name" => "header value"
* - an array of string headers is also accepted
* @param string $value. The header value.
* @return array
*/
public function responseHeader($header = null, $value = null) {
if ($header) {
if (is_array($header)) {
return $this->_responseHeaders = $header;
}
$this->_responseHeaders = array($header => $value);
}
return $this->_responseHeaders;
}
}
/**
* Parent class for all of the HTTP related exceptions in CakePHP.
* All HTTP status/error related exceptions should extend this class so
@ -26,7 +63,7 @@
* @package Cake.Error
*/
if (!class_exists('HttpException')) {
class HttpException extends RuntimeException {
class HttpException extends CakeBaseException {
}
}
@ -168,7 +205,7 @@ class InternalErrorException extends HttpException {
*
* @package Cake.Error
*/
class CakeException extends RuntimeException {
class CakeException extends CakeBaseException {
/**
* Array of attributes that are passed in from the constructor, and

View file

@ -17,9 +17,9 @@
*/
/**
* Represent the transport class of events across the system, it receives a name, and subject and an optional
* Represents the transport class of events across the system, it receives a name, and subject and an optional
* payload. The name can be any string that uniquely identifies the event across the application, while the subject
* represents the object that the event is applying to.
* represents the object that the event applies to.
*
* @package Cake.Event
*/

View file

@ -18,15 +18,15 @@
/**
* Objects implementing this interface should declare the `implementedEvents` function
* to hint the event manager what methods should be called when an event is triggered.
* to notify the event manager what methods should be called when an event is triggered.
*
* @package Cake.Event
*/
interface CakeEventListener {
/**
* Returns a list of events this object is implementing, when the class is registered
* in an event manager, each individual method will be associated to the respective event.
* Returns a list of events this object is implementing. When the class is registered
* in an event manager, each individual method will be associated with the respective event.
*
* ## Example:
*

View file

@ -19,9 +19,9 @@
App::uses('CakeEventListener', 'Event');
/**
* The event manager is responsible for keeping track of event listeners and pass the correct
* data to them, and fire them in the correct order, when associated events are triggered. You
* can create multiple instances of this objects to manage local events or keep a single instance
* The event manager is responsible for keeping track of event listeners, passing the correct
* data to them, and firing them in the correct order, when associated events are triggered. You
* can create multiple instances of this object to manage local events or keep a single instance
* and pass it around to manage all events in your app.
*
* @package Cake.Event
@ -29,7 +29,7 @@ App::uses('CakeEventListener', 'Event');
class CakeEventManager {
/**
* The default priority queue value for new attached listeners
* The default priority queue value for new, attached listeners
*
* @var int
*/
@ -50,7 +50,7 @@ class CakeEventManager {
protected $_listeners = array();
/**
* Internal flag to distinguish a common manager from the sigleton
* Internal flag to distinguish a common manager from the singleton
*
* @var boolean
*/
@ -62,7 +62,7 @@ class CakeEventManager {
* other managers were created. Usually for creating hook systems or inter-class
* communication
*
* If called with a first params, it will be set as the globally available instance
* If called with the first parameter, it will be set as the globally available instance
*
* @param CakeEventManager $manager
* @return CakeEventManager the global event manager
@ -83,15 +83,15 @@ class CakeEventManager {
* Adds a new listener to an event. Listeners
*
* @param callback|CakeEventListener $callable PHP valid callback type or instance of CakeEventListener to be called
* when the event named with $eventKey is triggered. If a CakeEventListener instances is passed, then the `implementedEvents`
* when the event named with $eventKey is triggered. If a CakeEventListener instance is passed, then the `implementedEvents`
* method will be called on the object to register the declared events individually as methods to be managed by this class.
* It is possible to define multiple event handlers per event name.
*
* @param string $eventKey The event unique identifier name to with the callback will be associated. If $callable
* @param string $eventKey The event unique identifier name with which the callback will be associated. If $callable
* is an instance of CakeEventListener this argument will be ignored
*
* @param array $options used to set the `priority` and `passParams` flags to the listener.
* Priorities are handled like queues, and multiple attachments into the same priority queue will be treated in
* Priorities are handled like queues, and multiple attachments added to the same priority queue will be treated in
* the order of insertion. `passParams` means that the event data property will be converted to function arguments
* when the listener is called. If $called is an instance of CakeEventListener, this parameter will be ignored
*
@ -145,7 +145,7 @@ class CakeEventManager {
* Auxiliary function to extract and return a PHP callback type out of the callable definition
* from the return value of the `implementedEvents` method on a CakeEventListener
*
* @param array $function the array taken from a handler definition for a event
* @param array $function the array taken from a handler definition for an event
* @param CakeEventListener $object The handler object
* @return callback
*/
@ -256,7 +256,7 @@ class CakeEventManager {
}
/**
* Returns a list of all listeners for a eventKey in the order they should be called
* Returns a list of all listeners for an eventKey in the order they should be called
*
* @param string $eventKey
* @return array

View file

@ -405,7 +405,7 @@ class I18n {
$header = unpack("L1magic/L1version/L1count/L1o_msg/L1o_trn", $header);
extract($header);
if ((dechex($magic) == '950412de' || dechex($magic) == 'ffffffff950412de') && $version == 0) {
if ((dechex($magic) == '950412de' || dechex($magic) == 'ffffffff950412de') && !$version) {
for ($n = 0; $n < $count; $n++) {
$r = unpack("L1len/L1offs", substr($data, $o_msg + $n * 8, 8));
$msgid = substr($data, $r["offs"], $r["len"]);
@ -585,19 +585,19 @@ class I18n {
$string = $string[1];
if (substr($string, 0, 2) === $this->_escape . 'x') {
$delimiter = $this->_escape . 'x';
return join('', array_map('chr', array_map('hexdec',array_filter(explode($delimiter, $string)))));
return implode('', array_map('chr', array_map('hexdec',array_filter(explode($delimiter, $string)))));
}
if (substr($string, 0, 2) === $this->_escape . 'd') {
$delimiter = $this->_escape . 'd';
return join('', array_map('chr', array_filter(explode($delimiter, $string))));
return implode('', array_map('chr', array_filter(explode($delimiter, $string))));
}
if ($string[0] === $this->_escape && isset($string[1]) && is_numeric($string[1])) {
$delimiter = $this->_escape;
return join('', array_map('chr', array_filter(explode($delimiter, $string))));
return implode('', array_map('chr', array_filter(explode($delimiter, $string))));
}
if (substr($string, 0, 3) === 'U00') {
$delimiter = 'U00';
return join('', array_map('chr', array_map('hexdec', array_filter(explode($delimiter, $string)))));
return implode('', array_map('chr', array_map('hexdec', array_filter(explode($delimiter, $string)))));
}
if (preg_match('/U([0-9a-fA-F]{4})/', $string, $match)) {
return Multibyte::ascii(array(hexdec($match[1])));

View file

@ -85,47 +85,53 @@ class L10n {
/**
* Maps ISO 639-3 to I10n::_l10nCatalog
* The terminological codes (first one per language) should be used if possible.
* They are the ones building the path in `/APP/Locale/[code]/`
* The bibliographic codes are aliases.
*
* @var array
*/
protected $_l10nMap = array(
/* Afrikaans */ 'afr' => 'af',
/* Albanian */ 'alb' => 'sq',
/* Albanian */ 'sqi' => 'sq',
/* Albanian - bibliographic */ 'alb' => 'sq',
/* Arabic */ 'ara' => 'ar',
/* Armenian - Armenia */ 'hye' => 'hy',
/* Armenian/Armenia */ 'hye' => 'hy',
/* Basque */ 'eus' => 'eu',
/* Basque */ 'baq' => 'eu',
/* Tibetan */ 'bod' => 'bo',
/* Tibetan - bibliographic */ 'tib' => 'bo',
/* Bosnian */ 'bos' => 'bs',
/* Bulgarian */ 'bul' => 'bg',
/* Byelorussian */ 'bel' => 'be',
/* Catalan */ 'cat' => 'ca',
/* Chinese */ 'chi' => 'zh',
/* Chinese */ 'zho' => 'zh',
/* Chinese - bibliographic */ 'chi' => 'zh',
/* Croatian */ 'hrv' => 'hr',
/* Czech */ 'cze' => 'cs',
/* Czech */ 'ces' => 'cs',
/* Czech - bibliographic */ 'cze' => 'cs',
/* Danish */ 'dan' => 'da',
/* Dutch (Standard) */ 'dut' => 'nl',
/* Dutch (Standard) */ 'nld' => 'nl',
/* Dutch (Standard) - bibliographic */ 'dut' => 'nl',
/* English */ 'eng' => 'en',
/* Estonian */ 'est' => 'et',
/* Faeroese */ 'fao' => 'fo',
/* Farsi */ 'fas' => 'fa',
/* Farsi */ 'per' => 'fa',
/* Farsi/Persian */ 'fas' => 'fa',
/* Farsi/Persian - bibliographic */ 'per' => 'fa',
/* Finnish */ 'fin' => 'fi',
/* French (Standard) */ 'fre' => 'fr',
/* French (Standard) */ 'fra' => 'fr',
/* French (Standard) - bibliographic */ 'fre' => 'fr',
/* Gaelic (Scots) */ 'gla' => 'gd',
/* Galician */ 'glg' => 'gl',
/* German (Standard) */ 'deu' => 'de',
/* German (Standard) */ 'ger' => 'de',
/* German (Standard) - bibliographic */ 'ger' => 'de',
/* Greek */ 'gre' => 'el',
/* Greek */ 'ell' => 'el',
/* Hebrew */ 'heb' => 'he',
/* Hindi */ 'hin' => 'hi',
/* Hungarian */ 'hun' => 'hu',
/* Icelandic */ 'ice' => 'is',
/* Icelandic */ 'isl' => 'is',
/* Icelandic - bibliographic */ 'ice' => 'is',
/* Indonesian */ 'ind' => 'id',
/* Irish */ 'gle' => 'ga',
/* Italian */ 'ita' => 'it',
@ -133,10 +139,10 @@ class L10n {
/* Korean */ 'kor' => 'ko',
/* Latvian */ 'lav' => 'lv',
/* Lithuanian */ 'lit' => 'lt',
/* Macedonian */ 'mac' => 'mk',
/* Macedonian */ 'mkd' => 'mk',
/* Malaysian */ 'may' => 'ms',
/* Macedonian - bibliographic */ 'mac' => 'mk',
/* Malaysian */ 'msa' => 'ms',
/* Malaysian - bibliographic */ 'may' => 'ms',
/* Maltese */ 'mlt' => 'mt',
/* Norwegian */ 'nor' => 'no',
/* Norwegian Bokmal */ 'nob' => 'nb',
@ -144,14 +150,13 @@ class L10n {
/* Polish */ 'pol' => 'pl',
/* Portuguese (Portugal) */ 'por' => 'pt',
/* Rhaeto-Romanic */ 'roh' => 'rm',
/* Romanian */ 'rum' => 'ro',
/* Romanian */ 'ron' => 'ro',
/* Romanian - bibliographic */ 'rum' => 'ro',
/* Russian */ 'rus' => 'ru',
/* Sami (Lappish) */ 'smi' => 'sz',
/* Serbian */ 'scc' => 'sr',
/* Serbian */ 'srp' => 'sr',
/* Slovak */ 'slo' => 'sk',
/* Slovak */ 'slk' => 'sk',
/* Slovak - bibliographic */ 'slo' => 'sk',
/* Slovenian */ 'slv' => 'sl',
/* Sorbian */ 'wen' => 'sb',
/* Spanish (Spain - Traditional) */ 'spa' => 'es',
@ -165,6 +170,7 @@ class L10n {
/* Venda */ 'ven' => 've',
/* Vietnamese */ 'vie' => 'vi',
/* Welsh */ 'cym' => 'cy',
/* Welsh - bibliographic */ 'wel' => 'cy',
/* Xhosa */ 'xho' => 'xh',
/* Yiddish */ 'yid' => 'yi',
/* Zulu */ 'zul' => 'zu'
@ -203,7 +209,7 @@ class L10n {
'bo-in' => array('language' => 'Tibetan (India)', 'locale' => 'bo_in', 'localeFallback' => 'bod', 'charset' => 'utf-8', 'direction' => 'ltr'),
'bs' => array('language' => 'Bosnian', 'locale' => 'bos', 'localeFallback' => 'bos', 'charset' => 'utf-8', 'direction' => 'ltr'),
'ca' => array('language' => 'Catalan', 'locale' => 'cat', 'localeFallback' => 'cat', 'charset' => 'utf-8', 'direction' => 'ltr'),
'cs' => array('language' => 'Czech', 'locale' => 'cze', 'localeFallback' => 'cze', 'charset' => 'utf-8', 'direction' => 'ltr'),
'cs' => array('language' => 'Czech', 'locale' => 'ces', 'localeFallback' => 'ces', 'charset' => 'utf-8', 'direction' => 'ltr'),
'da' => array('language' => 'Danish', 'locale' => 'dan', 'localeFallback' => 'dan', 'charset' => 'utf-8', 'direction' => 'ltr'),
'de' => array('language' => 'German (Standard)', 'locale' => 'deu', 'localeFallback' => 'deu', 'charset' => 'utf-8', 'direction' => 'ltr'),
'de-at' => array('language' => 'German (Austria)', 'locale' => 'de_at', 'localeFallback' => 'deu', 'charset' => 'utf-8', 'direction' => 'ltr'),
@ -245,16 +251,16 @@ class L10n {
'es-uy' => array('language' => 'Spanish (Uruguay)', 'locale' => 'es_uy', 'localeFallback' => 'spa', 'charset' => 'utf-8', 'direction' => 'ltr'),
'es-ve' => array('language' => 'Spanish (Venezuela)', 'locale' => 'es_ve', 'localeFallback' => 'spa', 'charset' => 'utf-8', 'direction' => 'ltr'),
'et' => array('language' => 'Estonian', 'locale' => 'est', 'localeFallback' => 'est', 'charset' => 'utf-8', 'direction' => 'ltr'),
'eu' => array('language' => 'Basque', 'locale' => 'baq', 'localeFallback' => 'baq', 'charset' => 'utf-8', 'direction' => 'ltr'),
'eu' => array('language' => 'Basque', 'locale' => 'eus', 'localeFallback' => 'eus', 'charset' => 'utf-8', 'direction' => 'ltr'),
'fa' => array('language' => 'Farsi', 'locale' => 'per', 'localeFallback' => 'per', 'charset' => 'utf-8', 'direction' => 'rtl'),
'fi' => array('language' => 'Finnish', 'locale' => 'fin', 'localeFallback' => 'fin', 'charset' => 'utf-8', 'direction' => 'ltr'),
'fo' => array('language' => 'Faeroese', 'locale' => 'fao', 'localeFallback' => 'fao', 'charset' => 'utf-8', 'direction' => 'ltr'),
'fr' => array('language' => 'French (Standard)', 'locale' => 'fre', 'localeFallback' => 'fre', 'charset' => 'utf-8', 'direction' => 'ltr'),
'fr-be' => array('language' => 'French (Belgium)', 'locale' => 'fr_be', 'localeFallback' => 'fre', 'charset' => 'utf-8', 'direction' => 'ltr'),
'fr-ca' => array('language' => 'French (Canadian)', 'locale' => 'fr_ca', 'localeFallback' => 'fre', 'charset' => 'utf-8', 'direction' => 'ltr'),
'fr-ch' => array('language' => 'French (Swiss)', 'locale' => 'fr_ch', 'localeFallback' => 'fre', 'charset' => 'utf-8', 'direction' => 'ltr'),
'fr-fr' => array('language' => 'French (France)', 'locale' => 'fr_fr', 'localeFallback' => 'fre', 'charset' => 'utf-8', 'direction' => 'ltr'),
'fr-lu' => array('language' => 'French (Luxembourg)', 'locale' => 'fr_lu', 'localeFallback' => 'fre', 'charset' => 'utf-8', 'direction' => 'ltr'),
'fr' => array('language' => 'French (Standard)', 'locale' => 'fra', 'localeFallback' => 'fra', 'charset' => 'utf-8', 'direction' => 'ltr'),
'fr-be' => array('language' => 'French (Belgium)', 'locale' => 'fr_be', 'localeFallback' => 'fra', 'charset' => 'utf-8', 'direction' => 'ltr'),
'fr-ca' => array('language' => 'French (Canadian)', 'locale' => 'fr_ca', 'localeFallback' => 'fra', 'charset' => 'utf-8', 'direction' => 'ltr'),
'fr-ch' => array('language' => 'French (Swiss)', 'locale' => 'fr_ch', 'localeFallback' => 'fra', 'charset' => 'utf-8', 'direction' => 'ltr'),
'fr-fr' => array('language' => 'French (France)', 'locale' => 'fr_fr', 'localeFallback' => 'fra', 'charset' => 'utf-8', 'direction' => 'ltr'),
'fr-lu' => array('language' => 'French (Luxembourg)', 'locale' => 'fr_lu', 'localeFallback' => 'fra', 'charset' => 'utf-8', 'direction' => 'ltr'),
'ga' => array('language' => 'Irish', 'locale' => 'gle', 'localeFallback' => 'gle', 'charset' => 'utf-8', 'direction' => 'ltr'),
'gd' => array('language' => 'Gaelic (Scots)', 'locale' => 'gla', 'localeFallback' => 'gla', 'charset' => 'utf-8', 'direction' => 'ltr'),
'gd-ie' => array('language' => 'Gaelic (Irish)', 'locale' => 'gd_ie', 'localeFallback' => 'gla', 'charset' => 'utf-8', 'direction' => 'ltr'),
@ -266,7 +272,7 @@ class L10n {
'hy' => array('language' => 'Armenian - Armenia', 'locale' => 'hye', 'localeFallback' => 'hye', 'charset' => 'utf-8', 'direction' => 'ltr'),
'id' => array('language' => 'Indonesian', 'locale' => 'ind', 'localeFallback' => 'ind', 'charset' => 'utf-8', 'direction' => 'ltr'),
'in' => array('language' => 'Indonesian', 'locale' => 'ind', 'localeFallback' => 'ind', 'charset' => 'utf-8', 'direction' => 'ltr'),
'is' => array('language' => 'Icelandic', 'locale' => 'ice', 'localeFallback' => 'ice', 'charset' => 'utf-8', 'direction' => 'ltr'),
'is' => array('language' => 'Icelandic', 'locale' => 'isl', 'localeFallback' => 'isl', 'charset' => 'utf-8', 'direction' => 'ltr'),
'it' => array('language' => 'Italian', 'locale' => 'ita', 'localeFallback' => 'ita', 'charset' => 'utf-8', 'direction' => 'ltr'),
'it-ch' => array('language' => 'Italian (Swiss) ', 'locale' => 'it_ch', 'localeFallback' => 'ita', 'charset' => 'utf-8', 'direction' => 'ltr'),
'ja' => array('language' => 'Japanese', 'locale' => 'jpn', 'localeFallback' => 'jpn', 'charset' => 'utf-8', 'direction' => 'ltr'),
@ -276,14 +282,14 @@ class L10n {
'koi8-r' => array('language' => 'Russian', 'locale' => 'koi8_r', 'localeFallback' => 'rus', 'charset' => 'koi8-r', 'direction' => 'ltr'),
'lt' => array('language' => 'Lithuanian', 'locale' => 'lit', 'localeFallback' => 'lit', 'charset' => 'utf-8', 'direction' => 'ltr'),
'lv' => array('language' => 'Latvian', 'locale' => 'lav', 'localeFallback' => 'lav', 'charset' => 'utf-8', 'direction' => 'ltr'),
'mk' => array('language' => 'FYRO Macedonian', 'locale' => 'mk', 'localeFallback' => 'mac', 'charset' => 'utf-8', 'direction' => 'ltr'),
'mk-mk' => array('language' => 'Macedonian', 'locale' => 'mk_mk', 'localeFallback' => 'mac', 'charset' => 'utf-8', 'direction' => 'ltr'),
'ms' => array('language' => 'Malaysian', 'locale' => 'may', 'localeFallback' => 'may', 'charset' => 'utf-8', 'direction' => 'ltr'),
'mk' => array('language' => 'FYRO Macedonian', 'locale' => 'mk', 'localeFallback' => 'mkd', 'charset' => 'utf-8', 'direction' => 'ltr'),
'mk-mk' => array('language' => 'Macedonian', 'locale' => 'mk_mk', 'localeFallback' => 'mkd', 'charset' => 'utf-8', 'direction' => 'ltr'),
'ms' => array('language' => 'Malaysian', 'locale' => 'msa', 'localeFallback' => 'msa', 'charset' => 'utf-8', 'direction' => 'ltr'),
'mt' => array('language' => 'Maltese', 'locale' => 'mlt', 'localeFallback' => 'mlt', 'charset' => 'utf-8', 'direction' => 'ltr'),
'n' => array('language' => 'Dutch (Standard)', 'locale' => 'dut', 'localeFallback' => 'dut', 'charset' => 'utf-8', 'direction' => 'ltr'),
'n' => array('language' => 'Dutch (Standard)', 'locale' => 'nld', 'localeFallback' => 'nld', 'charset' => 'utf-8', 'direction' => 'ltr'),
'nb' => array('language' => 'Norwegian Bokmal', 'locale' => 'nob', 'localeFallback' => 'nor', 'charset' => 'utf-8', 'direction' => 'ltr'),
'nl' => array('language' => 'Dutch (Standard)', 'locale' => 'dut', 'localeFallback' => 'dut', 'charset' => 'utf-8', 'direction' => 'ltr'),
'nl-be' => array('language' => 'Dutch (Belgium)', 'locale' => 'nl_be', 'localeFallback' => 'dut', 'charset' => 'utf-8', 'direction' => 'ltr'),
'nl' => array('language' => 'Dutch (Standard)', 'locale' => 'nld', 'localeFallback' => 'nld', 'charset' => 'utf-8', 'direction' => 'ltr'),
'nl-be' => array('language' => 'Dutch (Belgium)', 'locale' => 'nl_be', 'localeFallback' => 'nld', 'charset' => 'utf-8', 'direction' => 'ltr'),
'nn' => array('language' => 'Norwegian Nynorsk', 'locale' => 'nno', 'localeFallback' => 'nor', 'charset' => 'utf-8', 'direction' => 'ltr'),
'no' => array('language' => 'Norwegian', 'locale' => 'nor', 'localeFallback' => 'nor', 'charset' => 'utf-8', 'direction' => 'ltr'),
'p' => array('language' => 'Polish', 'locale' => 'pol', 'localeFallback' => 'pol', 'charset' => 'utf-8', 'direction' => 'ltr'),
@ -291,15 +297,15 @@ class L10n {
'pt' => array('language' => 'Portuguese (Portugal)', 'locale' => 'por', 'localeFallback' => 'por', 'charset' => 'utf-8', 'direction' => 'ltr'),
'pt-br' => array('language' => 'Portuguese (Brazil)', 'locale' => 'pt_br', 'localeFallback' => 'por', 'charset' => 'utf-8', 'direction' => 'ltr'),
'rm' => array('language' => 'Rhaeto-Romanic', 'locale' => 'roh', 'localeFallback' => 'roh', 'charset' => 'utf-8', 'direction' => 'ltr'),
'ro' => array('language' => 'Romanian', 'locale' => 'rum', 'localeFallback' => 'rum', 'charset' => 'utf-8', 'direction' => 'ltr'),
'ro-mo' => array('language' => 'Romanian (Moldavia)', 'locale' => 'ro_mo', 'localeFallback' => 'rum', 'charset' => 'utf-8', 'direction' => 'ltr'),
'ro' => array('language' => 'Romanian', 'locale' => 'ron', 'localeFallback' => 'ron', 'charset' => 'utf-8', 'direction' => 'ltr'),
'ro-mo' => array('language' => 'Romanian (Moldavia)', 'locale' => 'ro_mo', 'localeFallback' => 'ron', 'charset' => 'utf-8', 'direction' => 'ltr'),
'ru' => array('language' => 'Russian', 'locale' => 'rus', 'localeFallback' => 'rus', 'charset' => 'utf-8', 'direction' => 'ltr'),
'ru-mo' => array('language' => 'Russian (Moldavia)', 'locale' => 'ru_mo', 'localeFallback' => 'rus', 'charset' => 'utf-8', 'direction' => 'ltr'),
'sb' => array('language' => 'Sorbian', 'locale' => 'wen', 'localeFallback' => 'wen', 'charset' => 'utf-8', 'direction' => 'ltr'),
'sk' => array('language' => 'Slovak', 'locale' => 'slo', 'localeFallback' => 'slo', 'charset' => 'utf-8', 'direction' => 'ltr'),
'sk' => array('language' => 'Slovak', 'locale' => 'slk', 'localeFallback' => 'slk', 'charset' => 'utf-8', 'direction' => 'ltr'),
'sl' => array('language' => 'Slovenian', 'locale' => 'slv', 'localeFallback' => 'slv', 'charset' => 'utf-8', 'direction' => 'ltr'),
'sq' => array('language' => 'Albanian', 'locale' => 'alb', 'localeFallback' => 'alb', 'charset' => 'utf-8', 'direction' => 'ltr'),
'sr' => array('language' => 'Serbian', 'locale' => 'scc', 'localeFallback' => 'scc', 'charset' => 'utf-8', 'direction' => 'ltr'),
'sq' => array('language' => 'Albanian', 'locale' => 'sqi', 'localeFallback' => 'sqi', 'charset' => 'utf-8', 'direction' => 'ltr'),
'sr' => array('language' => 'Serbian', 'locale' => 'srp', 'localeFallback' => 'srp', 'charset' => 'utf-8', 'direction' => 'ltr'),
'sv' => array('language' => 'Swedish', 'locale' => 'swe', 'localeFallback' => 'swe', 'charset' => 'utf-8', 'direction' => 'ltr'),
'sv-fi' => array('language' => 'Swedish (Finland)', 'locale' => 'sv_fi', 'localeFallback' => 'swe', 'charset' => 'utf-8', 'direction' => 'ltr'),
'sx' => array('language' => 'Sutu', 'locale' => 'sx', 'localeFallback' => 'sx', 'charset' => 'utf-8', 'direction' => 'ltr'),
@ -315,11 +321,11 @@ class L10n {
'cy' => array('language' => 'Welsh', 'locale' => 'cym', 'localeFallback' => 'cym', 'charset' => 'utf-8', 'direction' => 'ltr'),
'xh' => array('language' => 'Xhosa', 'locale' => 'xho', 'localeFallback' => 'xho', 'charset' => 'utf-8', 'direction' => 'ltr'),
'yi' => array('language' => 'Yiddish', 'locale' => 'yid', 'localeFallback' => 'yid', 'charset' => 'utf-8', 'direction' => 'ltr'),
'zh' => array('language' => 'Chinese', 'locale' => 'chi', 'localeFallback' => 'chi', 'charset' => 'utf-8', 'direction' => 'ltr'),
'zh-cn' => array('language' => 'Chinese (PRC)', 'locale' => 'zh_cn', 'localeFallback' => 'chi', 'charset' => 'GB2312', 'direction' => 'ltr'),
'zh-hk' => array('language' => 'Chinese (Hong Kong)', 'locale' => 'zh_hk', 'localeFallback' => 'chi', 'charset' => 'utf-8', 'direction' => 'ltr'),
'zh-sg' => array('language' => 'Chinese (Singapore)', 'locale' => 'zh_sg', 'localeFallback' => 'chi', 'charset' => 'utf-8', 'direction' => 'ltr'),
'zh-tw' => array('language' => 'Chinese (Taiwan)', 'locale' => 'zh_tw', 'localeFallback' => 'chi', 'charset' => 'utf-8', 'direction' => 'ltr'),
'zh' => array('language' => 'Chinese', 'locale' => 'zho', 'localeFallback' => 'zho', 'charset' => 'utf-8', 'direction' => 'ltr'),
'zh-cn' => array('language' => 'Chinese (PRC)', 'locale' => 'zh_cn', 'localeFallback' => 'zho', 'charset' => 'GB2312', 'direction' => 'ltr'),
'zh-hk' => array('language' => 'Chinese (Hong Kong)', 'locale' => 'zh_hk', 'localeFallback' => 'zho', 'charset' => 'utf-8', 'direction' => 'ltr'),
'zh-sg' => array('language' => 'Chinese (Singapore)', 'locale' => 'zh_sg', 'localeFallback' => 'zho', 'charset' => 'utf-8', 'direction' => 'ltr'),
'zh-tw' => array('language' => 'Chinese (Taiwan)', 'locale' => 'zh_tw', 'localeFallback' => 'zho', 'charset' => 'utf-8', 'direction' => 'ltr'),
'zu' => array('language' => 'Zulu', 'locale' => 'zul', 'localeFallback' => 'zul', 'charset' => 'utf-8', 'direction' => 'ltr')
);

View file

@ -18,261 +18,6 @@
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
if (!function_exists('mb_stripos')) {
/**
* Find position of first occurrence of a case-insensitive string.
*
* @param string $haystack The string from which to get the position of the first occurrence of $needle.
* @param string $needle The string to find in $haystack.
* @param integer $offset The position in $haystack to start searching.
* @param string $encoding Character encoding name to use. If it is omitted, internal character encoding is used.
* @return integer|boolean The numeric position of the first occurrence of $needle in the $haystack string, or false
* if $needle is not found.
*/
function mb_stripos($haystack, $needle, $offset = 0, $encoding = null) {
return Multibyte::stripos($haystack, $needle, $offset);
}
}
if (!function_exists('mb_stristr')) {
/**
* Finds first occurrence of a string within another, case insensitive.
*
* @param string $haystack The string from which to get the first occurrence of $needle.
* @param string $needle The string to find in $haystack.
* @param boolean $part Determines which portion of $haystack this function returns.
* If set to true, it returns all of $haystack from the beginning to the first occurrence of $needle.
* If set to false, it returns all of $haystack from the first occurrence of $needle to the end,
* Default value is false.
* @param string $encoding Character encoding name to use. If it is omitted, internal character encoding is used.
* @return string|boolean The portion of $haystack, or false if $needle is not found.
*/
function mb_stristr($haystack, $needle, $part = false, $encoding = null) {
return Multibyte::stristr($haystack, $needle, $part);
}
}
if (!function_exists('mb_strlen')) {
/**
* Get string length.
*
* @param string $string The string being checked for length.
* @param string $encoding Character encoding name to use. If it is omitted, internal character encoding is used.
* @return integer The number of characters in string $string having character encoding encoding.
* A multi-byte character is counted as 1.
*/
function mb_strlen($string, $encoding = null) {
return Multibyte::strlen($string);
}
}
if (!function_exists('mb_strpos')) {
/**
* Find position of first occurrence of a string.
*
* @param string $haystack The string being checked.
* @param string $needle The position counted from the beginning of haystack.
* @param integer $offset The search offset. If it is not specified, 0 is used.
* @param string $encoding Character encoding name to use. If it is omitted, internal character encoding is used.
* @return integer|boolean The numeric position of the first occurrence of $needle in the $haystack string.
* If $needle is not found, it returns false.
*/
function mb_strpos($haystack, $needle, $offset = 0, $encoding = null) {
return Multibyte::strpos($haystack, $needle, $offset);
}
}
if (!function_exists('mb_strrchr')) {
/**
* Finds the last occurrence of a character in a string within another.
*
* @param string $haystack The string from which to get the last occurrence of $needle.
* @param string $needle The string to find in $haystack.
* @param boolean $part Determines which portion of $haystack this function returns.
* If set to true, it returns all of $haystack from the beginning to the last occurrence of $needle.
* If set to false, it returns all of $haystack from the last occurrence of $needle to the end,
* Default value is false.
* @param string $encoding Character encoding name to use. If it is omitted, internal character encoding is used.
* @return string|boolean The portion of $haystack. or false if $needle is not found.
*/
function mb_strrchr($haystack, $needle, $part = false, $encoding = null) {
return Multibyte::strrchr($haystack, $needle, $part);
}
}
if (!function_exists('mb_strrichr')) {
/**
* Finds the last occurrence of a character in a string within another, case insensitive.
*
* @param string $haystack The string from which to get the last occurrence of $needle.
* @param string $needle The string to find in $haystack.
* @param boolean $part Determines which portion of $haystack this function returns.
* If set to true, it returns all of $haystack from the beginning to the last occurrence of $needle.
* If set to false, it returns all of $haystack from the last occurrence of $needle to the end,
* Default value is false.
* @param string $encoding Character encoding name to use. If it is omitted, internal character encoding is used.
* @return string|boolean The portion of $haystack. or false if $needle is not found.
*/
function mb_strrichr($haystack, $needle, $part = false, $encoding = null) {
return Multibyte::strrichr($haystack, $needle, $part);
}
}
if (!function_exists('mb_strripos')) {
/**
* Finds position of last occurrence of a string within another, case insensitive
*
* @param string $haystack The string from which to get the position of the last occurrence of $needle.
* @param string $needle The string to find in $haystack.
* @param integer $offset The position in $haystack to start searching.
* @param string $encoding Character encoding name to use. If it is omitted, internal character encoding is used.
* @return integer|boolean The numeric position of the last occurrence of $needle in the $haystack string,
* or false if $needle is not found.
*/
function mb_strripos($haystack, $needle, $offset = 0, $encoding = null) {
return Multibyte::strripos($haystack, $needle, $offset);
}
}
if (!function_exists('mb_strrpos')) {
/**
* Find position of last occurrence of a string in a string.
*
* @param string $haystack The string being checked, for the last occurrence of $needle.
* @param string $needle The string to find in $haystack.
* @param integer $offset May be specified to begin searching an arbitrary number of characters into the string.
* Negative values will stop searching at an arbitrary point prior to the end of the string.
* @param string $encoding Character encoding name to use. If it is omitted, internal character encoding is used.
* @return integer|boolean The numeric position of the last occurrence of $needle in the $haystack string.
* If $needle is not found, it returns false.
*/
function mb_strrpos($haystack, $needle, $offset = 0, $encoding = null) {
return Multibyte::strrpos($haystack, $needle, $offset);
}
}
if (!function_exists('mb_strstr')) {
/**
* Finds first occurrence of a string within another
*
* @param string $haystack The string from which to get the first occurrence of $needle.
* @param string $needle The string to find in $haystack
* @param boolean $part Determines which portion of $haystack this function returns.
* If set to true, it returns all of $haystack from the beginning to the first occurrence of $needle.
* If set to false, it returns all of $haystack from the first occurrence of $needle to the end,
* Default value is FALSE.
* @param string $encoding Character encoding name to use. If it is omitted, internal character encoding is used.
* @return string|boolean The portion of $haystack, or true if $needle is not found.
*/
function mb_strstr($haystack, $needle, $part = false, $encoding = null) {
return Multibyte::strstr($haystack, $needle, $part);
}
}
if (!function_exists('mb_strtolower')) {
/**
* Make a string lowercase
*
* @param string $string The string being lowercased.
* @param string $encoding Character encoding name to use. If it is omitted, internal character encoding is used.
* @return string with all alphabetic characters converted to lowercase.
*/
function mb_strtolower($string, $encoding = null) {
return Multibyte::strtolower($string);
}
}
if (!function_exists('mb_strtoupper')) {
/**
* Make a string uppercase
*
* @param string $string The string being uppercased.
* @param string $encoding Character encoding name to use. If it is omitted, internal character encoding is used.
* @return string with all alphabetic characters converted to uppercase.
*/
function mb_strtoupper($string, $encoding = null) {
return Multibyte::strtoupper($string);
}
}
if (!function_exists('mb_substr_count')) {
/**
* Count the number of substring occurrences
*
* @param string $haystack The string being checked.
* @param string $needle The string being found.
* @param string $encoding Character encoding name to use. If it is omitted, internal character encoding is used.
* @return integer The number of times the $needle substring occurs in the $haystack string.
*/
function mb_substr_count($haystack, $needle, $encoding = null) {
return Multibyte::substrCount($haystack, $needle);
}
}
if (!function_exists('mb_substr')) {
/**
* Get part of string
*
* @param string $string The string being checked.
* @param integer $start The first position used in $string.
* @param integer $length The maximum length of the returned string.
* @param string $encoding Character encoding name to use. If it is omitted, internal character encoding is used.
* @return string The portion of $string specified by the $string and $length parameters.
*/
function mb_substr($string, $start, $length = null, $encoding = null) {
return Multibyte::substr($string, $start, $length);
}
}
if (!function_exists('mb_encode_mimeheader')) {
/**
* Encode string for MIME header
*
* @param string $str The string being encoded
* @param string $charset specifies the name of the character set in which str is represented in.
* The default value is determined by the current NLS setting (mbstring.language).
* @param string $transfer_encoding specifies the scheme of MIME encoding.
* It should be either "B" (Base64) or "Q" (Quoted-Printable). Falls back to "B" if not given.
* @param string $linefeed specifies the EOL (end-of-line) marker with which
* mb_encode_mimeheader() performs line-folding
* (a » RFC term, the act of breaking a line longer than a certain length into multiple lines.
* The length is currently hard-coded to 74 characters). Falls back to "\r\n" (CRLF) if not given.
* @param integer $indent [definition unknown and appears to have no affect]
* @return string A converted version of the string represented in ASCII.
*/
function mb_encode_mimeheader($str, $charset = 'UTF-8', $transferEncoding = 'B', $linefeed = "\r\n", $indent = 1) {
return Multibyte::mimeEncode($str, $charset, $linefeed);
}
}
/**
* Multibyte handling methods.
*
@ -1124,7 +869,7 @@ class Multibyte {
public static function checkMultibyte($string) {
$length = strlen($string);
for ($i = 0; $i < $length; $i++ ) {
for ($i = 0; $i < $length; $i++) {
$value = ord(($string[$i]));
if ($value > 128) {
return true;

View file

@ -18,6 +18,7 @@
*/
App::uses('BaseLog', 'Log/Engine');
App::uses('Hash', 'Utility');
/**
* File Storage stream for Logging. Writes logs to different files

View file

@ -18,6 +18,7 @@
* @since CakePHP v 1.2.0.4487
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
App::uses('ModelBehavior', 'Model');
App::uses('AclNode', 'Model');
App::uses('Hash', 'Utility');

View file

@ -18,6 +18,7 @@
* @since CakePHP(tm) v 1.2.0.5669
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
App::uses('ModelBehavior', 'Model');
/**
* Behavior to allow for dynamic and atomic manipulation of a Model's associations
@ -174,7 +175,7 @@ class ContainableBehavior extends ModelBehavior {
}
if ($this->settings[$Model->alias]['recursive']) {
$query['recursive'] = (isset($query['recursive'])) ? $query['recursive'] : $containments['depth'];
$query['recursive'] = (isset($query['recursive'])) ? max($query['recursive'], $containments['depth']) : $containments['depth'];
}
$autoFields = ($this->settings[$Model->alias]['autoFields']

View file

@ -13,6 +13,7 @@
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
App::uses('ModelBehavior', 'Model');
App::uses('I18n', 'I18n');
App::uses('I18nModel', 'Model');
@ -193,7 +194,7 @@ class TranslateBehavior extends ModelBehavior {
*/
protected function _checkConditions(Model $Model, $query) {
$conditionFields = array();
if (empty($query['conditions']) || (!empty($query['conditions']) && !is_array($query['conditions'])) ) {
if (empty($query['conditions']) || (!empty($query['conditions']) && !is_array($query['conditions']))) {
return $conditionFields;
}
foreach ($query['conditions'] as $col => $val) {
@ -337,7 +338,7 @@ class TranslateBehavior extends ModelBehavior {
* @return boolean true.
*/
public function beforeSave(Model $Model, $options = array()) {
if (isset($options['validate']) && $options['validate'] == false) {
if (isset($options['validate']) && !$options['validate']) {
unset($this->runtime[$Model->alias]['beforeSave']);
}
if (isset($this->runtime[$Model->alias]['beforeSave'])) {
@ -409,7 +410,6 @@ class TranslateBehavior extends ModelBehavior {
if (!isset($this->runtime[$Model->alias]['beforeValidate']) && !isset($this->runtime[$Model->alias]['beforeSave'])) {
return true;
}
$locale = $this->_getLocale($Model);
if (isset($this->runtime[$Model->alias]['beforeValidate'])) {
$tempData = $this->runtime[$Model->alias]['beforeValidate'];
} else {
@ -420,21 +420,10 @@ class TranslateBehavior extends ModelBehavior {
$conditions = array('model' => $Model->alias, 'foreign_key' => $Model->id);
$RuntimeModel = $this->translateModel($Model);
$fields = array_merge(
$this->settings[$Model->alias],
$this->runtime[$Model->alias]['fields']
);
if ($created) {
// set each field value to an empty string
foreach ($fields as $key => $field) {
if (!is_numeric($key)) {
$field = $key;
}
if (!isset($tempData[$field])) {
$tempData[$field] = '';
}
}
$tempData = $this->_prepareTranslations($Model, $tempData);
}
$locale = $this->_getLocale($Model);
foreach ($tempData as $field => $value) {
unset($conditions['content']);
@ -451,7 +440,10 @@ class TranslateBehavior extends ModelBehavior {
}
$translations = $RuntimeModel->find('list', array(
'conditions' => $conditions,
'fields' => array($RuntimeModel->alias . '.locale', $RuntimeModel->alias . '.id')
'fields' => array(
$RuntimeModel->alias . '.locale',
$RuntimeModel->alias . '.id'
)
));
foreach ($value as $_locale => $_value) {
$RuntimeModel->create();
@ -470,6 +462,37 @@ class TranslateBehavior extends ModelBehavior {
}
}
/**
* Prepares the data to be saved for translated records.
* Add blank fields, and populates data for multi-locale saves.
*
* @param array $data The sparse data that was provided.
* @return array The fully populated data to save.
*/
protected function _prepareTranslations(Model $Model, $data) {
$fields = array_merge($this->settings[$Model->alias], $this->runtime[$Model->alias]['fields']);
$locales = array();
foreach ($data as $key => $value) {
if (is_array($value)) {
$locales = array_merge($locales, array_keys($value));
}
}
$locales = array_unique($locales);
$hasLocales = count($locales) > 0;
foreach ($fields as $key => $field) {
if (!is_numeric($key)) {
$field = $key;
}
if ($hasLocales && !isset($data[$field])) {
$data[$field] = array_fill_keys($locales, '');
} elseif (!isset($data[$field])) {
$data[$field] = '';
}
}
return $data;
}
/**
* afterDelete Callback
*
@ -478,10 +501,7 @@ class TranslateBehavior extends ModelBehavior {
*/
public function afterDelete(Model $Model) {
$RuntimeModel = $this->translateModel($Model);
$conditions = array(
'model' => $Model->alias,
'foreign_key' => $Model->id
);
$conditions = array('model' => $Model->alias, 'foreign_key' => $Model->id);
$RuntimeModel->deleteAll($conditions);
}
@ -549,10 +569,7 @@ class TranslateBehavior extends ModelBehavior {
}
$associations = array();
$RuntimeModel = $this->translateModel($Model);
$default = array(
'className' => $RuntimeModel->alias,
'foreignKey' => 'foreign_key'
);
$default = array('className' => $RuntimeModel->alias, 'foreignKey' => 'foreign_key');
foreach ($fields as $key => $value) {
if (is_numeric($key)) {

View file

@ -18,6 +18,7 @@
* @since CakePHP v 1.2.0.4487
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
App::uses('ModelBehavior', 'Model');
/**
* Tree Behavior.
@ -354,17 +355,16 @@ class TreeBehavior extends ModelBehavior {
$recursive = $overrideRecursive;
}
if ($keyPath == null && $valuePath == null && $Model->hasField($Model->displayField)) {
$fields = array($Model->primaryKey, $Model->displayField, $left, $right);
} else {
$fields = null;
if (!$keyPath && !$valuePath && $Model->hasField($Model->displayField)) {
$fields = array($Model->primaryKey, $Model->displayField, $left, $right);
}
if ($keyPath == null) {
if (!$keyPath) {
$keyPath = '{n}.' . $Model->alias . '.' . $Model->primaryKey;
}
if ($valuePath == null) {
if (!$valuePath) {
$valuePath = array('%s%s', '{n}.tree_prefix', '{n}.' . $Model->alias . '.' . $Model->displayField);
} elseif (is_string($valuePath)) {
@ -644,9 +644,8 @@ class TreeBehavior extends ModelBehavior {
$db = ConnectionManager::getDataSource($Model->useDbConfig);
foreach ($Model->find('all', array('conditions' => $scope, 'fields' => array($Model->primaryKey, $parent), 'order' => $left)) as $array) {
$path = $this->getPath($Model, $array[$Model->alias][$Model->primaryKey]);
if ($path == null || count($path) < 2) {
$parentId = null;
} else {
if (count($path) > 1) {
$parentId = $path[count($path) - 2][$Model->alias][$Model->primaryKey];
}
$Model->updateAll(array($parent => $db->value($parentId, $parent)), array($Model->escapeField() => $array[$Model->alias][$Model->primaryKey]));
@ -799,7 +798,7 @@ class TreeBehavior extends ModelBehavior {
$scope, 'OR' => array($Model->escapeField($left) => $i, $Model->escapeField($right) => $i)
)));
if ($count != 1) {
if ($count == 0) {
if (!$count) {
$errors[] = array('index', $i, 'missing');
} else {
$errors[] = array('index', $i, 'duplicate');

View file

@ -254,15 +254,21 @@ class CakeSchema extends Object {
continue;
}
if (!is_object($Object) || $Object->useTable === false) {
continue;
}
$db = $Object->getDataSource();
if (is_object($Object) && $Object->useTable !== false) {
$fulltable = $table = $db->fullTableName($Object, false, false);
if ($prefix && strpos($table, $prefix) !== 0) {
continue;
}
if (!in_array($fulltable, $currentTables)) {
continue;
}
$table = $this->_noPrefixTable($prefix, $table);
if (in_array($fulltable, $currentTables)) {
$key = array_search($fulltable, $currentTables);
if (empty($tables[$table])) {
$tables[$table] = $this->_columns($Object);
@ -270,12 +276,16 @@ class CakeSchema extends Object {
$tables[$table]['tableParameters'] = $db->readTableParameters($fulltable);
unset($currentTables[$key]);
}
if (!empty($Object->hasAndBelongsToMany)) {
foreach ($Object->hasAndBelongsToMany as $assocData) {
if (empty($Object->hasAndBelongsToMany)) {
continue;
}
foreach ($Object->hasAndBelongsToMany as $Assoc => $assocData) {
if (isset($assocData['with'])) {
$class = $assocData['with'];
}
if (is_object($Object->$class)) {
if (!is_object($Object->$class)) {
continue;
}
$withTable = $db->fullTableName($Object->$class, false, false);
if ($prefix && strpos($withTable, $prefix) !== 0) {
continue;
@ -292,10 +302,6 @@ class CakeSchema extends Object {
}
}
}
}
}
}
}
if (!empty($currentTables)) {
foreach ($currentTables as $table) {
@ -412,28 +418,28 @@ class CakeSchema extends Object {
}
$col = "\t\t'{$field}' => array('type' => '" . $value['type'] . "', ";
unset($value['type']);
$col .= join(', ', $this->_values($value));
$col .= implode(', ', $this->_values($value));
} elseif ($field == 'indexes') {
$col = "\t\t'indexes' => array(\n\t\t\t";
$props = array();
foreach ((array)$value as $key => $index) {
$props[] = "'{$key}' => array(" . join(', ', $this->_values($index)) . ")";
$props[] = "'{$key}' => array(" . implode(', ', $this->_values($index)) . ")";
}
$col .= join(",\n\t\t\t", $props) . "\n\t\t";
$col .= implode(",\n\t\t\t", $props) . "\n\t\t";
} elseif ($field == 'tableParameters') {
$col = "\t\t'tableParameters' => array(";
$props = array();
foreach ((array)$value as $key => $param) {
$props[] = "'{$key}' => '$param'";
}
$col .= join(', ', $props);
$col .= implode(', ', $props);
}
$col .= ")";
$cols[] = $col;
}
$out .= join(",\n", $cols);
$out .= implode(",\n", $cols);
}
$out .= "\n\t);\n";
$out .= "\n\t);\n\n";
return $out;
}
@ -597,7 +603,7 @@ class CakeSchema extends Object {
$db = $Obj->getDataSource();
$fields = $Obj->schema(true);
$columns = array();
$columns = $props = array();
foreach ($fields as $name => $value) {
if ($Obj->primaryKey == $name) {
$value['key'] = 'primary';

View file

@ -131,7 +131,7 @@ class CakeSession {
self::$time = time();
$checkAgent = Configure::read('Session.checkAgent');
if (($checkAgent === true || $checkAgent === null) && env('HTTP_USER_AGENT') != null) {
if (($checkAgent === true || $checkAgent === null) && env('HTTP_USER_AGENT')) {
self::$_userAgent = md5(env('HTTP_USER_AGENT') . Configure::read('Security.salt'));
}
self::_setPath($base);
@ -218,8 +218,7 @@ class CakeSession {
if (empty($name)) {
return false;
}
$result = Hash::get($_SESSION, $name);
return isset($result);
return Hash::get($_SESSION, $name) !== null;
}
/**
@ -248,7 +247,7 @@ class CakeSession {
public static function delete($name) {
if (self::check($name)) {
self::_overwrite($_SESSION, Hash::remove($_SESSION, $name));
return (self::check($name) == false);
return !self::check($name);
}
self::_setError(2, __d('cake_dev', "%s doesn't exist", $name));
return false;
@ -283,9 +282,8 @@ class CakeSession {
protected static function _error($errorNumber) {
if (!is_array(self::$error) || !array_key_exists($errorNumber, self::$error)) {
return false;
} else {
return self::$error[$errorNumber];
}
return self::$error[$errorNumber];
}
/**
@ -662,7 +660,7 @@ class CakeSession {
*/
public static function renew() {
if (session_id()) {
if (session_id() != '' || isset($_COOKIE[session_name()])) {
if (session_id() || isset($_COOKIE[session_name()])) {
setcookie(Configure::read('Session.cookie'), '', time() - 42000, self::$path);
}
session_regenerate_id(true);

View file

@ -108,6 +108,7 @@ class Mysql extends DboSource {
'primary_key' => array('name' => 'NOT NULL AUTO_INCREMENT'),
'string' => array('name' => 'varchar', 'limit' => '255'),
'text' => array('name' => 'text'),
'biginteger' => array('name' => 'bigint', 'limit' => '20'),
'integer' => array('name' => 'int', 'limit' => '11', 'formatter' => 'intval'),
'float' => array('name' => 'float', 'formatter' => 'floatval'),
'datetime' => array('name' => 'datetime', 'format' => 'Y-m-d H:i:s', 'formatter' => 'date'),
@ -118,6 +119,13 @@ class Mysql extends DboSource {
'boolean' => array('name' => 'tinyint', 'limit' => '1')
);
/**
* Mapping of collation names to character set names
*
* @var array
*/
protected $_charsets = array();
/**
* Connects to the database using options in the given configuration array.
*
@ -155,6 +163,7 @@ class Mysql extends DboSource {
));
}
$this->_charsets = array();
$this->_useAlias = (bool)version_compare($this->getVersion(), "4.1", ">=");
return $this->connected;
@ -177,7 +186,7 @@ class Mysql extends DboSource {
*/
public function listSources($data = null) {
$cache = parent::listSources();
if ($cache != null) {
if ($cache) {
return $cache;
}
$result = $this->_execute('SHOW TABLES FROM ' . $this->name($this->config['database']));
@ -261,15 +270,24 @@ class Mysql extends DboSource {
* @return string Character set name
*/
public function getCharsetName($name) {
if ((bool)version_compare($this->getVersion(), "5", ">=")) {
$r = $this->_execute('SELECT CHARACTER_SET_NAME FROM INFORMATION_SCHEMA.COLLATIONS WHERE COLLATION_NAME = ?', array($name));
if ((bool)version_compare($this->getVersion(), "5", "<")) {
return false;
}
if (isset($this->_charsets[$name])) {
return $this->_charsets[$name];
}
$r = $this->_execute(
'SELECT CHARACTER_SET_NAME FROM INFORMATION_SCHEMA.COLLATIONS WHERE COLLATION_NAME = ?',
array($name)
);
$cols = $r->fetch(PDO::FETCH_ASSOC);
if (isset($cols['CHARACTER_SET_NAME'])) {
return $cols['CHARACTER_SET_NAME'];
$this->_charsets[$name] = $cols['CHARACTER_SET_NAME'];
} else {
$this->_charsets[$name] = false;
}
}
return false;
return $this->_charsets[$name];
}
/**
@ -282,7 +300,7 @@ class Mysql extends DboSource {
public function describe($model) {
$key = $this->fullTableName($model, false);
$cache = parent::describe($key);
if ($cache != null) {
if ($cache) {
return $cache;
}
$table = $this->fullTableName($model);
@ -334,7 +352,7 @@ class Mysql extends DboSource {
return parent::update($model, $fields, $values, $conditions);
}
if ($values == null) {
if (!$values) {
$combined = $fields;
} else {
$combined = array_combine($fields, $values);
@ -425,17 +443,22 @@ class Mysql extends DboSource {
$table = $this->fullTableName($model);
$old = version_compare($this->getVersion(), '4.1', '<=');
if ($table) {
$indices = $this->_execute('SHOW INDEX FROM ' . $table);
$indexes = $this->_execute('SHOW INDEX FROM ' . $table);
// @codingStandardsIgnoreStart
// MySQL columns don't match the cakephp conventions.
while ($idx = $indices->fetch(PDO::FETCH_OBJ)) {
while ($idx = $indexes->fetch(PDO::FETCH_OBJ)) {
if ($old) {
$idx = (object)current((array)$idx);
}
if (!isset($index[$idx->Key_name]['column'])) {
$col = array();
$index[$idx->Key_name]['column'] = $idx->Column_name;
if ($idx->Index_type === 'FULLTEXT') {
$index[$idx->Key_name]['type'] = strtolower($idx->Index_type);
} else {
$index[$idx->Key_name]['unique'] = intval($idx->Non_unique == 0);
}
} else {
if (!empty($index[$idx->Key_name]['column']) && !is_array($index[$idx->Key_name]['column'])) {
$col[] = $index[$idx->Key_name]['column'];
@ -445,7 +468,7 @@ class Mysql extends DboSource {
}
}
// @codingStandardsIgnoreEnd
$indices->closeCursor();
$indexes->closeCursor();
}
return $index;
}
@ -555,31 +578,18 @@ class Mysql extends DboSource {
if (isset($indexes['drop'])) {
foreach ($indexes['drop'] as $name => $value) {
$out = 'DROP ';
if ($name == 'PRIMARY') {
if ($name === 'PRIMARY') {
$out .= 'PRIMARY KEY';
} else {
$out .= 'KEY ' . $name;
$out .= 'KEY ' . $this->startQuote . $name . $this->endQuote;
}
$alter[] = $out;
}
}
if (isset($indexes['add'])) {
foreach ($indexes['add'] as $name => $value) {
$out = 'ADD ';
if ($name == 'PRIMARY') {
$out .= 'PRIMARY ';
$name = null;
} else {
if (!empty($value['unique'])) {
$out .= 'UNIQUE ';
}
}
if (is_array($value['column'])) {
$out .= 'KEY ' . $name . ' (' . implode(', ', array_map(array(&$this, 'name'), $value['column'])) . ')';
} else {
$out .= 'KEY ' . $name . ' (' . $this->name($value['column']) . ')';
}
$alter[] = $out;
$add = $this->buildIndex($indexes['add']);
foreach ($add as $index) {
$alter[] = 'ADD ' . $index;
}
}
return $alter;
@ -645,9 +655,12 @@ class Mysql extends DboSource {
if (in_array($col, array('date', 'time', 'datetime', 'timestamp'))) {
return $col;
}
if (($col === 'tinyint' && $limit == 1) || $col === 'boolean') {
if (($col === 'tinyint' && $limit === 1) || $col === 'boolean') {
return 'boolean';
}
if (strpos($col, 'bigint') !== false || $col === 'bigint') {
return 'biginteger';
}
if (strpos($col, 'int') !== false) {
return 'integer';
}

View file

@ -59,6 +59,7 @@ class Postgres extends DboSource {
'string' => array('name' => 'varchar', 'limit' => '255'),
'text' => array('name' => 'text'),
'integer' => array('name' => 'integer', 'formatter' => 'intval'),
'biginteger' => array('name' => 'bigint', 'limit' => '20'),
'float' => array('name' => 'float', 'formatter' => 'floatval'),
'datetime' => array('name' => 'timestamp', 'format' => 'Y-m-d H:i:s', 'formatter' => 'date'),
'timestamp' => array('name' => 'timestamp', 'format' => 'Y-m-d H:i:s', 'formatter' => 'date'),
@ -148,7 +149,7 @@ class Postgres extends DboSource {
public function listSources($data = null) {
$cache = parent::listSources();
if ($cache != null) {
if ($cache) {
return $cache;
}
@ -158,7 +159,8 @@ class Postgres extends DboSource {
if (!$result) {
return array();
} else {
}
$tables = array();
foreach ($result as $item) {
@ -169,7 +171,6 @@ class Postgres extends DboSource {
parent::listSources($tables);
return $tables;
}
}
/**
* Returns an array of the fields in given table name.
@ -286,13 +287,34 @@ class Postgres extends DboSource {
if (is_object($table)) {
$table = $this->fullTableName($table, false, false);
}
if (isset($this->_sequenceMap[$table]) && isset($this->_sequenceMap[$table][$field])) {
if (!isset($this->_sequenceMap[$table])) {
$this->describe($table);
}
if (isset($this->_sequenceMap[$table][$field])) {
return $this->_sequenceMap[$table][$field];
} else {
return "{$table}_{$field}_seq";
}
}
/**
* Reset a sequence based on the MAX() value of $column. Useful
* for resetting sequences after using insertMulti().
*
* @param string $table The name of the table to update.
* @param string $column The column to use when reseting the sequence value, the
* sequence name will be fetched using Postgres::getSequence();
* @return boolean success.
*/
public function resetSequence($table, $column) {
$tableName = $this->fullTableName($table, false, false);
$fullTable = $this->fullTableName($table);
$sequence = $this->value($this->getSequence($tableName, $column));
$this->execute("SELECT setval($sequence, (SELECT MAX(id) FROM $fullTable))");
return true;
}
/**
* Deletes all the records in a table and drops all associated auto-increment sequences
*
@ -640,6 +662,8 @@ class Postgres extends DboSource {
return 'datetime';
case (strpos($col, 'time') === 0):
return 'time';
case ($col == 'bigint'):
return 'biginteger';
case (strpos($col, 'int') !== false && $col != 'interval'):
return 'integer';
case (strpos($col, 'char') !== false || $col == 'uuid'):
@ -671,7 +695,7 @@ class Postgres extends DboSource {
if ($col == 'uuid') {
return 36;
}
if ($limit != null) {
if ($limit) {
return intval($limit);
}
return null;
@ -801,7 +825,19 @@ class Postgres extends DboSource {
if (!isset($col['length']) && !isset($col['limit'])) {
unset($column['length']);
}
$out = preg_replace('/integer\([0-9]+\)/', 'integer', parent::buildColumn($column));
$out = parent::buildColumn($column);
$out = preg_replace(
'/integer\([0-9]+\)/',
'integer',
$out
);
$out = preg_replace(
'/bigint\([0-9]+\)/',
'bigint',
$out
);
$out = str_replace('integer serial', 'serial', $out);
if (strpos($out, 'timestamp DEFAULT')) {
if (isset($column['null']) && $column['null']) {

View file

@ -70,6 +70,7 @@ class Sqlite extends DboSource {
'string' => array('name' => 'varchar', 'limit' => '255'),
'text' => array('name' => 'text'),
'integer' => array('name' => 'integer', 'limit' => null, 'formatter' => 'intval'),
'biginteger' => array('name' => 'bigint', 'limit' => 20),
'float' => array('name' => 'float', 'formatter' => 'floatval'),
'datetime' => array('name' => 'datetime', 'format' => 'Y-m-d H:i:s', 'formatter' => 'date'),
'timestamp' => array('name' => 'timestamp', 'format' => 'Y-m-d H:i:s', 'formatter' => 'date'),
@ -138,7 +139,7 @@ class Sqlite extends DboSource {
*/
public function listSources($data = null) {
$cache = parent::listSources();
if ($cache != null) {
if ($cache) {
return $cache;
}
@ -146,7 +147,8 @@ class Sqlite extends DboSource {
if (!$result || empty($result)) {
return array();
} else {
}
$tables = array();
foreach ($result as $table) {
$tables[] = $table[0]['name'];
@ -154,7 +156,6 @@ class Sqlite extends DboSource {
parent::listSources($tables);
return $tables;
}
}
/**
* Returns an array of the fields in given table name.
@ -165,7 +166,7 @@ class Sqlite extends DboSource {
public function describe($model) {
$table = $this->fullTableName($model, false, false);
$cache = parent::describe($table);
if ($cache != null) {
if ($cache) {
return $cache;
}
$fields = array();
@ -251,9 +252,22 @@ class Sqlite extends DboSource {
$limit = null;
@list($col, $limit) = explode('(', $col);
if (in_array($col, array('text', 'integer', 'float', 'boolean', 'timestamp', 'date', 'datetime', 'time'))) {
$standard = array(
'text',
'integer',
'float',
'boolean',
'timestamp',
'date',
'datetime',
'time'
);
if (in_array($col, $standard)) {
return $col;
}
if ($col === 'bigint') {
return 'biginteger';
}
if (strpos($col, 'char') !== false) {
return 'string';
}
@ -448,7 +462,7 @@ class Sqlite extends DboSource {
$out .= 'UNIQUE ';
}
if (is_array($value['column'])) {
$value['column'] = join(', ', array_map(array(&$this, 'name'), $value['column']));
$value['column'] = implode(', ', array_map(array(&$this, 'name'), $value['column']));
} else {
$value['column'] = $this->name($value['column']);
}
@ -513,10 +527,10 @@ class Sqlite extends DboSource {
case 'schema':
extract($data);
if (is_array($columns)) {
$columns = "\t" . join(",\n\t", array_filter($columns));
$columns = "\t" . implode(",\n\t", array_filter($columns));
}
if (is_array($indexes)) {
$indexes = "\t" . join("\n\t", array_filter($indexes));
$indexes = "\t" . implode("\n\t", array_filter($indexes));
}
return "CREATE TABLE {$table} (\n{$columns});\n{$indexes}";
default:

View file

@ -89,6 +89,7 @@ class Sqlserver extends DboSource {
'string' => array('name' => 'nvarchar', 'limit' => '255'),
'text' => array('name' => 'nvarchar', 'limit' => 'MAX'),
'integer' => array('name' => 'int', 'formatter' => 'intval'),
'biginteger' => array('name' => 'bigint'),
'float' => array('name' => 'numeric', 'formatter' => 'floatval'),
'datetime' => array('name' => 'datetime', 'format' => 'Y-m-d H:i:s', 'formatter' => 'date'),
'timestamp' => array('name' => 'timestamp', 'format' => 'Y-m-d H:i:s', 'formatter' => 'date'),
@ -186,7 +187,7 @@ class Sqlserver extends DboSource {
public function describe($model) {
$table = $this->fullTableName($model, false);
$cache = parent::describe($table);
if ($cache != null) {
if ($cache) {
return $cache;
}
$fields = array();
@ -402,6 +403,9 @@ class Sqlserver extends DboSource {
if ($col == 'bit') {
return 'boolean';
}
if (strpos($col, 'bigint') !== false) {
return 'biginteger';
}
if (strpos($col, 'int') !== false) {
return 'integer';
}
@ -618,7 +622,7 @@ class Sqlserver extends DboSource {
*/
public function insertMulti($table, $fields, $values) {
$primaryKey = $this->_getPrimaryKey($table);
$hasPrimaryKey = $primaryKey != null && (
$hasPrimaryKey = $primaryKey && (
(is_array($fields) && in_array($primaryKey, $fields)
|| (is_string($fields) && strpos($fields, $this->startQuote . $primaryKey . $this->endQuote) !== false))
);
@ -644,7 +648,7 @@ class Sqlserver extends DboSource {
*/
public function buildColumn($column) {
$result = parent::buildColumn($column);
$result = preg_replace('/(int|integer)\([0-9]+\)/i', '$1', $result);
$result = preg_replace('/(bigint|int|integer)\([0-9]+\)/i', '$1', $result);
$result = preg_replace('/(bit)\([0-9]+\)/i', '$1', $result);
if (strpos($result, 'DEFAULT NULL') !== false) {
if (isset($column['default']) && $column['default'] === '') {
@ -731,7 +735,7 @@ class Sqlserver extends DboSource {
*/
protected function _execute($sql, $params = array(), $prepareOptions = array()) {
$this->_lastAffected = false;
if (strncasecmp($sql, 'SELECT', 6) == 0 || preg_match('/^EXEC(?:UTE)?\s/mi', $sql) > 0) {
if (strncasecmp($sql, 'SELECT', 6) === 0 || preg_match('/^EXEC(?:UTE)?\s/mi', $sql) > 0) {
$prepareOptions += array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL);
return parent::_execute($sql, $params, $prepareOptions);
}

View file

@ -600,7 +600,7 @@ class DboSource extends DataSource {
} else {
if (isset($args[1]) && $args[1] === true) {
return $this->fetchAll($args[0], true);
} elseif (isset($args[1]) && !is_array($args[1]) ) {
} elseif (isset($args[1]) && !is_array($args[1])) {
return $this->fetchAll($args[0], false);
} elseif (isset($args[1]) && is_array($args[1])) {
if (isset($args[2])) {
@ -671,7 +671,7 @@ class DboSource extends DataSource {
if ($this->hasResult()) {
$first = $this->fetchRow();
if ($first != null) {
if ($first) {
$out[] = $first;
}
while ($item = $this->fetchResult()) {
@ -984,7 +984,7 @@ class DboSource extends DataSource {
public function create(Model $model, $fields = null, $values = null) {
$id = null;
if ($fields == null) {
if (!$fields) {
unset($fields, $values);
$fields = array_keys($model->data);
$values = array_values($model->data);
@ -1054,7 +1054,7 @@ class DboSource extends DataSource {
if ($model->recursive == -1) {
$_associations = array();
} elseif ($model->recursive == 0) {
} elseif ($model->recursive === 0) {
unset($_associations[2], $_associations[3]);
}
@ -1408,10 +1408,9 @@ class DboSource extends DataSource {
}
}
if (!isset($data[$association])) {
if ($merge[0][$association] != null) {
$data[$association] = $merge[0][$association];
} else {
$data[$association] = array();
if ($merge[0][$association]) {
$data[$association] = $merge[0][$association];
}
} else {
if (is_array($merge[0][$association])) {
@ -1767,7 +1766,7 @@ class DboSource extends DataSource {
case 'schema':
foreach (array('columns', 'indexes', 'tableParameters') as $var) {
if (is_array(${$var})) {
${$var} = "\t" . join(",\n\t", array_filter(${$var}));
${$var} = "\t" . implode(",\n\t", array_filter(${$var}));
} else {
${$var} = '';
}
@ -1821,7 +1820,7 @@ class DboSource extends DataSource {
* @return boolean Success
*/
public function update(Model $model, $fields = array(), $values = null, $conditions = null) {
if ($values == null) {
if (!$values) {
$combined = $fields;
} else {
$combined = array_combine($fields, $values);
@ -2514,7 +2513,7 @@ class DboSource extends DataSource {
$data = $this->_parseKey($model, trim($key), $value);
}
if ($data != null) {
if ($data) {
$out[] = $data;
$data = null;
}
@ -2925,6 +2924,19 @@ class DboSource extends DataSource {
return $this->commit();
}
/**
* Reset a sequence based on the MAX() value of $column. Useful
* for resetting sequences after using insertMulti().
*
* This method should be implemented by datasources that require sequences to be used.
*
* @param string $table The name of the table to update.
* @param string $column The column to use when reseting the sequence value.
* @return boolean success.
*/
public function resetSequence($table, $column) {
}
/**
* Returns an array of the indexes in given datasource name.
*
@ -3071,7 +3083,7 @@ class DboSource extends DataSource {
}
$out = $this->_buildFieldParameters($out, $column, 'beforeDefault');
if (isset($column['key']) && $column['key'] === 'primary' && $type === 'integer') {
if (isset($column['key']) && $column['key'] === 'primary' && ($type === 'integer' || $type === 'biginteger')) {
$out .= ' ' . $this->columns['primary_key']['name'];
} elseif (isset($column['key']) && $column['key'] === 'primary') {
$out .= ' NOT NULL';
@ -3117,7 +3129,7 @@ class DboSource extends DataSource {
}
/**
* Format indexes for create table
* Format indexes for create table.
*
* @param array $indexes
* @param string $table
@ -3133,6 +3145,8 @@ class DboSource extends DataSource {
} else {
if (!empty($value['unique'])) {
$out .= 'UNIQUE ';
} elseif (!empty($value['type']) && strtoupper($value['type']) === 'FULLTEXT') {
$out .= 'FULLTEXT ';
}
$name = $this->startQuote . $name . $this->endQuote;
}

View file

@ -12,6 +12,7 @@
* @since CakePHP(tm) v 1.2.0.4525
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
App::uses('AppModel', 'Model');
/**
* A model used by TranslateBehavior to access the translation tables.

View file

@ -235,6 +235,13 @@ class Model extends Object implements CakeEventListener {
*/
public $tablePrefix = null;
/**
* Plugin model belongs to.
*
* @var string
*/
public $plugin = null;
/**
* Name of the model.
*
@ -669,12 +676,16 @@ class Model extends Object implements CakeEventListener {
extract(array_merge(
array(
'id' => $this->id, 'table' => $this->useTable, 'ds' => $this->useDbConfig,
'name' => $this->name, 'alias' => $this->alias
'name' => $this->name, 'alias' => $this->alias, 'plugin' => $this->plugin
),
$id
));
}
if ($this->plugin === null) {
$this->plugin = (isset($plugin) ? $plugin : $this->plugin);
}
if ($this->name === null) {
$this->name = (isset($name) ? $name : get_class($this));
}
@ -720,7 +731,7 @@ class Model extends Object implements CakeEventListener {
$this->useTable = Inflector::tableize($this->name);
}
if ($this->displayField == null) {
if (!$this->displayField) {
unset($this->displayField);
}
$this->table = $this->useTable;
@ -1393,7 +1404,7 @@ class Model extends Object implements CakeEventListener {
$this->schema();
}
if ($this->_schema != null) {
if ($this->_schema) {
return isset($this->_schema[$name]);
}
return false;
@ -1447,7 +1458,7 @@ class Model extends Object implements CakeEventListener {
* or false if none $field exist.
*/
public function getVirtualField($field = null) {
if ($field == null) {
if (!$field) {
return empty($this->virtualFields) ? false : $this->virtualFields;
}
if ($this->isVirtualField($field)) {
@ -1503,7 +1514,7 @@ class Model extends Object implements CakeEventListener {
public function read($fields = null, $id = null) {
$this->validationErrors = array();
if ($id != null) {
if ($id) {
$this->id = $id;
}
@ -1519,9 +1530,8 @@ class Model extends Object implements CakeEventListener {
'fields' => $fields
));
return $this->data;
} else {
return false;
}
return false;
}
/**
@ -1874,7 +1884,7 @@ class Model extends Object implements CakeEventListener {
if ($keepExisting && !empty($links)) {
foreach ($links as $link) {
$oldJoin = $link[$join][$this->hasAndBelongsToMany[$assoc]['associationForeignKey']];
if (! in_array($oldJoin, $newJoins) ) {
if (!in_array($oldJoin, $newJoins)) {
$conditions[$associationForeignKey] = $oldJoin;
$db->delete($this->{$join}, $conditions);
} else {
@ -2220,6 +2230,7 @@ class Model extends Object implements CakeEventListener {
} else {
$data = array_merge(array($key => $this->{$association}->id), $data, array($key => $this->{$association}->id));
}
$options = $this->_addToWhiteList($key, $options);
} else {
$validationErrors[$association] = $this->{$association}->validationErrors;
}
@ -2250,6 +2261,7 @@ class Model extends Object implements CakeEventListener {
$validates = $this->{$association}->create(null) !== null;
$saved = false;
if ($validates) {
$options = $this->{$association}->_addToWhiteList($key, $options);
if ($options['deep']) {
$saved = $this->{$association}->saveAssociated($values, array_merge($options, array('atomic' => false)));
} else {
@ -2270,6 +2282,7 @@ class Model extends Object implements CakeEventListener {
$values[$i] = array_merge(array($key => $this->id), $value, array($key => $this->id));
}
}
$options = $this->{$association}->_addToWhiteList($key, $options);
$_return = $this->{$association}->saveMany($values, array_merge($options, array('atomic' => false)));
if (in_array(false, $_return, true)) {
$validationErrors[$association] = $this->{$association}->validationErrors;
@ -2302,6 +2315,29 @@ class Model extends Object implements CakeEventListener {
return false;
}
/**
* Helper method for saveAll() and friends, to add foreign key to fieldlist
*
* @param string $key fieldname to be added to list
* @param array $options
* @return array $options
*/
protected function _addToWhiteList($key, $options) {
if (empty($options['fieldList']) && $this->whitelist && !in_array($key, $this->whitelist)) {
$options['fieldList'][$this->alias] = $this->whitelist;
$options['fieldList'][$this->alias][] = $key;
return $options;
}
if (!empty($options['fieldList'][$this->alias]) && is_array($options['fieldList'][$this->alias])) {
$options['fieldList'][$this->alias][] = $key;
return $options;
}
if (!empty($options['fieldList']) && is_array($options['fieldList'])) {
$options['fieldList'][] = $key;
}
return $options;
}
/**
* Validates a single record, as well as all its directly associated records.
*
@ -2566,7 +2602,7 @@ class Model extends Object implements CakeEventListener {
* @return boolean True if such a record exists
*/
public function hasAny($conditions = null) {
return ($this->find('count', array('conditions' => $conditions, 'recursive' => -1)) != false);
return (bool)$this->find('count', array('conditions' => $conditions, 'recursive' => -1));
}
/**
@ -2731,7 +2767,7 @@ class Model extends Object implements CakeEventListener {
*/
protected function _findCount($state, $query, $results = array()) {
if ($state === 'before') {
if (!empty($query['type']) && isset($this->findMethods[$query['type']]) && $query['type'] !== 'count' ) {
if (!empty($query['type']) && isset($this->findMethods[$query['type']]) && $query['type'] !== 'count') {
$query['operation'] = 'count';
$query = $this->{'_find' . ucfirst($query['type'])}('before', $query);
}
@ -2987,7 +3023,7 @@ class Model extends Object implements CakeEventListener {
if (!empty($this->id)) {
$fields[$this->alias . '.' . $this->primaryKey . ' !='] = $this->id;
}
return ($this->find('count', array('conditions' => $fields, 'recursive' => -1)) == 0);
return !$this->find('count', array('conditions' => $fields, 'recursive' => -1));
}
/**
@ -3158,7 +3194,7 @@ class Model extends Object implements CakeEventListener {
public function setDataSource($dataSource = null) {
$oldConfig = $this->useDbConfig;
if ($dataSource != null) {
if ($dataSource) {
$this->useDbConfig = $dataSource;
}
$db = ConnectionManager::getDataSource($this->useDbConfig);
@ -3204,7 +3240,7 @@ class Model extends Object implements CakeEventListener {
* @return array Associations
*/
public function getAssociated($type = null) {
if ($type == null) {
if (!$type) {
$associated = array();
foreach ($this->_associations as $assoc) {
if (!empty($this->{$assoc})) {

View file

@ -81,7 +81,7 @@ class Permission extends AppModel {
* @return boolean Success (true if ARO has access to action in ACO, false otherwise)
*/
public function check($aro, $aco, $action = "*") {
if ($aro == null || $aco == null) {
if (!$aro || !$aco) {
return false;
}
@ -89,12 +89,12 @@ class Permission extends AppModel {
$aroPath = $this->Aro->node($aro);
$acoPath = $this->Aco->node($aco);
if (empty($aroPath) || empty($acoPath)) {
if (!$aroPath || !$acoPath) {
trigger_error(__d('cake_dev', "DbAcl::check() - Failed ARO/ACO node lookup in permissions check. Node references:\nAro: ") . print_r($aro, true) . "\nAco: " . print_r($aco, true), E_USER_WARNING);
return false;
}
if ($acoPath == null || $acoPath == array()) {
if (!$acoPath) {
trigger_error(__d('cake_dev', "DbAcl::check() - Failed ACO node lookup in permissions check. Node references:\nAro: ") . print_r($aro, true) . "\nAco: " . print_r($aco, true), E_USER_WARNING);
return false;
}
@ -146,7 +146,6 @@ class Permission extends AppModel {
return false;
case 0:
continue;
break;
case 1:
return true;
}
@ -171,7 +170,7 @@ class Permission extends AppModel {
$permKeys = $this->getAcoKeys($this->schema());
$save = array();
if ($perms == false) {
if (!$perms) {
trigger_error(__d('cake_dev', 'DbAcl::allow() - Invalid node'), E_USER_WARNING);
return false;
}
@ -198,7 +197,7 @@ class Permission extends AppModel {
}
list($save['aro_id'], $save['aco_id']) = array($perms['aro'], $perms['aco']);
if ($perms['link'] != null && !empty($perms['link'])) {
if ($perms['link'] && !empty($perms['link'])) {
$save['id'] = $perms['link'][0][$this->alias]['id'];
} else {
unset($save['id']);

View file

@ -273,7 +273,7 @@ class CakeValidationRule {
$this->_valid = call_user_func_array(array('Validation', $this->_rule), $this->_ruleParams);
} elseif (is_string($validator['rule'])) {
$this->_valid = preg_match($this->_rule, $data[$field]);
} elseif (Configure::read('debug') > 0) {
} else {
trigger_error(__d('cake_dev', 'Could not find validation handler %s for %s', $this->_rule, $field), E_USER_WARNING);
return false;
}

View file

@ -366,17 +366,17 @@ class CakeRequest implements ArrayAccess {
* @return string The client IP.
*/
public function clientIp($safe = true) {
if (!$safe && env('HTTP_X_FORWARDED_FOR') != null) {
if (!$safe && env('HTTP_X_FORWARDED_FOR')) {
$ipaddr = preg_replace('/(?:,.*)/', '', env('HTTP_X_FORWARDED_FOR'));
} else {
if (env('HTTP_CLIENT_IP') != null) {
if (env('HTTP_CLIENT_IP')) {
$ipaddr = env('HTTP_CLIENT_IP');
} else {
$ipaddr = env('REMOTE_ADDR');
}
}
if (env('HTTP_CLIENTADDRESS') != null) {
if (env('HTTP_CLIENTADDRESS')) {
$tmpipaddr = env('HTTP_CLIENTADDRESS');
if (!empty($tmpipaddr)) {
@ -696,8 +696,50 @@ class CakeRequest implements ArrayAccess {
* @return array An array of prefValue => array(content/types)
*/
public function parseAccept() {
return $this->_parseAcceptWithQualifier($this->header('accept'));
}
/**
* Get the languages accepted by the client, or check if a specific language is accepted.
*
* Get the list of accepted languages:
*
* {{{ CakeRequest::acceptLanguage(); }}}
*
* Check if a specific language is accepted:
*
* {{{ CakeRequest::acceptLanguage('es-es'); }}}
*
* @param string $language The language to test.
* @return If a $language is provided, a boolean. Otherwise the array of accepted languages.
*/
public static function acceptLanguage($language = null) {
$raw = self::_parseAcceptWithQualifier(self::header('Accept-Language'));
$accept = array();
$header = explode(',', $this->header('accept'));
foreach ($raw as $qualifier => $languages) {
foreach ($languages as &$lang) {
if (strpos($lang, '_')) {
$lang = str_replace('_', '-', $lang);
}
$lang = strtolower($lang);
}
$accept = array_merge($accept, $languages);
}
if ($language === null) {
return $accept;
}
return in_array(strtolower($language), $accept);
}
/**
* Parse Accept* headers with qualifier options
*
* @param string $header
* @return array
*/
protected static function _parseAcceptWithQualifier($header) {
$accept = array();
$header = explode(',', $header);
foreach (array_filter($header) as $value) {
$prefPos = strpos($value, ';');
if ($prefPos !== false) {
@ -719,31 +761,13 @@ class CakeRequest implements ArrayAccess {
}
/**
* Get the languages accepted by the client, or check if a specific language is accepted.
* Provides a read accessor for `$this->query`. Allows you
* to use a syntax similar to `CakeSession` for reading url query data.
*
* Get the list of accepted languages:
*
* {{{ CakeRequest::acceptLanguage(); }}}
*
* Check if a specific language is accepted:
*
* {{{ CakeRequest::acceptLanguage('es-es'); }}}
*
* @param string $language The language to test.
* @return If a $language is provided, a boolean. Otherwise the array of accepted languages.
* @return mixed The value being read
*/
public static function acceptLanguage($language = null) {
$accepts = preg_split('/[;,]/', self::header('Accept-Language'));
foreach ($accepts as &$accept) {
$accept = strtolower($accept);
if (strpos($accept, '_') !== false) {
$accept = str_replace('_', '-', $accept);
}
}
if ($language === null) {
return $accepts;
}
return in_array($language, $accepts);
public function query($name) {
return Hash::get($this->query, $name);
}
/**
@ -805,6 +829,38 @@ class CakeRequest implements ArrayAccess {
return $input;
}
/**
* Only allow certain HTTP request methods, if the request method does not match
* a 405 error will be shown and the required "Allow" response header will be set.
*
* Example:
*
* $this->request->onlyAllow('post', 'delete');
* or
* $this->request->onlyAllow(array('post', 'delete'));
*
* If the request would be GET, response header "Allow: POST, DELETE" will be set
* and a 405 error will be returned
*
* @param string|array $methods Allowed HTTP request methods
* @return boolean true
* @throws MethodNotAllowedException
*/
public function onlyAllow($methods) {
if (!is_array($methods)) {
$methods = func_get_args();
}
foreach ($methods as $method) {
if ($this->is($method)) {
return true;
}
}
$allowed = strtoupper(implode(', ', $methods));
$e = new MethodNotAllowedException();
$e->responseHeader('Allow', $allowed);
throw $e;
}
/**
* Read data from php://input, mocked in tests.
*

View file

@ -17,6 +17,8 @@
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
App::uses('File', 'Utility');
/**
* CakeResponse is responsible for managing the response text, status and headers of a HTTP response.
*
@ -115,10 +117,10 @@ class CakeResponse {
'7z' => 'application/x-7z-compressed',
'hdf' => 'application/x-hdf',
'hqx' => 'application/mac-binhex40',
'ico' => 'image/vnd.microsoft.icon',
'ico' => 'image/x-icon',
'ips' => 'application/x-ipscript',
'ipx' => 'application/x-ipix',
'js' => 'text/javascript',
'js' => 'application/javascript',
'latex' => 'application/x-latex',
'lha' => 'application/octet-stream',
'lsp' => 'application/x-lisp',
@ -171,6 +173,7 @@ class CakeResponse {
'texinfo' => 'application/x-texinfo',
'tr' => 'application/x-troff',
'tsp' => 'application/dsptype',
'ttc' => 'font/ttf',
'ttf' => 'font/ttf',
'unv' => 'application/i-deas',
'ustar' => 'application/x-ustar',
@ -237,6 +240,12 @@ class CakeResponse {
'ogv' => 'video/ogg',
'webm' => 'video/webm',
'mp4' => 'video/mp4',
'm4v' => 'video/mp4',
'f4v' => 'video/mp4',
'f4p' => 'video/mp4',
'm4a' => 'audio/mp4',
'f4a' => 'audio/mp4',
'f4b' => 'audio/mp4',
'gif' => 'image/gif',
'ief' => 'image/ief',
'jpe' => 'image/jpeg',
@ -265,7 +274,7 @@ class CakeResponse {
'mime' => 'www/mime',
'pdb' => 'chemical/x-pdb',
'xyz' => 'chemical/x-pdb',
'javascript' => 'text/javascript',
'javascript' => 'application/javascript',
'form' => 'application/x-www-form-urlencoded',
'file' => 'multipart/form-data',
'xhtml' => array('application/xhtml+xml', 'application/xhtml', 'text/xhtml'),
@ -276,6 +285,19 @@ class CakeResponse {
'wml' => 'text/vnd.wap.wml',
'wmlscript' => 'text/vnd.wap.wmlscript',
'wbmp' => 'image/vnd.wap.wbmp',
'woff' => 'application/x-font-woff',
'webp' => 'image/webp',
'appcache' => 'text/cache-manifest',
'manifest' => 'text/cache-manifest',
'htc' => 'text/x-component',
'rdf' => 'application/xml',
'crx' => 'application/x-chrome-extension',
'oex' => 'application/x-opera-extension',
'xpi' => 'application/x-xpinstall',
'safariextz' => 'application/octet-stream',
'webapp' => 'application/x-web-app-manifest+json',
'vcf' => 'text/x-vcard',
'vtt' => 'text/vtt',
);
/**
@ -314,6 +336,13 @@ class CakeResponse {
*/
protected $_body = null;
/**
* File object for file to be read out as response
*
* @var File
*/
protected $_file = null;
/**
* The charset the response body is encoded with
*
@ -355,9 +384,10 @@ class CakeResponse {
if (isset($options['type'])) {
$this->type($options['type']);
}
if (isset($options['charset'])) {
$this->charset($options['charset']);
if (!isset($options['charset'])) {
$options['charset'] = Configure::read('App.encoding');
}
$this->charset($options['charset']);
}
/**
@ -380,8 +410,13 @@ class CakeResponse {
foreach ($this->_headers as $header => $value) {
$this->_sendHeader($header, $value);
}
if ($this->_file) {
$this->_sendFile($this->_file);
$this->_file = null;
} else {
$this->_sendContent($this->_body);
}
}
/**
* Sets the cookies that have been added via static method CakeResponse::addCookie()
@ -712,7 +747,7 @@ class CakeResponse {
* @return void
*/
public function cache($since, $time = '+1 day') {
if (!is_integer($time)) {
if (!is_int($time)) {
$time = strtotime($time);
}
$this->header(array(
@ -755,7 +790,7 @@ class CakeResponse {
unset($this->_cacheDirectives['public']);
$this->maxAge($time);
}
if ($time == null) {
if (!$time) {
$this->_setCacheControl();
}
return (bool)$public;
@ -974,7 +1009,7 @@ class CakeResponse {
protected function _getUTCDate($time = null) {
if ($time instanceof DateTime) {
$result = clone $time;
} elseif (is_integer($time)) {
} elseif (is_int($time)) {
$result = new DateTime(date('Y-m-d H:i:s', $time));
} else {
$result = new DateTime($time);
@ -1036,7 +1071,7 @@ class CakeResponse {
* @return int
*/
public function length($bytes = null) {
if ($bytes !== null ) {
if ($bytes !== null) {
$this->_headers['Content-Length'] = $bytes;
}
if (isset($this->_headers['Content-Length'])) {
@ -1052,12 +1087,11 @@ class CakeResponse {
* is marked as so accordingly so the client can be informed of that.
*
* In order to mark a response as not modified, you need to set at least
* the Last-Modified response header or a response etag to be compared
* with the request itself
* the Last-Modified etag response header before calling this method. Otherwise
* a comparison will not be possible.
*
* @return boolean whether the response was marked as not modified or
* not
**/
* @return boolean whether the response was marked as not modified or not.
*/
public function checkNotModified(CakeRequest $request) {
$etags = preg_split('/\s*,\s*/', $request->header('If-None-Match'), null, PREG_SPLIT_NO_EMPTY);
$modifiedSince = $request->header('If-Modified-Since');
@ -1154,4 +1188,138 @@ class CakeResponse {
$this->_cookies[$options['name']] = $options;
}
/**
* Setup for display or download the given file
*
* @param string $path Path to file
* @param array $options Options
* ### Options keys
* - name: Alternate download name
* - download: If `true` sets download header and forces file to be downloaded rather than displayed in browser
* @return void
* @throws NotFoundException
*/
public function file($path, $options = array()) {
$options += array(
'name' => null,
'download' => null
);
if (!is_file($path)) {
$path = APP . $path;
}
$file = new File($path);
if (!$file->exists() || !$file->readable()) {
if (Configure::read('debug')) {
throw new NotFoundException(__d('cake_dev', 'The requested file %s was not found or not readable', $path));
}
throw new NotFoundException(__d('cake', 'The requested file was not found'));
}
$extension = strtolower($file->ext());
$download = $options['download'];
if ((!$extension || $this->type($extension) === false) && is_null($download)) {
$download = true;
}
$fileSize = $file->size();
if ($download) {
$agent = env('HTTP_USER_AGENT');
if (preg_match('%Opera(/| )([0-9].[0-9]{1,2})%', $agent)) {
$contentType = 'application/octetstream';
} elseif (preg_match('/MSIE ([0-9].[0-9]{1,2})/', $agent)) {
$contentType = 'application/force-download';
}
if (!empty($contentType)) {
$this->type($contentType);
}
if (is_null($options['name'])) {
$name = $file->name;
} else {
$name = $options['name'];
}
$this->download($name);
$this->header('Accept-Ranges', 'bytes');
$httpRange = env('HTTP_RANGE');
if (isset($httpRange)) {
list($toss, $range) = explode('=', $httpRange);
$size = $fileSize - 1;
$length = $fileSize - $range;
$this->header(array(
'Content-Length' => $length,
'Content-Range' => 'bytes ' . $range . $size . '/' . $fileSize
));
$this->statusCode(206);
$file->open('rb', true);
$file->offset($range);
} else {
$this->header('Content-Length', $fileSize);
}
} else {
$this->header('Content-Length', $fileSize);
}
$this->_clearBuffer();
$this->_file = $file;
}
/**
* Reads out a file, and echos the content to the client.
*
* @param File $file File object
* @return boolean True is whole file is echoed successfully or false if client connection is lost in between
*/
protected function _sendFile($file) {
$compress = $this->outputCompressed();
$file->open('rb');
while (!feof($file->handle)) {
if (!$this->_isActive()) {
$file->close();
return false;
}
set_time_limit(0);
echo fread($file->handle, 8192);
if (!$compress) {
$this->_flushBuffer();
}
}
$file->close();
return true;
}
/**
* Returns true if connection is still active
*
* @return boolean
*/
protected function _isActive() {
return connection_status() === CONNECTION_NORMAL && !connection_aborted();
}
/**
* Clears the contents of the topmost output buffer and discards them
*
* @return boolean
*/
protected function _clearBuffer() {
return @ob_end_clean();
}
/**
* Flushes the contents of the output buffer
*
* @return void
*/
protected function _flushBuffer() {
@flush();
@ob_flush();
}
}

View file

@ -76,6 +76,39 @@ class CakeSocket {
*/
public $lastError = array();
/**
* True if the socket stream is encrypted after a CakeSocket::enableCrypto() call
*
* @var boolean
*/
public $encrypted = false;
/**
* Contains all the encryption methods available
*
* @var array
*/
protected $_encryptMethods = array(
// @codingStandardsIgnoreStart
'sslv2_client' => STREAM_CRYPTO_METHOD_SSLv2_CLIENT,
'sslv3_client' => STREAM_CRYPTO_METHOD_SSLv3_CLIENT,
'sslv23_client' => STREAM_CRYPTO_METHOD_SSLv23_CLIENT,
'tls_client' => STREAM_CRYPTO_METHOD_TLS_CLIENT,
'sslv2_server' => STREAM_CRYPTO_METHOD_SSLv2_SERVER,
'sslv3_server' => STREAM_CRYPTO_METHOD_SSLv3_SERVER,
'sslv23_server' => STREAM_CRYPTO_METHOD_SSLv23_SERVER,
'tls_server' => STREAM_CRYPTO_METHOD_TLS_SERVER
// @codingStandardsIgnoreEnd
);
/**
* Used to capture connection warnings which can happen when there are
* SSL errors for example.
*
* @var array
*/
protected $_connectionErrors = array();
/**
* Constructor.
*
@ -96,26 +129,47 @@ class CakeSocket {
* @throws SocketException
*/
public function connect() {
if ($this->connection != null) {
if ($this->connection) {
$this->disconnect();
}
$scheme = null;
if (isset($this->config['request']) && $this->config['request']['uri']['scheme'] == 'https') {
if (isset($this->config['request']['uri']) && $this->config['request']['uri']['scheme'] == 'https') {
$scheme = 'ssl://';
}
if ($this->config['persistent'] == true) {
$this->connection = @pfsockopen($scheme . $this->config['host'], $this->config['port'], $errNum, $errStr, $this->config['timeout']);
if (!empty($this->config['context'])) {
$context = stream_context_create($this->config['context']);
} else {
$this->connection = @fsockopen($scheme . $this->config['host'], $this->config['port'], $errNum, $errStr, $this->config['timeout']);
$context = stream_context_create();
}
$connectAs = STREAM_CLIENT_CONNECT;
if ($this->config['persistent']) {
$connectAs |= STREAM_CLIENT_PERSISTENT;
}
set_error_handler(array($this, '_connectionErrorHandler'));
$this->connection = stream_socket_client(
$scheme . $this->config['host'] . ':' . $this->config['port'],
$errNum,
$errStr,
$this->config['timeout'],
$connectAs,
$context
);
restore_error_handler();
if (!empty($errNum) || !empty($errStr)) {
$this->setLastError($errNum, $errStr);
throw new SocketException($errStr, $errNum);
}
if (!$this->connection && $this->_connectionErrors) {
$message = implode("\n", $this->_connectionErrors);
throw new SocketException($message, E_WARNING);
}
$this->connected = is_resource($this->connection);
if ($this->connected) {
stream_set_timeout($this->connection, $this->config['timeout']);
@ -123,6 +177,31 @@ class CakeSocket {
return $this->connected;
}
/**
* socket_stream_client() does not populate errNum, or $errStr when there are
* connection errors, as in the case of SSL verification failure.
*
* Instead we need to handle those errors manually.
*
* @param int $code
* @param string $message
*/
protected function _connectionErrorHandler($code, $message) {
$this->_connectionErrors[] = $message;
}
/**
* Get the connection context.
*
* @return null|array Null when there is no connnection, an array when there is.
*/
public function context() {
if (!$this->connection) {
return;
}
return stream_context_get_options($this->connection);
}
/**
* Get the host name of the current connection.
*
@ -277,4 +356,36 @@ class CakeSocket {
return true;
}
/**
* Encrypts current stream socket, using one of the defined encryption methods
*
* @param string $type can be one of 'ssl2', 'ssl3', 'ssl23' or 'tls'
* @param string $clientOrServer can be one of 'client', 'server'. Default is 'client'
* @param boolean $enable enable or disable encryption. Default is true (enable)
* @return boolean True on success
* @throws InvalidArgumentException When an invalid encryption scheme is chosen.
* @throws SocketException When attempting to enable SSL/TLS fails
* @see stream_socket_enable_crypto
*/
public function enableCrypto($type, $clientOrServer = 'client', $enable = true) {
if (!array_key_exists($type . '_' . $clientOrServer, $this->_encryptMethods)) {
throw new InvalidArgumentException(__d('cake_dev', 'Invalid encryption scheme chosen'));
}
$enableCryptoResult = false;
try {
$enableCryptoResult = stream_socket_enable_crypto($this->connection, $enable, $this->_encryptMethods[$type . '_' . $clientOrServer]);
} catch (Exception $e) {
$this->setLastError(null, $e->getMessage());
throw new SocketException($e->getMessage());
}
if ($enableCryptoResult === true) {
$this->encrypted = $enable;
return true;
} else {
$errorMessage = __d('cake_dev', 'Unable to perform enableCrypto operation on CakeSocket');
$this->setLastError(null, $errorMessage);
throw new SocketException($errorMessage);
}
}
}

View file

@ -946,13 +946,17 @@ class CakeEmail {
* $email->attachments(array('custom_name.png' => array(
* 'file' => 'path/to/file',
* 'mimetype' => 'image/png',
* 'contentId' => 'abc123'
* 'contentId' => 'abc123',
* 'contentDisposition' => false
* ));
* }}}
*
* The `contentId` key allows you to specify an inline attachment. In your email text, you
* can use `<img src="cid:abc123" />` to display the image inline.
*
* The `contentDisposition` key allows you to disable the `Content-Disposition` header, this can improve
* attachment compatibility with outlook email clients.
*
* @param string|array $attachments String with the filename or array with filenames
* @return array|CakeEmail Either the array of attachments when getting or $this when setting.
* @throws SocketException
@ -991,6 +995,7 @@ class CakeEmail {
* @param string|array $attachments String with the filename or array with filenames
* @return CakeEmail $this
* @throws SocketException
* @see CakeEmail::attachments()
*/
public function addAttachments($attachments) {
$current = $this->_attachments;
@ -1355,7 +1360,12 @@ class CakeEmail {
$msg[] = '--' . $boundary;
$msg[] = 'Content-Type: ' . $fileInfo['mimetype'];
$msg[] = 'Content-Transfer-Encoding: base64';
if (
!isset($fileInfo['contentDisposition']) ||
$fileInfo['contentDisposition']
) {
$msg[] = 'Content-Disposition: attachment; filename="' . $filename . '"';
}
$msg[] = '';
$msg[] = $data;
$msg[] = '';

View file

@ -79,7 +79,8 @@ class SmtpTransport extends AbstractTransport {
'timeout' => 30,
'username' => null,
'password' => null,
'client' => null
'client' => null,
'tls' => false
);
$this->_config = $config + $default;
}
@ -107,7 +108,15 @@ class SmtpTransport extends AbstractTransport {
try {
$this->_smtpSend("EHLO {$host}", '250');
if ($this->_config['tls']) {
$this->_smtpSend("STARTTLS", '220');
$this->_socket->enableCrypto('tls');
$this->_smtpSend("EHLO {$host}", '250');
}
} catch (SocketException $e) {
if ($this->_config['tls']) {
throw new SocketException(__d('cake_dev', 'SMTP server did not accept the connection or trying to connect to non TLS SMTP server using TLS.'));
}
try {
$this->_smtpSend("HELO {$host}", '250');
} catch (SocketException $e2) {
@ -132,6 +141,8 @@ class SmtpTransport extends AbstractTransport {
if (!$this->_smtpSend(base64_encode($this->_config['password']), '235')) {
throw new SocketException(__d('cake_dev', 'SMTP server did not accept the password.'));
}
} elseif ($authRequired == '504') {
throw new SocketException(__d('cake_dev', 'SMTP authentication method not allowed, check if SMTP server requires TLS'));
} elseif ($authRequired != '503') {
throw new SocketException(__d('cake_dev', 'SMTP does not require authentication.'));
}

View file

@ -12,437 +12,24 @@
*
* @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @package Cake.Network.Http
* @since CakePHP(tm) v 2.0.0
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
App::uses('HttpSocketResponse', 'Network/Http');
if (class_exists('HttpResponse')) {
trigger_error(__d(
'cake_dev',
"HttpResponse is deprecated due to naming conflicts. Use HttpSocketResponse instead."
), E_USER_ERROR);
}
/**
* HTTP Response from HttpSocket.
*
* @package Cake.Network.Http
* @deprecated This class is deprecated as it has naming conflicts with pecl/http
*/
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 = '';
/**
* Constructor
*
* @param string $message
*/
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
* @param array $headers
* @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;
}
/**
* If return is a valid 3xx (Redirection)
*
* @return boolean
*/
public function isRedirect() {
return in_array($this->code, array(301, 302, 303, 307)) && !is_null($this->getHeader('Location'));
}
/**
* Parses the given message and breaks it down in parts.
*
* @param string $message Message to parse
* @return void
* @throws SocketException
*/
public function parseResponse($message) {
if (!is_string($message)) {
throw new SocketException(__d('cake_dev', 'Invalid response.'));
}
if (!preg_match("/^(.+\r\n)(.*)(?<=\r\n)\r\n/Us", $message, $match)) {
throw new SocketException(__d('cake_dev', '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 containing the body to decode.
* @param string|boolean $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 containing 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|\n)/iU', $body, $match)) {
throw new SocketException(__d('cake_dev', '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 received.
* @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;
}
foreach ($escape as $key => $char) {
$escape[$key] = '\\x' . str_pad(dechex(ord($char)), 2, '0', STR_PAD_LEFT);
}
return $escape;
}
/**
* ArrayAccess - Offset Exists
*
* @param string $offset
* @return boolean
*/
public function offsetExists($offset) {
return in_array($offset, array('raw', 'status', 'header', 'body', 'cookies'));
}
/**
* ArrayAccess - Offset Get
*
* @param string $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 - Offset Set
*
* @param string $offset
* @param mixed $value
* @return void
*/
public function offsetSet($offset, $value) {
}
/**
* ArrayAccess - Offset Unset
*
* @param string $offset
* @return void
*/
public function offsetUnset($offset) {
}
/**
* Instance as string
*
* @return string
*/
public function __toString() {
return $this->body();
}
class HttpResponse extends HttpSocketResponse {
}

View file

@ -18,6 +18,7 @@
*/
App::uses('CakeSocket', 'Network');
App::uses('Router', 'Routing');
App::uses('Hash', 'Utility');
/**
* Cake network socket connection class.
@ -64,7 +65,7 @@ class HttpSocket extends CakeSocket {
),
'raw' => null,
'redirect' => false,
'cookies' => array()
'cookies' => array(),
);
/**
@ -79,7 +80,7 @@ class HttpSocket extends CakeSocket {
*
* @var string
*/
public $responseClass = 'HttpResponse';
public $responseClass = 'HttpSocketResponse';
/**
* Configuration settings for the HttpSocket and the requests
@ -92,6 +93,9 @@ class HttpSocket extends CakeSocket {
'protocol' => 'tcp',
'port' => 80,
'timeout' => 30,
'ssl_verify_peer' => true,
'ssl_verify_depth' => 5,
'ssl_verify_host' => true,
'request' => array(
'uri' => array(
'scheme' => array('http', 'https'),
@ -99,7 +103,7 @@ class HttpSocket extends CakeSocket {
'port' => array(80, 443)
),
'redirect' => false,
'cookies' => array()
'cookies' => array(),
)
);
@ -246,7 +250,7 @@ class HttpSocket extends CakeSocket {
* method and provide a more granular interface.
*
* @param string|array $request Either an URI string, or an array defining host/uri
* @return mixed false on error, HttpResponse on success
* @return mixed false on error, HttpSocketResponse on success
* @throws SocketException
*/
public function request($request = array()) {
@ -348,6 +352,8 @@ class HttpSocket extends CakeSocket {
return false;
}
$this->_configContext($this->request['uri']['host']);
$this->request['raw'] = '';
if ($this->request['line'] !== false) {
$this->request['raw'] = $this->request['line'];
@ -395,6 +401,7 @@ class HttpSocket extends CakeSocket {
throw new SocketException(__d('cake_dev', 'Class %s not found.', $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();
@ -643,6 +650,33 @@ class HttpSocket extends CakeSocket {
return true;
}
/**
* Configure the socket's context. Adds in configuration
* that can not be declared in the class definition.
*
* @param string $host The host you're connecting to.
* @return void
*/
protected function _configContext($host) {
foreach ($this->config as $key => $value) {
if (substr($key, 0, 4) !== 'ssl_') {
continue;
}
$contextKey = substr($key, 4);
if (empty($this->config['context']['ssl'][$contextKey])) {
$this->config['context']['ssl'][$contextKey] = $value;
}
unset($this->config[$key]);
}
if (empty($this->_context['ssl']['cafile'])) {
$this->config['context']['ssl']['cafile'] = CAKE . 'Config' . DS . 'cacert.pem';
}
if (!empty($this->config['context']['ssl']['verify_host'])) {
$this->config['context']['ssl']['CN_match'] = $host;
unset($this->config['context']['ssl']['verify_host']);
}
}
/**
* Takes a $uri array and turns it into a fully qualified URL string
*
@ -944,7 +978,7 @@ class HttpSocket extends CakeSocket {
$escape[] = chr(127);
}
if ($hex == false) {
if (!$hex) {
return $escape;
}
foreach ($escape as $key => $char) {

View file

@ -0,0 +1,455 @@
<?php
/**
* HTTP Response from HttpSocket.
*
* PHP 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @since CakePHP(tm) v 2.0.0
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
/**
* HTTP Response from HttpSocket.
*
* @package Cake.Network.Http
*/
class HttpSocketResponse 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 = '';
/**
* Context data in the response.
* Contains SSL certificates for example.
*
* @var array
*/
public $context = array();
/**
* Constructor
*
* @param string $message
*/
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
* @param array $headers
* @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;
}
/**
* If return is a valid 3xx (Redirection)
*
* @return boolean
*/
public function isRedirect() {
return in_array($this->code, array(301, 302, 303, 307)) && !is_null($this->getHeader('Location'));
}
/**
* Parses the given message and breaks it down in parts.
*
* @param string $message Message to parse
* @return void
* @throws SocketException
*/
public function parseResponse($message) {
if (!is_string($message)) {
throw new SocketException(__d('cake_dev', 'Invalid response.'));
}
if (!preg_match("/^(.+\r\n)(.*)(?<=\r\n)\r\n/Us", $message, $match)) {
throw new SocketException(__d('cake_dev', '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 containing the body to decode.
* @param string|boolean $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 containing 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|\n)/iU', $body, $match)) {
throw new SocketException(__d('cake_dev', '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 received.
* @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) {
return $escape;
}
foreach ($escape as $key => $char) {
$escape[$key] = '\\x' . str_pad(dechex(ord($char)), 2, '0', STR_PAD_LEFT);
}
return $escape;
}
/**
* ArrayAccess - Offset Exists
*
* @param string $offset
* @return boolean
*/
public function offsetExists($offset) {
return in_array($offset, array('raw', 'status', 'header', 'body', 'cookies'));
}
/**
* ArrayAccess - Offset Get
*
* @param string $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 - Offset Set
*
* @param string $offset
* @param mixed $value
* @return void
*/
public function offsetSet($offset, $value) {
}
/**
* ArrayAccess - Offset Unset
*
* @param string $offset
* @return void
*/
public function offsetUnset($offset) {
}
/**
* Instance as string
*
* @return string
*/
public function __toString() {
return $this->body();
}
}

View file

@ -209,12 +209,6 @@ class Dispatcher implements CakeEventListener {
public function parseParams($event) {
$request = $event->data['request'];
Router::setRequestInfo($request);
if (count(Router::$routes) == 0) {
$namedExpressions = Router::getNamedExpressions();
extract($namedExpressions);
$this->_loadRoutes();
}
$params = Router::parse($request->url);
$request->addParams($params);
@ -269,13 +263,4 @@ class Dispatcher implements CakeEventListener {
return false;
}
/**
* Loads route configuration
*
* @return void
*/
protected function _loadRoutes() {
include APP . 'Config' . DS . 'routes.php';
}
}

View file

@ -42,8 +42,6 @@ class AssetDispatcher extends DispatcherFilter {
*/
public function beforeDispatch($event) {
$url = $event->data['request']->url;
$response = $event->data['response'];
if (strpos($url, '..') !== false || strpos($url, '.') === false) {
return;
}
@ -53,43 +51,27 @@ class AssetDispatcher extends DispatcherFilter {
return $result;
}
$pathSegments = explode('.', $url);
$ext = array_pop($pathSegments);
$parts = explode('/', $url);
$assetFile = null;
if ($parts[0] === 'theme') {
$themeName = $parts[1];
unset($parts[0], $parts[1]);
$fileFragment = urldecode(implode(DS, $parts));
$path = App::themePath($themeName) . 'webroot' . DS;
if (file_exists($path . $fileFragment)) {
$assetFile = $path . $fileFragment;
}
} else {
$plugin = Inflector::camelize($parts[0]);
if (CakePlugin::loaded($plugin)) {
unset($parts[0]);
$fileFragment = urldecode(implode(DS, $parts));
$pluginWebroot = CakePlugin::path($plugin) . 'webroot' . DS;
if (file_exists($pluginWebroot . $fileFragment)) {
$assetFile = $pluginWebroot . $fileFragment;
}
}
$assetFile = $this->_getAssetFile($url);
if ($assetFile === null || !file_exists($assetFile)) {
return null;
}
if ($assetFile !== null) {
$response = $event->data['response'];
$event->stopPropagation();
$response->modified(filemtime($assetFile));
if (!$response->checkNotModified($event->data['request'])) {
$this->_deliverAsset($response, $assetFile, $ext);
}
if ($response->checkNotModified($event->data['request'])) {
return $response;
}
$pathSegments = explode('.', $url);
$ext = array_pop($pathSegments);
$this->_deliverAsset($response, $assetFile, $ext);
return $response;
}
/**
* Checks if the client is requeting a filtered asset and runs the corresponding
* Checks if the client is requesting a filtered asset and runs the corresponding
* filter if any is configured
*
* @param CakeEvent $event containing the request and response object
@ -111,15 +93,44 @@ class AssetDispatcher extends DispatcherFilter {
if (($isCss && empty($filters['css'])) || ($isJs && empty($filters['js']))) {
$response->statusCode(404);
return $response;
} elseif ($isCss) {
}
if ($isCss) {
include WWW_ROOT . DS . $filters['css'];
return $response;
} elseif ($isJs) {
}
if ($isJs) {
include WWW_ROOT . DS . $filters['js'];
return $response;
}
}
/**
* Builds asset file path based off url
*
* @param string $url
* @return string Absolute path for asset file
*/
protected function _getAssetFile($url) {
$parts = explode('/', $url);
if ($parts[0] === 'theme') {
$themeName = $parts[1];
unset($parts[0], $parts[1]);
$fileFragment = urldecode(implode(DS, $parts));
$path = App::themePath($themeName) . 'webroot' . DS;
return $path . $fileFragment;
}
$plugin = Inflector::camelize($parts[0]);
if (CakePlugin::loaded($plugin)) {
unset($parts[0]);
$fileFragment = urldecode(implode(DS, $parts));
$pluginWebroot = CakePlugin::path($plugin) . 'webroot' . DS;
return $pluginWebroot . $fileFragment;
}
}
/**
* Sends an asset file to the client
*

View file

@ -154,7 +154,8 @@ class CakeRoute {
if (preg_match('#\/\*\*$#', $route)) {
$parsed = preg_replace('#/\\\\\*\\\\\*$#', '(?:/(?P<_trailing_>.*))?', $parsed);
$this->_greedy = true;
} elseif (preg_match('#\/\*$#', $route)) {
}
if (preg_match('#\/\*$#', $route)) {
$parsed = preg_replace('#/\\\\\*$#', '(?:/(?P<_args_>.*))?', $parsed);
$this->_greedy = true;
}
@ -163,7 +164,7 @@ class CakeRoute {
$this->_compiledRoute = '#^' . $parsed . '[/]*$#';
$this->keys = $names;
//remove defaults that are also keys. They can cause match failures
// Remove defaults that are also keys. They can cause match failures
foreach ($this->keys as $key) {
unset($this->defaults[$key]);
}
@ -219,7 +220,7 @@ class CakeRoute {
if (isset($route[$key])) {
continue;
}
if (is_integer($key)) {
if (is_int($key)) {
$route['pass'][] = $value;
continue;
}

View file

@ -74,7 +74,7 @@ class RedirectRoute extends CakeRoute {
$this->response = new CakeResponse();
}
$redirect = $this->redirect;
if (count($this->redirect) == 1 && !isset($this->redirect['controller'])) {
if (count($this->redirect) === 1 && !isset($this->redirect['controller'])) {
$redirect = $this->redirect[0];
}
if (isset($this->options['persist']) && is_array($redirect)) {

View file

@ -48,6 +48,13 @@ class Router {
*/
public static $routes = array();
/**
* Have routes been loaded
*
* @var boolean
*/
public static $initialized = false;
/**
* List of action prefixes used in connected routes.
* Includes admin prefix
@ -284,6 +291,8 @@ class Router {
* @throws RouterException
*/
public static function connect($route, $defaults = array(), $options = array()) {
self::$initialized = true;
foreach (self::$_prefixes as $prefix) {
if (isset($defaults[$prefix])) {
if ($defaults[$prefix]) {
@ -304,7 +313,12 @@ class Router {
}
$routeClass = self::$_routeClass;
if (isset($options['routeClass'])) {
$routeClass = self::_validateRouteClass($options['routeClass']);
if (strpos($options['routeClass'], '.') === false) {
$routeClass = $options['routeClass'];
} else {
list($plugin, $routeClass) = pluginSplit($options['routeClass'], true);
}
$routeClass = self::_validateRouteClass($routeClass);
unset($options['routeClass']);
}
if ($routeClass == 'RedirectRoute' && isset($defaults['redirect'])) {
@ -420,7 +434,7 @@ class Router {
$options = array_merge(array('default' => false, 'reset' => false, 'greedy' => true), $options);
}
if ($options['reset'] == true || self::$_namedConfig['rules'] === false) {
if ($options['reset'] || self::$_namedConfig['rules'] === false) {
self::$_namedConfig['rules'] = array();
}
@ -515,6 +529,10 @@ class Router {
* @return array Parsed elements from URL
*/
public static function parse($url) {
if (!self::$initialized) {
self::_loadRoutes();
}
$ext = null;
$out = array();
@ -743,6 +761,10 @@ class Router {
* @return string Full translated URL with base path.
*/
public static function url($url = null, $full = false) {
if (!self::$initialized) {
self::_loadRoutes();
}
$params = array('plugin' => null, 'controller' => null, 'action' => 'index');
if (is_bool($full)) {
@ -829,12 +851,7 @@ class Router {
$output = self::_handleNoRoute($url);
}
} else {
if (
(strpos($url, '://') !== false ||
(strpos($url, 'javascript:') === 0) ||
(strpos($url, 'mailto:') === 0)) ||
(!strncmp($url, '#', 1))
) {
if (preg_match('/:\/\/|^(javascript|mailto|tel|sms):|\#/i', $url)) {
return $url;
}
if (substr($url, 0, 1) === '/') {
@ -928,9 +945,9 @@ class Router {
if (!empty($named)) {
foreach ($named as $name => $value) {
if (is_array($value)) {
$flattend = Hash::flatten($value, '][');
$flattend = Hash::flatten($value, '%5D%5B');
foreach ($flattend as $namedKey => $namedValue) {
$output .= '/' . $name . "[$namedKey]" . self::$_namedConfig['separator'] . rawurlencode($namedValue);
$output .= '/' . $name . "%5B{$namedKey}%5D" . self::$_namedConfig['separator'] . rawurlencode($namedValue);
}
} else {
$output .= '/' . $name . self::$_namedConfig['separator'] . rawurlencode($value);
@ -1073,7 +1090,7 @@ class Router {
* @return string base url with plugin name removed if present
*/
public static function stripPlugin($base, $plugin = null) {
if ($plugin != null) {
if ($plugin) {
$base = preg_replace('/(?:' . $plugin . ')/', '', $base);
$base = str_replace('//', '', $base);
$pos1 = strrpos($base, '/');
@ -1117,6 +1134,10 @@ class Router {
* @return array Array of extensions Router is configured to parse.
*/
public static function extensions() {
if (!self::$initialized) {
self::_loadRoutes();
}
return self::$_validExtensions;
}
@ -1138,6 +1159,16 @@ class Router {
return self::$_validExtensions = array_merge(self::$_validExtensions, $extensions);
}
/**
* Loads route configuration
*
* @return void
*/
protected static function _loadRoutes() {
self::$initialized = true;
include APP . 'Config' . DS . 'routes.php';
}
}
//Save the initial state

View file

@ -825,6 +825,18 @@ EXPECTED;
########## DEBUG ##########
'<div>this-is-a-test</div>'
###########################
EXPECTED;
$expected = sprintf($expected, str_replace(CAKE_CORE_INCLUDE_PATH, '', __FILE__), __LINE__ - 8);
$this->assertEquals($expected, $result);
ob_start();
debug(false, false, false);
$result = ob_get_clean();
$expected = <<<EXPECTED
########## DEBUG ##########
false
###########################
EXPECTED;
$expected = sprintf($expected, str_replace(CAKE_CORE_INCLUDE_PATH, '', __FILE__), __LINE__ - 8);
$this->assertEquals($expected, $result);

View file

@ -73,7 +73,8 @@ class RegisEngineTest extends CakeTestCase {
'server' => '127.0.0.1',
'port' => 6379,
'timeout' => 0,
'persistent' => true
'persistent' => true,
'password' => false,
);
$this->assertEquals($expecting, $settings);
}

View file

@ -261,6 +261,7 @@ three.four = value four
is_null = null
bool_false = false
bool_true = true
[Asset]
timestamp = force
INI;

View file

@ -88,7 +88,7 @@ class CommandListShellTest extends CakeTestCase {
$expected = "/\[.*TestPluginTwo.*\] example, welcome/";
$this->assertRegExp($expected, $output);
$expected = "/\[.*CORE.*\] acl, api, bake, command_list, console, i18n, schema, test, testsuite, upgrade/";
$expected = "/\[.*CORE.*\] acl, api, bake, command_list, console, i18n, schema, server, test, testsuite, upgrade/";
$this->assertRegExp($expected, $output);
$expected = "/\[.*app.*\] sample/";

View file

@ -362,6 +362,40 @@ class SchemaShellTest extends CakeTestCase {
CakePlugin::unload();
}
/**
* test generate with specific models
*
* @return void
*/
public function testGenerateModels() {
App::build(array(
'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS)
), App::RESET);
CakePlugin::load('TestPlugin');
$this->db->cacheSources = false;
$this->Shell->params = array(
'plugin' => 'TestPlugin',
'connection' => 'test',
'models' => 'TestPluginComment',
'force' => false,
'overwrite' => true
);
$this->Shell->startup();
$this->Shell->Schema->path = TMP . 'tests' . DS;
$this->Shell->generate();
$this->file = new File(TMP . 'tests' . DS . 'schema.php');
$contents = $this->file->read();
$this->assertRegExp('/class TestPluginSchema/', $contents);
$this->assertRegExp('/public \$test_plugin_comments/', $contents);
$this->assertNotRegExp('/public \$authors/', $contents);
$this->assertNotRegExp('/public \$auth_users/', $contents);
$this->assertNotRegExp('/public \$posts/', $contents);
CakePlugin::unload();
}
/**
* Test schema run create with no table args.
*
@ -463,6 +497,35 @@ class SchemaShellTest extends CakeTestCase {
CakePlugin::unload();
}
/**
* test that underscored names also result in CamelCased class names
*
* @return void
*/
public function testName() {
App::build(array(
'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS)
));
CakePlugin::load('TestPlugin');
$this->Shell->params = array(
'plugin' => 'TestPlugin',
'connection' => 'test',
'name' => 'custom_name',
'force' => false,
'overwrite' => true,
);
$this->Shell->startup();
if (file_exists($this->Shell->Schema->path . DS . 'custom_name.php')) {
unlink($this->Shell->Schema->path . DS . 'custom_name.php');
}
$this->Shell->generate();
$contents = file_get_contents($this->Shell->Schema->path . DS . 'custom_name.php');
$this->assertRegExp('/class CustomNameSchema/', $contents);
unlink($this->Shell->Schema->path . DS . 'custom_name.php');
CakePlugin::unload();
}
/**
* test that using Plugin.name with write.
*

View file

@ -191,9 +191,9 @@ class ControllerTaskTest extends CakeTestCase {
*/
public function testDoHelpersTrailingSpace() {
$this->Task->expects($this->at(0))->method('in')->will($this->returnValue('y'));
$this->Task->expects($this->at(1))->method('in')->will($this->returnValue(' Javascript, Ajax, CustomOne '));
$this->Task->expects($this->at(1))->method('in')->will($this->returnValue(' Text, Number, CustomOne '));
$result = $this->Task->doHelpers();
$expected = array('Javascript', 'Ajax', 'CustomOne');
$expected = array('Text', 'Number', 'CustomOne');
$this->assertEquals($expected, $result);
}
@ -204,9 +204,9 @@ class ControllerTaskTest extends CakeTestCase {
*/
public function testDoHelpersTrailingCommas() {
$this->Task->expects($this->at(0))->method('in')->will($this->returnValue('y'));
$this->Task->expects($this->at(1))->method('in')->will($this->returnValue(' Javascript, Ajax, CustomOne, , '));
$this->Task->expects($this->at(1))->method('in')->will($this->returnValue(' Text, Number, CustomOne, , '));
$result = $this->Task->doHelpers();
$expected = array('Javascript', 'Ajax', 'CustomOne');
$expected = array('Text', 'Number', 'CustomOne');
$this->assertEquals($expected, $result);
}
@ -257,11 +257,11 @@ class ControllerTaskTest extends CakeTestCase {
public function testConfirmController() {
$controller = 'Posts';
$scaffold = false;
$helpers = array('Ajax', 'Time');
$helpers = array('Js', 'Time');
$components = array('Acl', 'Auth');
$this->Task->expects($this->at(4))->method('out')->with("Controller Name:\n\t$controller");
$this->Task->expects($this->at(5))->method('out')->with("Helpers:\n\tAjax, Time");
$this->Task->expects($this->at(5))->method('out')->with("Helpers:\n\tJs, Time");
$this->Task->expects($this->at(6))->method('out')->with("Components:\n\tAcl, Auth");
$this->Task->confirmController($controller, $scaffold, $helpers, $components);
}
@ -272,7 +272,7 @@ class ControllerTaskTest extends CakeTestCase {
* @return void
*/
public function testBake() {
$helpers = array('Ajax', 'Time');
$helpers = array('Js', 'Time');
$components = array('Acl', 'Auth');
$this->Task->expects($this->any())->method('createFile')->will($this->returnValue(true));
@ -282,7 +282,7 @@ class ControllerTaskTest extends CakeTestCase {
$this->assertContains(' * @property AuthComponent $Auth', $result);
$this->assertContains('class ArticlesController extends AppController', $result);
$this->assertContains("public \$components = array('Acl', 'Auth')", $result);
$this->assertContains("public \$helpers = array('Ajax', 'Time')", $result);
$this->assertContains("public \$helpers = array('Js', 'Time')", $result);
$this->assertContains("--actions--", $result);
$result = $this->Task->bake('Articles', 'scaffold', $helpers, $components);
@ -350,7 +350,8 @@ class ControllerTaskTest extends CakeTestCase {
$this->assertContains('function view($id = null)', $result);
$this->assertContains("throw new NotFoundException(__('Invalid bake article'));", $result);
$this->assertContains("\$this->set('bakeArticle', \$this->BakeArticle->read(null, \$id)", $result);
$this->assertContains("\$options = array('conditions' => array('BakeArticle.' . \$this->BakeArticle->primaryKey => \$id));", $result);
$this->assertContains("\$this->set('bakeArticle', \$this->BakeArticle->find('first', \$options));", $result);
$this->assertContains('function add()', $result);
$this->assertContains("if (\$this->request->is('post'))", $result);
@ -389,7 +390,7 @@ class ControllerTaskTest extends CakeTestCase {
$this->assertContains('function view($id = null)', $result);
$this->assertContains("throw new NotFoundException(__('Invalid bake article'));", $result);
$this->assertContains("\$this->set('bakeArticle', \$this->BakeArticle->read(null, \$id)", $result);
$this->assertContains("\$this->set('bakeArticle', \$this->BakeArticle->find('first', \$options));", $result);
$this->assertContains('function add()', $result);
$this->assertContains("if (\$this->request->is('post'))", $result);
@ -402,6 +403,7 @@ class ControllerTaskTest extends CakeTestCase {
$this->assertContains("\$this->set(compact('bakeTags'))", $result);
$this->assertContains('function delete($id = null)', $result);
$this->assertContains("\$this->request->onlyAllow('post', 'delete')", $result);
$this->assertContains('if ($this->BakeArticle->delete())', $result);
$this->assertContains("\$this->flash(__('Bake article deleted'), array('action' => 'index'))", $result);
}

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