Merge remote-tracking branch 'origin/2.0' into 2.0-plugin-loader

Conflicts:
	lib/Cake/tests/test_app/plugins/TestPlugin/Model/test_plugin_post.php
	lib/Cake/tests/test_app/plugins/test_plugin/Model/TestPluginPost.php
	lib/Cake/tests/test_app/plugins/test_plugin/Model/test_plugin_post.php
This commit is contained in:
Jose Lorenzo Rodriguez 2011-05-08 22:08:31 -04:30
commit 77788a965d
112 changed files with 2360 additions and 1089 deletions

3
.gitignore vendored
View file

@ -1,4 +1,5 @@
/app/config /app/config
/app/tmp /app/tmp
/plugins /plugins
/vendors /vendors
.DS_Store

12
README
View file

@ -18,17 +18,11 @@ http://bakery.cakephp.org
The Show - live and archived podcasts about CakePHP and more The Show - live and archived podcasts about CakePHP and more
http://live.cakephp.org http://live.cakephp.org
CakePHP TV - screen casts from events and video tutorials
http://tv.cakephp.org
CakePHP Google Group - community mailing list and forum CakePHP Google Group - community mailing list and forum
http://groups.google.com/group/cake-php http://groups.google.com/group/cake-php
#cakephp on irc.freenode.net - chat with CakePHP developers #cakephp on irc.freenode.net - chat with CakePHP developers
irc://irc.freenode.net/cakephp irc://irc.freenode.net/cakephp
CakeForge - open development for CakePHP
http://cakeforge.org
CakePHP gear
http://www.cafepress.com/cakefoundation
Recommended Reading
http://astore.amazon.com/cakesoftwaref-20/

View file

@ -286,7 +286,7 @@
/** /**
* Pick the caching engine to use. If APC is enabled use it. * Pick the caching engine to use. If APC is enabled use it.
* If running via cli - apc is disabled by default. ensure it's avaiable and enabled in this case * If running via cli - apc is disabled by default. ensure it's available and enabled in this case
* *
*/ */
$engine = 'File'; $engine = 'File';

View file

@ -71,10 +71,8 @@ class AclShell extends Shell {
if (!in_array(Configure::read('Acl.classname'), array('DbAcl', 'DB_ACL'))) { if (!in_array(Configure::read('Acl.classname'), array('DbAcl', 'DB_ACL'))) {
$out = "--------------------------------------------------\n"; $out = "--------------------------------------------------\n";
$out .= __d('cake_console', 'Error: Your current Cake configuration is set to') . "\n"; $out .= __d('cake_console', 'Error: Your current Cake configuration is set to an ACL implementation other than DB.') . "\n";
$out .= __d('cake_console', 'an ACL implementation other than DB. Please change') . "\n"; $out .= __d('cake_console', 'Please change your core config to reflect your decision to use DbAcl before attempting to use this script') . "\n";
$out .= __d('cake_console', 'your core config to reflect your decision to use') . "\n";
$out .= __d('cake_console', 'DbAcl before attempting to use this script') . ".\n";
$out .= "--------------------------------------------------\n"; $out .= "--------------------------------------------------\n";
$out .= __d('cake_console', 'Current ACL Classname: %s', Configure::read('Acl.classname')) . "\n"; $out .= __d('cake_console', 'Current ACL Classname: %s', Configure::read('Acl.classname')) . "\n";
$out .= "--------------------------------------------------\n"; $out .= "--------------------------------------------------\n";
@ -150,7 +148,7 @@ class AclShell extends Shell {
$nodeId = $this->_getNodeId($class, $identifier); $nodeId = $this->_getNodeId($class, $identifier);
if (!$this->Acl->{$class}->delete($nodeId)) { if (!$this->Acl->{$class}->delete($nodeId)) {
$this->error(__d('cake_console', 'Node Not Deleted') . __d('cake_console', 'There was an error deleting the %s. Check that the node exists', $class) . ".\n"); $this->error(__d('cake_console', 'Node Not Deleted') . __d('cake_console', 'There was an error deleting the %s. Check that the node exists.', $class) . "\n");
} }
$this->out(__d('cake_console', '<success>%s deleted.</success>', $class), 2); $this->out(__d('cake_console', '<success>%s deleted.</success>', $class), 2);
} }
@ -263,7 +261,7 @@ class AclShell extends Shell {
} }
/** /**
* Set an ARO to inhermit permission to an ACO. * Set an ARO to inherit permission to an ACO.
* *
*/ */
public function inherit() { public function inherit() {
@ -308,7 +306,7 @@ class AclShell extends Shell {
$this->error(__d('cake_console', '%s not found', $this->args[0]), __d('cake_console', 'No tree returned.')); $this->error(__d('cake_console', '%s not found', $this->args[0]), __d('cake_console', 'No tree returned.'));
} }
} }
$this->out($class . " tree:"); $this->out($class . ' tree:');
$this->hr(); $this->hr();
$stack = array(); $stack = array();
@ -357,7 +355,7 @@ class AclShell extends Shell {
'help' => __d('cake_console', 'Type of node to create.') 'help' => __d('cake_console', 'Type of node to create.')
); );
$parser->description('A console tool for managing the DbAcl') $parser->description(__d('cake_console', 'A console tool for managing the DbAcl'))
->addSubcommand('create', array( ->addSubcommand('create', array(
'help' => __d('cake_console', 'Create a new ACL node'), 'help' => __d('cake_console', 'Create a new ACL node'),
'parser' => array( 'parser' => array(
@ -407,8 +405,7 @@ class AclShell extends Shell {
'parser' => array( 'parser' => array(
'description' => array( 'description' => array(
__d('cake_console', "Returns the path to the ACL object specified by <node>."), __d('cake_console', "Returns the path to the ACL object specified by <node>."),
__d('cake_console', "This command is useful in determining the inhertiance of permissions"), __d('cake_console', "This command is useful in determining the inheritance of permissions for a certain object in the tree.")
__d('cake_console', "for a certain object in the tree.")
), ),
'arguments' => array( 'arguments' => array(
'type' => $type, 'type' => $type,
@ -422,9 +419,7 @@ class AclShell extends Shell {
'help' => __d('cake_console', 'Check the permissions between an ACO and ARO.'), 'help' => __d('cake_console', 'Check the permissions between an ACO and ARO.'),
'parser' => array( 'parser' => array(
'description' => array( 'description' => array(
__d('cake_console', "Use this command to grant ACL permissions. Once executed, the ARO "), __d('cake_console', 'Use this command to grant ACL permissions. Once executed, the ARO specified (and its children, if any) will have ALLOW access to the specified ACO action (and the ACO\'s children, if any).')
__d('cake_console', "specified (and its children, if any) will have ALLOW access to the"),
__d('cake_console', "specified ACO action (and the ACO's children, if any).")
), ),
'arguments' => array( 'arguments' => array(
'aro' => array('help' => __d('cake_console', 'ARO to check.'), 'required' => true), 'aro' => array('help' => __d('cake_console', 'ARO to check.'), 'required' => true),
@ -436,9 +431,7 @@ class AclShell extends Shell {
'help' => __d('cake_console', 'Grant an ARO permissions to an ACO.'), 'help' => __d('cake_console', 'Grant an ARO permissions to an ACO.'),
'parser' => array( 'parser' => array(
'description' => array( 'description' => array(
__d('cake_console', "Use this command to grant ACL permissions. Once executed, the ARO"), __d('cake_console', 'Use this command to grant ACL permissions. Once executed, the ARO specified (and its children, if any) will have ALLOW access to the specified ACO action (and the ACO\'s children, if any).')
__d('cake_console', "specified (and its children, if any) will have ALLOW access to the"),
__d('cake_console', "specified ACO action (and the ACO's children, if any).")
), ),
'arguments' => array( 'arguments' => array(
'aro' => array('help' => __d('cake_console', 'ARO to grant permission to.'), 'required' => true), 'aro' => array('help' => __d('cake_console', 'ARO to grant permission to.'), 'required' => true),
@ -450,9 +443,7 @@ class AclShell extends Shell {
'help' => __d('cake_console', 'Deny an ARO permissions to an ACO.'), 'help' => __d('cake_console', 'Deny an ARO permissions to an ACO.'),
'parser' => array( 'parser' => array(
'description' => array( 'description' => array(
__d('cake_console', "Use this command to deny ACL permissions. Once executed, the ARO"), __d('cake_console', 'Use this command to deny ACL permissions. Once executed, the ARO specified (and its children, if any) will have DENY access to the specified ACO action (and the ACO\'s children, if any).')
__d('cake_console', "specified (and its children, if any) will have DENY access to the"),
__d('cake_console', "specified ACO action (and the ACO's children, if any).")
), ),
'arguments' => array( 'arguments' => array(
'aro' => array('help' => __d('cake_console', 'ARO to deny.'), 'required' => true), 'aro' => array('help' => __d('cake_console', 'ARO to deny.'), 'required' => true),
@ -464,11 +455,10 @@ class AclShell extends Shell {
'help' => __d('cake_console', 'Inherit an ARO\'s parent permissions.'), 'help' => __d('cake_console', 'Inherit an ARO\'s parent permissions.'),
'parser' => array( 'parser' => array(
'description' => array( 'description' => array(
__d('cake_console', "Use this command to force a child ARO object to inherit its"), __d('cake_console', "Use this command to force a child ARO object to inherit its permissions settings from its parent.")
__d('cake_console', "permissions settings from its parent.")
), ),
'arguments' => array( 'arguments' => array(
'aro' => array('help' => __d('cake_console', 'ARO to have permisssions inherit.'), 'required' => true), 'aro' => array('help' => __d('cake_console', 'ARO to have permissions inherit.'), 'required' => true),
'aco' => array('help' => __d('cake_console', 'ACO to inherit permissions on.'), 'required' => true), 'aco' => array('help' => __d('cake_console', 'ACO to inherit permissions on.'), 'required' => true),
'action' => array('help' => __d('cake_console', 'Action to inherit'), 'default' => 'all') 'action' => array('help' => __d('cake_console', 'Action to inherit'), 'default' => 'all')
) )
@ -526,7 +516,7 @@ class AclShell extends Shell {
} }
/** /**
* Parse an identifier into Model.foriegnKey or an alias. * Parse an identifier into Model.foreignKey or an alias.
* Takes an identifier determines its type and returns the result as used by other methods. * Takes an identifier determines its type and returns the result as used by other methods.
* *
* @param string $identifier Identifier to parse * @param string $identifier Identifier to parse

View file

@ -36,7 +36,7 @@ class ApiShell extends Shell {
public $paths = array(); public $paths = array();
/** /**
* Override intialize of the Shell * Override initialize of the Shell
* *
*/ */
public function initialize() { public function initialize() {
@ -140,9 +140,9 @@ class ApiShell extends Shell {
public function getOptionParser() { public function getOptionParser() {
$parser = parent::getOptionParser(); $parser = parent::getOptionParser();
$parser->addArgument('type', array( $parser->addArgument('type', array(
'help' => 'Either a full path or type of class (model, behavior, controller, component, view, helper)' 'help' => __d('cake_console', 'Either a full path or type of class (model, behavior, controller, component, view, helper)')
))->addArgument('className', array( ))->addArgument('className', array(
'help' => 'A CakePHP core class name (e.g: Component, HtmlHelper).' 'help' => __d('cake_console', 'A CakePHP core class name (e.g: Component, HtmlHelper).')
))->addOption('method', array( ))->addOption('method', array(
'short' => 'm', 'short' => 'm',
'help' => __d('cake_console', 'The specific method you want help on.') 'help' => __d('cake_console', 'The specific method you want help on.')
@ -181,7 +181,7 @@ class ApiShell extends Shell {
} elseif (isset($commands[strtolower($this->args[1])])) { } elseif (isset($commands[strtolower($this->args[1])])) {
$this->out($commands[strtolower($this->args[1])] . "\n\n"); $this->out($commands[strtolower($this->args[1])] . "\n\n");
} else { } else {
$this->out("Command '" . $this->args[1] . "' not found"); $this->out(__d('cake_console', 'Command %s not found', $this->args[1]));
} }
} }

View file

@ -79,16 +79,16 @@ class BakeShell extends Shell {
$this->args = null; $this->args = null;
return $this->DbConfig->execute(); return $this->DbConfig->execute();
} }
$this->out('Interactive Bake Shell'); $this->out(__d('cake_console', 'Interactive Bake Shell'));
$this->hr(); $this->hr();
$this->out('[D]atabase Configuration'); $this->out(__d('cake_console', '[D]atabase Configuration'));
$this->out('[M]odel'); $this->out(__d('cake_console', '[M]odel'));
$this->out('[V]iew'); $this->out(__d('cake_console', '[V]iew'));
$this->out('[C]ontroller'); $this->out(__d('cake_console', '[C]ontroller'));
$this->out('[P]roject'); $this->out(__d('cake_console', '[P]roject'));
$this->out('[F]ixture'); $this->out(__d('cake_console', '[F]ixture'));
$this->out('[T]est case'); $this->out(__d('cake_console', '[T]est case'));
$this->out('[Q]uit'); $this->out(__d('cake_console', '[Q]uit'));
$classToBake = strtoupper($this->in(__d('cake_console', 'What would you like to Bake?'), array('D', 'M', 'V', 'C', 'P', 'F', 'T', 'Q'))); $classToBake = strtoupper($this->in(__d('cake_console', 'What would you like to Bake?'), array('D', 'M', 'V', 'C', 'P', 'F', 'T', 'Q')));
switch ($classToBake) { switch ($classToBake) {
@ -199,12 +199,11 @@ class BakeShell extends Shell {
*/ */
public function getOptionParser() { public function getOptionParser() {
$parser = parent::getOptionParser(); $parser = parent::getOptionParser();
return $parser->description( return $parser->description(__d('cake_console',
'The Bake script generates controllers, views and models for your application.' . 'The Bake script generates controllers, views and models for your application.'
'If run with no command line arguments, Bake guides the user through the class' . . ' If run with no command line arguments, Bake guides the user through the class creation process.'
'creation process. You can customize the generation process by telling Bake' . . ' You can customize the generation process by telling Bake where different parts of your application are using command line arguments.'
'where different parts of your application are using command line arguments.' ))->addSubcommand('all', array(
)->addSubcommand('all', array(
'help' => __d('cake_console', 'Bake a complete MVC. optional <name> of a Model'), 'help' => __d('cake_console', 'Bake a complete MVC. optional <name> of a Model'),
))->addSubcommand('project', array( ))->addSubcommand('project', array(
'help' => __d('cake_console', 'Bake a new app folder in the path supplied or in current directory if no path is specified'), 'help' => __d('cake_console', 'Bake a new app folder in the path supplied or in current directory if no path is specified'),
@ -231,7 +230,7 @@ class BakeShell extends Shell {
'help' => __d('cake_console', 'Bake a unit test.'), 'help' => __d('cake_console', 'Bake a unit test.'),
'parser' => $this->Test->getOptionParser() 'parser' => $this->Test->getOptionParser()
))->addOption('connection', array( ))->addOption('connection', array(
'help' => __d('cake_console', 'Database connection to use in conjunction with `bake all`.'), 'help' => __d('cake_console', 'Database connection to use in conjunction with `bake all`.'),
'short' => 'c', 'short' => 'c',
'default' => 'default' 'default' => 'default'
)); ));

View file

@ -43,18 +43,17 @@ class CommandListShell extends Shell {
*/ */
public function main() { public function main() {
if (empty($this->params['xml'])) { if (empty($this->params['xml'])) {
$this->out("<info>Current Paths:</info>", 2); $this->out(__d('cake_console', "<info>Current Paths:</info>"), 2);
$this->out(" -app: ". APP_DIR); $this->out(" -app: ". APP_DIR);
$this->out(" -working: " . rtrim(APP_PATH, DS)); $this->out(" -working: " . rtrim(APP_PATH, DS));
$this->out(" -root: " . rtrim(ROOT, DS)); $this->out(" -root: " . rtrim(ROOT, DS));
$this->out(" -core: " . rtrim(CORE_PATH, DS)); $this->out(" -core: " . rtrim(CORE_PATH, DS));
$this->out(""); $this->out("");
$this->out("<info>Changing Paths:</info>", 2); $this->out(__d('cake_console', "<info>Changing Paths:</info>"), 2);
$this->out("Your working path should be the same as your application path"); $this->out(__d('cake_console', "Your working path should be the same as your application path to change your path use the '-app' param."));
$this->out("to change your path use the '-app' param."); $this->out(__d('cake_console', "Example: -app relative/path/to/myapp or -app /absolute/path/to/myapp"), 2);
$this->out("Example: -app relative/path/to/myapp or -app /absolute/path/to/myapp", 2);
$this->out("<info>Available Shells:</info>", 2); $this->out(__d('cake_console', "<info>Available Shells:</info>"), 2);
} }
$shellList = $this->_getShellList(); $shellList = $this->_getShellList();
@ -140,8 +139,8 @@ class CommandListShell extends Shell {
$this->out(" " . $row); $this->out(" " . $row);
} }
$this->out(); $this->out();
$this->out("To run a command, type <info>cake shell_name [args]</info>"); $this->out(__d('cake_console', "To run a command, type <info>cake shell_name [args]</info>"));
$this->out("To get help on a specific command, type <info>cake shell_name --help</info>", 2); $this->out(__d('cake_console', "To get help on a specific command, type <info>cake shell_name --help</info>"), 2);
} }
/** /**
@ -212,7 +211,7 @@ class CommandListShell extends Shell {
*/ */
public function getOptionParser() { public function getOptionParser() {
$parser = parent::getOptionParser(); $parser = parent::getOptionParser();
return $parser->description('Get the list of available shells for this CakePHP application.') return $parser->description(__d('cake_console', 'Get the list of available shells for this CakePHP application.'))
->addOption('xml', array( ->addOption('xml', array(
'help' => __d('cake_console', 'Get the listing as XML.'), 'help' => __d('cake_console', 'Get the listing as XML.'),
'boolean' => true 'boolean' => true

View file

@ -47,7 +47,7 @@ class ConsoleShell extends Shell {
public $models = array(); public $models = array();
/** /**
* Override intialize of the Shell * Override initialize of the Shell
* *
*/ */
public function initialize() { public function initialize() {
@ -61,8 +61,8 @@ class ConsoleShell extends Shell {
App::uses($class, 'Model'); App::uses($class, 'Model');
$this->{$class} = new $class(); $this->{$class} = new $class();
} }
$this->out('Model classes:'); $this->out(__d('cake_console', 'Model classes:'));
$this->out('--------------'); $this->hr();
foreach ($this->models as $model) { foreach ($this->models as $model) {
$this->out(" - {$model}"); $this->out(" - {$model}");
@ -151,7 +151,7 @@ class ConsoleShell extends Shell {
return true; return true;
break; break;
case 'models': case 'models':
$this->out('Model classes:'); $this->out(__d('cake_console', 'Model classes:'));
$this->hr(); $this->hr();
foreach ($this->models as $model) { foreach ($this->models as $model) {
$this->out(" - {$model}"); $this->out(" - {$model}");
@ -169,9 +169,10 @@ class ConsoleShell extends Shell {
if ($this->_isValidModel($modelA) && $this->_isValidModel($modelB) && in_array($association, $this->associations)) { if ($this->_isValidModel($modelA) && $this->_isValidModel($modelB) && in_array($association, $this->associations)) {
$this->{$modelA}->bindModel(array($association => array($modelB => array('className' => $modelB))), false); $this->{$modelA}->bindModel(array($association => array($modelB => array('className' => $modelB))), false);
$this->out("Created $association association between $modelA and $modelB"); $this->out(__d('cake_console', "Created %s association between %s and %s",
$association, $modelA, $modelB));
} else { } else {
$this->out("Please verify you are using valid models and association types"); $this->out(__d('cake_console', "Please verify you are using valid models and association types"));
} }
break; break;
case (preg_match("/^(\w+) unbind (\w+) (\w+)/", $command, $tmp) == true): case (preg_match("/^(\w+) unbind (\w+) (\w+)/", $command, $tmp) == true):
@ -196,9 +197,10 @@ class ConsoleShell extends Shell {
if ($this->_isValidModel($modelA) && $this->_isValidModel($modelB) && in_array($association, $this->associations) && $validCurrentAssociation) { if ($this->_isValidModel($modelA) && $this->_isValidModel($modelB) && in_array($association, $this->associations) && $validCurrentAssociation) {
$this->{$modelA}->unbindModel(array($association => array($modelB))); $this->{$modelA}->unbindModel(array($association => array($modelB)));
$this->out("Removed $association association between $modelA and $modelB"); $this->out(__d('cake_console', "Removed %s association between %s and %s",
$association, $modelA, $modelB));
} else { } else {
$this->out("Please verify you are using valid models, valid current association, and valid association types"); $this->out(__d('cake_console', "Please verify you are using valid models, valid current association, and valid association types"));
} }
break; break;
case (strpos($command, "->find") > 0): case (strpos($command, "->find") > 0):
@ -248,10 +250,11 @@ class ConsoleShell extends Shell {
} }
} }
} else { } else {
$this->out("\nNo result set found"); $this->out();
$this->out(__d('cake_console', "No result set found"));
} }
} else { } else {
$this->out("$modelToCheck is not a valid model"); $this->out(__d('cake_console', "%s is not a valid model", $modelToCheck));
} }
break; break;
@ -267,7 +270,7 @@ class ConsoleShell extends Shell {
$data = preg_replace('/^\(*(array)?\(*(.+?)\)*$/i', '\\2', $data); $data = preg_replace('/^\(*(array)?\(*(.+?)\)*$/i', '\\2', $data);
$saveCommand = "\$this->{$modelToSave}->save(array('{$modelToSave}' => array({$data})));"; $saveCommand = "\$this->{$modelToSave}->save(array('{$modelToSave}' => array({$data})));";
@eval($saveCommand); @eval($saveCommand);
$this->out('Saved record for ' . $modelToSave); $this->out(__d('cake_console', 'Saved record for %s', $modelToSave));
} }
break; break;
case (preg_match("/^(\w+) columns/", $command, $tmp) == true): case (preg_match("/^(\w+) columns/", $command, $tmp) == true):
@ -284,17 +287,16 @@ class ConsoleShell extends Shell {
} }
} }
} else { } else {
$this->out("Please verify that you selected a valid model"); $this->out(__d('cake_console', "Please verify that you selected a valid model"));
} }
break; break;
case (preg_match("/^routes\s+reload/i", $command, $tmp) == true): case (preg_match("/^routes\s+reload/i", $command, $tmp) == true):
$router = Router::getInstance(); $router = Router::getInstance();
if (!$this->_loadRoutes()) { if (!$this->_loadRoutes()) {
$this->out("There was an error loading the routes config. Please check that the file"); $this->out(__d('cake_console', "There was an error loading the routes config. Please check that the file exists and is free of parse errors."));
$this->out("exists and is free of parse errors.");
break; break;
} }
$this->out("Routes configuration reloaded, " . count($router->routes) . " routes connected"); $this->out(__d('cake_console', "Routes configuration reloaded, %d routes connected", count($router->routes)));
break; break;
case (preg_match("/^routes\s+show/i", $command, $tmp) == true): case (preg_match("/^routes\s+show/i", $command, $tmp) == true):
$router = Router::getInstance(); $router = Router::getInstance();
@ -309,7 +311,8 @@ class ConsoleShell extends Shell {
$this->out(var_export(Router::parse($tmp[1]), true)); $this->out(var_export(Router::parse($tmp[1]), true));
break; break;
default: default:
$this->out("Invalid command\n"); $this->out(__d('cake_console', "Invalid command"));
$this->out();
break; break;
} }
$command = ''; $command = '';

View file

@ -137,7 +137,8 @@ class SchemaShell extends Shell {
if (!$snapshot && file_exists($this->Schema->path . DS . $this->params['file'])) { if (!$snapshot && file_exists($this->Schema->path . DS . $this->params['file'])) {
$snapshot = true; $snapshot = true;
$result = strtolower($this->in("Schema file exists.\n [O]verwrite\n [S]napshot\n [Q]uit\nWould you like to do?", array('o', 's', 'q'), 's')); $prompt = __d('cake_console', "Schema file exists.\n [O]verwrite\n [S]napshot\n [Q]uit\nWould you like to do?");
$result = strtolower($this->in($prompt, array('o', 's', 'q'), 's'));
if ($result === 'q') { if ($result === 'q') {
return $this->_stop(); return $this->_stop();
} }
@ -453,7 +454,7 @@ class SchemaShell extends Shell {
'help' => __d('cake_console', 'Snapshot number to use/make.') 'help' => __d('cake_console', 'Snapshot number to use/make.')
); );
$dry = array( $dry = array(
'help' => 'Perform a dry run on create and update commands. Queries will be output instead of run.', 'help' => __d('cake_console', 'Perform a dry run on create and update commands. Queries will be output instead of run.'),
'boolean' => true 'boolean' => true
); );
$force = array( $force = array(
@ -467,10 +468,9 @@ class SchemaShell extends Shell {
$parser = parent::getOptionParser(); $parser = parent::getOptionParser();
$parser->description( $parser->description(
'The Schema Shell generates a schema object from' . __d('cake_console', 'The Schema Shell generates a schema object from the database and updates the database from the schema.')
'the database and updates the database from the schema.'
)->addSubcommand('view', array( )->addSubcommand('view', array(
'help' => 'read and output the contents of a schema file', 'help' => __d('cake_console', 'Read and output the contents of a schema file'),
'parser' => array( 'parser' => array(
'options' => compact('plugin', 'path', 'file', 'name', 'connection'), 'options' => compact('plugin', 'path', 'file', 'name', 'connection'),
'arguments' => compact('name') 'arguments' => compact('name')

View file

@ -18,6 +18,7 @@
*/ */
App::uses('BakeTask', 'Console/Command/Task'); App::uses('BakeTask', 'Console/Command/Task');
App::uses('AppModel', 'Model');
/** /**
* Task class for creating and updating controller files. * Task class for creating and updating controller files.
@ -305,7 +306,7 @@ class ControllerTask extends BakeTask {
* @return string Baked controller * @return string Baked controller
*/ */
public function bake($controllerName, $actions = '', $helpers = null, $components = null) { public function bake($controllerName, $actions = '', $helpers = null, $components = null) {
$this->out("\nBaking controller class for $controllerName...", 1, Shell::QUIET); $this->out("\n" . __d('cake_console', 'Baking controller class for %s...', $controllerName), 1, Shell::QUIET);
$isScaffold = ($actions === 'scaffold') ? true : false; $isScaffold = ($actions === 'scaffold') ? true : false;
@ -499,4 +500,4 @@ class ControllerTask extends BakeTask {
$this->out(); $this->out();
$this->_stop(); $this->_stop();
} }
} }

View file

@ -38,7 +38,7 @@ class DbConfigTask extends Shell {
*/ */
protected $_defaultConfig = array( protected $_defaultConfig = array(
'name' => 'default', 'name' => 'default',
'driver'=> 'mysql', 'datasource'=> 'Database/Mysql',
'persistent'=> 'false', 'persistent'=> 'false',
'host'=> 'localhost', 'host'=> 'localhost',
'login'=> 'root', 'login'=> 'root',
@ -94,19 +94,19 @@ class DbConfigTask extends Shell {
$name = ''; $name = '';
while ($name == '') { while ($name == '') {
$name = $this->in("Name:", null, 'default'); $name = $this->in(__d('cake_console', "Name:"), null, 'default');
if (preg_match('/[^a-z0-9_]/i', $name)) { if (preg_match('/[^a-z0-9_]/i', $name)) {
$name = ''; $name = '';
$this->out('The name may only contain unaccented latin characters, numbers or underscores'); $this->out(__d('cake_console', 'The name may only contain unaccented latin characters, numbers or underscores'));
} else if (preg_match('/^[^a-z_]/i', $name)) { } else if (preg_match('/^[^a-z_]/i', $name)) {
$name = ''; $name = '';
$this->out('The name must start with an unaccented latin character or an underscore'); $this->out(__d('cake_console', 'The name must start with an unaccented latin character or an underscore'));
} }
} }
$driver = $this->in('Driver:', array('mssql', 'mysql', 'oracle', 'postgres', 'sqlite'), 'mysql'); $driver = $this->in(__d('cake_console', 'Driver:'), array('Mssql', 'Mysql', 'Oracle', 'Postgres', 'Sqlite'), 'Mysql');
$persistent = $this->in('Persistent Connection?', array('y', 'n'), 'n'); $persistent = $this->in(__d('cake_console', 'Persistent Connection?'), array('y', 'n'), 'n');
if (strtolower($persistent) == 'n') { if (strtolower($persistent) == 'n') {
$persistent = 'false'; $persistent = 'false';
} else { } else {
@ -115,12 +115,12 @@ class DbConfigTask extends Shell {
$host = ''; $host = '';
while ($host == '') { while ($host == '') {
$host = $this->in('Database Host:', null, 'localhost'); $host = $this->in(__d('cake_console', 'Database Host:'), null, 'localhost');
} }
$port = ''; $port = '';
while ($port == '') { while ($port == '') {
$port = $this->in('Port?', null, 'n'); $port = $this->in(__d('cake_console', 'Port?'), null, 'n');
} }
if (strtolower($port) == 'n') { if (strtolower($port) == 'n') {
@ -129,16 +129,16 @@ class DbConfigTask extends Shell {
$login = ''; $login = '';
while ($login == '') { while ($login == '') {
$login = $this->in('User:', null, 'root'); $login = $this->in(__d('cake_console', 'User:'), null, 'root');
} }
$password = ''; $password = '';
$blankPassword = false; $blankPassword = false;
while ($password == '' && $blankPassword == false) { while ($password == '' && $blankPassword == false) {
$password = $this->in('Password:'); $password = $this->in(__d('cake_console', 'Password:'));
if ($password == '') { if ($password == '') {
$blank = $this->in('The password you supplied was empty. Use an empty password?', array('y', 'n'), 'n'); $blank = $this->in(__d('cake_console', 'The password you supplied was empty. Use an empty password?'), array('y', 'n'), 'n');
if ($blank == 'y') { if ($blank == 'y') {
$blankPassword = true; $blankPassword = true;
} }
@ -147,12 +147,12 @@ class DbConfigTask extends Shell {
$database = ''; $database = '';
while ($database == '') { while ($database == '') {
$database = $this->in('Database Name:', null, 'cake'); $database = $this->in(__d('cake_console', 'Database Name:'), null, 'cake');
} }
$prefix = ''; $prefix = '';
while ($prefix == '') { while ($prefix == '') {
$prefix = $this->in('Table Prefix?', null, 'n'); $prefix = $this->in(__d('cake_console', 'Table Prefix?'), null, 'n');
} }
if (strtolower($prefix) == 'n') { if (strtolower($prefix) == 'n') {
$prefix = null; $prefix = null;
@ -160,7 +160,7 @@ class DbConfigTask extends Shell {
$encoding = ''; $encoding = '';
while ($encoding == '') { while ($encoding == '') {
$encoding = $this->in('Table encoding?', null, 'n'); $encoding = $this->in(__d('cake_console', 'Table encoding?'), null, 'n');
} }
if (strtolower($encoding) == 'n') { if (strtolower($encoding) == 'n') {
$encoding = null; $encoding = null;
@ -169,7 +169,7 @@ class DbConfigTask extends Shell {
$schema = ''; $schema = '';
if ($driver == 'postgres') { if ($driver == 'postgres') {
while ($schema == '') { while ($schema == '') {
$schema = $this->in('Table schema?', null, 'n'); $schema = $this->in(__d('cake_console', 'Table schema?'), null, 'n');
} }
} }
if (strtolower($schema) == 'n') { if (strtolower($schema) == 'n') {
@ -183,7 +183,7 @@ class DbConfigTask extends Shell {
} }
$dbConfigs[] = $config; $dbConfigs[] = $config;
$doneYet = $this->in('Do you wish to add another database configuration?', null, 'n'); $doneYet = $this->in(__d('cake_console', 'Do you wish to add another database configuration?'), null, 'n');
if (strtolower($doneYet == 'n')) { if (strtolower($doneYet == 'n')) {
$done = true; $done = true;
@ -205,35 +205,35 @@ class DbConfigTask extends Shell {
extract($config); extract($config);
$this->out(); $this->out();
$this->hr(); $this->hr();
$this->out('The following database configuration will be created:'); $this->out(__d('cake_console', 'The following database configuration will be created:'));
$this->hr(); $this->hr();
$this->out("Name: $name"); $this->out(__d('cake_console', "Name: %s", $name));
$this->out("Driver: $driver"); $this->out(__d('cake_console', "Driver: %s", $driver));
$this->out("Persistent: $persistent"); $this->out(__d('cake_console', "Persistent: %s", $persistent));
$this->out("Host: $host"); $this->out(__d('cake_console', "Host: %s", $host));
if ($port) { if ($port) {
$this->out("Port: $port"); $this->out(__d('cake_console', "Port: %s", $port));
} }
$this->out("User: $login"); $this->out(__d('cake_console', "User: %s", $login));
$this->out("Pass: " . str_repeat('*', strlen($password))); $this->out(__d('cake_console', "Pass: %s", str_repeat('*', strlen($password))));
$this->out("Database: $database"); $this->out(__d('cake_console', "Database: %s", $database));
if ($prefix) { if ($prefix) {
$this->out("Table prefix: $prefix"); $this->out(__d('cake_console', "Table prefix: %s", $prefix));
} }
if ($schema) { if ($schema) {
$this->out("Schema: $schema"); $this->out(__d('cake_console', "Schema: %s", $schema));
} }
if ($encoding) { if ($encoding) {
$this->out("Encoding: $encoding"); $this->out(__d('cake_console', "Encoding: %s", $encoding));
} }
$this->hr(); $this->hr();
$looksGood = $this->in('Look okay?', array('y', 'n'), 'y'); $looksGood = $this->in(__d('cake_console', 'Look okay?'), array('y', 'n'), 'y');
if (strtolower($looksGood) == 'y') { if (strtolower($looksGood) == 'y') {
return $config; return $config;
@ -249,7 +249,7 @@ class DbConfigTask extends Shell {
*/ */
public function bake($configs) { public function bake($configs) {
if (!is_dir($this->path)) { if (!is_dir($this->path)) {
$this->err($this->path . ' not found'); $this->err(__d('cake_console', '%s not found', $this->path));
return false; return false;
} }
@ -313,7 +313,7 @@ class DbConfigTask extends Shell {
extract($config); extract($config);
$out .= "\tpublic \${$name} = array(\n"; $out .= "\tpublic \${$name} = array(\n";
$out .= "\t\t'driver' => '{$driver}',\n"; $out .= "\t\t'datasource' => 'Database/{$driver}',\n";
$out .= "\t\t'persistent' => {$persistent},\n"; $out .= "\t\t'persistent' => {$persistent},\n";
$out .= "\t\t'host' => '{$host}',\n"; $out .= "\t\t'host' => '{$host}',\n";

View file

@ -30,65 +30,65 @@ class ExtractTask extends Shell {
* Paths to use when looking for strings * Paths to use when looking for strings
* *
* @var string * @var string
* @access private * @access protected
*/ */
private $__paths = array(); protected $_paths = array();
/** /**
* Files from where to extract * Files from where to extract
* *
* @var array * @var array
* @access private * @access protected
*/ */
private $__files = array(); protected $_files = array();
/** /**
* Merge all domains string into the default.pot file * Merge all domains string into the default.pot file
* *
* @var boolean * @var boolean
* @access private * @access protected
*/ */
private $__merge = false; protected $_merge = false;
/** /**
* Current file being processed * Current file being processed
* *
* @var string * @var string
* @access private * @access protected
*/ */
private $__file = null; protected $_file = null;
/** /**
* Contains all content waiting to be write * Contains all content waiting to be write
* *
* @var string * @var string
* @access private * @access protected
*/ */
private $__storage = array(); protected $_storage = array();
/** /**
* Extracted tokens * Extracted tokens
* *
* @var array * @var array
* @access private * @access protected
*/ */
private $__tokens = array(); protected $_tokens = array();
/** /**
* Extracted strings * Extracted strings
* *
* @var array * @var array
* @access private * @access protected
*/ */
private $__strings = array(); protected $_strings = array();
/** /**
* Destination path * Destination path
* *
* @var string * @var string
* @access private * @access protected
*/ */
private $__output = null; protected $_output = null;
/** /**
* An array of directories to exclude. * An array of directories to exclude.
@ -101,17 +101,17 @@ class ExtractTask extends Shell {
* Execution method always used for tasks * Execution method always used for tasks
* *
* @return void * @return void
* @access private * @access public
*/ */
function execute() { public function execute() {
if (!empty($this->params['exclude'])) { if (!empty($this->params['exclude'])) {
$this->_exclude = explode(',', $this->params['exclude']); $this->_exclude = explode(',', $this->params['exclude']);
} }
if (isset($this->params['files']) && !is_array($this->params['files'])) { if (isset($this->params['files']) && !is_array($this->params['files'])) {
$this->__files = explode(',', $this->params['files']); $this->_files = explode(',', $this->params['files']);
} }
if (isset($this->params['paths'])) { if (isset($this->params['paths'])) {
$this->__paths = explode(',', $this->params['paths']); $this->_paths = explode(',', $this->params['paths']);
} else { } else {
$defaultPath = APP_PATH; $defaultPath = APP_PATH;
$message = __d('cake_console', "What is the path you would like to extract?\n[Q]uit [D]one"); $message = __d('cake_console', "What is the path you would like to extract?\n[Q]uit [D]one");
@ -124,7 +124,7 @@ class ExtractTask extends Shell {
$this->out(); $this->out();
break; break;
} elseif (is_dir($response)) { } elseif (is_dir($response)) {
$this->__paths[] = $response; $this->_paths[] = $response;
$defaultPath = 'D'; $defaultPath = 'D';
} else { } else {
$this->err(__d('cake_console', 'The directory path you supplied was not found. Please try again.')); $this->err(__d('cake_console', 'The directory path you supplied was not found. Please try again.'));
@ -134,16 +134,16 @@ class ExtractTask extends Shell {
} }
if (isset($this->params['output'])) { if (isset($this->params['output'])) {
$this->__output = $this->params['output']; $this->_output = $this->params['output'];
} else { } else {
$message = __d('cake_console', "What is the path you would like to output?\n[Q]uit", $this->__paths[0] . DS . 'locale'); $message = __d('cake_console', "What is the path you would like to output?\n[Q]uit", $this->_paths[0] . DS . 'locale');
while (true) { while (true) {
$response = $this->in($message, null, $this->__paths[0] . DS . 'locale'); $response = $this->in($message, null, $this->_paths[0] . DS . 'locale');
if (strtoupper($response) === 'Q') { if (strtoupper($response) === 'Q') {
$this->out(__d('cake_console', 'Extract Aborted')); $this->out(__d('cake_console', 'Extract Aborted'));
$this->_stop(); $this->_stop();
} elseif (is_dir($response)) { } elseif (is_dir($response)) {
$this->__output = $response . DS; $this->_output = $response . DS;
break; break;
} else { } else {
$this->err(__d('cake_console', 'The directory path you supplied was not found. Please try again.')); $this->err(__d('cake_console', 'The directory path you supplied was not found. Please try again.'));
@ -153,41 +153,41 @@ class ExtractTask extends Shell {
} }
if (isset($this->params['merge'])) { if (isset($this->params['merge'])) {
$this->__merge = !(strtolower($this->params['merge']) === 'no'); $this->_merge = !(strtolower($this->params['merge']) === 'no');
} else { } else {
$this->out(); $this->out();
$response = $this->in(__d('cake_console', 'Would you like to merge all domains strings into the default.pot file?'), array('y', 'n'), 'n'); $response = $this->in(__d('cake_console', 'Would you like to merge all domains strings into the default.pot file?'), array('y', 'n'), 'n');
$this->__merge = strtolower($response) === 'y'; $this->_merge = strtolower($response) === 'y';
} }
if (empty($this->__files)) { if (empty($this->_files)) {
$this->__searchFiles(); $this->_searchFiles();
} }
$this->__extract(); $this->_extract();
} }
/** /**
* Extract text * Extract text
* *
* @return void * @return void
* @access private * @access protected
*/ */
function __extract() { protected function _extract() {
$this->out(); $this->out();
$this->out(); $this->out();
$this->out(__d('cake_console', 'Extracting...')); $this->out(__d('cake_console', 'Extracting...'));
$this->hr(); $this->hr();
$this->out(__d('cake_console', 'Paths:')); $this->out(__d('cake_console', 'Paths:'));
foreach ($this->__paths as $path) { foreach ($this->_paths as $path) {
$this->out(' ' . $path); $this->out(' ' . $path);
} }
$this->out(__d('cake_console', 'Output Directory: ') . $this->__output); $this->out(__d('cake_console', 'Output Directory: ') . $this->_output);
$this->hr(); $this->hr();
$this->__extractTokens(); $this->_extractTokens();
$this->__buildFiles(); $this->_buildFiles();
$this->__writeFiles(); $this->_writeFiles();
$this->__paths = $this->__files = $this->__storage = array(); $this->_paths = $this->_files = $this->_storage = array();
$this->__strings = $this->__tokens = array(); $this->_strings = $this->_tokens = array();
$this->out(); $this->out();
$this->out(__d('cake_console', 'Done.')); $this->out(__d('cake_console', 'Done.'));
} }
@ -201,7 +201,7 @@ class ExtractTask extends Shell {
$parser = parent::getOptionParser(); $parser = parent::getOptionParser();
return $parser->description(__d('cake_console', 'CakePHP Language String Extraction:')) return $parser->description(__d('cake_console', 'CakePHP Language String Extraction:'))
->addOption('app', array('help' => __d('cake_console', 'Directory where your application is located.'))) ->addOption('app', array('help' => __d('cake_console', 'Directory where your application is located.')))
->addOption('paths', array('help' => __d('cake_console', 'Comma separted list of paths.'))) ->addOption('paths', array('help' => __d('cake_console', 'Comma separated list of paths.')))
->addOption('merge', array( ->addOption('merge', array(
'help' => __d('cake_console', 'Merge all domain strings into the default.po file.'), 'help' => __d('cake_console', 'Merge all domain strings into the default.po file.'),
'choices' => array('yes', 'no') 'choices' => array('yes', 'no')
@ -245,40 +245,30 @@ class ExtractTask extends Shell {
* Extract tokens out of all files to be processed * Extract tokens out of all files to be processed
* *
* @return void * @return void
* @access private * @access protected
*/ */
function __extractTokens() { protected function _extractTokens() {
foreach ($this->__files as $file) { foreach ($this->_files as $file) {
$this->__file = $file; $this->_file = $file;
$this->out(__d('cake_console', 'Processing %s...', $file)); $this->out(__d('cake_console', 'Processing %s...', $file));
$code = file_get_contents($file); $code = file_get_contents($file);
$allTokens = token_get_all($code); $allTokens = token_get_all($code);
$this->__tokens = array();
$lineNumber = 1;
$this->_tokens = array();
foreach ($allTokens as $token) { foreach ($allTokens as $token) {
if ((!is_array($token)) || (($token[0] != T_WHITESPACE) && ($token[0] != T_INLINE_HTML))) { if (!is_array($token) || ($token[0] != T_WHITESPACE && $token[0] != T_INLINE_HTML)) {
if (is_array($token)) { $this->_tokens[] = $token;
$token[] = $lineNumber;
}
$this->__tokens[] = $token;
}
if (is_array($token)) {
$lineNumber += count(explode("\n", $token[1])) - 1;
} else {
$lineNumber += count(explode("\n", $token)) - 1;
} }
} }
unset($allTokens); unset($allTokens);
$this->__parse('__', array('singular')); $this->_parse('__', array('singular'));
$this->__parse('__n', array('singular', 'plural')); $this->_parse('__n', array('singular', 'plural'));
$this->__parse('__d', array('domain', 'singular')); $this->_parse('__d', array('domain', 'singular'));
$this->__parse('__c', array('singular')); $this->_parse('__c', array('singular'));
$this->__parse('__dc', array('domain', 'singular')); $this->_parse('__dc', array('domain', 'singular'));
$this->__parse('__dn', array('domain', 'singular', 'plural')); $this->_parse('__dn', array('domain', 'singular', 'plural'));
$this->__parse('__dcn', array('domain', 'singular', 'plural')); $this->_parse('__dcn', array('domain', 'singular', 'plural'));
} }
} }
@ -288,14 +278,14 @@ class ExtractTask extends Shell {
* @param string $functionName Function name that indicates translatable string (e.g: '__') * @param string $functionName Function name that indicates translatable string (e.g: '__')
* @param array $map Array containing what variables it will find (e.g: domain, singular, plural) * @param array $map Array containing what variables it will find (e.g: domain, singular, plural)
* @return void * @return void
* @access private * @access protected
*/ */
function __parse($functionName, $map) { protected function _parse($functionName, $map) {
$count = 0; $count = 0;
$tokenCount = count($this->__tokens); $tokenCount = count($this->_tokens);
while (($tokenCount - $count) > 1) { while (($tokenCount - $count) > 1) {
list($countToken, $firstParenthesis) = array($this->__tokens[$count], $this->__tokens[$count + 1]); list($countToken, $firstParenthesis) = array($this->_tokens[$count], $this->_tokens[$count + 1]);
if (!is_array($countToken)) { if (!is_array($countToken)) {
$count++; $count++;
continue; continue;
@ -307,35 +297,24 @@ class ExtractTask extends Shell {
$depth = 0; $depth = 0;
while ($depth == 0) { while ($depth == 0) {
if ($this->__tokens[$position] == '(') { if ($this->_tokens[$position] == '(') {
$depth++; $depth++;
} elseif ($this->__tokens[$position] == ')') { } elseif ($this->_tokens[$position] == ')') {
$depth--; $depth--;
} }
$position++; $position++;
} }
$mapCount = count($map); $mapCount = count($map);
$strings = array(); $strings = $this->_getStrings($position, $mapCount);
while (count($strings) < $mapCount && ($this->__tokens[$position] == ',' || $this->__tokens[$position][0] == T_CONSTANT_ENCAPSED_STRING)) {
if ($this->__tokens[$position][0] == T_CONSTANT_ENCAPSED_STRING) {
$strings[] = $this->__tokens[$position][1];
}
$position++;
}
if ($mapCount == count($strings)) { if ($mapCount == count($strings)) {
extract(array_combine($map, $strings)); extract(array_combine($map, $strings));
if (!isset($domain)) { $domain = isset($domain) ? $domain : 'default';
$domain = '\'default\''; $string = isset($plural) ? $singular . "\0" . $plural : $singular;
} $this->_strings[$domain][$string][$this->_file][] = $line;
$string = $this->__formatString($singular);
if (isset($plural)) {
$string .= "\0" . $this->__formatString($plural);
}
$this->__strings[$this->__formatString($domain)][$string][$this->__file][] = $line;
} else { } else {
$this->__markerError($this->__file, $line, $functionName, $count); $this->_markerError($this->_file, $line, $functionName, $count);
} }
} }
$count++; $count++;
@ -346,17 +325,17 @@ class ExtractTask extends Shell {
* Build the translate template file contents out of obtained strings * Build the translate template file contents out of obtained strings
* *
* @return void * @return void
* @access private * @access protected
*/ */
function __buildFiles() { protected function _buildFiles() {
foreach ($this->__strings as $domain => $strings) { foreach ($this->_strings as $domain => $strings) {
foreach ($strings as $string => $files) { foreach ($strings as $string => $files) {
$occurrences = array(); $occurrences = array();
foreach ($files as $file => $lines) { foreach ($files as $file => $lines) {
$occurrences[] = $file . ':' . implode(';', $lines); $occurrences[] = $file . ':' . implode(';', $lines);
} }
$occurrences = implode("\n#: ", $occurrences); $occurrences = implode("\n#: ", $occurrences);
$header = '#: ' . str_replace($this->__paths, '', $occurrences) . "\n"; $header = '#: ' . str_replace($this->_paths, '', $occurrences) . "\n";
if (strpos($string, "\0") === false) { if (strpos($string, "\0") === false) {
$sentence = "msgid \"{$string}\"\n"; $sentence = "msgid \"{$string}\"\n";
@ -369,9 +348,9 @@ class ExtractTask extends Shell {
$sentence .= "msgstr[1] \"\"\n\n"; $sentence .= "msgstr[1] \"\"\n\n";
} }
$this->__store($domain, $header, $sentence); $this->_store($domain, $header, $sentence);
if ($domain != 'default' && $this->__merge) { if ($domain != 'default' && $this->_merge) {
$this->__store('default', $header, $sentence); $this->_store('default', $header, $sentence);
} }
} }
} }
@ -381,16 +360,16 @@ class ExtractTask extends Shell {
* Prepare a file to be stored * Prepare a file to be stored
* *
* @return void * @return void
* @access private * @access protected
*/ */
function __store($domain, $header, $sentence) { protected function _store($domain, $header, $sentence) {
if (!isset($this->__storage[$domain])) { if (!isset($this->_storage[$domain])) {
$this->__storage[$domain] = array(); $this->_storage[$domain] = array();
} }
if (!isset($this->__storage[$domain][$sentence])) { if (!isset($this->_storage[$domain][$sentence])) {
$this->__storage[$domain][$sentence] = $header; $this->_storage[$domain][$sentence] = $header;
} else { } else {
$this->__storage[$domain][$sentence] .= $header; $this->_storage[$domain][$sentence] .= $header;
} }
} }
@ -398,18 +377,18 @@ class ExtractTask extends Shell {
* Write the files that need to be stored * Write the files that need to be stored
* *
* @return void * @return void
* @access private * @access protected
*/ */
function __writeFiles() { protected function _writeFiles() {
$overwriteAll = false; $overwriteAll = false;
foreach ($this->__storage as $domain => $sentences) { foreach ($this->_storage as $domain => $sentences) {
$output = $this->__writeHeader(); $output = $this->_writeHeader();
foreach ($sentences as $sentence => $header) { foreach ($sentences as $sentence => $header) {
$output .= $header . $sentence; $output .= $header . $sentence;
} }
$filename = $domain . '.pot'; $filename = $domain . '.pot';
$File = new File($this->__output . $filename); $File = new File($this->_output . $filename);
$response = ''; $response = '';
while ($overwriteAll === false && $File->exists() && strtoupper($response) !== 'Y') { while ($overwriteAll === false && $File->exists() && strtoupper($response) !== 'Y') {
$this->out(); $this->out();
@ -418,7 +397,7 @@ class ExtractTask extends Shell {
$response = ''; $response = '';
while ($response == '') { while ($response == '') {
$response = $this->in(__d('cake_console', "What would you like to name this file?"), null, 'new_' . $filename); $response = $this->in(__d('cake_console', "What would you like to name this file?"), null, 'new_' . $filename);
$File = new File($this->__output . $response); $File = new File($this->_output . $response);
$filename = $response; $filename = $response;
} }
} elseif (strtoupper($response) === 'A') { } elseif (strtoupper($response) === 'A') {
@ -434,9 +413,9 @@ class ExtractTask extends Shell {
* Build the translation template header * Build the translation template header
* *
* @return string Translation template header * @return string Translation template header
* @access private * @access protected
*/ */
function __writeHeader() { protected function _writeHeader() {
$output = "# LANGUAGE translation of CakePHP Application\n"; $output = "# LANGUAGE translation of CakePHP Application\n";
$output .= "# Copyright YEAR NAME <EMAIL@ADDRESS>\n"; $output .= "# Copyright YEAR NAME <EMAIL@ADDRESS>\n";
$output .= "#\n"; $output .= "#\n";
@ -454,15 +433,43 @@ class ExtractTask extends Shell {
$output .= "\"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\\n\"\n\n"; $output .= "\"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\\n\"\n\n";
return $output; return $output;
} }
/**
* Get the strings from the position forward
*
* @param int $position Actual position on tokens array
* @param int $target Number of strings to extract
* @return array Strings extracted
* @access protected
*/
protected function _getStrings(&$position, $target) {
$strings = array();
while (count($strings) < $target && ($this->_tokens[$position] == ',' || $this->_tokens[$position][0] == T_CONSTANT_ENCAPSED_STRING)) {
if ($this->_tokens[$position][0] == T_CONSTANT_ENCAPSED_STRING && $this->_tokens[$position+1] == '.') {
$string = '';
while ($this->_tokens[$position][0] == T_CONSTANT_ENCAPSED_STRING || $this->_tokens[$position] == '.') {
if ($this->_tokens[$position][0] == T_CONSTANT_ENCAPSED_STRING) {
$string .= $this->_formatString($this->_tokens[$position][1]);
}
$position++;
}
$strings[] = $string;
} else if ($this->_tokens[$position][0] == T_CONSTANT_ENCAPSED_STRING) {
$strings[] = $this->_formatString($this->_tokens[$position][1]);
}
$position++;
}
return $strings;
}
/** /**
* Format a string to be added as a translateable string * Format a string to be added as a translatable string
* *
* @param string $string String to format * @param string $string String to format
* @return string Formatted string * @return string Formatted string
* @access private * @access protected
*/ */
function __formatString($string) { protected function _formatString($string) {
$quote = substr($string, 0, 1); $quote = substr($string, 0, 1);
$string = substr($string, 1, -1); $string = substr($string, 1, -1);
if ($quote == '"') { if ($quote == '"') {
@ -482,24 +489,24 @@ class ExtractTask extends Shell {
* @param string $marker Marker found * @param string $marker Marker found
* @param integer $count Count * @param integer $count Count
* @return void * @return void
* @access private * @access protected
*/ */
function __markerError($file, $line, $marker, $count) { protected function _markerError($file, $line, $marker, $count) {
$this->out(__d('cake_console', "Invalid marker content in %s:%s\n* %s(", $file, $line, $marker), true); $this->out(__d('cake_console', "Invalid marker content in %s:%s\n* %s(", $file, $line, $marker), true);
$count += 2; $count += 2;
$tokenCount = count($this->__tokens); $tokenCount = count($this->_tokens);
$parenthesis = 1; $parenthesis = 1;
while ((($tokenCount - $count) > 0) && $parenthesis) { while ((($tokenCount - $count) > 0) && $parenthesis) {
if (is_array($this->__tokens[$count])) { if (is_array($this->_tokens[$count])) {
$this->out($this->__tokens[$count][1], false); $this->out($this->_tokens[$count][1], false);
} else { } else {
$this->out($this->__tokens[$count], false); $this->out($this->_tokens[$count], false);
if ($this->__tokens[$count] == '(') { if ($this->_tokens[$count] == '(') {
$parenthesis++; $parenthesis++;
} }
if ($this->__tokens[$count] == ')') { if ($this->_tokens[$count] == ')') {
$parenthesis--; $parenthesis--;
} }
} }
@ -509,17 +516,17 @@ class ExtractTask extends Shell {
} }
/** /**
* Search files that may contain translateable strings * Search files that may contain translatable strings
* *
* @return void * @return void
* @access private * @access protected
*/ */
function __searchFiles() { protected function _searchFiles() {
$pattern = false; $pattern = false;
if (!empty($this->_exclude)) { if (!empty($this->_exclude)) {
$pattern = '/[\/\\\\]' . implode('|', $this->_exclude) . '[\/\\\\]/'; $pattern = '/[\/\\\\]' . implode('|', $this->_exclude) . '[\/\\\\]/';
} }
foreach ($this->__paths as $path) { foreach ($this->_paths as $path) {
$Folder = new Folder($path); $Folder = new Folder($path);
$files = $Folder->findRecursive('.*\.(php|ctp|thtml|inc|tpl)', true); $files = $Folder->findRecursive('.*\.(php|ctp|thtml|inc|tpl)', true);
if (!empty($pattern)) { if (!empty($pattern)) {
@ -530,7 +537,7 @@ class ExtractTask extends Shell {
} }
$files = array_values($files); $files = array_values($files);
} }
$this->__files = array_merge($this->__files, $files); $this->_files = array_merge($this->_files, $files);
} }
} }
} }

View file

@ -83,7 +83,7 @@ class FixtureTask extends BakeTask {
'help' => __d('cake_console', 'CamelCased name of the plugin to bake fixtures for.'), 'help' => __d('cake_console', 'CamelCased name of the plugin to bake fixtures for.'),
'short' => 'p', 'short' => 'p',
))->addOption('records', array( ))->addOption('records', array(
'help' => 'Used with --count and <name>/all commands to pull [n] records from the live tables, where [n] is either --count or the default of 10', 'help' => __d('cake_console', 'Used with --count and <name>/all commands to pull [n] records from the live tables, where [n] is either --count or the default of 10'),
'short' => 'r', 'short' => 'r',
'boolean' => true 'boolean' => true
))->epilog(__d('cake_console', 'Omitting all arguments and options will enter into an interactive mode.'));; ))->epilog(__d('cake_console', 'Omitting all arguments and options will enter into an interactive mode.'));;
@ -91,7 +91,7 @@ class FixtureTask extends BakeTask {
/** /**
* Execution method always used for tasks * Execution method always used for tasks
* Handles dispatching to interactive, named, or all processess. * Handles dispatching to interactive, named, or all processeses.
* *
* @return void * @return void
*/ */
@ -137,7 +137,7 @@ class FixtureTask extends BakeTask {
protected function _interactive() { protected function _interactive() {
$this->DbConfig->interactive = $this->Model->interactive = $this->interactive = true; $this->DbConfig->interactive = $this->Model->interactive = $this->interactive = true;
$this->hr(); $this->hr();
$this->out(sprintf("Bake Fixture\nPath: %s", $this->path)); $this->out(__d('cake_console', "Bake Fixture\nPath: %s", $this->path));
$this->hr(); $this->hr();
if (!isset($this->connection)) { if (!isset($this->connection)) {
@ -254,7 +254,7 @@ class FixtureTask extends BakeTask {
$this->Template->set($vars); $this->Template->set($vars);
$content = $this->Template->generate('classes', 'fixture'); $content = $this->Template->generate('classes', 'fixture');
$this->out("\nBaking test fixture for $model...", 1, Shell::QUIET); $this->out("\n" . __d('cake_console', 'Baking test fixture for %s...', $model), 1, Shell::QUIET);
$this->createFile($path . $filename, $content); $this->createFile($path . $filename, $content);
return $content; return $content;
} }

View file

@ -168,7 +168,7 @@ class ModelTask extends BakeTask {
*/ */
protected function _interactive() { protected function _interactive() {
$this->hr(); $this->hr();
$this->out(sprintf("Bake Model\nPath: %s", $this->path)); $this->out(__d('cake_console', "Bake Model\nPath: %s", $this->path));
$this->hr(); $this->hr();
$this->interactive = true; $this->interactive = true;
@ -215,7 +215,7 @@ class ModelTask extends BakeTask {
$this->hr(); $this->hr();
$this->out(__d('cake_console', 'The following Model will be created:')); $this->out(__d('cake_console', 'The following Model will be created:'));
$this->hr(); $this->hr();
$this->out("Name: " . $currentModelName); $this->out(__d('cake_console', "Name: %s", $currentModelName));
if ($this->connection !== 'default') { if ($this->connection !== 'default') {
$this->out(__d('cake_console', "DB Config: %s", $this->connection)); $this->out(__d('cake_console', "DB Config: %s", $this->connection));
@ -561,7 +561,7 @@ class ModelTask extends BakeTask {
* Find the hasAndBelongsToMany relations and add them to associations list * Find the hasAndBelongsToMany relations and add them to associations list
* *
* @param object $model Model instance being generated * @param object $model Model instance being generated
* @param array $associations Array of inprogress associations * @param array $associations Array of in-progress associations
* @return array $associations with hasAndBelongsToMany added in. * @return array $associations with hasAndBelongsToMany added in.
*/ */
public function findHasAndBelongsToMany($model, $associations) { public function findHasAndBelongsToMany($model, $associations) {
@ -738,7 +738,7 @@ class ModelTask extends BakeTask {
$path = $this->getPath(); $path = $this->getPath();
$filename = $path . $name . '.php'; $filename = $path . $name . '.php';
$this->out("\nBaking model class for $name...", 1, Shell::QUIET); $this->out("\n" . __d('cake_console', 'Baking model class for %s...', $name), 1, Shell::QUIET);
$this->createFile($filename, $out); $this->createFile($filename, $out);
ClassRegistry::flush(); ClassRegistry::flush();
return $out; return $out;

View file

@ -185,10 +185,10 @@ class PluginTask extends Shell {
*/ */
public function getOptionParser() { public function getOptionParser() {
$parser = parent::getOptionParser(); $parser = parent::getOptionParser();
return $parser->description( return $parser->description(__d('cake_console',
'Create the directory structure, AppModel and AppController classes for a new plugin. ' . 'Create the directory structure, AppModel and AppController classes for a new plugin. ' .
'Can create plugins in any of your bootstrapped plugin paths.' 'Can create plugins in any of your bootstrapped plugin paths.'
)->addArgument('name', array( ))->addArgument('name', array(
'help' => __d('cake_console', 'CamelCased name of the plugin to create.') 'help' => __d('cake_console', 'CamelCased name of the plugin to create.')
)); ));

View file

@ -357,7 +357,7 @@ class ProjectTask extends Shell {
} }
if ($this->interactive) { if ($this->interactive) {
$this->hr(); $this->hr();
$this->out('You need to enable Configure::write(\'Routing.prefixes\',array(\'admin\')) in /app/config/core.php to use prefix routing.'); $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', 'What would you like the prefix route to be?'));
$this->out(__d('cake_console', 'Example: www.example.com/admin/controller')); $this->out(__d('cake_console', 'Example: www.example.com/admin/controller'));
while ($admin == '') { while ($admin == '') {
@ -365,7 +365,7 @@ class ProjectTask extends Shell {
} }
if ($this->cakeAdmin($admin) !== true) { if ($this->cakeAdmin($admin) !== true) {
$this->out(__d('cake_console', '<error>Unable to write to</error> /app/config/core.php.')); $this->out(__d('cake_console', '<error>Unable to write to</error> /app/config/core.php.'));
$this->out('You need to enable Configure::write(\'Routing.prefixes\',array(\'admin\')) in /app/config/core.php to use prefix routing.'); $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->_stop(); $this->_stop();
} }
return $admin . '_'; return $admin . '_';

View file

@ -142,7 +142,7 @@ class TestTask extends BakeTask {
if ($this->plugin) { if ($this->plugin) {
$plugin = $this->plugin . '.'; $plugin = $this->plugin . '.';
} }
$this->out("\nBaking test case for $className $type...", 1, Shell::QUIET); $this->out("\n" . __d('cake_console', 'Baking test case for %s %s ...', $className, $type), 1, Shell::QUIET);
$this->Template->set('fixtures', $this->_fixtures); $this->Template->set('fixtures', $this->_fixtures);
$this->Template->set('plugin', $plugin); $this->Template->set('plugin', $plugin);

View file

@ -367,7 +367,7 @@ class ViewTask extends BakeTask {
if (empty($content)) { if (empty($content)) {
return false; return false;
} }
$this->out("\nBaking `$action` view file...", 1, Shell::QUIET); $this->out("\n" . __d('cake_console', 'Baking `%s` view file...', $action), 1, Shell::QUIET);
$path = $this->getPath(); $path = $this->getPath();
$filename = $path . $this->controllerPath . DS . Inflector::underscore($action) . '.ctp'; $filename = $path . $this->controllerPath . DS . Inflector::underscore($action) . '.ctp';
return $this->createFile($filename, $content); return $this->createFile($filename, $content);

View file

@ -41,8 +41,8 @@ class TestsuiteShell extends Shell {
public function getOptionParser() { public function getOptionParser() {
$parser = new ConsoleOptionParser($this->name); $parser = new ConsoleOptionParser($this->name);
$parser->description(array( $parser->description(array(
'The CakePHP Testsuite allows you to run test cases from the command line', __d('cake_console', 'The CakePHP Testsuite allows you to run test cases from the command line'),
'If run with no command line arguments, a list of available core test cases will be shown' __d('cake_console', 'If run with no command line arguments, a list of available core test cases will be shown')
))->addArgument('category', array( ))->addArgument('category', array(
'help' => __d('cake_console', 'app, core or name of a plugin.'), 'help' => __d('cake_console', 'app, core or name of a plugin.'),
'required' => true 'required' => true
@ -157,7 +157,7 @@ class TestsuiteShell extends Shell {
} }
/** /**
* Initialization method installs Simpletest and loads all plugins * Initialization method installs PHPUnit and loads all plugins
* *
* @return void * @return void
*/ */

View file

@ -0,0 +1,554 @@
<?php
/**
* A shell class to help developers upgrade applications to CakePHP 2.0
*
* @package cake.console/shells
*/
App::uses('Folder', 'Utility');
class UpgradeShell extends Shell {
protected $_files = array();
protected $_paths = array();
protected $_map = array(
'Controller' => 'Controller',
'Component' => 'Controller/Component',
'Model' => 'Model',
'Behavior' => 'Model/Behavior',
'Datasource' => 'Model/Datasource',
'Dbo' => 'Model/Datasource/Database',
'View' => 'View',
'Helper' => 'View/Helper',
'Shell' => 'Console/Command',
'Task' => 'Console/Command/Task',
'Case' => 'tests/Case',
'Fixture' => 'tests/Fixture',
'Error' => 'Lib/Error',
);
/**
* Shell startup, prints info message about dry run.
*
* @return void
*/
function startup() {
parent::startup();
if ($this->params['dry-run']) {
$this->out('<warning>Dry-run mode enabled!</warning>', 1, Shell::QUIET);
}
if ($this->params['git'] && !is_dir('.git')) {
$this->out('<warning>No git repository detected!</warning>', 1, Shell::QUIET);
}
}
/**
* Run all upgrade steps one at a time
*
* @access public
* @return void
*/
function all() {
foreach($this->OptionParser->subcommands() as $command) {
$name = $command->name();
if ($name === 'all') {
continue;
}
$this->out('Running ' . $name);
$this->$name();
}
}
/**
* Move files and folders to their new homes
*
* Moves folders containing files which cannot necessarily be autodetected (libs and templates)
* and then looks for all php files except vendors, and moves them to where Cake 2.0 expects
* to find them.
*
* @access public
* @return void
*/
function locations() {
$cwd = getcwd();
if (is_dir('plugins')) {
$Folder = new Folder('plugins');
list($plugins) = $Folder->read();
foreach($plugins as $plugin) {
chdir($cwd . DS . 'plugins' . DS . $plugin);
$this->locations();
}
$this->_files = array();
chdir($cwd);
}
$moves = array(
'libs' => 'Lib',
'vendors' . DS . 'shells' . DS . 'templates' => 'Console' . DS . 'templates',
);
foreach($moves as $old => $new) {
if (is_dir($old)) {
$this->out("Moving $old to $new");
if (!$this->params['dry-run']) {
$Folder = new Folder($old);
$Folder->move($new);
}
if ($this->params['git']) {
exec('git mv -f ' . escapeshellarg($old) . ' ' . escapeshellarg($new));
}
}
}
$sourceDirs = array(
'.' => array('recursive' => false),
'Console',
'Controller',
'controllers',
'Lib' => array('checkFolder' => false),
'Model',
'models',
'tests',
'View',
'views',
'vendors/shells',
);
$defaultOptions = array(
'recursive' => true,
'checkFolder' => true,
);
foreach($sourceDirs as $dir => $options) {
if (is_numeric($dir)) {
$dir = $options;
$options = array();
}
$options = array_merge($defaultOptions, $options);
$this->_movePhpFiles($dir, $options);
}
}
/**
* Update helpers.
*
* - Converts helpers usage to new format.
*
* @return void
*/
function helpers() {
$this->_paths = array_diff(App::path('views'), App::core('views'));
if (!empty($this->params['plugin'])) {
$this->_paths = array(App::pluginPath($this->params['plugin']) . 'views' . DS);
}
$patterns = array();
$helpers = App::objects('helper');
$plugins = App::objects('plugin');
$pluginHelpers = array();
foreach ($plugins as $plugin) {
$pluginHelpers = array_merge(
$pluginHelpers,
App::objects('helper', App::pluginPath($plugin) . DS . 'views' . DS . 'helpers' . DS, false)
);
}
$helpers = array_merge($pluginHelpers, $helpers);
foreach ($helpers as $helper) {
$oldHelper = strtolower(substr($helper, 0, 1)).substr($helper, 1);
$patterns[] = array(
"\${$oldHelper} to \$this->{$helper}",
"/\\\${$oldHelper}->/",
"\\\$this->{$helper}->"
);
}
$this->_filesRegexpUpdate($patterns);
}
/**
* Update i18n.
*
* - Removes extra true param.
* - Add the echo to __*() calls that didn't need them before.
*
* @return void
*/
function i18n() {
$this->_paths = array(
APP
);
if (!empty($this->params['plugin'])) {
$this->_paths = array(App::pluginPath($this->params['plugin']));
}
$patterns = array(
array(
'<?php __*(*) to <?php echo __*(*)',
'/<\?php\s*(__[a-z]*\(.*?\))/',
'<?php echo \1'
),
array(
'<?php __*(*, true) to <?php echo __*()',
'/<\?php\s*(__[a-z]*\(.*?)(,\s*true)(\))/',
'<?php echo \1\3'
),
array('__*(*, true) to __*(*)', '/(__[a-z]*\(.*?)(,\s*true)(\))/', '\1\3')
);
$this->_filesRegexpUpdate($patterns);
}
/**
* Upgrade the removed basics functions.
*
* - a(*) -> array(*)
* - e(*) -> echo *
* - ife(*, *, *) -> empty(*) ? * : *
* - a(*) -> array(*)
* - r(*, *, *) -> str_replace(*, *, *)
* - up(*) -> strtoupper(*)
* - low(*, *, *) -> strtolower(*)
* - getMicrotime() -> microtime(true)
*
* @return void
*/
public function basics() {
$this->_paths = array(
APP
);
if (!empty($this->params['plugin'])) {
$this->_paths = array(App::pluginPath($this->params['plugin']));
}
$patterns = array(
array(
'a(*) -> array(*)',
'/\ba\((.*)\)/',
'array(\1)'
),
array(
'e(*) -> echo *',
'/\be\((.*)\)/',
'echo \1'
),
array(
'ife(*, *, *) -> empty(*) ? * : *',
'/ife\((.*), (.*), (.*)\)/',
'empty(\1) ? \2 : \3'
),
array(
'r(*, *, *) -> str_replace(*, *, *)',
'/\br\(/',
'str_replace('
),
array(
'up(*) -> strtoupper(*)',
'/\bup\(/',
'strtoupper('
),
array(
'low(*) -> strtolower(*)',
'/\blow\(/',
'strtolower('
),
array(
'getMicrotime() -> microtime(true)',
'/getMicrotime\(\)/',
'microtime(true)'
),
);
$this->_filesRegexpUpdate($patterns);
}
/**
* Update the properties moved to CakeRequest.
*
* @return void
*/
public function request() {
$views = array_diff(App::path('views'), App::core('views'));
$controllers = array_diff(App::path('controllers'), App::core('controllers'), array(APP));
$components = array_diff(App::path('components'), App::core('components'));
$this->_paths = array_merge($views, $controllers, $components);
if (!empty($this->params['plugin'])) {
$pluginPath = App::pluginPath($this->params['plugin']);
$this->_paths = array(
$pluginPath . 'controllers' . DS,
$pluginPath . 'controllers' . DS . 'components' .DS,
$pluginPath . 'views' . DS,
);
}
$patterns = array(
array(
'$this->data -> $this->request->data',
'/(\$this->data\b(?!\())/',
'$this->request->data'
),
array(
'$this->params -> $this->request->params',
'/(\$this->params\b(?!\())/',
'$this->request->params'
),
array(
'$this->webroot -> $this->request->webroot',
'/(\$this->webroot\b(?!\())/',
'$this->request->webroot'
),
array(
'$this->base -> $this->request->base',
'/(\$this->base\b(?!\())/',
'$this->request->base'
),
array(
'$this->here -> $this->request->here',
'/(\$this->here\b(?!\())/',
'$this->request->here'
),
array(
'$this->action -> $this->request->action',
'/(\$this->action\b(?!\())/',
'$this->request->action'
),
);
$this->_filesRegexpUpdate($patterns);
}
/**
* Update Configure::read() calls with no params.
*
* @return void
*/
public function configure() {
$this->_paths = array(
APP
);
if (!empty($this->params['plugin'])) {
$this->_paths = array(App::pluginPath($this->params['plugin']));
}
$patterns = array(
array(
"Configure::read() -> Configure::read('debug')",
'/Configure::read\(\)/',
'Configure::read(\'debug\')'
),
);
$this->_filesRegexpUpdate($patterns);
}
/**
* Move application php files to where they now should be
*
* Find all php files in the folder (honoring recursive) and determine where cake expects the file to be
* If the file is not exactly where cake expects it - move it.
*
* @param mixed $path
* @param mixed $options array(recursive, checkFolder)
* @access protected
* @return void
*/
protected function _movePhpFiles($path, $options) {
if (!is_dir($path)) {
return;
}
$paths = $this->_paths;
$this->_paths = array($path);
$this->_files = array();
if ($options['recursive']) {
$this->_findFiles('php');
} else {
$this->_files = scandir($path);
foreach($this->_files as $i => $file) {
if (strlen($file) < 5 || substr($file, -4) !== '.php') {
unset($this->_files[$i]);
}
}
}
$cwd = getcwd();
foreach ($this->_files as &$file) {
$file = $cwd . DS . $file;
$contents = file_get_contents($file);
preg_match('@class (\S*) .*{@', $contents, $match);
if (!$match) {
continue;
}
$class = $match[1];
if (substr($class, 0, 3) === 'Dbo') {
$type = 'Dbo';
} else {
preg_match('@([A-Z][^A-Z]*)$@', $class, $match);
if ($match) {
$type = $match[1];
} else {
$type = 'unknown';
}
}
preg_match('@^.*[\\\/]plugins[\\\/](.*?)[\\\/]@', $file, $match);
$base = $cwd . DS;
$plugin = false;
if ($match) {
$base = $match[0];
$plugin = $match[1];
}
if ($options['checkFolder'] && !empty($this->_map[$type])) {
$folder = str_replace('/', DS, $this->_map[$type]);
$new = $base . $folder . DS . $class . '.php';
} else {
$new = dirname($file) . DS . $class . '.php';
}
if ($file === $new) {
continue;
}
$dir = dirname($new);
if (!is_dir($dir)) {
new Folder($dir, true);
}
$this->out('Moving ' . $file . ' to ' . $new, 1, Shell::VERBOSE);
if (!$this->params['dry-run']) {
if ($this->params['git']) {
exec('git mv -f ' . escapeshellarg($file) . ' ' . escapeshellarg($new));
} else {
rename($file, $new);
}
}
}
$this->_paths = $paths;
}
/**
* Updates files based on regular expressions.
*
* @param array $patterns Array of search and replacement patterns.
* @return void
*/
protected function _filesRegexpUpdate($patterns) {
$this->_findFiles($this->params['ext']);
foreach ($this->_files as $file) {
$this->out('Updating ' . $file . '...', 1, Shell::VERBOSE);
$this->_updateFile($file, $patterns);
}
}
/**
* Searches the paths and finds files based on extension.
*
* @param string $extensions
* @return void
*/
protected function _findFiles($extensions = '') {
foreach ($this->_paths as $path) {
if (!is_dir($path)) {
continue;
}
$files = array();
$Iterator = new RegexIterator(
new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path)),
'/^.+\.(' . $extensions . ')$/i',
RegexIterator::MATCH
);
foreach ($Iterator as $file) {
if ($file->isFile()) {
$files[] = $file->getPathname();
}
}
$this->_files = array_merge($this->_files, $files);
}
}
/**
* Update a single file.
*
* @param string $file The file to update
* @param array $patterns The replacement patterns to run.
* @return void
*/
protected function _updateFile($file, $patterns) {
$contents = file_get_contents($file);
foreach ($patterns as $pattern) {
$this->out(' * Updating ' . $pattern[0], 1, Shell::VERBOSE);
$contents = preg_replace($pattern[1], $pattern[2], $contents);
}
$this->out('Done updating ' . $file, 1);
if (!$this->params['dry-run']) {
file_put_contents($file, $contents);
}
}
/**
* get the option parser
*
* @return ConsoleOptionParser
*/
function getOptionParser() {
$subcommandParser = array(
'options' => array(
'plugin' => array(
'short' => 'p',
'help' => __('The plugin to update. Only the specified plugin will be updated.'
)),
'ext' => array(
'short' => 'e',
'help' => __('The extension(s) to search. A pipe delimited list, or a preg_match compatible subpattern'),
'default' => 'php|ctp|thtml|inc|tpl'
),
'git'=> array(
'help' => __('use git command for moving files around.'),
'default' => 0
),
'dry-run'=> array(
'short' => 'd',
'help' => __('Dry run the update, no files will actually be modified.'),
'boolean' => true
)
)
);
return parent::getOptionParser()
->description("A shell to help automate upgrading from CakePHP 1.3 to 2.0. \n" .
"Be sure to have a backup of your application before running these commands.")
->addSubcommand('all', array(
'help' => 'Run all upgrade commands.',
'parser' => $subcommandParser
))
->addSubcommand('locations', array(
'help' => 'Move files and folders to their new homes.',
'parser' => $subcommandParser
))
->addSubcommand('i18n', array(
'help' => 'Update the i18n translation method calls.',
'parser' => $subcommandParser
))
->addSubcommand('helpers', array(
'help' => 'Update calls to helpers.',
'parser' => $subcommandParser
))
->addSubcommand('basics', array(
'help' => 'Update removed basics functions to PHP native functions.',
'parser' => $subcommandParser
))
->addSubcommand('request', array(
'help' => 'Update removed request access, and replace with $this->request.',
'parser' => $subcommandParser
))
->addSubcommand('configure', array(
'help' => "Update Configure::read() to Configure::read('debug')",
'parser' => $subcommandParser
));
}
}

View file

@ -57,8 +57,7 @@ class ConsoleErrorHandler extends ErrorHandler {
*/ */
public static function handleException(Exception $exception) { public static function handleException(Exception $exception) {
$stderr = self::getStderr(); $stderr = self::getStderr();
$stderr->write(sprintf( $stderr->write(__d('cake_console', "<error>Error:</error> %s\n%s",
__d('cake_console', "<error>Error:</error> %s\n%s"),
$exception->getMessage(), $exception->getMessage(),
$exception->getTraceAsString() $exception->getTraceAsString()
)); ));
@ -70,7 +69,7 @@ class ConsoleErrorHandler extends ErrorHandler {
* @param int $code Error code * @param int $code Error code
* @param string $description Description of the error. * @param string $description Description of the error.
* @param string $file The file the error occurred in. * @param string $file The file the error occurred in.
* @param int $line The line the error ocurrred on. * @param int $line The line the error occurred on.
* @param array $context The backtrace of the error. * @param array $context The backtrace of the error.
* @return void * @return void
*/ */

View file

@ -55,7 +55,7 @@ class ConsoleInputArgument {
/** /**
* Make a new Input Argument * Make a new Input Argument
* *
* @param mixed $name The long name of the option, or an array with all the properites. * @param mixed $name The long name of the option, or an array with all the properties.
* @param string $help The help text for this option * @param string $help The help text for this option
* @param boolean $required Whether this argument is required. Missing required args will trigger exceptions * @param boolean $required Whether this argument is required. Missing required args will trigger exceptions
* @param array $choices Valid choices for this option. * @param array $choices Valid choices for this option.
@ -139,8 +139,8 @@ class ConsoleInputArgument {
return true; return true;
} }
if (!in_array($value, $this->_choices)) { if (!in_array($value, $this->_choices)) {
throw new ConsoleException(sprintf( throw new ConsoleException(
__d('cake_console', '"%s" is not a valid value for %s. Please use one of "%s"'), __d('cake_console', '"%s" is not a valid value for %s. Please use one of "%s"',
$value, $this->_name, implode(', ', $this->_choices) $value, $this->_name, implode(', ', $this->_choices)
)); ));
} }

View file

@ -70,7 +70,7 @@ class ConsoleInputOption {
/** /**
* Make a new Input Option * Make a new Input Option
* *
* @param mixed $name The long name of the option, or an array with all the properites. * @param mixed $name The long name of the option, or an array with all the properties.
* @param string $short The short alias for this option * @param string $short The short alias for this option
* @param string $help The help text for this option * @param string $help The help text for this option
* @param boolean $boolean Whether this option is a boolean option. Boolean options don't consume extra tokens * @param boolean $boolean Whether this option is a boolean option. Boolean options don't consume extra tokens
@ -179,8 +179,8 @@ class ConsoleInputOption {
return true; return true;
} }
if (!in_array($value, $this->_choices)) { if (!in_array($value, $this->_choices)) {
throw new ConsoleException(sprintf( throw new ConsoleException(
__d('cake_console', '"%s" is not a valid value for --%s. Please use one of "%s"'), __d('cake_console', '"%s" is not a valid value for --%s. Please use one of "%s"',
$value, $this->_name, implode(', ', $this->_choices) $value, $this->_name, implode(', ', $this->_choices)
)); ));
} }

View file

@ -50,7 +50,7 @@ class ConsoleInputSubcommand {
/** /**
* Make a new Subcommand * Make a new Subcommand
* *
* @param mixed $name The long name of the subcommand, or an array with all the properites. * @param mixed $name The long name of the subcommand, or an array with all the properties.
* @param string $help The help text for this option * @param string $help The help text for this option
* @param mixed $parser A parser for this subcommand. Either a ConsoleOptionParser, or an array that can be * @param mixed $parser A parser for this subcommand. Either a ConsoleOptionParser, or an array that can be
* used with ConsoleOptionParser::buildFromArray() * used with ConsoleOptionParser::buildFromArray()

View file

@ -86,9 +86,9 @@ class ConsoleOptionParser {
* *
* ### Options * ### Options
* *
* Named arguments come in two forms, long and short. Long arguments are preceeded * Named arguments come in two forms, long and short. Long arguments are preceded
* by two - and give a more verbose option name. i.e. `--version`. Short arguments are * by two - and give a more verbose option name. i.e. `--version`. Short arguments are
* preceeded by one - and are only one character long. They usually match with a long option, * preceded by one - and are only one character long. They usually match with a long option,
* and provide a more terse alternative. * and provide a more terse alternative.
* *
* ### Using Options * ### Using Options
@ -102,7 +102,7 @@ class ConsoleOptionParser {
* *
* `cake myshell command --connection default --name=something` * `cake myshell command --connection default --name=something`
* *
* Short options can be defined singally or in groups. * Short options can be defined signally or in groups.
* *
* `cake myshell command -cn` * `cake myshell command -cn`
* *
@ -127,7 +127,7 @@ class ConsoleOptionParser {
$this->addOption('help', array( $this->addOption('help', array(
'short' => 'h', 'short' => 'h',
'help' => 'Display this help.', 'help' => __d('cake_console', 'Display this help.'),
'boolean' => true 'boolean' => true
)); ));
@ -330,7 +330,7 @@ class ConsoleOptionParser {
} }
/** /**
* Add multiple arugments at once. Take an array of arugment defintions. * Add multiple arguments at once. Take an array of argument definitions.
* The keys are used as the argument names, and the values as params for the argument. * The keys are used as the argument names, and the values as params for the argument.
* *
* @param array $args Array of arguments to add. * @param array $args Array of arguments to add.

View file

@ -17,10 +17,10 @@
* @license MIT License (http://www.opensource.org/licenses/mit-license.php) * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/ */
/** /**
* Object wrapper for outputing information from a shell application. * Object wrapper for outputting information from a shell application.
* Can be connected to any stream resource that can be used with fopen() * Can be connected to any stream resource that can be used with fopen()
* *
* Can generate colourized output on consoles that support it. There are a few * Can generate colorized output on consoles that support it. There are a few
* built in styles * built in styles
* *
* - `error` Error messages. * - `error` Error messages.
@ -37,7 +37,7 @@
* *
* `$this->out('<warning>Overwrite:</warning> foo.php was overwritten.');` * `$this->out('<warning>Overwrite:</warning> foo.php was overwritten.');`
* *
* This would create orange 'Overwrite:' text, while the rest of the text would remain the normal colour. * This would create orange 'Overwrite:' text, while the rest of the text would remain the normal color.
* See ConsoleOutput::styles() to learn more about defining your own styles. Nested styles are not supported * See ConsoleOutput::styles() to learn more about defining your own styles. Nested styles are not supported
* at this time. * at this time.
* *
@ -55,7 +55,7 @@ class ConsoleOutput {
const PLAIN = 1; const PLAIN = 1;
/** /**
* Colour output - Convert known tags in to ANSI color escape codes. * Color output - Convert known tags in to ANSI color escape codes.
*/ */
const COLOR = 2; const COLOR = 2;
@ -79,7 +79,7 @@ class ConsoleOutput {
protected $_outputAs = self::COLOR; protected $_outputAs = self::COLOR;
/** /**
* text colors used in coloured output. * text colors used in colored output.
* *
* @var array * @var array
*/ */
@ -95,7 +95,7 @@ class ConsoleOutput {
); );
/** /**
* background colours used in coloured output. * background colors used in colored output.
* *
* @var array * @var array
*/ */
@ -111,7 +111,7 @@ class ConsoleOutput {
); );
/** /**
* formatting options for coloured output * formatting options for colored output
* *
* @var string * @var string
*/ */
@ -140,7 +140,7 @@ class ConsoleOutput {
/** /**
* Construct the output object. * Construct the output object.
* *
* Checks for a pretty console enviornment. Ansicon allows pretty consoles * Checks for a pretty console environment. Ansicon allows pretty consoles
* on windows, and is supported. * on windows, and is supported.
* *
* @param string $stream The identifier of the stream to write output to. * @param string $stream The identifier of the stream to write output to.
@ -267,7 +267,7 @@ class ConsoleOutput {
/** /**
* Get/Set the output type to use. The output type how formatting tags are treated. * Get/Set the output type to use. The output type how formatting tags are treated.
* *
* @param int $type The output type to use. Should be one of the class contstants. * @param int $type The output type to use. Should be one of the class constants.
* @return mixed Either null or the value if getting. * @return mixed Either null or the value if getting.
*/ */
public function outputAs($type = null) { public function outputAs($type = null) {

View file

@ -23,7 +23,7 @@ App::uses('String', 'Utility');
* Generally not directly used. Using $parser->help($command, 'xml'); is usually * Generally not directly used. Using $parser->help($command, 'xml'); is usually
* how you would access help. Or via the `--help=xml` option on the command line. * how you would access help. Or via the `--help=xml` option on the command line.
* *
* Xml output is useful for intergration with other tools like IDE's or other build tools. * Xml output is useful for integration with other tools like IDE's or other build tools.
* *
* @package cake.console.libs * @package cake.console.libs
* @since CakePHP(tm) v 2.0 * @since CakePHP(tm) v 2.0
@ -52,12 +52,12 @@ class HelpFormatter {
$out[] = String::wrap($description, $width); $out[] = String::wrap($description, $width);
$out[] = ''; $out[] = '';
} }
$out[] = '<info>Usage:</info>'; $out[] = __d('cake_console', '<info>Usage:</info>');
$out[] = $this->_generateUsage(); $out[] = $this->_generateUsage();
$out[] = ''; $out[] = '';
$subcommands = $parser->subcommands(); $subcommands = $parser->subcommands();
if (!empty($subcommands)) { if (!empty($subcommands)) {
$out[] = '<info>Subcommands:</info>'; $out[] = __d('cake_console', '<info>Subcommands:</info>');
$out[] = ''; $out[] = '';
$max = $this->_getMaxLength($subcommands) + 2; $max = $this->_getMaxLength($subcommands) + 2;
foreach ($subcommands as $command) { foreach ($subcommands as $command) {
@ -68,17 +68,14 @@ class HelpFormatter {
)); ));
} }
$out[] = ''; $out[] = '';
$out[] = sprintf( $out[] = __d('cake_console', 'To see help on a subcommand use <info>`cake %s [subcommand] --help`</info>', $parser->command());
__d('cake_console', 'To see help on a subcommand use <info>`cake %s [subcommand] --help`</info>'),
$parser->command()
);
$out[] = ''; $out[] = '';
} }
$options = $parser->options(); $options = $parser->options();
if (!empty($options)) { if (!empty($options)) {
$max = $this->_getMaxLength($options) + 8; $max = $this->_getMaxLength($options) + 8;
$out[] = '<info>Options:</info>'; $out[] = __d('cake_console', '<info>Options:</info>');
$out[] = ''; $out[] = '';
foreach ($options as $option) { foreach ($options as $option) {
$out[] = String::wrap($option->help($max), array( $out[] = String::wrap($option->help($max), array(
@ -93,7 +90,7 @@ class HelpFormatter {
$arguments = $parser->arguments(); $arguments = $parser->arguments();
if (!empty($arguments)) { if (!empty($arguments)) {
$max = $this->_getMaxLength($arguments) + 2; $max = $this->_getMaxLength($arguments) + 2;
$out[] = '<info>Arguments:</info>'; $out[] = __d('cake_console', '<info>Arguments:</info>');
$out[] = ''; $out[] = '';
foreach ($arguments as $argument) { foreach ($arguments as $argument) {
$out[] = String::wrap($argument->help($max), array( $out[] = String::wrap($argument->help($max), array(
@ -114,7 +111,7 @@ class HelpFormatter {
/** /**
* Generate the usage for a shell based on its arguments and options. * Generate the usage for a shell based on its arguments and options.
* Usage strings favour short options over the long ones. and optional args will * Usage strings favor short options over the long ones. and optional args will
* be indicated with [] * be indicated with []
* *
* @return string * @return string
@ -156,7 +153,7 @@ class HelpFormatter {
public function xml($string = true) { public function xml($string = true) {
$parser = $this->_parser; $parser = $this->_parser;
$xml = new SimpleXmlElement('<shell></shell>'); $xml = new SimpleXmlElement('<shell></shell>');
$xml->addChild('commmand', $parser->command()); $xml->addChild('command', $parser->command());
$xml->addChild('description', $parser->description()); $xml->addChild('description', $parser->description());
$xml->addChild('epilog', $parser->epilog()); $xml->addChild('epilog', $parser->epilog());

View file

@ -188,7 +188,7 @@ class Shell extends Object {
/** /**
* Starts up the Shell * Starts up the Shell
* allows for checking and configuring prior to command or main execution * allows for checking and configuring prior to command or main execution
* can be overriden in subclasses * can be overridden in subclasses
* *
*/ */
public function startup() { public function startup() {
@ -201,10 +201,10 @@ class Shell extends Object {
*/ */
protected function _welcome() { protected function _welcome() {
$this->out(); $this->out();
$this->out('<info>Welcome to CakePHP v' . Configure::version() . ' Console</info>'); $this->out(__d('cake_console', '<info>Welcome to CakePHP %s Console</info>', 'v' . Configure::version()));
$this->hr(); $this->hr();
$this->out('App : '. APP_DIR); $this->out(__d('cake_console', 'App : %s', APP_DIR));
$this->out('Path: '. APP_PATH); $this->out(__d('cake_console', 'Path: %s', APP_PATH));
$this->hr(); $this->hr();
} }
@ -220,7 +220,7 @@ class Shell extends Object {
if ($this->uses === null || $this->uses === false) { if ($this->uses === null || $this->uses === false) {
return; return;
} }
App::import('Core', 'ClassRegistry'); App::uses('ClassRegistry', 'Utility');
if ($this->uses !== true && !empty($this->uses)) { if ($this->uses !== true && !empty($this->uses)) {
$uses = is_array($this->uses) ? $this->uses : array($this->uses); $uses = is_array($this->uses) ? $this->uses : array($this->uses);
@ -296,7 +296,7 @@ class Shell extends Object {
* *
* ### Usage: * ### Usage:
* *
* With a string commmand: * With a string command:
* *
* `return $this->dispatchShell('schema create DbAcl');` * `return $this->dispatchShell('schema create DbAcl');`
* *
@ -578,7 +578,7 @@ class Shell extends Object {
*/ */
public function clear() { public function clear() {
if (empty($this->params['noclear'])) { if (empty($this->params['noclear'])) {
if ( DS === '/') { if (DS === '/') {
passthru('clear'); passthru('clear');
} else { } else {
passthru('cls'); passthru('cls');
@ -600,7 +600,7 @@ class Shell extends Object {
if (is_file($path) && $this->interactive === true) { if (is_file($path) && $this->interactive === true) {
$this->out(__d('cake_console', '<warning>File `%s` exists</warning>', $path)); $this->out(__d('cake_console', '<warning>File `%s` exists</warning>', $path));
$key = $this->in(__d('cake_console', 'Do you want to overwrite?'), array('y', 'n', 'q'), 'n'); $key = $this->in(__d('cake_console', 'Do you want to overwrite?'), array('y', 'n', 'q'), 'n');
if (strtolower($key) == 'q') { if (strtolower($key) == 'q') {
$this->out(__d('cake_console', '<error>Quitting</error>.'), 2); $this->out(__d('cake_console', '<error>Quitting</error>.'), 2);
@ -636,13 +636,13 @@ class Shell extends Object {
if (@include 'PHPUnit' . DS . 'Autoload.php') { if (@include 'PHPUnit' . DS . 'Autoload.php') {
return true; return true;
} }
$prompt = 'PHPUnit is not installed. Do you want to bake unit test files anyway?'; $prompt = __d('cake_console', 'PHPUnit is not installed. Do you want to bake unit test files anyway?');
$unitTest = $this->in($prompt, array('y','n'), 'y'); $unitTest = $this->in($prompt, array('y','n'), 'y');
$result = strtolower($unitTest) == 'y' || strtolower($unitTest) == 'yes'; $result = strtolower($unitTest) == 'y' || strtolower($unitTest) == 'yes';
if ($result) { if ($result) {
$this->out(); $this->out();
$this->out('You can download PHPUnit from http://phpunit.de'); $this->out(__d('cake_console', 'You can download PHPUnit from %s', 'http://phpunit.de'));
} }
return $result; return $result;
} }

View file

@ -99,13 +99,13 @@ class ShellDispatcher {
*/ */
protected function _initEnvironment() { protected function _initEnvironment() {
if (!$this->__bootstrap()) { if (!$this->__bootstrap()) {
$message = "Unable to load CakePHP core.\nMake sure " . DS . 'cake' . DS . 'libs exists in ' . CAKE_CORE_INCLUDE_PATH; $message = "Unable to load CakePHP core.\nMake sure " . DS . 'lib' . DS . 'Cake exists in ' . CAKE_CORE_INCLUDE_PATH;
throw new CakeException($message); throw new CakeException($message);
} }
if (!isset($this->args[0]) || !isset($this->params['working'])) { if (!isset($this->args[0]) || !isset($this->params['working'])) {
$message = "This file has been loaded incorrectly and cannot continue.\n" . $message = "This file has been loaded incorrectly and cannot continue.\n" .
"Please make sure that " . DIRECTORY_SEPARATOR . "cake" . DIRECTORY_SEPARATOR . "console is in your system path,\n" . "Please make sure that " . DS . 'lib' . DS . 'Cake' . DS . "Console is in your system path,\n" .
"and check the cookbook for the correct usage of this command.\n" . "and check the cookbook for the correct usage of this command.\n" .
"(http://book.cakephp.org/)"; "(http://book.cakephp.org/)";
throw new CakeException($message); throw new CakeException($message);

View file

@ -37,9 +37,9 @@ class CakeErrorController extends AppController {
function beforeRender() { function beforeRender() {
parent::beforeRender(); parent::beforeRender();
foreach ($this->viewVars as $key => $value) { foreach ($this->viewVars as $key => $value) {
if (!is_object($value)){ if (!is_object($value)){
$this->viewVars[$key] = h($value); $this->viewVars[$key] = h($value);
} }
} }
} }
} }

View file

@ -282,8 +282,14 @@ class CookieComponent extends Component {
$this->read(); $this->read();
} }
if (strpos($key, '.') === false) { if (strpos($key, '.') === false) {
if (isset($this->_values[$key]) && is_array($this->_values[$key])) {
foreach ($this->_values[$key] as $idx => $val) {
$this->_delete("[$key][$idx]");
}
} else {
$this->_delete("[$key]");
}
unset($this->_values[$key]); unset($this->_values[$key]);
$this->_delete("[$key]");
return; return;
} }
$names = explode('.', $key, 2); $names = explode('.', $key, 2);

View file

@ -19,7 +19,7 @@
App::uses('Component', 'Controller'); App::uses('Component', 'Controller');
App::uses('Multibyte', 'I18n'); App::uses('Multibyte', 'I18n');
App::uses('CakeEmail', 'Network'); App::uses('CakeEmail', 'Network/Email');
/** /**
* EmailComponent * EmailComponent

View file

@ -34,7 +34,6 @@ class RequestHandlerComponent extends Component {
* The layout that will be switched to for Ajax requests * The layout that will be switched to for Ajax requests
* *
* @var string * @var string
* @access public
* @see RequestHandler::setAjax() * @see RequestHandler::setAjax()
*/ */
public $ajaxLayout = 'ajax'; public $ajaxLayout = 'ajax';
@ -43,7 +42,6 @@ class RequestHandlerComponent extends Component {
* Determines whether or not callbacks will be fired on this component * Determines whether or not callbacks will be fired on this component
* *
* @var boolean * @var boolean
* @access public
*/ */
public $enabled = true; public $enabled = true;
@ -51,7 +49,6 @@ class RequestHandlerComponent extends Component {
* Holds the reference to Controller::$request * Holds the reference to Controller::$request
* *
* @var CakeRequest * @var CakeRequest
* @access public
*/ */
public $request; public $request;
@ -59,35 +56,33 @@ class RequestHandlerComponent extends Component {
* Holds the reference to Controller::$response * Holds the reference to Controller::$response
* *
* @var CakeResponse * @var CakeResponse
* @access public
*/ */
public $response; public $response;
/**
* The template to use when rendering the given content type.
*
* @var string
* @access private
*/
private $__renderType = null;
/** /**
* Contains the file extension parsed out by the Router * Contains the file extension parsed out by the Router
* *
* @var string * @var string
* @access public
* @see Router::parseExtensions() * @see Router::parseExtensions()
*/ */
public $ext = null; public $ext = null;
/** /**
* Flag set when MIME types have been initialized * The template to use when rendering the given content type.
* *
* @var boolean * @var string
* @access private
* @see RequestHandler::__initializeTypes()
*/ */
private $__typesInitialized = false; private $__renderType = null;
/**
* A mapping between extensions and deserializers for request bodies of that type.
* By default only JSON and XML are mapped, use RequestHandlerComponent::addInputType()
*
* @var array
*/
private $__inputTypeMap = array(
'json' => array('json_decode', true)
);
/** /**
* Constructor. Parses the accepted content types accepted by the client using HTTP_ACCEPT * Constructor. Parses the accepted content types accepted by the client using HTTP_ACCEPT
@ -96,14 +91,7 @@ class RequestHandlerComponent extends Component {
* @param array $settings Array of settings. * @param array $settings Array of settings.
*/ */
function __construct(ComponentCollection $collection, $settings = array()) { function __construct(ComponentCollection $collection, $settings = array()) {
$this->__acceptTypes = explode(',', env('HTTP_ACCEPT')); $this->addInputType('xml', array(array($this, '_convertXml')));
foreach ($this->__acceptTypes as $i => $type) {
if (strpos($type, ';')) {
$type = explode(';', $type);
$this->__acceptTypes[$i] = $type[0];
}
}
parent::__construct($collection, $settings); parent::__construct($collection, $settings);
} }
@ -124,7 +112,7 @@ class RequestHandlerComponent extends Component {
if (isset($this->request->params['url']['ext'])) { if (isset($this->request->params['url']['ext'])) {
$this->ext = $this->request->params['url']['ext']; $this->ext = $this->request->params['url']['ext'];
} }
if (empty($this->ext)) { if (empty($this->ext) || $this->ext == 'html') {
$accepts = $this->request->accepts(); $accepts = $this->request->accepts();
$extensions = Router::extensions(); $extensions = Router::extensions();
if (count($accepts) == 1) { if (count($accepts) == 1) {
@ -172,19 +160,34 @@ class RequestHandlerComponent extends Component {
$this->respondAs('html', array('charset' => Configure::read('App.encoding'))); $this->respondAs('html', array('charset' => Configure::read('App.encoding')));
} }
if ($this->requestedWith('xml')) { foreach ($this->__inputTypeMap as $type => $handler) {
try { if ($this->requestedWith($type)) {
$xml = Xml::build(trim(file_get_contents('php://input'))); $input = call_user_func_array(array($controller->request, 'input'), $handler);
$controller->request->data = $input;
if (isset($xml->data)) { }
$controller->data = Xml::toArray($xml->data);
} else {
$controller->data = Xml::toArray($xml);
}
} catch (Exception $e) {}
} }
} }
/**
* Helper method to parse xml input data, due to lack of anonymous functions
* this lives here.
*
* @param string $xml
* @return array Xml array data
* @access protected
*/
public function _convertXml($xml) {
try {
$xml = Xml::build($xml);
if (isset($xml->data)) {
return Xml::toArray($xml->data);
}
return Xml::toArray($xml);
} catch (XmlException $e) {
return array();
}
}
/** /**
* Handles (fakes) redirects for Ajax requests using requestAction() * Handles (fakes) redirects for Ajax requests using requestAction()
* *
@ -216,6 +219,7 @@ class RequestHandlerComponent extends Component {
* Returns true if the current HTTP request is Ajax, false otherwise * Returns true if the current HTTP request is Ajax, false otherwise
* *
* @return boolean True if call is Ajax * @return boolean True if call is Ajax
* @deprecated use `$this->request->is('ajax')` instead.
*/ */
public function isAjax() { public function isAjax() {
return $this->request->is('ajax'); return $this->request->is('ajax');
@ -225,6 +229,7 @@ class RequestHandlerComponent extends Component {
* Returns true if the current HTTP request is coming from a Flash-based client * Returns true if the current HTTP request is coming from a Flash-based client
* *
* @return boolean True if call is from Flash * @return boolean True if call is from Flash
* @deprecated use `$this->request->is('flash')` instead.
*/ */
public function isFlash() { public function isFlash() {
return $this->request->is('flash'); return $this->request->is('flash');
@ -234,6 +239,7 @@ class RequestHandlerComponent extends Component {
* Returns true if the current request is over HTTPS, false otherwise. * Returns true if the current request is over HTTPS, false otherwise.
* *
* @return bool True if call is over HTTPS * @return bool True if call is over HTTPS
* @deprecated use `$this->request->is('ssl')` instead.
*/ */
public function isSSL() { public function isSSL() {
return $this->request->is('ssl'); return $this->request->is('ssl');
@ -348,6 +354,7 @@ class RequestHandlerComponent extends Component {
* @param mixed $type The Content-type or array of Content-types assigned to the name, * @param mixed $type The Content-type or array of Content-types assigned to the name,
* i.e. "text/html", or "application/xml" * i.e. "text/html", or "application/xml"
* @return void * @return void
* @deprecated use `$this->response->type()` instead.
*/ */
public function setContent($name, $type = null) { public function setContent($name, $type = null) {
$this->response->type(array($name => $type)); $this->response->type(array($name => $type));
@ -367,7 +374,7 @@ class RequestHandlerComponent extends Component {
* Gets remote client IP * Gets remote client IP
* *
* @return string Client IP address * @return string Client IP address
* @deprecated use $this->request->clientIp() from your controller instead. * @deprecated use $this->request->clientIp() from your, controller instead.
*/ */
public function getClientIP($safe = true) { public function getClientIP($safe = true) {
return $this->request->clientIp($safe); return $this->request->clientIp($safe);
@ -641,4 +648,21 @@ class RequestHandlerComponent extends Component {
} }
return null; return null;
} }
/**
* Add a new mapped input type. Mapped input types are automatically
* converted by RequestHandlerComponent during the startup() callback.
*
* @param string $type The type alias being converted, ie. json
* @param array $handler The handler array for the type. The first index should
* be the handling callback, all other arguments should be additional parameters
* for the handler.
* @return void
*/
public function addInputType($type, $handler) {
if (!is_array($handler) || !isset($handler[0]) || !is_callable($handler[0])) {
throw new CakeException(__d('cake_dev', 'You must give a handler callback.'));
}
$this->__inputTypeMap[$type] = $handler;
}
} }

View file

@ -336,6 +336,7 @@ class Controller extends Object {
/** /**
* Provides backwards compatibility to avoid problems with empty and isset to alias properties. * Provides backwards compatibility to avoid problems with empty and isset to alias properties.
* Lazy loads models using the loadModel() method if declared in $uses
* *
* @return void * @return void
*/ */
@ -349,6 +350,27 @@ class Controller extends Object {
case 'params': case 'params':
return true; return true;
} }
if (is_array($this->uses)) {
foreach ($this->uses as $modelClass) {
list($plugin, $class) = pluginSplit($modelClass, true);
if ($name === $class) {
if (!$plugin) {
$plugin = $this->plugin ? $this->plugin . '.' : null;
}
return $this->loadModel($modelClass);
}
}
}
if ($name === $this->modelClass) {
list($plugin, $class) = pluginSplit($name, true);
if (!$plugin) {
$plugin = $this->plugin ? $this->plugin . '.' : null;
}
return $this->loadModel($plugin . $this->modelClass);
}
return false; return false;
} }
@ -372,6 +394,11 @@ class Controller extends Object {
case 'paginate': case 'paginate':
return $this->Components->load('Paginator')->settings; return $this->Components->load('Paginator')->settings;
} }
if (isset($this->{$name})) {
return $this->{$name};
}
return null; return null;
} }
@ -493,25 +520,9 @@ class Controller extends Object {
public function constructClasses() { public function constructClasses() {
$this->__mergeVars(); $this->__mergeVars();
$this->Components->init($this); $this->Components->init($this);
if ($this->uses) {
if ($this->uses !== null || ($this->uses !== array())) { $this->uses = (array) $this->uses;
if (empty($this->passedArgs) || !isset($this->passedArgs['0'])) { list(, $this->modelClass) = pluginSplit(current($this->uses));
$id = false;
} else {
$id = $this->passedArgs['0'];
}
$plugin = $this->plugin ? $this->plugin . '.' : null;
if ($this->uses === false) {
$this->loadModel($plugin . $this->modelClass, $id);
} elseif ($this->uses) {
$uses = is_array($this->uses) ? $this->uses : array($this->uses);
list($plugin, $modelClassName) = pluginSplit($uses[0]);
$this->modelClass = $modelClassName;
foreach ($uses as $modelClass) {
$this->loadModel($modelClass);
}
}
} }
return true; return true;
} }

View file

@ -62,6 +62,27 @@
*/ */
class App { class App {
/**
* Append paths
*
* @constant APPEND
*/
const APPEND = 'append';
/**
* Prepend paths
*
* @constant PREPEND
*/
const PREPEND = 'prepend';
/**
* Reset paths instead of merging
*
* @constant RESET
*/
const RESET = true;
/** /**
* List of object types and their properties * List of object types and their properties
* *
@ -222,17 +243,17 @@ class App {
* *
* `App::build(array(Model' => array('/a/full/path/to/models/'))); will setup a new search path for the Model package` * `App::build(array(Model' => array('/a/full/path/to/models/'))); will setup a new search path for the Model package`
* *
* `App::build(array('Model' => array('/path/to/models/')), true); will setup the path as the only valid path for searching models` * `App::build(array('Model' => array('/path/to/models/')), App::RESET); will setup the path as the only valid path for searching models`
* *
* `App::build(array('View/Helper' => array('/path/to/models/', '/another/path/))); will setup multiple search paths for helpers` * `App::build(array('View/Helper' => array('/path/to/helpers/', '/another/path/))); will setup multiple search paths for helpers`
* *
* If reset is set to true, all loaded plugins will be forgotten and they will be needed to be loaded again. * If reset is set to true, all loaded plugins will be forgotten and they will be needed to be loaded again.
* *
* @param array $paths associative array with package names as keys and a list of directories for new search paths * @param array $paths associative array with package names as keys and a list of directories for new search paths
* @param boolean $reset true will set paths, false merges paths [default] false * @param mixed $mode App::RESET will set paths, App::APPEND with append paths, App::PREPEND will prepend paths, [default] App::PREPEND
* @return void * @return void
*/ */
public static function build($paths = array(), $reset = false) { public static function build($paths = array(), $mode = App::PREPEND) {
if (empty(self::$__packageFormat)) { if (empty(self::$__packageFormat)) {
self::$__packageFormat = array( self::$__packageFormat = array(
'Model' => array( 'Model' => array(
@ -298,7 +319,7 @@ class App {
); );
} }
if ($reset == true) { if ($mode === App::RESET) {
foreach ($paths as $type => $new) { foreach ($paths as $type => $new) {
if (!empty(self::$legacy[$type])) { if (!empty(self::$legacy[$type])) {
$type = self::$legacy[$type]; $type = self::$legacy[$type];
@ -331,7 +352,11 @@ class App {
} }
if (!empty($paths[$type])) { if (!empty($paths[$type])) {
$path = array_merge((array)$paths[$type], self::$__packages[$type]); if ($mode === App::PREPEND) {
$path = array_merge((array)$paths[$type], self::$__packages[$type]);
} else {
$path = array_merge(self::$__packages[$type], (array)$paths[$type]);
}
} else { } else {
$path = self::$__packages[$type]; $path = self::$__packages[$type];
} }
@ -385,9 +410,7 @@ class App {
* @return string full path to package * @return string full path to package
*/ */
public static function core($type) { public static function core($type) {
if ($type) { return array(LIBS . str_replace('/', DS, $type) . DS);
return isset($paths[$type]) ? $paths[$type] : array(LIBS . $type . DS);
}
} }
/** /**
@ -612,10 +635,10 @@ class App {
return true; return true;
} }
$originalType = $type = strtolower($type); $originalType = strtolower($type);
$specialPackage = in_array($type, array('file', 'vendor')); $specialPackage = in_array($originalType, array('file', 'vendor'));
if (!$specialPackage && isset(self::$legacy[$type . 's'])) { if (!$specialPackage && isset(self::$legacy[$originalType . 's'])) {
$type = self::$legacy[$type . 's']; $type = self::$legacy[$originalType . 's'];
} }
list($plugin, $name) = pluginSplit($name); list($plugin, $name) = pluginSplit($name);
if (!empty($plugin)) { if (!empty($plugin)) {
@ -626,11 +649,11 @@ class App {
return self::_loadClass($name, $plugin, $type, $originalType, $parent); return self::_loadClass($name, $plugin, $type, $originalType, $parent);
} }
if ($type == 'file' && !empty($file)) { if ($originalType == 'file' && !empty($file)) {
return self::_loadFile($name, $plugin, $search, $file, $return); return self::_loadFile($name, $plugin, $search, $file, $return);
} }
if ($type == 'vendor') { if ($originalType == 'vendor') {
return self::_loadVendor($name, $plugin, $file, $ext); return self::_loadVendor($name, $plugin, $file, $ext);
} }

View file

@ -54,13 +54,13 @@ App::uses('AppController', 'Controller');
* *
* This controller method is called instead of the default exception rendering. It receives the * This controller method is called instead of the default exception rendering. It receives the
* thrown exception as its only argument. You should implement your error handling in that method. * thrown exception as its only argument. You should implement your error handling in that method.
* Using AppController::appError(), will superseed any configuration for Exception.renderer. * Using AppController::appError(), will supersede any configuration for Exception.renderer.
* *
* #### Using a custom renderer with `Exception.renderer` * #### Using a custom renderer with `Exception.renderer`
* *
* If you don't want to take control of the exception handling, but want to change how exceptions are * If you don't want to take control of the exception handling, but want to change how exceptions are
* rendered you can use `Exception.renderer` to choose a class to render exception pages. By default * rendered you can use `Exception.renderer` to choose a class to render exception pages. By default
* `ExceptionRenderer` is used. Your custom exception renderer class should be placed in app/libs. * `ExceptionRenderer` is used. Your custom exception renderer class should be placed in app/Lib/Error.
* *
* Your custom renderer should expect an exception in its constructor, and implement a render method. * Your custom renderer should expect an exception in its constructor, and implement a render method.
* Failing to do so will cause additional errors. * Failing to do so will cause additional errors.
@ -116,10 +116,12 @@ class ErrorHandler {
); );
CakeLog::write(LOG_ERR, $message); CakeLog::write(LOG_ERR, $message);
} }
if ($config['renderer'] !== 'ExceptionRenderer') { $renderer = $config['renderer'];
App::uses($config['renderer'], 'Error'); if ($renderer !== 'ExceptionRenderer') {
list($plugin, $renderer) = pluginSplit($renderer, true);
App::uses($renderer, $plugin . 'Error');
} }
$error = new $config['renderer']($exception); $error = new $renderer($exception);
$error->render(); $error->render();
} }

View file

@ -184,7 +184,7 @@ class ExceptionRenderer {
$this->controller->set($error->getAttributes()); $this->controller->set($error->getAttributes());
$this->_outputMessage($this->template); $this->_outputMessage($this->template);
} catch (Exception $e) { } catch (Exception $e) {
$this->_outputMessage('error500'); $this->_outputMessageSafe('error500');
} }
} }
@ -235,4 +235,16 @@ class ExceptionRenderer {
$this->controller->afterFilter(); $this->controller->afterFilter();
$this->controller->response->send(); $this->controller->response->send();
} }
/**
* A safer way to render error messages, replaces all helpers, with basics
* and doesn't call component methods.
*
* @param string $template The template to render
*/
protected function _outputMessageSafe($template) {
$this->controller->helpers = array('Form', 'Html', 'Session');
$this->controller->render($template);
$this->controller->response->send();
}
} }

View file

@ -426,7 +426,7 @@ class TreeBehavior extends ModelBehavior {
* *
* @param AppModel $Model Model instance * @param AppModel $Model Model instance
* @param mixed $id The ID of the record to move * @param mixed $id The ID of the record to move
* @param mixed $number how many places to move the node or true to move to last position * @param int|bool $number how many places to move the node or true to move to last position
* @return boolean true on success, false on failure * @return boolean true on success, false on failure
* @link http://book.cakephp.org/view/1352/moveDown * @link http://book.cakephp.org/view/1352/moveDown
*/ */
@ -484,7 +484,7 @@ class TreeBehavior extends ModelBehavior {
* *
* @param AppModel $Model Model instance * @param AppModel $Model Model instance
* @param mixed $id The ID of the record to move * @param mixed $id The ID of the record to move
* @param mixed $number how many places to move the node, or true to move to first position * @param int|bool $number how many places to move the node, or true to move to first position
* @return boolean true on success, false on failure * @return boolean true on success, false on failure
* @link http://book.cakephp.org/view/1353/moveUp * @link http://book.cakephp.org/view/1353/moveUp
*/ */

View file

@ -390,12 +390,21 @@ class Mysql extends DboSource {
if (empty($conditions)) { if (empty($conditions)) {
$alias = $joins = false; $alias = $joins = false;
} }
$conditions = $this->conditions($this->defaultConditions($model, $conditions, $alias), true, true, $model); $complexConditions = false;
foreach ((array)$conditions as $key => $value) {
if (strpos($key, $model->alias) === false) {
$complexConditions = true;
break;
}
}
if (!$complexConditions) {
$joins = false;
}
$conditions = $this->conditions($this->defaultConditions($model, $conditions, $alias), true, true, $model);
if ($conditions === false) { if ($conditions === false) {
return false; return false;
} }
if ($this->execute($this->renderStatement('delete', compact('alias', 'table', 'joins', 'conditions'))) === false) { if ($this->execute($this->renderStatement('delete', compact('alias', 'table', 'joins', 'conditions'))) === false) {
$model->onError(); $model->onError();
return false; return false;

View file

@ -2650,7 +2650,7 @@ class DboSource extends DataSource {
} }
if (strpos($key, '.')) { if (strpos($key, '.')) {
$key = preg_replace_callback('/([a-zA-Z0-9_]{1,})\\.([a-zA-Z0-9_]{1,})/', array(&$this, '__quoteMatchedField'), $key); $key = preg_replace_callback('/([a-zA-Z0-9_-]{1,})\\.([a-zA-Z0-9_-]{1,})/', array(&$this, '__quoteMatchedField'), $key);
} }
if (!preg_match('/\s/', $key) && strpos($key, '.') === false) { if (!preg_match('/\s/', $key) && strpos($key, '.') === false) {
$key = $this->name($key); $key = $this->name($key);
@ -3146,4 +3146,4 @@ class DboSource extends DataSource {
return false; return false;
} }
} }

View file

@ -106,6 +106,15 @@ class CakeRequest implements ArrayAccess {
'webOS', 'Windows CE', 'Xiino' 'webOS', 'Windows CE', 'Xiino'
)) ))
); );
/**
* Copy of php://input. Since this stream can only be read once in most SAPI's
* keep a copy of it so users don't need to know about that detail.
*
* @var string
*/
private $__input = '';
/** /**
* Constructor * Constructor
* *
@ -133,28 +142,30 @@ class CakeRequest implements ArrayAccess {
/** /**
* process the post data and set what is there into the object. * process the post data and set what is there into the object.
* processed data is available at $this->data
* *
* @return void * @return void
*/ */
protected function _processPost() { protected function _processPost() {
$this->params['form'] = $_POST; $this->data = $_POST;
if (ini_get('magic_quotes_gpc') === '1') { if (ini_get('magic_quotes_gpc') === '1') {
$this->params['form'] = stripslashes_deep($this->params['form']); $this->data = stripslashes_deep($this->data);
} }
if (env('HTTP_X_HTTP_METHOD_OVERRIDE')) { if (env('HTTP_X_HTTP_METHOD_OVERRIDE')) {
$this->params['form']['_method'] = env('HTTP_X_HTTP_METHOD_OVERRIDE'); $this->data['_method'] = env('HTTP_X_HTTP_METHOD_OVERRIDE');
} }
if (isset($this->params['form']['_method'])) { if (isset($this->data['_method'])) {
if (!empty($_SERVER)) { if (!empty($_SERVER)) {
$_SERVER['REQUEST_METHOD'] = $this->params['form']['_method']; $_SERVER['REQUEST_METHOD'] = $this->data['_method'];
} else { } else {
$_ENV['REQUEST_METHOD'] = $this->params['form']['_method']; $_ENV['REQUEST_METHOD'] = $this->data['_method'];
} }
unset($this->params['form']['_method']); unset($this->data['_method']);
} }
if (isset($this->params['form']['data'])) { if (isset($this->data['data'])) {
$this->data = $this->params['form']['data']; $data = $this->data['data'];
unset($this->params['form']['data']); unset($this->data['data']);
$this->data = Set::merge($this->data, $data);
} }
} }
@ -480,7 +491,7 @@ class CakeRequest implements ArrayAccess {
* @return The current object, you can chain this method. * @return The current object, you can chain this method.
*/ */
public function addParams($params) { public function addParams($params) {
$this->params = array_merge($this->params, $params); $this->params = array_merge($this->params, (array)$params);
return $this; return $this;
} }
@ -533,6 +544,14 @@ class CakeRequest implements ArrayAccess {
/** /**
* Get the HTTP method used for this request. * Get the HTTP method used for this request.
* There are a few ways to specify a method.
*
* - If your client supports it you can use native HTTP methods.
* - You can set the HTTP-X-Method-Override header.
* - You can submit an input with the name `_method`
*
* Any of these 3 approaches can be used to set the HTTP method used
* by CakePHP internally, and will effect the result of this method.
* *
* @return string The name of the HTTP method used. * @return string The name of the HTTP method used.
*/ */
@ -662,6 +681,51 @@ class CakeRequest implements ArrayAccess {
return Set::classicExtract($this->data, $name); return Set::classicExtract($this->data, $name);
} }
/**
* Read data from `php://stdin`. Useful when interacting with XML or JSON
* request body content.
*
* Getting input with a decoding function:
*
* `$this->request->input('json_decode');`
*
* Getting input using a decoding function, and additional params:
*
* `$this->request->input('Xml::build', array('return' => 'DOMDocument'));`
*
* Any additional parameters are applied to the callback in the order they are given.
*
* @param string $callback A decoding callback that will convert the string data to another
* representation. Leave empty to access the raw input data. You can also
* supply additional parameters for the decoding callback using var args, see above.
* @return The decoded/processed request data.
*/
public function input($callback = null) {
$input = $this->_readStdin();
$args = func_get_args();
if (!empty($args)) {
$callback = array_shift($args);
array_unshift($args, $input);
return call_user_func_array($callback, $args);
}
return $input;
}
/**
* Read data from php://stdin, mocked in tests.
*
* @return string contents of stdin
*/
protected function _readStdin() {
if (empty($this->__input)) {
$fh = fopen('php://input', 'r');
$content = stream_get_contents($fh);
fclose($fh);
$this->__input = $content;
}
return $this->__input;
}
/** /**
* Array access read implementation * Array access read implementation
* *
@ -711,4 +775,4 @@ class CakeRequest implements ArrayAccess {
public function offsetUnset($name) { public function offsetUnset($name) {
unset($this->params[$name]); unset($this->params[$name]);
} }
} }

View file

@ -199,8 +199,14 @@ class CakeSocket {
return false; return false;
} }
} }
$totalBytes = strlen($data);
return fwrite($this->connection, $data, strlen($data)); for ($written = 0, $rv = 0; $written < $totalBytes; $written += $rv) {
$rv = fwrite($this->connection, substr($data, $written));
if ($rv === false || $rv === 0) {
return $written;
}
}
return $written;
} }
/** /**

View file

@ -277,7 +277,7 @@ class CakeEmail {
* @param mixed $email * @param mixed $email
* @param string $name * @param string $name
* @return mixed * @return mixed
* @thrown SocketException * @throws SocketException
*/ */
public function from($email = null, $name = null) { public function from($email = null, $name = null) {
if ($email === null) { if ($email === null) {
@ -292,7 +292,7 @@ class CakeEmail {
* @param mixed $email * @param mixed $email
* @param string $name * @param string $name
* @return mixed * @return mixed
* @thrown SocketException * @throws SocketException
*/ */
public function sender($email = null, $name = null) { public function sender($email = null, $name = null) {
if ($email === null) { if ($email === null) {
@ -307,7 +307,7 @@ class CakeEmail {
* @param mixed $email * @param mixed $email
* @param string $name * @param string $name
* @return mixed * @return mixed
* @thrown SocketException * @throws SocketException
*/ */
public function replyTo($email = null, $name = null) { public function replyTo($email = null, $name = null) {
if ($email === null) { if ($email === null) {
@ -322,7 +322,7 @@ class CakeEmail {
* @param mixed $email * @param mixed $email
* @param string $name * @param string $name
* @return mixed * @return mixed
* @thrown SocketException * @throws SocketException
*/ */
public function readReceipt($email = null, $name = null) { public function readReceipt($email = null, $name = null) {
if ($email === null) { if ($email === null) {
@ -337,7 +337,7 @@ class CakeEmail {
* @param mixed $email * @param mixed $email
* @param string $name * @param string $name
* @return mixed * @return mixed
* @thrown SocketException * @throws SocketException
*/ */
public function returnPath($email = null, $name = null) { public function returnPath($email = null, $name = null) {
if ($email === null) { if ($email === null) {
@ -428,7 +428,7 @@ class CakeEmail {
* @param mixed $email * @param mixed $email
* @param mixed $name * @param mixed $name
* @return object $this * @return object $this
* @thrown SocketException * @throws SocketException
*/ */
protected function _setEmail($varName, $email, $name) { protected function _setEmail($varName, $email, $name) {
if (!is_array($email)) { if (!is_array($email)) {
@ -463,7 +463,7 @@ class CakeEmail {
* @param string $name * @param string $name
* @param string $throwMessage * @param string $throwMessage
* @return object $this * @return object $this
* @thrown SocketExpceiton * @throws SocketExpceiton
*/ */
protected function _setEmailSingle($varName, $email, $name, $throwMessage) { protected function _setEmailSingle($varName, $email, $name, $throwMessage) {
$current = $this->{$varName}; $current = $this->{$varName};
@ -527,7 +527,7 @@ class CakeEmail {
* *
* @param array Associative array containing headers to be set. * @param array Associative array containing headers to be set.
* @return object $this * @return object $this
* @thrown SocketException * @throws SocketException
*/ */
public function setHeaders($headers) { public function setHeaders($headers) {
if (!is_array($headers)) { if (!is_array($headers)) {
@ -542,7 +542,7 @@ class CakeEmail {
* *
* @param array $headers * @param array $headers
* @return mixed $this * @return mixed $this
* @thrown SocketException * @throws SocketException
*/ */
public function addHeaders($headers) { public function addHeaders($headers) {
if (!is_array($headers)) { if (!is_array($headers)) {
@ -720,7 +720,7 @@ class CakeEmail {
* *
* @param string $format * @param string $format
* @return mixed * @return mixed
* @thrown SocketException * @throws SocketException
*/ */
public function emailFormat($format = null) { public function emailFormat($format = null) {
if ($format === null) { if ($format === null) {
@ -752,7 +752,7 @@ class CakeEmail {
* Return the transport class * Return the transport class
* *
* @return object * @return object
* @thrown SocketException * @throws SocketException
*/ */
public function transportClass() { public function transportClass() {
if ($this->_transportClass) { if ($this->_transportClass) {
@ -775,7 +775,7 @@ class CakeEmail {
* *
* @param mixed $message True to generate a new Message-ID, False to ignore (not send in email), String to set as Message-ID * @param mixed $message True to generate a new Message-ID, False to ignore (not send in email), String to set as Message-ID
* @return mixed * @return mixed
* @thrown SocketException * @throws SocketException
*/ */
public function messageId($message = null) { public function messageId($message = null) {
if ($message === null) { if ($message === null) {
@ -797,7 +797,7 @@ class CakeEmail {
* *
* @param mixed $attachments String with the filename or array with filenames * @param mixed $attachments String with the filename or array with filenames
* @return mixed * @return mixed
* @thrown SocketException * @throws SocketException
*/ */
public function attachments($attachments = null) { public function attachments($attachments = null) {
if ($attachments === null) { if ($attachments === null) {
@ -832,7 +832,7 @@ class CakeEmail {
* *
* @param mixed $attachments String with the filename or array with filenames * @param mixed $attachments String with the filename or array with filenames
* @return object $this * @return object $this
* @thrown SocketException * @throws SocketException
*/ */
public function addAttachments($attachments) { public function addAttachments($attachments) {
$current = $this->_attachments; $current = $this->_attachments;
@ -885,7 +885,7 @@ class CakeEmail {
* Send an email using the specified content, template and layout * Send an email using the specified content, template and layout
* *
* @return boolean Success * @return boolean Success
* @thrown SocketException * @throws SocketException
*/ */
public function send($content = null) { public function send($content = null) {
if (is_string($this->_config)) { if (is_string($this->_config)) {

View file

@ -44,7 +44,7 @@ class SmtpTransport extends AbstractTransport {
* *
* @params object $email CakeEmail * @params object $email CakeEmail
* @return boolean * @return boolean
* @thrown SocketException * @throws SocketException
*/ */
public function send(CakeEmail $email) { public function send(CakeEmail $email) {
$this->_cakeEmail = $email; $this->_cakeEmail = $email;
@ -80,7 +80,7 @@ class SmtpTransport extends AbstractTransport {
* Connect to SMTP Server * Connect to SMTP Server
* *
* @return void * @return void
* @thrown SocketException * @throws SocketException
*/ */
protected function _connect() { protected function _connect() {
$this->_generateSocket(); $this->_generateSocket();
@ -112,7 +112,7 @@ class SmtpTransport extends AbstractTransport {
* Send authentication * Send authentication
* *
* @return void * @return void
* @thrown SocketException * @throws SocketException
*/ */
protected function _auth() { protected function _auth() {
if (isset($this->_config['username']) && isset($this->_config['password'])) { if (isset($this->_config['username']) && isset($this->_config['password'])) {
@ -134,7 +134,7 @@ class SmtpTransport extends AbstractTransport {
* Send emails * Send emails
* *
* @return void * @return void
* @thrown SocketException * @throws SocketException
*/ */
protected function _sendRcpt() { protected function _sendRcpt() {
$from = $this->_cakeEmail->from(); $from = $this->_cakeEmail->from();
@ -153,7 +153,7 @@ class SmtpTransport extends AbstractTransport {
* Send Data * Send Data
* *
* @return void * @return void
* @thrown SocketException * @throws SocketException
*/ */
protected function _sendData() { protected function _sendData() {
$this->_smtpSend('DATA', '354'); $this->_smtpSend('DATA', '354');
@ -168,7 +168,7 @@ class SmtpTransport extends AbstractTransport {
* Disconnect * Disconnect
* *
* @return void * @return void
* @thrown SocketException * @throws SocketException
*/ */
protected function _disconnect() { protected function _disconnect() {
$this->_smtpSend('QUIT', false); $this->_smtpSend('QUIT', false);
@ -179,7 +179,7 @@ class SmtpTransport extends AbstractTransport {
* Helper method to generate socket * Helper method to generate socket
* *
* @return void * @return void
* @thrown SocketException * @throws SocketException
*/ */
protected function _generateSocket() { protected function _generateSocket() {
$this->_socket = new CakeSocket($this->_config); $this->_socket = new CakeSocket($this->_config);
@ -191,7 +191,7 @@ class SmtpTransport extends AbstractTransport {
* @param string $data data to be sent to SMTP server * @param string $data data to be sent to SMTP server
* @param mixed $checkCode code to check for in server response, false to skip * @param mixed $checkCode code to check for in server response, false to skip
* @return void * @return void
* @thrown SocketException * @throws SocketException
*/ */
function _smtpSend($data, $checkCode = '250') { function _smtpSend($data, $checkCode = '250') {
if (!is_null($data)) { if (!is_null($data)) {

View file

@ -128,7 +128,7 @@ class HttpSocket extends CakeSocket {
* You can use a url string to set the url and use default configurations for * You can use a url string to set the url and use default configurations for
* all other options: * all other options:
* *
* `$http = new HttpSockect('http://cakephp.org/');` * `$http = new HttpSocket('http://cakephp.org/');`
* *
* Or use an array to configure multiple options: * Or use an array to configure multiple options:
* *
@ -405,7 +405,7 @@ class HttpSocket extends CakeSocket {
*/ */
public function get($uri = null, $query = array(), $request = array()) { public function get($uri = null, $query = array(), $request = array()) {
if (!empty($query)) { if (!empty($query)) {
$uri = $this->_parseUri($uri); $uri = $this->_parseUri($uri, $this->config['request']['uri']);
if (isset($uri['query'])) { if (isset($uri['query'])) {
$uri['query'] = array_merge($uri['query'], $query); $uri['query'] = array_merge($uri['query'], $query);
} else { } else {

View file

@ -543,9 +543,6 @@ class Router {
} }
} }
} }
if (empty($ext)) {
$ext = 'html';
}
} }
return compact('ext', 'url'); return compact('ext', 'url');
} }

View file

@ -70,7 +70,7 @@ class CakeTestFixture {
public function init() { public function init() {
if (isset($this->import) && (is_string($this->import) || is_array($this->import))) { if (isset($this->import) && (is_string($this->import) || is_array($this->import))) {
$import = array_merge( $import = array_merge(
array('connection' => 'default', 'records' => false), array('connection' => 'default', 'records' => false),
is_array($this->import) ? $this->import : array('model' => $this->import) is_array($this->import) ? $this->import : array('model' => $this->import)
); );
@ -178,9 +178,15 @@ class CakeTestFixture {
if (!isset($this->_insert)) { if (!isset($this->_insert)) {
$values = array(); $values = array();
if (isset($this->records) && !empty($this->records)) { if (isset($this->records) && !empty($this->records)) {
$fields = array();
foreach($this->records as $record) {
$fields = array_merge($fields, array_keys(array_intersect_key($record, $this->fields)));
}
$fields = array_unique($fields);
$default = array_fill_keys($fields, null);
foreach ($this->records as $record) { foreach ($this->records as $record) {
$fields = array_keys($record); $fields = array_keys($record);
$values[] = array_values($record); $values[] = array_values(array_merge($default, $record));
} }
return $db->insertMulti($this->table, $fields, $values); return $db->insertMulti($this->table, $fields, $values);
} }
@ -188,6 +194,7 @@ class CakeTestFixture {
} }
} }
/** /**
* Truncates the current fixture. Can be overwritten by classes extending CakeFixture to trigger other events before / after * Truncates the current fixture. Can be overwritten by classes extending CakeFixture to trigger other events before / after
* truncate. * truncate.

View file

@ -68,12 +68,13 @@ class ClassRegistry {
} }
/** /**
* Loads a class, registers the object in the registry and returns instance of the object. * Loads a class, registers the object in the registry and returns instance of the object. ClassRegistry::init()
* is used as a factory for models, and handle correct injecting of settings, that assist in testing.
* *
* Examples * Examples
* Simple Use: Get a Post model instance ```ClassRegistry::init('Post');``` * Simple Use: Get a Post model instance ```ClassRegistry::init('Post');```
* *
* Exapanded: ```array('class' => 'ClassName', 'alias' => 'AliasNameStoredInTheRegistry', 'type' => 'TypeOfClass');``` * Exapanded: ```array('class' => 'ClassName', 'alias' => 'AliasNameStoredInTheRegistry', 'type' => 'Model');```
* *
* Model Classes can accept optional ```array('id' => $id, 'table' => $table, 'ds' => $ds, 'alias' => $alias);``` * Model Classes can accept optional ```array('id' => $id, 'table' => $table, 'ds' => $ds, 'alias' => $alias);```
* *
@ -81,14 +82,14 @@ class ClassRegistry {
* no instance of the object will be returned * no instance of the object will be returned
* {{{ * {{{
* array( * array(
* array('class' => 'ClassName', 'alias' => 'AliasNameStoredInTheRegistry', 'type' => 'TypeOfClass'), * array('class' => 'ClassName', 'alias' => 'AliasNameStoredInTheRegistry', 'type' => 'Model'),
* array('class' => 'ClassName', 'alias' => 'AliasNameStoredInTheRegistry', 'type' => 'TypeOfClass'), * array('class' => 'ClassName', 'alias' => 'AliasNameStoredInTheRegistry', 'type' => 'Model'),
* array('class' => 'ClassName', 'alias' => 'AliasNameStoredInTheRegistry', 'type' => 'TypeOfClass') * array('class' => 'ClassName', 'alias' => 'AliasNameStoredInTheRegistry', 'type' => 'Model')
* ); * );
* }}} * }}}
* @param mixed $class as a string or a single key => value array instance will be created, * @param mixed $class as a string or a single key => value array instance will be created,
* stored in the registry and returned. * stored in the registry and returned.
* @param string $type TypeOfClass * @param string $type Only model is accepted as a valid value for $type.
* @return object instance of ClassName * @return object instance of ClassName
*/ */
public static function &init($class, $type = null) { public static function &init($class, $type = null) {

View file

@ -176,7 +176,6 @@ class Debugger {
if (!$instance || strtolower($class) != strtolower(get_class($instance[0]))) { if (!$instance || strtolower($class) != strtolower(get_class($instance[0]))) {
$instance[0] = new $class(); $instance[0] = new $class();
if (Configure::read('debug') > 0) { if (Configure::read('debug') > 0) {
Configure::version(); // Make sure the core config is loaded
$instance[0]->helpPath = Configure::read('Cake.Debugger.HelpPath'); $instance[0]->helpPath = Configure::read('Cake.Debugger.HelpPath');
} }
} }
@ -185,7 +184,6 @@ class Debugger {
if (!$instance) { if (!$instance) {
$instance[0] = new Debugger(); $instance[0] = new Debugger();
if (Configure::read('debug') > 0) { if (Configure::read('debug') > 0) {
Configure::version(); // Make sure the core config is loaded
$instance[0]->helpPath = Configure::read('Cake.Debugger.HelpPath'); $instance[0]->helpPath = Configure::read('Cake.Debugger.HelpPath');
} }
} }
@ -609,7 +607,7 @@ class Debugger {
$this->_outputFormat = 'js'; $this->_outputFormat = 'js';
} }
$data['id'] = 'cakeErr' . count($this->errors); $data['id'] = 'cakeErr' . uniqid();
$tpl = array_merge($this->_templates['base'], $this->_templates[$this->_outputFormat]); $tpl = array_merge($this->_templates['base'], $this->_templates[$this->_outputFormat]);
$insert = array('context' => join("\n", $context), 'helpPath' => $this->helpPath) + $data; $insert = array('context' => join("\n", $context), 'helpPath' => $this->helpPath) + $data;

View file

@ -63,7 +63,7 @@ class Sanitize {
* @return string SQL safe string * @return string SQL safe string
*/ */
public static function escape($string, $connection = 'default') { public static function escape($string, $connection = 'default') {
$db =& ConnectionManager::getDataSource($connection); $db = ConnectionManager::getDataSource($connection);
if (is_numeric($string) || $string === null || is_bool($string)) { if (is_numeric($string) || $string === null || is_bool($string)) {
return $string; return $string;
} }
@ -266,9 +266,9 @@ class Sanitize {
public static function formatColumns($model) { public static function formatColumns($model) {
foreach ($model->data as $name => $values) { foreach ($model->data as $name => $values) {
if ($name == $model->alias) { if ($name == $model->alias) {
$curModel =& $model; $curModel = $model;
} elseif (isset($model->{$name}) && is_object($model->{$name}) && is_subclass_of($model->{$name}, 'Model')) { } elseif (isset($model->{$name}) && is_object($model->{$name}) && is_subclass_of($model->{$name}, 'Model')) {
$curModel =& $model->{$name}; $curModel = $model->{$name};
} else { } else {
$curModel = null; $curModel = null;
} }
@ -278,7 +278,7 @@ class Sanitize {
$colType = $curModel->getColumnType($column); $colType = $curModel->getColumnType($column);
if ($colType != null) { if ($colType != null) {
$db =& ConnectionManager::getDataSource($curModel->useDbConfig); $db = ConnectionManager::getDataSource($curModel->useDbConfig);
$colData = $db->columns[$colType]; $colData = $db->columns[$colType];
if (isset($colData['limit']) && strlen(strval($data)) > $colData['limit']) { if (isset($colData['limit']) && strlen(strval($data)) > $colData['limit']) {

View file

@ -421,6 +421,13 @@ class Set {
'key' => $key, 'key' => $key,
'item' => array_keys($context['item']), 'item' => array_keys($context['item']),
); );
} elseif (($key === $token || (ctype_digit($token) && $key == $token) || $token === '.')) {
$context['trace'][] = $key;
$matches[] = array(
'trace' => $context['trace'],
'key' => $key,
'item' => $context['item'],
);
} elseif (is_array($context['item']) && array_key_exists($token, $context['item'])) { } elseif (is_array($context['item']) && array_key_exists($token, $context['item'])) {
$items = $context['item'][$token]; $items = $context['item'][$token];
if (!is_array($items)) { if (!is_array($items)) {
@ -460,13 +467,6 @@ class Set {
'item' => $item, 'item' => $item,
); );
} }
} elseif (($key === $token || (ctype_digit($token) && $key == $token) || $token === '.')) {
$context['trace'][] = $key;
$matches[] = array(
'trace' => $context['trace'],
'key' => $key,
'item' => $context['item'],
);
} }
} }
if ($conditions) { if ($conditions) {

View file

@ -692,7 +692,7 @@ class Helper extends Object {
$result = $data[$habtmKey][$habtmKey]; $result = $data[$habtmKey][$habtmKey];
} elseif (empty($result) && isset($data[$habtmKey]) && is_array($data[$habtmKey])) { } elseif (empty($result) && isset($data[$habtmKey]) && is_array($data[$habtmKey])) {
if (ClassRegistry::isKeySet($habtmKey)) { if (ClassRegistry::isKeySet($habtmKey)) {
$model =& ClassRegistry::getObject($habtmKey); $model = ClassRegistry::getObject($habtmKey);
$result = $this->__selectedArray($data[$habtmKey], $model->primaryKey); $result = $this->__selectedArray($data[$habtmKey], $model->primaryKey);
} }
} }

View file

@ -204,7 +204,7 @@ class FormHelper extends AppHelper {
$models = ClassRegistry::keys(); $models = ClassRegistry::keys();
foreach ($models as $currentModel) { foreach ($models as $currentModel) {
if (ClassRegistry::isKeySet($currentModel)) { if (ClassRegistry::isKeySet($currentModel)) {
$currentObject =& ClassRegistry::getObject($currentModel); $currentObject = ClassRegistry::getObject($currentModel);
if (is_a($currentObject, 'Model') && !empty($currentObject->validationErrors)) { if (is_a($currentObject, 'Model') && !empty($currentObject->validationErrors)) {
$this->validationErrors[Inflector::camelize($currentModel)] =& $currentObject->validationErrors; $this->validationErrors[Inflector::camelize($currentModel)] =& $currentObject->validationErrors;
} }
@ -695,7 +695,9 @@ class FormHelper extends AppHelper {
* ### Options * ### Options
* *
* See each field type method for more information. Any options that are part of * See each field type method for more information. Any options that are part of
* $attributes or $options for the different **type** methods can be included in `$options` for input(). * $attributes or $options for the different **type** methods can be included in `$options` for input().i
* Additionally, any unknown keys that are not in the list below, or part of the selected type's options
* will be treated as a regular html attribute for the generated input.
* *
* - `type` - Force the type of widget you want. e.g. `type => 'select'` * - `type` - Force the type of widget you want. e.g. `type => 'select'`
* - `label` - Either a string label, or an array of options for the label. See FormHelper::label() * - `label` - Either a string label, or an array of options for the label. See FormHelper::label()
@ -1498,14 +1500,16 @@ class FormHelper extends AppHelper {
'escape' => true, 'escape' => true,
'secure' => null, 'secure' => null,
'empty' => '', 'empty' => '',
'showParents' => false 'showParents' => false,
'hiddenField' => true
); );
$escapeOptions = $this->_extractOption('escape', $attributes); $escapeOptions = $this->_extractOption('escape', $attributes);
$secure = $this->_extractOption('secure', $attributes); $secure = $this->_extractOption('secure', $attributes);
$showEmpty = $this->_extractOption('empty', $attributes); $showEmpty = $this->_extractOption('empty', $attributes);
$showParents = $this->_extractOption('showParents', $attributes); $showParents = $this->_extractOption('showParents', $attributes);
unset($attributes['escape'], $attributes['secure'], $attributes['empty'], $attributes['showParents']); $hiddenField = $this->_extractOption('hiddenField', $attributes);
unset($attributes['escape'], $attributes['secure'], $attributes['empty'], $attributes['showParents'], $attributes['hiddenField']);
$attributes = $this->_initInputField($fieldName, array_merge( $attributes = $this->_initInputField($fieldName, array_merge(
(array)$attributes, array('secure' => false) (array)$attributes, array('secure' => false)
@ -1520,19 +1524,25 @@ class FormHelper extends AppHelper {
unset($attributes['type']); unset($attributes['type']);
} }
if (isset($attributes) && array_key_exists('multiple', $attributes)) { if (!isset($selected)) {
$selected = $attributes['value'];
}
if (!empty($attributes['multiple'])) {
$style = ($attributes['multiple'] === 'checkbox') ? 'checkbox' : null; $style = ($attributes['multiple'] === 'checkbox') ? 'checkbox' : null;
$template = ($style) ? 'checkboxmultiplestart' : 'selectmultiplestart'; $template = ($style) ? 'checkboxmultiplestart' : 'selectmultiplestart';
$tag = $template; $tag = $template;
$hiddenAttributes = array( if ($hiddenField) {
'value' => '', $hiddenAttributes = array(
'id' => $attributes['id'] . ($style ? '' : '_'), 'value' => '',
'secure' => false, 'id' => $attributes['id'] . ($style ? '' : '_'),
'name' => $attributes['name'] 'secure' => false,
); 'name' => $attributes['name']
$select[] = $this->hidden(null, $hiddenAttributes); );
$select[] = $this->hidden(null, $hiddenAttributes);
}
} else { } else {
$tag = 'selectstart'; $tag = 'selectstart';
} }
if (!empty($tag) || isset($template)) { if (!empty($tag) || isset($template)) {
@ -1809,7 +1819,7 @@ class FormHelper extends AppHelper {
$attributes['value'] = $meridian; $attributes['value'] = $meridian;
} else { } else {
if (empty($value)) { if (empty($value)) {
if (!$attribues['empty']) { if (!$attributes['empty']) {
$attributes['value'] = date('a'); $attributes['value'] = date('a');
} }
} else { } else {

View file

@ -27,13 +27,6 @@ App::uses('AppHelper', 'View/Helper');
* @package cake.view.helpers * @package cake.view.helpers
*/ */
abstract class JsBaseEngineHelper extends AppHelper { abstract class JsBaseEngineHelper extends AppHelper {
/**
* Determines whether native JSON extension is used for encoding. Set by object constructor.
*
* @var boolean
* @access public
*/
public $useNative = false;
/** /**
* The js snippet for the current selection. * The js snippet for the current selection.
@ -76,7 +69,6 @@ abstract class JsBaseEngineHelper extends AppHelper {
*/ */
function __construct($View, $settings = array()) { function __construct($View, $settings = array()) {
parent::__construct($View, $settings); parent::__construct($View, $settings);
$this->useNative = function_exists('json_encode');
} }
/** /**
@ -154,50 +146,7 @@ abstract class JsBaseEngineHelper extends AppHelper {
); );
$options = array_merge($defaultOptions, $options); $options = array_merge($defaultOptions, $options);
if (is_object($data)) { return $options['prefix'] . json_encode($data) . $options['postfix'];
$data = get_object_vars($data);
}
$out = $keys = array();
$numeric = true;
if ($this->useNative && function_exists('json_encode')) {
$rt = json_encode($data);
} else {
if (is_null($data)) {
return 'null';
}
if (is_bool($data)) {
return $data ? 'true' : 'false';
}
if (is_array($data)) {
$keys = array_keys($data);
}
if (!empty($keys)) {
$numeric = (array_values($keys) === array_keys(array_values($keys)));
}
foreach ($data as $key => $val) {
if (is_array($val) || is_object($val)) {
$val = $this->object($val);
} else {
$val = $this->value($val);
}
if (!$numeric) {
$val = '"' . $this->value($key, false) . '":' . $val;
}
$out[] = $val;
}
if (!$numeric) {
$rt = '{' . join(',', $out) . '}';
} else {
$rt = '[' . join(',', $out) . ']';
}
}
$rt = $options['prefix'] . $rt . $options['postfix'];
return $rt;
} }
/** /**

View file

@ -179,10 +179,10 @@ class TextHelper extends AppHelper {
$this->_linkOptions = $options; $this->_linkOptions = $options;
$atom = '[a-z0-9!#$%&\'*+\/=?^_`{|}~-]'; $atom = '[a-z0-9!#$%&\'*+\/=?^_`{|}~-]';
return preg_replace_callback( return preg_replace_callback(
'/(' . $atom . '+(?:\.' . $atom . '+)*@[a-z0-9-]+(?:\.[a-z0-9-]+)*)/i', '/(' . $atom . '+(?:\.' . $atom . '+)*@[a-z0-9-]+(?:\.[a-z0-9-]+)+)/i',
array(&$this, '_linkEmails'), array(&$this, '_linkEmails'),
$text $text
); );
} }
/** /**

View file

@ -618,33 +618,33 @@ class TimeHelper extends AppHelper {
} else { } else {
if ($years > 0) { if ($years > 0) {
// years and months and days // years and months and days
$relativeDate .= ($relativeDate ? ', ' : '') . $years . ' ' . __dn('cake', 'year', 'years', $years); $relativeDate .= ($relativeDate ? ', ' : '') . __dn('cake', '%d year', '%d years', $years, $years);
$relativeDate .= $months > 0 ? ($relativeDate ? ', ' : '') . $months . ' ' . __dn('cake', 'month', 'months', $months) : ''; $relativeDate .= $months > 0 ? ($relativeDate ? ', ' : '') . __dn('cake', '%d month', '%d months', $months, $months) : '';
$relativeDate .= $weeks > 0 ? ($relativeDate ? ', ' : '') . $weeks . ' ' . __dn('cake', 'week', 'weeks', $weeks) : ''; $relativeDate .= $weeks > 0 ? ($relativeDate ? ', ' : '') . __dn('cake', '%d week', '%d weeks', $weeks, $weeks) : '';
$relativeDate .= $days > 0 ? ($relativeDate ? ', ' : '') . $days . ' ' . __dn('cake', 'day', 'days', $days) : ''; $relativeDate .= $days > 0 ? ($relativeDate ? ', ' : '') . __dn('cake', '%d day', '%d days', $days, $days) : '';
} elseif (abs($months) > 0) { } elseif (abs($months) > 0) {
// months, weeks and days // months, weeks and days
$relativeDate .= ($relativeDate ? ', ' : '') . $months . ' ' . __dn('cake', 'month', 'months', $months); $relativeDate .= ($relativeDate ? ', ' : '') . __dn('cake', '%d month', '%d months', $months, $months);
$relativeDate .= $weeks > 0 ? ($relativeDate ? ', ' : '') . $weeks . ' ' . __dn('cake', 'week', 'weeks', $weeks) : ''; $relativeDate .= $weeks > 0 ? ($relativeDate ? ', ' : '') . __dn('cake', '%d week', '%d weeks', $weeks, $weeks) : '';
$relativeDate .= $days > 0 ? ($relativeDate ? ', ' : '') . $days . ' ' . __dn('cake', 'day', 'days', $days) : ''; $relativeDate .= $days > 0 ? ($relativeDate ? ', ' : '') . __dn('cake', '%d day', '%d days', $days, $days) : '';
} elseif (abs($weeks) > 0) { } elseif (abs($weeks) > 0) {
// weeks and days // weeks and days
$relativeDate .= ($relativeDate ? ', ' : '') . $weeks . ' ' . __dn('cake', 'week', 'weeks', $weeks); $relativeDate .= ($relativeDate ? ', ' : '') . __dn('cake', '%d week', '%d weeks', $weeks, $weeks);
$relativeDate .= $days > 0 ? ($relativeDate ? ', ' : '') . $days . ' ' . __dn('cake', 'day', 'days', $days) : ''; $relativeDate .= $days > 0 ? ($relativeDate ? ', ' : '') . __dn('cake', '%d day', '%d days', $days, $days) : '';
} elseif (abs($days) > 0) { } elseif (abs($days) > 0) {
// days and hours // days and hours
$relativeDate .= ($relativeDate ? ', ' : '') . $days . ' ' . __dn('cake', 'day', 'days', $days); $relativeDate .= ($relativeDate ? ', ' : '') . __dn('cake', '%d day', '%d days', $days, $days);
$relativeDate .= $hours > 0 ? ($relativeDate ? ', ' : '') . $hours . ' ' . __dn('cake', 'hour', 'hours', $hours) : ''; $relativeDate .= $hours > 0 ? ($relativeDate ? ', ' : '') . __dn('cake', '%d hour', '%d hours', $hours, $hours) : '';
} elseif (abs($hours) > 0) { } elseif (abs($hours) > 0) {
// hours and minutes // hours and minutes
$relativeDate .= ($relativeDate ? ', ' : '') . $hours . ' ' . __dn('cake', 'hour', 'hours', $hours); $relativeDate .= ($relativeDate ? ', ' : '') . __dn('cake', '%d hour', '%d hours', $hours, $hours);
$relativeDate .= $minutes > 0 ? ($relativeDate ? ', ' : '') . $minutes . ' ' . __dn('cake', 'minute', 'minutes', $minutes) : ''; $relativeDate .= $minutes > 0 ? ($relativeDate ? ', ' : '') . __dn('cake', '%d minute', '%d minutes', $minutes, $minutes) : '';
} elseif (abs($minutes) > 0) { } elseif (abs($minutes) > 0) {
// minutes only // minutes only
$relativeDate .= ($relativeDate ? ', ' : '') . $minutes . ' ' . __dn('cake', 'minute', 'minutes', $minutes); $relativeDate .= ($relativeDate ? ', ' : '') . __dn('cake', '%d minute', '%d minutes', $minutes, $minutes);
} else { } else {
// seconds only // seconds only
$relativeDate .= ($relativeDate ? ', ' : '') . $seconds . ' ' . __dn('cake', 'second', 'seconds', $seconds); $relativeDate .= ($relativeDate ? ', ' : '') . __dn('cake', '%d second', '%d seconds', $seconds, $seconds);
} }
if (!$backwards) { if (!$backwards) {
@ -752,4 +752,4 @@ class TimeHelper extends AppHelper {
$format = $this->convertSpecifiers($format, $date); $format = $this->convertSpecifiers($format, $date);
return strftime($format, $date); return strftime($format, $date);
} }
} }

View file

@ -25,7 +25,7 @@ if ($noLogs):
$logs = array(); $logs = array();
foreach ($sources as $source): foreach ($sources as $source):
$db =& ConnectionManager::getDataSource($source); $db = ConnectionManager::getDataSource($source);
if (!method_exists($db, 'getLog')): if (!method_exists($db, 'getLog')):
continue; continue;
endif; endif;

View file

@ -1,4 +1,5 @@
<?php <?php
/** /**
* Basic Cake functionality. * Basic Cake functionality.
* *
@ -40,25 +41,25 @@
* @return boolean Success * @return boolean Success
* @link http://book.cakephp.org/view/1125/config * @link http://book.cakephp.org/view/1125/config
*/ */
function config() { function config() {
$args = func_get_args(); $args = func_get_args();
foreach ($args as $arg) { foreach ($args as $arg) {
if ($arg === 'database' && file_exists(CONFIGS . 'database.php')) { if ($arg === 'database' && file_exists(CONFIGS . 'database.php')) {
include_once(CONFIGS . $arg . '.php'); include_once(CONFIGS . $arg . '.php');
} elseif (file_exists(CONFIGS . $arg . '.php')) { } elseif (file_exists(CONFIGS . $arg . '.php')) {
include_once(CONFIGS . $arg . '.php'); include_once(CONFIGS . $arg . '.php');
if (count($args) == 1) { if (count($args) == 1) {
return true; return true;
} }
} else { } else {
if (count($args) == 1) { if (count($args) == 1) {
return false; return false;
}
} }
} }
return true;
} }
return true;
}
/** /**
* Prints out debug information about given variable. * Prints out debug information about given variable.
@ -71,16 +72,16 @@
* @link http://book.cakephp.org/view/1190/Basic-Debugging * @link http://book.cakephp.org/view/1190/Basic-Debugging
* @link http://book.cakephp.org/view/1128/debug * @link http://book.cakephp.org/view/1128/debug
*/ */
function debug($var = false, $showHtml = null, $showFrom = true) { function debug($var = false, $showHtml = null, $showFrom = true) {
if (Configure::read('debug') > 0) { if (Configure::read('debug') > 0) {
$file = ''; $file = '';
$line = ''; $line = '';
if ($showFrom) { if ($showFrom) {
$calledFrom = debug_backtrace(); $calledFrom = debug_backtrace();
$file = substr(str_replace(ROOT, '', $calledFrom[0]['file']), 1); $file = substr(str_replace(ROOT, '', $calledFrom[0]['file']), 1);
$line = $calledFrom[0]['line']; $line = $calledFrom[0]['line'];
} }
$html = <<<HTML $html = <<<HTML
<strong>%s</strong> (line <strong>%s</strong>) <strong>%s</strong> (line <strong>%s</strong>)
<pre class="cake-debug"> <pre class="cake-debug">
%s %s
@ -94,32 +95,32 @@ HTML;
########################### ###########################
TEXT; TEXT;
$template = $html; $template = $html;
if (php_sapi_name() == 'cli') { if (php_sapi_name() == 'cli') {
$template = $text; $template = $text;
}
if ($showHtml === null && $template !== $text) {
$showHtml = true;
}
$var = print_r($var, true);
if ($showHtml) {
$var = str_replace(array('<', '>'), array('&lt;', '&gt;'), $var);
}
printf($template, $file, $line, $var);
} }
if ($showHtml === null && $template !== $text) {
$showHtml = true;
}
$var = print_r($var, true);
if ($showHtml) {
$var = str_replace(array('<', '>'), array('&lt;', '&gt;'), $var);
}
printf($template, $file, $line, $var);
} }
}
if (!function_exists('sortByKey')) { if (!function_exists('sortByKey')) {
/** /**
* Sorts given $array by key $sortby. * Sorts given $array by key $sortby.
* *
* @param array $array Array to sort * @param array $array Array to sort
* @param string $sortby Sort by this key * @param string $sortby Sort by this key
* @param string $order Sort order asc/desc (ascending or descending). * @param string $order Sort order asc/desc (ascending or descending).
* @param integer $type Type of sorting to perform * @param integer $type Type of sorting to perform
* @return mixed Sorted array * @return mixed Sorted array
*/ */
function sortByKey(&$array, $sortby, $order = 'asc', $type = SORT_NUMERIC) { function sortByKey(&$array, $sortby, $order = 'asc', $type = SORT_NUMERIC) {
if (!is_array($array)) { if (!is_array($array)) {
return null; return null;
@ -151,28 +152,28 @@ if (!function_exists('sortByKey')) {
* @return string Wrapped text * @return string Wrapped text
* @link http://book.cakephp.org/view/1132/h * @link http://book.cakephp.org/view/1132/h
*/ */
function h($text, $double = true, $charset = null) { function h($text, $double = true, $charset = null) {
if (is_array($text)) { if (is_array($text)) {
$texts = array(); $texts = array();
foreach ($text as $k => $t) { foreach ($text as $k => $t) {
$texts[$k] = h($t, $double, $charset); $texts[$k] = h($t, $double, $charset);
}
return $texts;
} }
return $texts;
static $defaultCharset = false;
if ($defaultCharset === false) {
$defaultCharset = Configure::read('App.encoding');
if ($defaultCharset === null) {
$defaultCharset = 'UTF-8';
}
}
if (is_string($double)) {
$charset = $double;
}
return htmlspecialchars($text, ENT_QUOTES, ($charset) ? $charset : $defaultCharset, $double);
} }
static $defaultCharset = false;
if ($defaultCharset === false) {
$defaultCharset = Configure::read('App.encoding');
if ($defaultCharset === null) {
$defaultCharset = 'UTF-8';
}
}
if (is_string($double)) {
$charset = $double;
}
return htmlspecialchars($text, ENT_QUOTES, ($charset) ? $charset : $defaultCharset, $double);
}
/** /**
* Splits a dot syntax plugin name into its plugin and classname. * Splits a dot syntax plugin name into its plugin and classname.
* If $name does not have a dot, then index 0 will be null. * If $name does not have a dot, then index 0 will be null.
@ -184,16 +185,16 @@ if (!function_exists('sortByKey')) {
* @param string $plugin Optional default plugin to use if no plugin is found. Defaults to null. * @param string $plugin Optional default plugin to use if no plugin is found. Defaults to null.
* @return array Array with 2 indexes. 0 => plugin name, 1 => classname * @return array Array with 2 indexes. 0 => plugin name, 1 => classname
*/ */
function pluginSplit($name, $dotAppend = false, $plugin = null) { function pluginSplit($name, $dotAppend = false, $plugin = null) {
if (strpos($name, '.') !== false) { if (strpos($name, '.') !== false) {
$parts = explode('.', $name, 2); $parts = explode('.', $name, 2);
if ($dotAppend) { if ($dotAppend) {
$parts[0] .= '.'; $parts[0] .= '.';
}
return $parts;
} }
return array($plugin, $name); return $parts;
} }
return array($plugin, $name);
}
/** /**
* Print_r convenience function, which prints out <PRE> tags around * Print_r convenience function, which prints out <PRE> tags around
@ -203,13 +204,13 @@ if (!function_exists('sortByKey')) {
* @param array $var Variable to print out * @param array $var Variable to print out
* @link http://book.cakephp.org/view/1136/pr * @link http://book.cakephp.org/view/1136/pr
*/ */
function pr($var) { function pr($var) {
if (Configure::read('debug') > 0) { if (Configure::read('debug') > 0) {
echo '<pre>'; echo '<pre>';
print_r($var); print_r($var);
echo '</pre>'; echo '</pre>';
}
} }
}
/** /**
* Merge a group of arrays * Merge a group of arrays
@ -221,17 +222,17 @@ if (!function_exists('sortByKey')) {
* @return array All array parameters merged into one * @return array All array parameters merged into one
* @link http://book.cakephp.org/view/1124/am * @link http://book.cakephp.org/view/1124/am
*/ */
function am() { function am() {
$r = array(); $r = array();
$args = func_get_args(); $args = func_get_args();
foreach ($args as $a) { foreach ($args as $a) {
if (!is_array($a)) { if (!is_array($a)) {
$a = array($a); $a = array($a);
}
$r = array_merge($r, $a);
} }
return $r; $r = array_merge($r, $a);
} }
return $r;
}
/** /**
* Gets an environment variable from available sources, and provides emulation * Gets an environment variable from available sources, and provides emulation
@ -243,83 +244,105 @@ if (!function_exists('sortByKey')) {
* @return string Environment variable setting. * @return string Environment variable setting.
* @link http://book.cakephp.org/view/1130/env * @link http://book.cakephp.org/view/1130/env
*/ */
function env($key) { function env($key) {
if ($key === 'HTTPS') { if ($key === 'HTTPS') {
if (isset($_SERVER['HTTPS'])) { if (isset($_SERVER['HTTPS'])) {
return (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off'); return (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off');
}
return (strpos(env('SCRIPT_URI'), 'https://') === 0);
} }
return (strpos(env('SCRIPT_URI'), 'https://') === 0);
if ($key === 'SCRIPT_NAME') {
if (env('CGI_MODE') && isset($_ENV['SCRIPT_URL'])) {
$key = 'SCRIPT_URL';
}
}
$val = null;
if (isset($_SERVER[$key])) {
$val = $_SERVER[$key];
} elseif (isset($_ENV[$key])) {
$val = $_ENV[$key];
} elseif (getenv($key) !== false) {
$val = getenv($key);
}
if ($key === 'REMOTE_ADDR' && $val === env('SERVER_ADDR')) {
$addr = env('HTTP_PC_REMOTE_ADDR');
if ($addr !== null) {
$val = $addr;
}
}
if ($val !== null) {
return $val;
}
switch ($key) {
case 'SCRIPT_FILENAME':
if (defined('SERVER_IIS') && SERVER_IIS === true) {
return str_replace('\\\\', '\\', env('PATH_TRANSLATED'));
}
break;
case 'DOCUMENT_ROOT':
$name = env('SCRIPT_NAME');
$filename = env('SCRIPT_FILENAME');
$offset = 0;
if (!strpos($name, '.php')) {
$offset = 4;
}
return substr($filename, 0, strlen($filename) - (strlen($name) + $offset));
break;
case 'PHP_SELF':
return str_replace(env('DOCUMENT_ROOT'), '', env('SCRIPT_FILENAME'));
break;
case 'CGI_MODE':
return (PHP_SAPI === 'cgi');
break;
case 'HTTP_BASE':
$host = env('HTTP_HOST');
$parts = explode('.', $host);
$count = count($parts);
if ($count === 1) {
return '.' . $host;
} elseif ($count === 2) {
return '.' . $host;
} elseif ($count === 3) {
$gTLD = array('aero', 'asia', 'biz', 'cat', 'com', 'coop', 'edu', 'gov', 'info', 'int', 'jobs', 'mil', 'mobi', 'museum', 'name', 'net', 'org', 'pro', 'tel', 'travel', 'xxx');
if (in_array($parts[1], $gTLD)) {
return '.' . $host;
}
}
array_shift($parts);
return '.' . implode('.', $parts);
break;
}
return null;
} }
if ($key === 'SCRIPT_NAME') {
if (env('CGI_MODE') && isset($_ENV['SCRIPT_URL'])) {
$key = 'SCRIPT_URL';
}
}
$val = null;
if (isset($_SERVER[$key])) {
$val = $_SERVER[$key];
} elseif (isset($_ENV[$key])) {
$val = $_ENV[$key];
} elseif (getenv($key) !== false) {
$val = getenv($key);
}
if ($key === 'REMOTE_ADDR' && $val === env('SERVER_ADDR')) {
$addr = env('HTTP_PC_REMOTE_ADDR');
if ($addr !== null) {
$val = $addr;
}
}
if ($val !== null) {
return $val;
}
switch ($key) {
case 'SCRIPT_FILENAME':
if (defined('SERVER_IIS') && SERVER_IIS === true) {
return str_replace('\\\\', '\\', env('PATH_TRANSLATED'));
}
break;
case 'DOCUMENT_ROOT':
$name = env('SCRIPT_NAME');
$filename = env('SCRIPT_FILENAME');
$offset = 0;
if (!strpos($name, '.php')) {
$offset = 4;
}
return substr($filename, 0, strlen($filename) - (strlen($name) + $offset));
break;
case 'PHP_SELF':
return str_replace(env('DOCUMENT_ROOT'), '', env('SCRIPT_FILENAME'));
break;
case 'CGI_MODE':
return (PHP_SAPI === 'cgi');
break;
case 'HTTP_BASE':
$host = env('HTTP_HOST');
$parts = explode('.', $host);
$count = count($parts);
if ($count === 1) {
return '.' . $host;
} elseif ($count === 2) {
return '.' . $host;
} elseif ($count === 3) {
$gTLD = array(
'aero',
'asia',
'biz',
'cat',
'com',
'coop',
'edu',
'gov',
'info',
'int',
'jobs',
'mil',
'mobi',
'museum',
'name',
'net',
'org',
'pro',
'tel',
'travel',
'xxx'
);
if (in_array($parts[1], $gTLD)) {
return '.' . $host;
}
}
array_shift($parts);
return '.' . implode('.', $parts);
break;
}
return null;
}
/** /**
* Reads/writes temporary data to cache files or session. * Reads/writes temporary data to cache files or session.
* *
@ -330,47 +353,47 @@ if (!function_exists('sortByKey')) {
* @return mixed The contents of the temporary file. * @return mixed The contents of the temporary file.
* @deprecated Please use Cache::write() instead * @deprecated Please use Cache::write() instead
*/ */
function cache($path, $data = null, $expires = '+1 day', $target = 'cache') { function cache($path, $data = null, $expires = '+1 day', $target = 'cache') {
if (Configure::read('Cache.disable')) { if (Configure::read('Cache.disable')) {
return null; return null;
}
$now = time();
if (!is_numeric($expires)) {
$expires = strtotime($expires, $now);
}
switch (strtolower($target)) {
case 'cache':
$filename = CACHE . $path;
break;
case 'public':
$filename = WWW_ROOT . $path;
break;
case 'tmp':
$filename = TMP . $path;
break;
}
$timediff = $expires - $now;
$filetime = false;
if (file_exists($filename)) {
$filetime = @filemtime($filename);
}
if ($data === null) {
if (file_exists($filename) && $filetime !== false) {
if ($filetime + $timediff < $now) {
@unlink($filename);
} else {
$data = @file_get_contents($filename);
}
}
} elseif (is_writable(dirname($filename))) {
@file_put_contents($filename, $data);
}
return $data;
} }
$now = time();
if (!is_numeric($expires)) {
$expires = strtotime($expires, $now);
}
switch (strtolower($target)) {
case 'cache':
$filename = CACHE . $path;
break;
case 'public':
$filename = WWW_ROOT . $path;
break;
case 'tmp':
$filename = TMP . $path;
break;
}
$timediff = $expires - $now;
$filetime = false;
if (file_exists($filename)) {
$filetime = @filemtime($filename);
}
if ($data === null) {
if (file_exists($filename) && $filetime !== false) {
if ($filetime + $timediff < $now) {
@unlink($filename);
} else {
$data = @file_get_contents($filename);
}
}
} elseif (is_writable(dirname($filename))) {
@file_put_contents($filename, $data);
}
return $data;
}
/** /**
* Used to delete files in the cache directories, or clear contents of cache directories * Used to delete files in the cache directories, or clear contents of cache directories
@ -382,57 +405,57 @@ if (!function_exists('sortByKey')) {
* @param string $ext The file extension you are deleting * @param string $ext The file extension you are deleting
* @return true if files found and deleted false otherwise * @return true if files found and deleted false otherwise
*/ */
function clearCache($params = null, $type = 'views', $ext = '.php') { function clearCache($params = null, $type = 'views', $ext = '.php') {
if (is_string($params) || $params === null) { if (is_string($params) || $params === null) {
$params = preg_replace('/\/\//', '/', $params); $params = preg_replace('/\/\//', '/', $params);
$cache = CACHE . $type . DS . $params; $cache = CACHE . $type . DS . $params;
if (is_file($cache . $ext)) { if (is_file($cache . $ext)) {
@unlink($cache . $ext); @unlink($cache . $ext);
return true; return true;
} elseif (is_dir($cache)) { } elseif (is_dir($cache)) {
$files = glob($cache . '*'); $files = glob($cache . '*');
if ($files === false) { if ($files === false) {
return false; return false;
}
foreach ($files as $file) {
if (is_file($file) && strrpos($file, DS . 'empty') !== strlen($file) - 6) {
@unlink($file);
}
}
return true;
} else {
$cache = array(
CACHE . $type . DS . '*' . $params . $ext,
CACHE . $type . DS . '*' . $params . '_*' . $ext
);
$files = array();
while ($search = array_shift($cache)) {
$results = glob($search);
if ($results !== false) {
$files = array_merge($files, $results);
}
}
if (empty($files)) {
return false;
}
foreach ($files as $file) {
if (is_file($file) && strrpos($file, DS . 'empty') !== strlen($file) - 6) {
@unlink($file);
}
}
return true;
} }
} elseif (is_array($params)) {
foreach ($params as $file) { foreach ($files as $file) {
clearCache($file, $type, $ext); if (is_file($file) && strrpos($file, DS . 'empty') !== strlen($file) - 6) {
@unlink($file);
}
}
return true;
} else {
$cache = array(
CACHE . $type . DS . '*' . $params . $ext,
CACHE . $type . DS . '*' . $params . '_*' . $ext
);
$files = array();
while ($search = array_shift($cache)) {
$results = glob($search);
if ($results !== false) {
$files = array_merge($files, $results);
}
}
if (empty($files)) {
return false;
}
foreach ($files as $file) {
if (is_file($file) && strrpos($file, DS . 'empty') !== strlen($file) - 6) {
@unlink($file);
}
} }
return true; return true;
} }
return false; } elseif (is_array($params)) {
foreach ($params as $file) {
clearCache($file, $type, $ext);
}
return true;
} }
return false;
}
/** /**
* Recursively strips slashes from all values in an array * Recursively strips slashes from all values in an array
@ -441,16 +464,16 @@ if (!function_exists('sortByKey')) {
* @return mixed What is returned from calling stripslashes * @return mixed What is returned from calling stripslashes
* @link http://book.cakephp.org/view/1138/stripslashes_deep * @link http://book.cakephp.org/view/1138/stripslashes_deep
*/ */
function stripslashes_deep($values) { function stripslashes_deep($values) {
if (is_array($values)) { if (is_array($values)) {
foreach ($values as $key => $value) { foreach ($values as $key => $value) {
$values[$key] = stripslashes_deep($value); $values[$key] = stripslashes_deep($value);
}
} else {
$values = stripslashes($values);
} }
return $values; } else {
$values = stripslashes($values);
} }
return $values;
}
/** /**
* Returns a translated string if one is found; Otherwise, the submitted message. * Returns a translated string if one is found; Otherwise, the submitted message.
@ -460,21 +483,21 @@ if (!function_exists('sortByKey')) {
* @return mixed translated string * @return mixed translated string
* @link http://book.cakephp.org/view/1121/__ * @link http://book.cakephp.org/view/1121/__
*/ */
function __($singular, $args = null) { function __($singular, $args = null) {
if (!$singular) { if (!$singular) {
return; return;
}
App::uses('I18n', 'I18n');
$translated = I18n::translate($singular);
if ($args === null) {
return $translated;
} elseif (!is_array($args)) {
$args = array_slice(func_get_args(), 1);
}
return vsprintf($translated, $args);
} }
App::uses('I18n', 'I18n');
$translated = I18n::translate($singular);
if ($args === null) {
return $translated;
} elseif (!is_array($args)) {
$args = array_slice(func_get_args(), 1);
}
return vsprintf($translated, $args);
}
/** /**
* Returns correct plural form of message identified by $singular and $plural for count $count. * Returns correct plural form of message identified by $singular and $plural for count $count.
* Some languages have more than one form for plural messages dependent on the count. * Some languages have more than one form for plural messages dependent on the count.
@ -485,21 +508,21 @@ if (!function_exists('sortByKey')) {
* @param mixed $args Array with arguments or multiple arguments in function * @param mixed $args Array with arguments or multiple arguments in function
* @return mixed plural form of translated string * @return mixed plural form of translated string
*/ */
function __n($singular, $plural, $count, $args = null) { function __n($singular, $plural, $count, $args = null) {
if (!$singular) { if (!$singular) {
return; return;
}
App::uses('I18n', 'I18n');
$translated = I18n::translate($singular, $plural, null, 6, $count);
if ($args === null) {
return $translated;
} elseif (!is_array($args)) {
$args = array_slice(func_get_args(), 3);
}
return vsprintf($translated, $args);
} }
App::uses('I18n', 'I18n');
$translated = I18n::translate($singular, $plural, null, 6, $count);
if ($args === null) {
return $translated;
} elseif (!is_array($args)) {
$args = array_slice(func_get_args(), 3);
}
return vsprintf($translated, $args);
}
/** /**
* Allows you to override the current domain for a single message lookup. * Allows you to override the current domain for a single message lookup.
* *
@ -508,19 +531,19 @@ if (!function_exists('sortByKey')) {
* @param mixed $args Array with arguments or multiple arguments in function * @param mixed $args Array with arguments or multiple arguments in function
* @return translated string * @return translated string
*/ */
function __d($domain, $msg, $args = null) { function __d($domain, $msg, $args = null) {
if (!$msg) { if (!$msg) {
return; return;
}
App::uses('I18n', 'I18n');
$translated = I18n::translate($msg, null, $domain);
if ($args === null) {
return $translated;
} elseif (!is_array($args)) {
$args = array_slice(func_get_args(), 2);
}
return vsprintf($translated, $args);
} }
App::uses('I18n', 'I18n');
$translated = I18n::translate($msg, null, $domain);
if ($args === null) {
return $translated;
} elseif (!is_array($args)) {
$args = array_slice(func_get_args(), 2);
}
return vsprintf($translated, $args);
}
/** /**
* Allows you to override the current domain for a single plural message lookup. * Allows you to override the current domain for a single plural message lookup.
@ -534,19 +557,19 @@ if (!function_exists('sortByKey')) {
* @param mixed $args Array with arguments or multiple arguments in function * @param mixed $args Array with arguments or multiple arguments in function
* @return plural form of translated string * @return plural form of translated string
*/ */
function __dn($domain, $singular, $plural, $count, $args = null) { function __dn($domain, $singular, $plural, $count, $args = null) {
if (!$singular) { if (!$singular) {
return; return;
}
App::uses('I18n', 'I18n');
$translated = I18n::translate($singular, $plural, $domain, 6, $count);
if ($args === null) {
return $translated;
} elseif (!is_array($args)) {
$args = array_slice(func_get_args(), 4);
}
return vsprintf($translated, $args);
} }
App::uses('I18n', 'I18n');
$translated = I18n::translate($singular, $plural, $domain, 6, $count);
if ($args === null) {
return $translated;
} elseif (!is_array($args)) {
$args = array_slice(func_get_args(), 4);
}
return vsprintf($translated, $args);
}
/** /**
* Allows you to override the current domain for a single message lookup. * Allows you to override the current domain for a single message lookup.
@ -571,19 +594,19 @@ if (!function_exists('sortByKey')) {
* @param mixed $args Array with arguments or multiple arguments in function * @param mixed $args Array with arguments or multiple arguments in function
* @return translated string * @return translated string
*/ */
function __dc($domain, $msg, $category, $args = null) { function __dc($domain, $msg, $category, $args = null) {
if (!$msg) { if (!$msg) {
return; return;
}
App::uses('I18n', 'I18n');
$translated = I18n::translate($msg, null, $domain, $category);
if ($args === null) {
return $translated;
} elseif (!is_array($args)) {
$args = array_slice(func_get_args(), 3);
}
return vsprintf($translated, $args);
} }
App::uses('I18n', 'I18n');
$translated = I18n::translate($msg, null, $domain, $category);
if ($args === null) {
return $translated;
} elseif (!is_array($args)) {
$args = array_slice(func_get_args(), 3);
}
return vsprintf($translated, $args);
}
/** /**
* Allows you to override the current domain for a single plural message lookup. * Allows you to override the current domain for a single plural message lookup.
@ -612,19 +635,19 @@ if (!function_exists('sortByKey')) {
* @param mixed $args Array with arguments or multiple arguments in function * @param mixed $args Array with arguments or multiple arguments in function
* @return plural form of translated string * @return plural form of translated string
*/ */
function __dcn($domain, $singular, $plural, $count, $category, $args = null) { function __dcn($domain, $singular, $plural, $count, $category, $args = null) {
if (!$singular) { if (!$singular) {
return; return;
}
App::uses('I18n', 'I18n');
$translated = I18n::translate($singular, $plural, $domain, $category, $count);
if ($args === null) {
return $translated;
} elseif (!is_array($args)) {
$args = array_slice(func_get_args(), 5);
}
return vsprintf($translated, $args);
} }
App::uses('I18n', 'I18n');
$translated = I18n::translate($singular, $plural, $domain, $category, $count);
if ($args === null) {
return $translated;
} elseif (!is_array($args)) {
$args = array_slice(func_get_args(), 5);
}
return vsprintf($translated, $args);
}
/** /**
* The category argument allows a specific category of the locale settings to be used for fetching a message. * The category argument allows a specific category of the locale settings to be used for fetching a message.
@ -645,31 +668,31 @@ if (!function_exists('sortByKey')) {
* @param mixed $args Array with arguments or multiple arguments in function * @param mixed $args Array with arguments or multiple arguments in function
* @return translated string * @return translated string
*/ */
function __c($msg, $category, $args = null) { function __c($msg, $category, $args = null) {
if (!$msg) { if (!$msg) {
return; return;
}
App::uses('I18n', 'I18n');
$translated = I18n::translate($msg, null, null, $category);
if ($args === null) {
return $translated;
} elseif (!is_array($args)) {
$args = array_slice(func_get_args(), 2);
}
return vsprintf($translated, $args);
} }
App::uses('I18n', 'I18n');
$translated = I18n::translate($msg, null, null, $category);
if ($args === null) {
return $translated;
} elseif (!is_array($args)) {
$args = array_slice(func_get_args(), 2);
}
return vsprintf($translated, $args);
}
/** /**
* Shortcut to Log::write. * Shortcut to Log::write.
* *
* @param string $message Message to write to log * @param string $message Message to write to log
*/ */
function LogError($message) { function LogError($message) {
App::uses('CakeLog', 'Log'); App::uses('CakeLog', 'Log');
$bad = array("\n", "\r", "\t"); $bad = array("\n", "\r", "\t");
$good = ' '; $good = ' ';
CakeLog::write('error', str_replace($bad, $good, $message)); CakeLog::write('error', str_replace($bad, $good, $message));
} }
/** /**
* Searches include path for files. * Searches include path for files.
@ -678,19 +701,19 @@ if (!function_exists('sortByKey')) {
* @return Full path to file if exists, otherwise false * @return Full path to file if exists, otherwise false
* @link http://book.cakephp.org/view/1131/fileExistsInPath * @link http://book.cakephp.org/view/1131/fileExistsInPath
*/ */
function fileExistsInPath($file) { function fileExistsInPath($file) {
$paths = explode(PATH_SEPARATOR, ini_get('include_path')); $paths = explode(PATH_SEPARATOR, ini_get('include_path'));
foreach ($paths as $path) { foreach ($paths as $path) {
$fullPath = $path . DS . $file; $fullPath = $path . DS . $file;
if (file_exists($fullPath)) { if (file_exists($fullPath)) {
return $fullPath; return $fullPath;
} elseif (file_exists($file)) { } elseif (file_exists($file)) {
return $file; return $file;
}
} }
return false;
} }
return false;
}
/** /**
* Convert forward slashes to underscores and removes first and last underscores in a string * Convert forward slashes to underscores and removes first and last underscores in a string
@ -699,9 +722,9 @@ if (!function_exists('sortByKey')) {
* @return string with underscore remove from start and end of string * @return string with underscore remove from start and end of string
* @link http://book.cakephp.org/view/1126/convertSlash * @link http://book.cakephp.org/view/1126/convertSlash
*/ */
function convertSlash($string) { function convertSlash($string) {
$string = trim($string, '/'); $string = trim($string, '/');
$string = preg_replace('/\/\//', '/', $string); $string = preg_replace('/\/\//', '/', $string);
$string = str_replace('/', '_', $string); $string = str_replace('/', '_', $string);
return $string; return $string;
} }

View file

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

View file

@ -40,7 +40,7 @@ class AllDatabaseTest extends PHPUnit_Framework_TestSuite {
'CakeSchema', 'CakeSchema',
'ConnectionManager', 'ConnectionManager',
'Datasource' . DS . 'DboSource', 'Datasource' . DS . 'DboSource',
'Datasource' . DS . 'Database' . DS . 'MySql', 'Datasource' . DS . 'Database' . DS . 'Mysql',
'Datasource' . DS . 'Database' . DS . 'Postgres', 'Datasource' . DS . 'Database' . DS . 'Postgres',
'Datasource' . DS . 'Database' . DS . 'Sqlite' 'Datasource' . DS . 'Database' . DS . 'Sqlite'
); );

View file

@ -35,6 +35,7 @@ class AllNetworkTest extends PHPUnit_Framework_TestSuite {
$suite = new CakeTestSuite('All Network related class tests'); $suite = new CakeTestSuite('All Network related class tests');
$suite->addTestDirectory(CORE_TEST_CASES . DS . 'Network'); $suite->addTestDirectory(CORE_TEST_CASES . DS . 'Network');
$suite->addTestDirectory(CORE_TEST_CASES . DS . 'Network' . DS . 'Email');
$suite->addTestDirectory(CORE_TEST_CASES . DS . 'Network' . DS . 'Http'); $suite->addTestDirectory(CORE_TEST_CASES . DS . 'Network' . DS . 'Http');
return $suite; return $suite;
} }

View file

@ -235,7 +235,7 @@ class CacheTest extends CakeTestCase {
function testInitSettings() { function testInitSettings() {
$initial = Cache::settings(); $initial = Cache::settings();
$override = array('engine' => 'File', 'path' => TMP . 'tests'); $override = array('engine' => 'File', 'path' => TMP . 'tests');
Cache::config('default', $override); Cache::config('for_test', $override);
$settings = Cache::settings(); $settings = Cache::settings();
$expecting = $override + $initial; $expecting = $override + $initial;

View file

@ -257,7 +257,7 @@ class FileEngineTest extends CakeTestCase {
$result = Cache::read('views.countries.something', 'file_test'); $result = Cache::read('views.countries.something', 'file_test');
$this->assertEqual($result, 'here'); $this->assertEqual($result, 'here');
$result = Cache::clear(); $result = Cache::clear(false, 'file_test');
$this->assertTrue($result); $this->assertTrue($result);
} }

View file

@ -82,7 +82,7 @@ class ApiShellTest extends CakeTestCase {
$this->Shell->expects($this->at(2))->method('out')->with($expected); $this->Shell->expects($this->at(2))->method('out')->with($expected);
$this->Shell->args = array('controller'); $this->Shell->args = array('controller');
$this->Shell->paths['controller'] = LIBS . 'controller' . DS; $this->Shell->paths['controller'] = LIBS . 'Controller' . DS;
$this->Shell->main(); $this->Shell->main();
} }
} }

View file

@ -473,7 +473,7 @@ class SchemaShellTest extends CakeTestCase {
$this->Shell->expects($this->any())->method('in')->will($this->returnValue('y')); $this->Shell->expects($this->any())->method('in')->will($this->returnValue('y'));
$this->Shell->create(); $this->Shell->create();
$db =& ConnectionManager::getDataSource('test'); $db = ConnectionManager::getDataSource('test');
$sources = $db->listSources(); $sources = $db->listSources();
$this->assertTrue(in_array($db->config['prefix'] . 'test_plugin_acos', $sources)); $this->assertTrue(in_array($db->config['prefix'] . 'test_plugin_acos', $sources));

View file

@ -118,7 +118,6 @@ class ExtractTaskTest extends CakeTestCase {
$pattern = '/To change its layout, create: APP\/views\/layouts\/default\.ctp\./s'; $pattern = '/To change its layout, create: APP\/views\/layouts\/default\.ctp\./s';
$this->assertPattern($pattern, $result); $this->assertPattern($pattern, $result);
// extract.ctp // extract.ctp
$pattern = '/\#: (\\\\|\/)extract\.ctp:6\n'; $pattern = '/\#: (\\\\|\/)extract\.ctp:6\n';
$pattern .= 'msgid "You have %d new message."\nmsgid_plural "You have %d new messages."/'; $pattern .= 'msgid "You have %d new message."\nmsgid_plural "You have %d new messages."/';
@ -131,9 +130,15 @@ class ExtractTaskTest extends CakeTestCase {
$pattern = '/\#: (\\\\|\/)extract\.ctp:14\n'; $pattern = '/\#: (\\\\|\/)extract\.ctp:14\n';
$pattern .= '\#: (\\\\|\/)home\.ctp:99\n'; $pattern .= '\#: (\\\\|\/)home\.ctp:99\n';
$pattern .= 'msgid "Editing this Page"\nmsgstr ""/'; $pattern .= 'msgid "Editing this Page"\nmsgstr ""/';
$this->assertPattern($pattern, $result); $this->assertPattern($pattern, $result);
$pattern = '/\#: (\\\\|\/)extract\.ctp:17\nmsgid "';
$pattern .= 'Hot features!';
$pattern .= '\\\n - No Configuration: Set-up the database and let the magic begin';
$pattern .= '\\\n - Extremely Simple: Just look at the name...It\'s Cake';
$pattern .= '\\\n - Active, Friendly Community: Join us #cakephp on IRC. We\'d love to help you get started';
$pattern .= '"\nmsgstr ""/';
$this->assertPattern($pattern, $result);
// extract.ctp - reading the domain.pot // extract.ctp - reading the domain.pot
$result = file_get_contents($this->path . DS . 'domain.pot'); $result = file_get_contents($this->path . DS . 'domain.pot');

View file

@ -496,7 +496,23 @@ class CookieComponentTest extends CakeTestCase {
$this->assertNull($this->Cookie->read('value')); $this->assertNull($this->Cookie->read('value'));
} }
/**
* test that deleting a top level keys kills the child elements too.
*
* @return void
*/
function testDeleteRemovesChildren() {
$_COOKIE['CakeTestCookie'] = array(
'User' => array('email' => 'example@example.com', 'name' => 'mark'),
'other' => 'value'
);
$this->assertEqual('mark', $this->Cookie->read('User.name'));
$this->Cookie->delete('User');
$this->assertNull($this->Cookie->read('User.email'));
$this->Cookie->destroy();
}
/** /**
* Helper method for generating old style encoded cookie values. * Helper method for generating old style encoded cookie values.
* *

View file

@ -292,6 +292,7 @@ class RequestHandlerComponentTest extends CakeTestCase {
function testStartupCallback() { function testStartupCallback() {
$_SERVER['REQUEST_METHOD'] = 'PUT'; $_SERVER['REQUEST_METHOD'] = 'PUT';
$_SERVER['CONTENT_TYPE'] = 'application/xml'; $_SERVER['CONTENT_TYPE'] = 'application/xml';
$this->Controller->request = $this->getMock('CakeRequest', array('_readStdin'));
$this->RequestHandler->startup($this->Controller); $this->RequestHandler->startup($this->Controller);
$this->assertTrue(is_array($this->Controller->data)); $this->assertTrue(is_array($this->Controller->data));
$this->assertFalse(is_object($this->Controller->data)); $this->assertFalse(is_object($this->Controller->data));
@ -305,11 +306,35 @@ class RequestHandlerComponentTest extends CakeTestCase {
function testStartupCallbackCharset() { function testStartupCallbackCharset() {
$_SERVER['REQUEST_METHOD'] = 'PUT'; $_SERVER['REQUEST_METHOD'] = 'PUT';
$_SERVER['CONTENT_TYPE'] = 'application/xml; charset=UTF-8'; $_SERVER['CONTENT_TYPE'] = 'application/xml; charset=UTF-8';
$this->Controller->request = $this->getMock('CakeRequest', array('_readStdin'));
$this->RequestHandler->startup($this->Controller); $this->RequestHandler->startup($this->Controller);
$this->assertTrue(is_array($this->Controller->data)); $this->assertTrue(is_array($this->Controller->data));
$this->assertFalse(is_object($this->Controller->data)); $this->assertFalse(is_object($this->Controller->data));
} }
/**
* Test mapping a new type and having startup process it.
*
* @return void
*/
function testStartupCustomTypeProcess() {
if (!function_exists('str_getcsv')) {
$this->markTestSkipped('Need "str_getcsv" for this test.');
}
$_SERVER['REQUEST_METHOD'] = 'POST';
$_SERVER['CONTENT_TYPE'] = 'text/csv';
$this->Controller->request = $this->getMock('CakeRequest', array('_readStdin'));
$this->Controller->request->expects($this->once())
->method('_readStdin')
->will($this->returnValue('"A","csv","string"'));
$this->RequestHandler->addInputType('csv', array('str_getcsv'));
$this->RequestHandler->startup($this->Controller);
$expected = array(
'A', 'csv', 'string'
);
$this->assertEquals($expected, $this->Controller->request->data);
}
/** /**
* testNonAjaxRedirect method * testNonAjaxRedirect method
* *
@ -774,4 +799,11 @@ class RequestHandlerComponentTest extends CakeTestCase {
$result = ob_get_clean(); $result = ob_get_clean();
} }
/**
* @expectedException CakeException
* @return void
*/
function testAddInputTypeException() {
$this->RequestHandler->addInputType('csv', array('I am not callable'));
}
} }

View file

@ -339,7 +339,6 @@ class ComponentTest extends CakeTestCase {
$this->assertInstanceOf('SomethingWithEmailComponent', $Controller->SomethingWithEmail); $this->assertInstanceOf('SomethingWithEmailComponent', $Controller->SomethingWithEmail);
$this->assertInstanceOf('EmailComponent', $Controller->SomethingWithEmail->Email); $this->assertInstanceOf('EmailComponent', $Controller->SomethingWithEmail->Email);
$this->assertInstanceOf('ComponentTestController', $Controller->SomethingWithEmail->Email->Controller);
} }
} }

View file

@ -470,16 +470,8 @@ class ControllerTest extends CakeTestCase {
$request = new CakeRequest('controller_posts/index'); $request = new CakeRequest('controller_posts/index');
$Controller = new Controller($request); $Controller = new Controller($request);
$Controller->modelClass = 'ControllerPost';
$Controller->passedArgs[] = '1';
$Controller->constructClasses();
$this->assertEqual($Controller->ControllerPost->id, 1);
unset($Controller);
$Controller = new Controller($request); $Controller = new Controller($request);
$Controller->uses = array('ControllerPost', 'ControllerComment'); $Controller->uses = array('ControllerPost', 'ControllerComment');
$Controller->passedArgs[] = '1';
$Controller->constructClasses(); $Controller->constructClasses();
$this->assertTrue(is_a($Controller->ControllerPost, 'ControllerPost')); $this->assertTrue(is_a($Controller->ControllerPost, 'ControllerPost'));
$this->assertTrue(is_a($Controller->ControllerComment, 'ControllerComment')); $this->assertTrue(is_a($Controller->ControllerComment, 'ControllerComment'));
@ -494,7 +486,6 @@ class ControllerTest extends CakeTestCase {
$Controller->uses = array('TestPlugin.TestPluginPost'); $Controller->uses = array('TestPlugin.TestPluginPost');
$Controller->constructClasses(); $Controller->constructClasses();
$this->assertEqual($Controller->modelClass, 'TestPluginPost');
$this->assertTrue(isset($Controller->TestPluginPost)); $this->assertTrue(isset($Controller->TestPluginPost));
$this->assertTrue(is_a($Controller->TestPluginPost, 'TestPluginPost')); $this->assertTrue(is_a($Controller->TestPluginPost, 'TestPluginPost'));
@ -917,7 +908,7 @@ class ControllerTest extends CakeTestCase {
$this->assertTrue(in_array('ControllerPost', $appVars['uses'])); $this->assertTrue(in_array('ControllerPost', $appVars['uses']));
$this->assertNull($testVars['uses']); $this->assertNull($testVars['uses']);
$this->assertFalse(isset($TestController->ControllerPost)); $this->assertFalse(property_exists($TestController, 'ControllerPost'));
$TestController = new ControllerCommentsController($request); $TestController = new ControllerCommentsController($request);

View file

@ -22,9 +22,7 @@ class AppImportTest extends CakeTestCase {
$this->assertEqual($expected, $old); $this->assertEqual($expected, $old);
App::build(array('Model' => array('/path/to/models/'))); App::build(array('Model' => array('/path/to/models/')));
$new = App::path('Model'); $new = App::path('Model');
$expected = array( $expected = array(
'/path/to/models/', '/path/to/models/',
APP . 'Model' . DS, APP . 'Model' . DS,
@ -32,6 +30,46 @@ class AppImportTest extends CakeTestCase {
); );
$this->assertEqual($expected, $new); $this->assertEqual($expected, $new);
App::build();
App::build(array('Model' => array('/path/to/models/')), App::PREPEND);
$new = App::path('Model');
$expected = array(
'/path/to/models/',
APP . 'Model' . DS,
APP . 'models' . DS
);
$this->assertEqual($expected, $new);
App::build();
App::build(array('Model' => array('/path/to/models/')), App::APPEND);
$new = App::path('Model');
$expected = array(
APP . 'Model' . DS,
APP . 'models' . DS,
'/path/to/models/'
);
$this->assertEqual($expected, $new);
App::build();
App::build(array(
'Model' => array('/path/to/models/'),
'Controller' => array('/path/to/controllers/'),
), App::APPEND);
$new = App::path('Model');
$expected = array(
APP . 'Model' . DS,
APP . 'models' . DS,
'/path/to/models/'
);
$this->assertEqual($expected, $new);
$new = App::path('Controller');
$expected = array(
APP . 'Controller' . DS,
APP . 'controllers' . DS,
'/path/to/controllers/'
);
$this->assertEqual($expected, $new);
App::build(); //reset defaults App::build(); //reset defaults
$defaults = App::path('Model'); $defaults = App::path('Model');
$this->assertEqual($old, $defaults); $this->assertEqual($old, $defaults);
@ -152,7 +190,7 @@ class AppImportTest extends CakeTestCase {
); );
$this->assertEqual($expected, $old); $this->assertEqual($expected, $old);
App::build(array('Model' => array('/path/to/models/')), true); App::build(array('Model' => array('/path/to/models/')), App::RESET);
$new = App::path('Model'); $new = App::path('Model');
@ -183,13 +221,13 @@ class AppImportTest extends CakeTestCase {
$this->assertEqual(array(LIBS . 'Controller' . DS), $controller); $this->assertEqual(array(LIBS . 'Controller' . DS), $controller);
$component = App::core('Controller/Component'); $component = App::core('Controller/Component');
$this->assertEqual(array(LIBS . 'Controller' . DS . 'Component' . DS), $component); $this->assertEqual(array(LIBS . 'Controller' . DS . 'Component' . DS), str_replace('/', DS, $component));
$auth = App::core('Controller/Component/Auth'); $auth = App::core('Controller/Component/Auth');
$this->assertEqual(array(LIBS . 'Controller' . DS . 'Component' . DS . 'Auth' . DS), $auth); $this->assertEqual(array(LIBS . 'Controller' . DS . 'Component' . DS . 'Auth' . DS), str_replace('/', DS, $auth));
$datasource = App::core('Model/Datasource'); $datasource = App::core('Model/Datasource');
$this->assertEqual(array(LIBS . 'Model' . DS . 'Datasource' . DS), $datasource); $this->assertEqual(array(LIBS . 'Model' . DS . 'Datasource' . DS), str_replace('/', DS, $datasource));
} }
/** /**
@ -210,7 +248,7 @@ class AppImportTest extends CakeTestCase {
'View' => App::core('View'), 'View' => App::core('View'),
'Model' => App::core('Model'), 'Model' => App::core('Model'),
'View/Helper' => App::core('View/Helper'), 'View/Helper' => App::core('View/Helper'),
), true); ), App::RESET);
$result = App::objects('behavior', null, false); $result = App::objects('behavior', null, false);
$this->assertTrue(in_array('TreeBehavior', $result)); $this->assertTrue(in_array('TreeBehavior', $result));
$result = App::objects('Model/Behavior', null, false); $result = App::objects('Model/Behavior', null, false);
@ -285,9 +323,11 @@ class AppImportTest extends CakeTestCase {
$this->assertTrue(in_array('TestPluginPersisterOne', $result)); $this->assertTrue(in_array('TestPluginPersisterOne', $result));
$result = App::objects('TestPlugin.helper'); $result = App::objects('TestPlugin.helper');
sort($result);
$expected = array('OtherHelperHelper', 'PluggedHelper', 'TestPluginApp'); $expected = array('OtherHelperHelper', 'PluggedHelper', 'TestPluginApp');
$this->assertEquals($result, $expected); $this->assertEquals($result, $expected);
$result = App::objects('TestPlugin.View/Helper'); $result = App::objects('TestPlugin.View/Helper');
sort($result);
$expected = array('OtherHelperHelper', 'PluggedHelper', 'TestPluginApp'); $expected = array('OtherHelperHelper', 'PluggedHelper', 'TestPluginApp');
$this->assertEquals($result, $expected); $this->assertEquals($result, $expected);
@ -462,7 +502,7 @@ class AppImportTest extends CakeTestCase {
$result = App::import('Helper', 'TestPlugin.OtherHelper'); $result = App::import('Helper', 'TestPlugin.OtherHelper');
$this->assertTrue($result); $this->assertTrue($result);
$this->assertTrue(class_exists('OtherHelperHelper')); $this->assertTrue(class_exists('OtherHelperHelper'));
$result = App::import('Helper', 'TestPlugin.TestPluginApp'); $result = App::import('Helper', 'TestPlugin.TestPluginApp');
$this->assertTrue($result); $this->assertTrue($result);
$this->assertTrue(class_exists('TestPluginAppHelper')); $this->assertTrue(class_exists('TestPluginAppHelper'));
@ -470,7 +510,7 @@ class AppImportTest extends CakeTestCase {
$result = App::import('Datasource', 'TestPlugin.TestSource'); $result = App::import('Datasource', 'TestPlugin.TestSource');
$this->assertTrue($result); $this->assertTrue($result);
$this->assertTrue(class_exists('TestSource')); $this->assertTrue(class_exists('TestSource'));
App::build(); App::build();
} }
@ -621,7 +661,7 @@ class AppImportTest extends CakeTestCase {
App::build(array( App::build(array(
'plugins' => array(LIBS . 'tests' . DS . 'test_app' . DS . 'plugins' . DS), 'plugins' => array(LIBS . 'tests' . DS . 'test_app' . DS . 'plugins' . DS),
'vendors' => array(LIBS . 'tests' . DS . 'test_app' . DS . 'vendors'. DS), 'vendors' => array(LIBS . 'tests' . DS . 'test_app' . DS . 'vendors'. DS),
), true); ), App::RESET);
ob_start(); ob_start();
$result = App::import('Vendor', 'css/TestAsset', array('ext' => 'css')); $result = App::import('Vendor', 'css/TestAsset', array('ext' => 'css'));
@ -677,7 +717,7 @@ class AppImportTest extends CakeTestCase {
App::build(array( App::build(array(
'libs' => array(LIBS . 'tests' . DS . 'test_app' . DS . 'libs' . DS), 'libs' => array(LIBS . 'tests' . DS . 'test_app' . DS . 'libs' . DS),
'plugins' => array(LIBS . 'tests' . DS . 'test_app' . DS . 'plugins' . DS) 'plugins' => array(LIBS . 'tests' . DS . 'test_app' . DS . 'plugins' . DS)
), true); ), App::RESET);
$this->assertFalse(class_exists('CustomLibClass', false)); $this->assertFalse(class_exists('CustomLibClass', false));
App::uses('CustomLibClass', 'TestPlugin.Custom/Package'); App::uses('CustomLibClass', 'TestPlugin.Custom/Package');

View file

@ -822,7 +822,6 @@ class ObjectTest extends CakeTestCase {
$this->assertEqual($result->url, 'request_action/params_pass'); $this->assertEqual($result->url, 'request_action/params_pass');
$this->assertEqual($result['controller'], 'request_action'); $this->assertEqual($result['controller'], 'request_action');
$this->assertEqual($result['action'], 'params_pass'); $this->assertEqual($result['action'], 'params_pass');
$this->assertEqual($result['form'], array());
$this->assertEqual($result['plugin'], null); $this->assertEqual($result['plugin'], null);
$result = $this->object->requestAction('/request_action/params_pass/sort:desc/limit:5'); $result = $this->object->requestAction('/request_action/params_pass/sort:desc/limit:5');

View file

@ -37,8 +37,7 @@ class ErrorHandlerTest extends CakeTestCase {
function setUp() { function setUp() {
App::build(array( App::build(array(
'View' => array( 'View' => array(
LIBS . 'tests' . DS . 'test_app' . DS . 'views'. DS, LIBS . 'tests' . DS . 'test_app' . DS . 'View'. DS
LIBS . 'libs' . DS . 'view' . DS
) )
), true); ), true);
Router::reload(); Router::reload();
@ -148,7 +147,7 @@ class ErrorHandlerTest extends CakeTestCase {
$result = file(LOGS . 'debug.log'); $result = file(LOGS . 'debug.log');
$this->assertEqual(count($result), 1); $this->assertEqual(count($result), 1);
$this->assertPattern( $this->assertPattern(
'/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} Notice: Notice \(8\): Undefined variable:\s+out in \[.+ line \d+\]$/', '/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} (Notice|Debug): Notice \(8\): Undefined variable:\s+out in \[.+ line \d+\]$/',
$result[0] $result[0]
); );
@unlink(LOGS . 'debug.log'); @unlink(LOGS . 'debug.log');
@ -173,7 +172,7 @@ class ErrorHandlerTest extends CakeTestCase {
$result = file(LOGS . 'debug.log'); $result = file(LOGS . 'debug.log');
$this->assertPattern( $this->assertPattern(
'/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} Notice: Notice \(8\): Undefined variable:\s+out in \[.+ line \d+\]$/', '/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} (Notice|Debug): Notice \(8\): Undefined variable:\s+out in \[.+ line \d+\]$/',
$result[0] $result[0]
); );
$this->assertPattern('/^Trace:/', $result[1]); $this->assertPattern('/^Trace:/', $result[1]);
@ -223,4 +222,23 @@ class ErrorHandlerTest extends CakeTestCase {
$this->assertPattern('/\#0.*ErrorHandlerTest->testHandleExceptionLog/', $log[1], 'Stack trace missing.'); $this->assertPattern('/\#0.*ErrorHandlerTest->testHandleExceptionLog/', $log[1], 'Stack trace missing.');
} }
/**
* tests it is possible to load a plugin exception renderer
*
* @return void
*/
function testLoadPluginHanlder() {
App::build(array(
'plugins' => array(
LIBS . 'tests' . DS . 'test_app' . DS . 'plugins' . DS
)
), true);
Configure::write('Exception.renderer', 'TestPlugin.TestPluginExceptionRenderer');
$error = new NotFoundException('Kaboom!');
ob_start();
ErrorHandler::handleException($error);
$result = ob_get_clean();
$this->assertEquals($result, 'Rendered by test plugin');
}
} }

View file

@ -609,4 +609,32 @@ class ExceptionRendererTest extends CakeTestCase {
$this->assertPattern($pattern, $result); $this->assertPattern($pattern, $result);
} }
} }
/**
* Test exceptions being raised when helpers are missing.
*
* @return void
*/
function testMissingRenderSafe() {
$exception = new MissingHelperFileException(array('class' => 'Fail'));
$ExceptionRenderer = new ExceptionRenderer($exception);
$ExceptionRenderer->controller = $this->getMock('Controller');
$ExceptionRenderer->controller->helpers = array('Fail', 'Boom');
$ExceptionRenderer->controller->request = $this->getMock('CakeRequest');
$ExceptionRenderer->controller->expects($this->at(2))
->method('render')
->with('missingHelperFile')
->will($this->throwException($exception));
$ExceptionRenderer->controller->expects($this->at(3))
->method('render')
->with('error500')
->will($this->returnValue(true));
$ExceptionRenderer->controller->response = $this->getMock('CakeResponse');
$ExceptionRenderer->render();
sort($ExceptionRenderer->controller->helpers);
$this->assertEquals(array('Form', 'Html', 'Session'), $ExceptionRenderer->controller->helpers);
}
} }

View file

@ -55,7 +55,7 @@ class I18nTest extends CakeTestCase {
function testTranslationCaching() { function testTranslationCaching() {
Configure::write('Config.language', 'cache_test_po'); Configure::write('Config.language', 'cache_test_po');
$i18n =& i18n::getInstance(); $i18n = i18n::getInstance();
// reset internally stored entries // reset internally stored entries
I18n::clear(); I18n::clear();

View file

@ -266,7 +266,7 @@ class AclBehaviorTest extends CakeTestCase {
* @access public * @access public
*/ */
function testSetupMulti() { function testSetupMulti() {
$User =& new AclPerson(); $User = new AclPerson();
$this->assertTrue(isset($User->Behaviors->Acl->settings['AclPerson'])); $this->assertTrue(isset($User->Behaviors->Acl->settings['AclPerson']));
$this->assertEqual($User->Behaviors->Acl->settings['AclPerson']['type'], 'both'); $this->assertEqual($User->Behaviors->Acl->settings['AclPerson']['type'], 'both');
$this->assertTrue(is_object($User->Aro)); $this->assertTrue(is_object($User->Aro));

View file

@ -209,7 +209,7 @@ class TestAppSchema extends CakeSchema {
*/ */
public $datatypes = array( public $datatypes = array(
'id' => array('type' => 'integer', 'null' => false, 'default' => 0, 'key' => 'primary'), 'id' => array('type' => 'integer', 'null' => false, 'default' => 0, 'key' => 'primary'),
'float_field' => array('type' => 'float', 'null' => false, 'length' => '5,2', 'default' => '', 'collate' => null, 'comment' => null), 'float_field' => array('type' => 'float', 'null' => false, 'length' => '5,2', 'default' => ''),
'bool' => array('type' => 'boolean', 'null' => false, 'default' => false), 'bool' => array('type' => 'boolean', 'null' => false, 'default' => false),
'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => true)), 'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => true)),
'tableParameters' => array() 'tableParameters' => array()

View file

@ -147,6 +147,8 @@ class DboMysqlTest extends CakeTestCase {
* @return void * @return void
*/ */
function testLocalizedFloats() { function testLocalizedFloats() {
$this->skipIf(DS === '\\', 'The locale is not supported in Windows and affect the others tests.');
$restore = setlocale(LC_ALL, null); $restore = setlocale(LC_ALL, null);
setlocale(LC_ALL, 'de_DE'); setlocale(LC_ALL, 'de_DE');

View file

@ -540,7 +540,7 @@ class ModelDeleteTest extends BaseModelTest {
*/ */
function testDeleteLinksWithPLuginJoinModel() { function testDeleteLinksWithPLuginJoinModel() {
$this->loadFixtures('Article', 'ArticlesTag', 'Tag'); $this->loadFixtures('Article', 'ArticlesTag', 'Tag');
$Article =& new Article(); $Article = new Article();
$Article->unbindModel(array('hasAndBelongsToMany' => array('Tag')), false); $Article->unbindModel(array('hasAndBelongsToMany' => array('Tag')), false);
unset($Article->Tag, $Article->ArticleTags); unset($Article->Tag, $Article->ArticleTags);
$Article->bindModel(array('hasAndBelongsToMany' => array( $Article->bindModel(array('hasAndBelongsToMany' => array(

View file

@ -565,7 +565,7 @@ class ModelValidationTest extends BaseModelTest {
); );
$Something = new Something(); $Something = new Something();
$JoinThing =& $Something->JoinThing; $JoinThing = $Something->JoinThing;
$JoinThing->validate = array('doomed' => array('rule' => 'notEmpty')); $JoinThing->validate = array('doomed' => array('rule' => 'notEmpty'));
@ -618,7 +618,7 @@ class ModelValidationTest extends BaseModelTest {
) )
); );
$Something = new Something(); $Something = new Something();
$JoinThing =& $Something->JoinThing; $JoinThing = $Something->JoinThing;
$JoinThing->validate = array('doomed' => array('rule' => 'notEmpty')); $JoinThing->validate = array('doomed' => array('rule' => 'notEmpty'));
$expectedError = array('doomed' => array('This field cannot be left blank')); $expectedError = array('doomed' => array('This field cannot be left blank'));

View file

@ -3016,7 +3016,7 @@ class ModelWriteTest extends BaseModelTest {
$testDb = ConnectionManager::getDataSource('test'); $testDb = ConnectionManager::getDataSource('test');
$mock = $this->getMock('DboSource', array(), array(), 'MockTransactionAssociatedDboSource', false); $mock = $this->getMock('DboSource', array(), array(), 'MockTransactionAssociatedDboSource', false);
$db =& ConnectionManager::create('mock_transaction_assoc', array( $db = ConnectionManager::create('mock_transaction_assoc', array(
'datasource' => 'MockTransactionAssociatedDboSource', 'datasource' => 'MockTransactionAssociatedDboSource',
)); ));
$this->mockObjects[] = $db; $this->mockObjects[] = $db;
@ -3824,12 +3824,24 @@ class ModelWriteTest extends BaseModelTest {
} }
/** /**
* testProductUpdateAllWithForeignKey * test updateAll with empty values.
*
* @return void
*/
function testUpdateAllEmptyValues() {
$this->loadFixtures('Author', 'Post');
$model = new Author();
$result = $model->updateAll(array('user' => '""'));
$this->assertTrue($result);
}
/**
* testUpdateAllWithJoins
* *
* @access public * @access public
* @return void * @return void
*/ */
function testProductUpdateAll() { function testUpdateAllWithJoins() {
$this->skipIf( $this->skipIf(
!$this->db instanceof Mysql, !$this->db instanceof Mysql,
'%s Currently, there is no way of doing joins in an update statement in postgresql or sqlite' '%s Currently, there is no way of doing joins in an update statement in postgresql or sqlite'
@ -3874,12 +3886,12 @@ class ModelWriteTest extends BaseModelTest {
} }
/** /**
* testProductUpdateAllWithoutForeignKey * testUpdateAllWithoutForeignKey
* *
* @access public * @access public
* @return void * @return void
*/ */
function testProductUpdateAllWithoutForeignKey() { function testUpdateAllWithoutForeignKey() {
$this->skipIf( $this->skipIf(
!$this->db instanceof Mysql, !$this->db instanceof Mysql,
'%s Currently, there is no way of doing joins in an update statement in postgresql' '%s Currently, there is no way of doing joins in an update statement in postgresql'

View file

@ -18,6 +18,7 @@
*/ */
App::uses('Dispatcher', 'Routing'); App::uses('Dispatcher', 'Routing');
App::uses('Xml', 'Utility');
App::uses('CakeRequest', 'Network'); App::uses('CakeRequest', 'Network');
class CakeRequestTestCase extends CakeTestCase { class CakeRequestTestCase extends CakeTestCase {
@ -33,6 +34,11 @@ class CakeRequestTestCase extends CakeTestCase {
$this->_post = $_POST; $this->_post = $_POST;
$this->_files = $_FILES; $this->_files = $_FILES;
$this->_app = Configure::read('App'); $this->_app = Configure::read('App');
$this->_case = null;
if (isset($_GET['case'])) {
$this->_case = $_GET['case'];
unset($_GET['case']);
}
Configure::write('App.baseUrl', false); Configure::write('App.baseUrl', false);
} }
@ -48,6 +54,9 @@ class CakeRequestTestCase extends CakeTestCase {
$_GET = $this->_get; $_GET = $this->_get;
$_POST = $this->_post; $_POST = $this->_post;
$_FILES = $this->_files; $_FILES = $this->_files;
if (!empty($this->_case)) {
$_GET['case'] = $this->_case;
}
Configure::write('App', $this->_app); Configure::write('App', $this->_app);
} }
@ -152,7 +161,7 @@ class CakeRequestTestCase extends CakeTestCase {
$_POST = array('one' => 1, 'two' => 'three'); $_POST = array('one' => 1, 'two' => 'three');
$request = new CakeRequest('some/path'); $request = new CakeRequest('some/path');
$this->assertEqual($request->params['form'], $_POST); $this->assertEquals($_POST, $request->data);
} }
/** /**
@ -1173,7 +1182,7 @@ class CakeRequestTestCase extends CakeTestCase {
), ),
), ),
array( array(
'Apache - No rewrite, document root set above top level cake dir, reques root, no PATH_INFO', 'Apache - No rewrite, document root set above top level cake dir, request root, no PATH_INFO',
array( array(
'App' => array( 'App' => array(
'base' => false, 'base' => false,
@ -1426,6 +1435,59 @@ class CakeRequestTestCase extends CakeTestCase {
$this->assertEquals('/posts/base_path/1/name:value?test=value', $result); $this->assertEquals('/posts/base_path/1/name:value?test=value', $result);
} }
/**
* Test the input() method.
*
* @return void
*/
function testInput() {
$request = $this->getMock('CakeRequest', array('_readStdin'));
$request->expects($this->once())->method('_readStdin')
->will($this->returnValue('I came from stdin'));
$result = $request->input();
$this->assertEquals('I came from stdin', $result);
}
/**
* Test input() decoding.
*
* @return void
*/
function testInputDecode() {
$request = $this->getMock('CakeRequest', array('_readStdin'));
$request->expects($this->once())->method('_readStdin')
->will($this->returnValue('{"name":"value"}'));
$result = $request->input('json_decode');
$this->assertEquals(array('name' => 'value'), (array)$result);
}
/**
* Test input() decoding with additional arguments.
*
* @return void
*/
function testInputDecodeExtraParams() {
$xml = <<<XML
<?xml version="1.0" encoding="utf-8"?>
<post>
<title id="title">Test</title>
</post>
XML;
$request = $this->getMock('CakeRequest', array('_readStdin'));
$request->expects($this->once())->method('_readStdin')
->will($this->returnValue($xml));
$result = $request->input('Xml::build', array('return' => 'domdocument'));
$this->assertInstanceOf('DOMDocument', $result);
$this->assertEquals(
'Test',
$result->getElementsByTagName('title')->item(0)->childNodes->item(0)->wholeText
);
}
/** /**
* loadEnvironment method * loadEnvironment method
* *
@ -1457,4 +1519,4 @@ class CakeRequestTestCase extends CakeTestCase {
} }
} }
} }

View file

@ -16,7 +16,7 @@
* @since CakePHP(tm) v 2.0.0 * @since CakePHP(tm) v 2.0.0
* @license MIT License (http://www.opensource.org/licenses/mit-license.php) * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/ */
App::uses('CakeEmail', 'Network'); App::uses('CakeEmail', 'Network/Email');
/** /**
* Help to test CakeEmail * Help to test CakeEmail

View file

@ -16,7 +16,7 @@
* @since CakePHP(tm) v 2.0.0 * @since CakePHP(tm) v 2.0.0
* @license MIT License (http://www.opensource.org/licenses/mit-license.php) * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/ */
App::uses('CakeEmail', 'Network'); App::uses('CakeEmail', 'Network/Email');
App::uses('AbstractTransport', 'Network/Email'); App::uses('AbstractTransport', 'Network/Email');
App::uses('SmtpTransport', 'Network/Email'); App::uses('SmtpTransport', 'Network/Email');
@ -211,8 +211,8 @@ class StmpProtocolTest extends CakeTestCase {
* @return void * @return void
*/ */
public function testSendData() { public function testSendData() {
$this->getMock('CakeEmail', array('message'), array(), 'TestCakeEmail'); $this->getMock('CakeEmail', array('message'), array(), 'SmtpCakeEmail');
$email = new TestCakeEmail(); $email = new SmtpCakeEmail();
$email->from('noreply@cakephp.org', 'CakePHP Test'); $email->from('noreply@cakephp.org', 'CakePHP Test');
$email->to('cake@cakephp.org', 'CakePHP'); $email->to('cake@cakephp.org', 'CakePHP');
$email->cc(array('mark@cakephp.org' => 'Mark Story', 'juan@cakephp.org' => 'Juan Basso')); $email->cc(array('mark@cakephp.org' => 'Mark Story', 'juan@cakephp.org' => 'Juan Basso'));
@ -225,10 +225,11 @@ class StmpProtocolTest extends CakeTestCase {
$data .= "To: CakePHP <cake@cakephp.org>\r\n"; $data .= "To: CakePHP <cake@cakephp.org>\r\n";
$data .= "Cc: Mark Story <mark@cakephp.org>, Juan Basso <juan@cakephp.org>\r\n"; $data .= "Cc: Mark Story <mark@cakephp.org>, Juan Basso <juan@cakephp.org>\r\n";
$data .= "Bcc: phpnut@cakephp.org\r\n"; $data .= "Bcc: phpnut@cakephp.org\r\n";
$data .= "X-Mailer: CakePHP Email Component\r\n"; $data .= "X-Mailer: CakePHP Email\r\n";
$data .= "Date: " . date(DATE_RFC2822) . "\r\n"; $data .= "Date: " . date(DATE_RFC2822) . "\r\n";
$data .= "Message-ID: <4d9946cf-0a44-4907-88fe-1d0ccbdd56cb@localhost>\r\n"; $data .= "Message-ID: <4d9946cf-0a44-4907-88fe-1d0ccbdd56cb@localhost>\r\n";
$data .= "Subject: Testing SMTP\r\n"; $data .= "Subject: Testing SMTP\r\n";
$data .= "MIME-Version: 1.0\r\n";
$data .= "Content-Type: text/plain; charset=UTF-8\r\n"; $data .= "Content-Type: text/plain; charset=UTF-8\r\n";
$data .= "Content-Transfer-Encoding: 7bit\r\n"; $data .= "Content-Transfer-Encoding: 7bit\r\n";
$data .= "\r\n"; $data .= "\r\n";

View file

@ -595,6 +595,34 @@ class HttpSocketTest extends CakeTestCase {
$this->assertFalse($this->Socket->connected); $this->assertFalse($this->Socket->connected);
} }
/**
* testRequestWithConstructor method
*
* @return void
*/
public function testRequestWithConstructor() {
$request = array(
'request' => array(
'uri' => array(
'scheme' => 'http',
'host' => 'localhost',
'port' => '5984',
'user' => null,
'pass' => null
)
)
);
$http = new MockHttpSocketRequests($request);
$expected = array('method' => 'GET', 'uri' => '/_test');
$http->expects($this->at(0))->method('request')->with($expected);
$http->get('/_test');
$expected = array('method' => 'GET', 'uri' => 'http://localhost:5984/_test?count=4');
$http->expects($this->at(0))->method('request')->with($expected);
$http->get('/_test', array('count' => 4));
}
/** /**
* testRequestWithResource * testRequestWithResource
* *

View file

@ -585,8 +585,7 @@ class DispatcherTest extends CakeTestCase {
$Dispatcher = new Dispatcher(); $Dispatcher = new Dispatcher();
$test = $Dispatcher->parseParams(new CakeRequest("/")); $test = $Dispatcher->parseParams(new CakeRequest("/"));
$this->assertFalse(empty($test['form']), "Parsed URL not returning post data"); $this->assertEquals($test['data']['testdata'], "My Posted Content");
$this->assertEquals($test['form']['testdata'], "My Posted Content");
} }
/** /**
@ -868,7 +867,7 @@ class DispatcherTest extends CakeTestCase {
$expected = array( $expected = array(
'pass' => array('home'), 'pass' => array('home'),
'named' => array('param'=> 'value', 'param2'=> 'value2'), 'plugin'=> 'my_plugin', 'named' => array('param'=> 'value', 'param2'=> 'value2'), 'plugin'=> 'my_plugin',
'controller'=> 'some_pages', 'action'=> 'display', 'form'=> array(), 'controller'=> 'some_pages', 'action'=> 'display'
); );
foreach ($expected as $key => $value) { foreach ($expected as $key => $value) {
$this->assertEqual($result[$key], $value, 'Value mismatch ' . $key . ' %'); $this->assertEqual($result[$key], $value, 'Value mismatch ' . $key . ' %');
@ -1000,7 +999,6 @@ class DispatcherTest extends CakeTestCase {
'action' => 'admin_index', 'action' => 'admin_index',
'prefix' => 'admin', 'prefix' => 'admin',
'admin' => true, 'admin' => true,
'form' => array(),
'return' => 1 'return' => 1
); );
foreach ($expected as $key => $value) { foreach ($expected as $key => $value) {
@ -1524,7 +1522,7 @@ class DispatcherTest extends CakeTestCase {
$dispatcher = new Dispatcher(); $dispatcher = new Dispatcher();
$result = $dispatcher->parseParams(new CakeRequest('/posts')); $result = $dispatcher->parseParams(new CakeRequest('/posts'));
$expected = array('pass' => array(), 'named' => array(), 'plugin' => null, 'controller' => 'posts', 'action' => 'add', '[method]' => 'POST', 'form' => array()); $expected = array('pass' => array(), 'named' => array(), 'plugin' => null, 'controller' => 'posts', 'action' => 'add', '[method]' => 'POST');
foreach ($expected as $key => $value) { foreach ($expected as $key => $value) {
$this->assertEqual($result[$key], $value, 'Value mismatch for ' . $key . ' %s'); $this->assertEqual($result[$key], $value, 'Value mismatch for ' . $key . ' %s');
} }
@ -1533,7 +1531,15 @@ class DispatcherTest extends CakeTestCase {
$_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE'] = 'PUT'; $_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE'] = 'PUT';
$result = $dispatcher->parseParams(new CakeRequest('/posts/5')); $result = $dispatcher->parseParams(new CakeRequest('/posts/5'));
$expected = array('pass' => array('5'), 'named' => array(), 'id' => '5', 'plugin' => null, 'controller' => 'posts', 'action' => 'edit', '[method]' => 'PUT', 'form' => array()); $expected = array(
'pass' => array('5'),
'named' => array(),
'id' => '5',
'plugin' => null,
'controller' => 'posts',
'action' => 'edit',
'[method]' => 'PUT'
);
foreach ($expected as $key => $value) { foreach ($expected as $key => $value) {
$this->assertEqual($result[$key], $value, 'Value mismatch for ' . $key . ' %s'); $this->assertEqual($result[$key], $value, 'Value mismatch for ' . $key . ' %s');
} }
@ -1542,7 +1548,7 @@ class DispatcherTest extends CakeTestCase {
$_SERVER['REQUEST_METHOD'] = 'GET'; $_SERVER['REQUEST_METHOD'] = 'GET';
$result = $dispatcher->parseParams(new CakeRequest('/posts/5')); $result = $dispatcher->parseParams(new CakeRequest('/posts/5'));
$expected = array('pass' => array('5'), 'named' => array(), 'id' => '5', 'plugin' => null, 'controller' => 'posts', 'action' => 'view', '[method]' => 'GET', 'form' => array()); $expected = array('pass' => array('5'), 'named' => array(), 'id' => '5', 'plugin' => null, 'controller' => 'posts', 'action' => 'view', '[method]' => 'GET');
foreach ($expected as $key => $value) { foreach ($expected as $key => $value) {
$this->assertEqual($result[$key], $value, 'Value mismatch for ' . $key . ' %s'); $this->assertEqual($result[$key], $value, 'Value mismatch for ' . $key . ' %s');
} }
@ -1550,7 +1556,7 @@ class DispatcherTest extends CakeTestCase {
$_POST['_method'] = 'PUT'; $_POST['_method'] = 'PUT';
$result = $dispatcher->parseParams(new CakeRequest('/posts/5')); $result = $dispatcher->parseParams(new CakeRequest('/posts/5'));
$expected = array('pass' => array('5'), 'named' => array(), 'id' => '5', 'plugin' => null, 'controller' => 'posts', 'action' => 'edit', '[method]' => 'PUT', 'form' => array()); $expected = array('pass' => array('5'), 'named' => array(), 'id' => '5', 'plugin' => null, 'controller' => 'posts', 'action' => 'edit', '[method]' => 'PUT');
foreach ($expected as $key => $value) { foreach ($expected as $key => $value) {
$this->assertEqual($result[$key], $value, 'Value mismatch for ' . $key . ' %s'); $this->assertEqual($result[$key], $value, 'Value mismatch for ' . $key . ' %s');
} }
@ -1563,7 +1569,7 @@ class DispatcherTest extends CakeTestCase {
$result = $dispatcher->parseParams(new CakeRequest('/posts')); $result = $dispatcher->parseParams(new CakeRequest('/posts'));
$expected = array( $expected = array(
'pass' => array(), 'named' => array(), 'plugin' => null, 'controller' => 'posts', 'action' => 'add', 'pass' => array(), 'named' => array(), 'plugin' => null, 'controller' => 'posts', 'action' => 'add',
'[method]' => 'POST', 'form' => array('extra' => 'data'), 'data' => array('Post' => array('title' => 'New Post')), '[method]' => 'POST', 'data' => array('extra' => 'data', 'Post' => array('title' => 'New Post')),
); );
foreach ($expected as $key => $value) { foreach ($expected as $key => $value) {
$this->assertEqual($result[$key], $value, 'Value mismatch for ' . $key . ' %s'); $this->assertEqual($result[$key], $value, 'Value mismatch for ' . $key . ' %s');

View file

@ -1275,7 +1275,7 @@ class RouterTest extends CakeTestCase {
$this->assertEqual($result, $expected); $this->assertEqual($result, $expected);
$result = Router::parse('/posts.atom?hello=goodbye'); $result = Router::parse('/posts.atom?hello=goodbye');
$expected = array('plugin' => null, 'controller' => 'posts.atom', 'action' => 'index', 'pass' => array(), 'named' => array(), 'url' => array('ext' => 'html')); $expected = array('plugin' => null, 'controller' => 'posts.atom', 'action' => 'index', 'pass' => array(), 'named' => array());
$this->assertEqual($result, $expected); $this->assertEqual($result, $expected);
Router::reload(); Router::reload();
@ -2164,7 +2164,7 @@ class RouterTest extends CakeTestCase {
$expected = array( $expected = array(
'plugin' => null, 'controller' => false, 'action' => false, 'plugin' => null, 'controller' => false, 'action' => false,
'param1' => '1', 'param2' => '2', 'form' => array() 'param1' => '1', 'param2' => '2'
); );
$this->assertEqual(Router::getParams(), $expected); $this->assertEqual(Router::getParams(), $expected);
$this->assertEqual(Router::getParam('controller'), false); $this->assertEqual(Router::getParam('controller'), false);
@ -2175,7 +2175,7 @@ class RouterTest extends CakeTestCase {
$params = array('controller' => 'pages', 'action' => 'display'); $params = array('controller' => 'pages', 'action' => 'display');
Router::setRequestInfo(array($params, $paths)); Router::setRequestInfo(array($params, $paths));
$expected = array('plugin' => null, 'controller' => 'pages', 'action' => 'display', 'form' => array()); $expected = array('plugin' => null, 'controller' => 'pages', 'action' => 'display');
$this->assertEqual(Router::getParams(), $expected); $this->assertEqual(Router::getParams(), $expected);
$this->assertEqual(Router::getParams(true), $expected); $this->assertEqual(Router::getParams(true), $expected);
} }

View file

@ -64,6 +64,53 @@ class CakeTestFixtureTestFixture extends CakeTestFixture {
); );
} }
/**
* StringFieldsTestFixture class
*
* @package cake
* @subpackage cake.cake.tests.cases.libs
*/
class StringsTestFixture extends CakeTestFixture {
/**
* name Property
*
* @var string
*/
var $name = 'Strings';
/**
* table property
*
* @var string
*/
var $table = 'strings';
/**
* Fields array
*
* @var array
*/
var $fields = array(
'id' => array('type' => 'integer', 'key' => 'primary'),
'name' => array('type' => 'string', 'length' => '255'),
'email' => array('type' => 'string', 'length' => '255'),
'age' => array('type' => 'integer', 'default' => 10)
);
/**
* Records property
*
* @var array
*/
var $records = array(
array('name' => 'Mark Doe', 'email' => 'mark.doe@email.com'),
array('name' => 'John Doe', 'email' => 'john.doe@email.com', 'age' => 20),
array('email' => 'jane.doe@email.com', 'name' => 'Jane Doe', 'age' => 30)
);
}
/** /**
* CakeTestFixtureImportFixture class * CakeTestFixtureImportFixture class
* *
@ -120,6 +167,7 @@ class FixturePrefixTest extends Model {
public $useDbConfig = 'test'; public $useDbConfig = 'test';
} }
/** /**
* Test case for CakeTestFixture * Test case for CakeTestFixture
* *
@ -203,7 +251,7 @@ class CakeTestFixtureTest extends CakeTestCase {
$Fixture->init(); $Fixture->init();
$this->assertEqual(array_keys($Fixture->fields), array('id', 'name', 'created')); $this->assertEqual(array_keys($Fixture->fields), array('id', 'name', 'created'));
$this->assertEqual($Fixture->table, 'fixture_tests'); $this->assertEqual($Fixture->table, 'fixture_tests');
$keys = array_flip(ClassRegistry::keys()); $keys = array_flip(ClassRegistry::keys());
$this->assertFalse(array_key_exists('fixtureimporttestmodel', $keys)); $this->assertFalse(array_key_exists('fixtureimporttestmodel', $keys));
@ -302,7 +350,7 @@ class CakeTestFixtureTest extends CakeTestCase {
} }
/** /**
* test that importing with records works. Make sure to try with postgres as its * test that importing with records works. Make sure to try with postgres as its
* handling of aliases is a workaround at best. * handling of aliases is a workaround at best.
* *
* @return void * @return void
@ -334,7 +382,7 @@ class CakeTestFixtureTest extends CakeTestCase {
$defaultDb->config = $defaultConfig; $defaultDb->config = $defaultConfig;
$Source->drop($newTestSuiteDb); $Source->drop($newTestSuiteDb);
} }
/** /**
@ -364,11 +412,62 @@ class CakeTestFixtureTest extends CakeTestCase {
*/ */
function testInsert() { function testInsert() {
$Fixture = new CakeTestFixtureTestFixture(); $Fixture = new CakeTestFixtureTestFixture();
$this->criticDb->expects($this->atLeastOnce())->method('insertMulti')->will($this->returnValue(true)); $this->criticDb->expects($this->atLeastOnce())
->method('insertMulti')
->will($this->returnCallback(array($this, '_insertCallback')));
$return = $Fixture->insert($this->criticDb);
$this->assertTrue(!empty($this->insertMulti));
$this->assertTrue($this->criticDb->fullDebug);
$this->assertTrue($return);
$this->assertEqual('fixture_tests', $this->insertMulti['table']);
$this->assertEqual(array('name', 'created'), $this->insertMulti['fields']);
$expected = array(
array('Gandalf', '2009-04-28 19:20:00'),
array('Captain Picard', '2009-04-28 19:20:00'),
array('Chewbacca', '2009-04-28 19:20:00')
);
$this->assertEqual($expected, $this->insertMulti['values']);
}
/**
* Helper function to be used as callback and store the parameters of an insertMulti call
*
* @param string $table
* @param string $fields
* @param string $values
* @return boolean true
*/
function _insertCallback($table, $fields, $values) {
$this->insertMulti['table'] = $table;
$this->insertMulti['fields'] = $fields;
$this->insertMulti['values'] = $values;
return true;
}
/**
* test the insert method
*
* @access public
* @return void
*/
function testInsertStrings() {
$Fixture = new StringsTestFixture();
$this->criticDb->expects($this->atLeastOnce())
->method('insertMulti')
->will($this->returnCallback(array($this, '_insertCallback')));
$return = $Fixture->insert($this->criticDb); $return = $Fixture->insert($this->criticDb);
$this->assertTrue($this->criticDb->fullDebug); $this->assertTrue($this->criticDb->fullDebug);
$this->assertTrue($return); $this->assertTrue($return);
$this->assertEqual('strings', $this->insertMulti['table']);
$this->assertEqual(array('email', 'name', 'age'), $this->insertMulti['fields']);
$expected = array(
array('Mark Doe', 'mark.doe@email.com', null),
array('John Doe', 'john.doe@email.com', 20),
array('Jane Doe', 'jane.doe@email.com', 30),
);
$this->assertEqual($expected, $this->insertMulti['values']);
} }
/** /**

View file

@ -145,9 +145,9 @@ class DebuggerTest extends CakeTestCase {
'pre' => array('class' => 'cake-debug'), 'pre' => array('class' => 'cake-debug'),
'a' => array( 'a' => array(
'href' => "javascript:void(0);", 'href' => "javascript:void(0);",
'onclick' => "document.getElementById('cakeErr9-trace').style.display = " . 'onclick' => "preg:/document\.getElementById\('cakeErr[a-z0-9]+\-trace'\)\.style\.display = " .
"(document.getElementById('cakeErr9-trace').style.display == 'none'" . "\(document\.getElementById\('cakeErr[a-z0-9]+\-trace'\)\.style\.display == 'none'" .
" ? '' : 'none');" " \? '' \: 'none'\);/"
), ),
'b' => array(), 'Notice', '/b', ' (8)', 'b' => array(), 'Notice', '/b', ' (8)',
)); ));
@ -171,7 +171,7 @@ class DebuggerTest extends CakeTestCase {
'&line={:line}">{:path}</a>, line {:line}' '&line={:line}">{:path}</a>, line {:line}'
)); ));
$result = Debugger::trace(); $result = Debugger::trace();
$this->assertPattern('/' . preg_quote('txmt://open?url=file:///', '/') . '/', $result); $this->assertPattern('/' . preg_quote('txmt://open?url=file://', '/') . '(\/|[A-Z]:\\\\)' . '/', $result);
Debugger::output('xml', array( Debugger::output('xml', array(
'error' => '<error><code>{:code}</code><file>{:file}</file><line>{:line}</line>' . 'error' => '<error><code>{:code}</code><file>{:file}</file><line>{:line}</line>' .

View file

@ -957,6 +957,40 @@ class SetTest extends CakeTestCase {
$result = Set::extract('/ParentNode/name', $hasMany); $result = Set::extract('/ParentNode/name', $hasMany);
$expected = array('Second'); $expected = array('Second');
$this->assertEqual($result, $expected); $this->assertEqual($result, $expected);
$data = array(
array(
'Category' => array(
'id' => 1,
'name' => 'First'
),
0 => array(
'value' => 50
)
),
array(
'Category' => array(
'id' => 2,
'name' => 'Second'
),
0 => array(
'value' => 60
)
)
);
$expected = array(
array(
'Category' => array(
'id' => 1,
'name' => 'First'
),
0 => array(
'value' => 50
)
)
);
$result = Set::extract('/Category[id=1]/..', $data);
$this->assertEqual($result, $expected);
} }
/** /**

View file

@ -3451,6 +3451,26 @@ class FormHelperTest extends CakeTestCase {
'/select' '/select'
); );
$this->assertTags($result, $expected); $this->assertTags($result, $expected);
$result = $this->Form->select(
'Model.multi_field', $options, array('multiple' => false, 'value' => array(0, 1))
);
$expected = array(
'select' => array(
'name' => 'data[Model][multi_field]', 'id' => 'ModelMultiField'
),
array('option' => array('value' => '0', 'selected' => 'selected')),
'first',
'/option',
array('option' => array('value' => '1', 'selected' => 'selected')),
'second',
'/option',
array('option' => array('value' => '2')),
'third',
'/option',
'/select'
);
$this->assertTags($result, $expected);
} }
/** /**
@ -3844,6 +3864,61 @@ class FormHelperTest extends CakeTestCase {
); );
$this->assertTags($result, $expected); $this->assertTags($result, $expected);
} }
/**
* testSelectHiddenFieldOmission method
*
* test that select() with 'hiddenField' => false omits the hidden field
*
* @access public
* @return void
*/
function testSelectHiddenFieldOmission() {
$result = $this->Form->select('Model.multi_field',
array('first', 'second'),
array('multiple' => 'checkbox', 'hiddenField' => false, 'value' => null)
);
$expected = array(
array('div' => array('class' => 'checkbox')),
array('input' => array('type' => 'checkbox', 'name' => 'data[Model][multi_field][]', 'value' => '0', 'id' => 'ModelMultiField0')),
array('label' => array('for' => 'ModelMultiField0')),
'first',
'/label',
'/div',
array('div' => array('class' => 'checkbox')),
array('input' => array('type' => 'checkbox', 'name' => 'data[Model][multi_field][]', 'value' => '1', 'id' => 'ModelMultiField1')),
array('label' => array('for' => 'ModelMultiField1')),
'second',
'/label',
'/div'
);
$this->assertTags($result, $expected);
$result = $this->Form->input('Model.multi_field', array(
'options' => array('first', 'second'),
'multiple' => 'checkbox',
'hiddenField' => false
));
$expected = array(
array('div' => array('class' => 'input select')),
array('label' => array('for' => 'ModelMultiField')),
'Multi Field',
'/label',
array('div' => array('class' => 'checkbox')),
array('input' => array('type' => 'checkbox', 'name' => 'data[Model][multi_field][]', 'value' => '0', 'id' => 'ModelMultiField0')),
array('label' => array('for' => 'ModelMultiField0')),
'first',
'/label',
'/div',
array('div' => array('class' => 'checkbox')),
array('input' => array('type' => 'checkbox', 'name' => 'data[Model][multi_field][]', 'value' => '1', 'id' => 'ModelMultiField1')),
array('label' => array('for' => 'ModelMultiField1')),
'second',
'/label',
'/div',
'/div'
);
$this->assertTags($result, $expected);
}
/** /**
* test that select() with multiple = checkbox works with overriding name attribute. * test that select() with multiple = checkbox works with overriding name attribute.

View file

@ -25,6 +25,12 @@ App::uses('FormHelper', 'View/Helper');
App::uses('View', 'View'); App::uses('View', 'View');
App::uses('ClassRegistry', 'Utility'); App::uses('ClassRegistry', 'Utility');
class JsEncodingObject {
protected $_title = 'Old thing';
private $__noshow = 'Never ever';
}
class OptionEngineHelper extends JsBaseEngineHelper { class OptionEngineHelper extends JsBaseEngineHelper {
protected $_optionMap = array( protected $_optionMap = array(
'request' => array( 'request' => array(
@ -797,13 +803,18 @@ class JsBaseEngineTest extends CakeTestCase {
* @return void * @return void
*/ */
function testObject() { function testObject() {
$this->JsEngine->useNative = false;
$object = array('title' => 'New thing', 'indexes' => array(5, 6, 7, 8)); $object = array('title' => 'New thing', 'indexes' => array(5, 6, 7, 8));
$result = $this->JsEngine->object($object); $result = $this->JsEngine->object($object);
$expected = '{"title":"New thing","indexes":[5,6,7,8]}'; $expected = '{"title":"New thing","indexes":[5,6,7,8]}';
$this->assertEqual($result, $expected); $this->assertEqual($result, $expected);
$object = new JsEncodingObject();
$object->title = 'New thing';
$object->indexes = array(5,6,7,8);
$result = $this->JsEngine->object($object);
$this->assertEqual($result, $expected);
$result = $this->JsEngine->object(array('default' => 0)); $result = $this->JsEngine->object(array('default' => 0));
$expected = '{"default":0}'; $expected = '{"default":0}';
$this->assertEqual($result, $expected); $this->assertEqual($result, $expected);
@ -842,70 +853,6 @@ class JsBaseEngineTest extends CakeTestCase {
$this->assertNoPattern('/.POSTFIX./', $result); $this->assertNoPattern('/.POSTFIX./', $result);
} }
/**
* test compatibility of JsBaseEngineHelper::object() vs. json_encode()
*
* @return void
*/
function testObjectAgainstJsonEncode() {
$skip = $this->skipIf(!function_exists('json_encode'), 'json_encode() not found, comparison tests skipped. %s');
if ($skip) {
return;
}
$this->JsEngine->useNative = false;
$data = array();
$data['mystring'] = "simple string";
$this->assertEqual(json_encode($data), $this->JsEngine->object($data));
$data['mystring'] = "strïng with spécial chârs";
$this->assertEqual(json_encode($data), $this->JsEngine->object($data));
$data['mystring'] = "a two lines\nstring";
$this->assertEqual(json_encode($data), $this->JsEngine->object($data));
$data['mystring'] = "a \t tabbed \t string";
$this->assertEqual(json_encode($data), $this->JsEngine->object($data));
$data['mystring'] = "a \"double-quoted\" string";
$this->assertEqual(json_encode($data), $this->JsEngine->object($data));
$data['mystring'] = 'a \\"double-quoted\\" string';
$this->assertEqual(json_encode($data), $this->JsEngine->object($data));
unset($data['mystring']);
$data[3] = array(1, 2, 3);
$this->assertEqual(json_encode($data), $this->JsEngine->object($data));
unset($data[3]);
$data = array('mystring' => null, 'bool' => false, 'array' => array(1, 44, 66));
$this->assertEqual(json_encode($data), $this->JsEngine->object($data));
}
/**
* test that JSON made with JsBaseEngineHelper::object() against json_decode()
*
* @return void
*/
function testObjectAgainstJsonDecode() {
$skip = $this->skipIf(!function_exists('json_encode'), 'json_encode() not found, comparison tests skipped. %s');
if ($skip) {
return;
}
$this->JsEngine->useNative = false;
$data = array("simple string");
$result = $this->JsEngine->object($data);
$this->assertEqual(json_decode($result), $data);
$data = array('my "string"');
$result = $this->JsEngine->object($data);
$this->assertEqual(json_decode($result), $data);
$data = array('my \\"string\\"');
$result = $this->JsEngine->object($data);
$this->assertEqual(json_decode($result), $data);
}
/** /**
* test Mapping of options. * test Mapping of options.
* *

View file

@ -314,6 +314,17 @@ class TextHelperTest extends CakeTestCase {
$this->assertPattern('#^' . $expected . '$#', $result); $this->assertPattern('#^' . $expected . '$#', $result);
} }
/**
* test invalid email addresses.
*
* @return void
*/
function testAutoLinkEmailInvalid() {
$result = $this->Text->autoLinkEmails('this is a myaddress@gmx-de test');
$expected = 'this is a myaddress@gmx-de test';
$this->assertEqual($expected, $result);
}
/** /**
* testHighlightCaseInsensitivity method * testHighlightCaseInsensitivity method
* *

View file

@ -111,12 +111,14 @@ class MediaViewTest extends CakeTestCase {
} }
/** /**
* testRenderWithUnknownFileType method * testRenderWithUnknownFileTypeGeneric method
* *
* @access public * @access public
* @return void * @return void
*/ */
function testRenderWithUnknownFileType() { function testRenderWithUnknownFileTypeGeneric() {
$currentUserAgent = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : null;
$_SERVER['HTTP_USER_AGENT'] = 'Some generic browser';
$this->MediaView->viewVars = array( $this->MediaView->viewVars = array(
'path' => LIBS . 'tests' . DS . 'test_app' . DS . 'config' . DS, 'path' => LIBS . 'tests' . DS . 'test_app' . DS . 'config' . DS,
'id' => 'no_section.ini', 'id' => 'no_section.ini',
@ -163,6 +165,139 @@ class MediaViewTest extends CakeTestCase {
$output = ob_get_clean(); $output = ob_get_clean();
$this->assertEqual("some_key = some_value\nbool_key = 1\n", $output); $this->assertEqual("some_key = some_value\nbool_key = 1\n", $output);
$this->assertTrue($result !== false); $this->assertTrue($result !== false);
if ($currentUserAgent !== null) {
$_SERVER['HTTP_USER_AGENT'] = $currentUserAgent;
}
}
/**
* testRenderWithUnknownFileTypeOpera method
*
* @access public
* @return void
*/
function testRenderWithUnknownFileTypeOpera() {
$currentUserAgent = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : null;
$_SERVER['HTTP_USER_AGENT'] = 'Opera/9.80 (Windows NT 6.0; U; en) Presto/2.8.99 Version/11.10';
$this->MediaView->viewVars = array(
'path' => LIBS . 'tests' . DS . 'test_app' . DS . 'config' . DS,
'id' => 'no_section.ini',
'extension' => 'ini',
);
$this->MediaView->expects($this->exactly(2))
->method('_isActive')
->will($this->returnValue(true));
$this->MediaView->response->expects($this->at(0))
->method('type')
->with('ini')
->will($this->returnValue(false));
$this->MediaView->response->expects($this->at(1))
->method('header')
->with(array(
'Date' => gmdate('D, d M Y H:i:s', time()) . ' GMT',
'Expires' => '0',
'Cache-Control' => 'private, must-revalidate, post-check=0, pre-check=0',
'Pragma' => 'no-cache'
));
$this->MediaView->response->expects($this->at(2))
->method('type')
->with('application/octetstream')
->will($this->returnValue(false));
$this->MediaView->response->expects($this->once())
->method('download')
->with('no_section.ini');
$this->MediaView->response->expects($this->at(4))
->method('header')
->with(array(
'Accept-Ranges' => 'bytes'
));
$this->MediaView->response->expects($this->at(5))
->method('header')
->with('Content-Length', 35);
$this->MediaView->response->expects($this->once())->method('send');
$this->MediaView->expects($this->once())->method('_clearBuffer');
$this->MediaView->expects($this->once())->method('_flushBuffer');
ob_start();
$result = $this->MediaView->render();
$output = ob_get_clean();
$this->assertEqual("some_key = some_value\nbool_key = 1\n", $output);
$this->assertTrue($result !== false);
if ($currentUserAgent !== null) {
$_SERVER['HTTP_USER_AGENT'] = $currentUserAgent;
}
}
/**
* testRenderWithUnknownFileTypeIE method
*
* @access public
* @return void
*/
function testRenderWithUnknownFileTypeIE() {
$currentUserAgent = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : null;
$_SERVER['HTTP_USER_AGENT'] = 'Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 5.2; Trident/4.0; Media Center PC 4.0; SLCC1; .NET CLR 3.0.04320)';
$this->MediaView->viewVars = array(
'path' => LIBS . 'tests' . DS . 'test_app' . DS . 'config' . DS,
'id' => 'no_section.ini',
'extension' => 'ini',
);
$this->MediaView->expects($this->exactly(2))
->method('_isActive')
->will($this->returnValue(true));
$this->MediaView->response->expects($this->at(0))
->method('type')
->with('ini')
->will($this->returnValue(false));
$this->MediaView->response->expects($this->at(1))
->method('header')
->with(array(
'Date' => gmdate('D, d M Y H:i:s', time()) . ' GMT',
'Expires' => '0',
'Cache-Control' => 'private, must-revalidate, post-check=0, pre-check=0',
'Pragma' => 'no-cache'
));
$this->MediaView->response->expects($this->at(2))
->method('type')
->with('application/force-download')
->will($this->returnValue(false));
$this->MediaView->response->expects($this->once())
->method('download')
->with('no_section.ini');
$this->MediaView->response->expects($this->at(4))
->method('header')
->with(array(
'Accept-Ranges' => 'bytes'
));
$this->MediaView->response->expects($this->at(5))
->method('header')
->with('Content-Length', 35);
$this->MediaView->response->expects($this->once())->method('send');
$this->MediaView->expects($this->once())->method('_clearBuffer');
$this->MediaView->expects($this->once())->method('_flushBuffer');
ob_start();
$result = $this->MediaView->render();
$output = ob_get_clean();
$this->assertEqual("some_key = some_value\nbool_key = 1\n", $output);
$this->assertTrue($result !== false);
if ($currentUserAgent !== null) {
$_SERVER['HTTP_USER_AGENT'] = $currentUserAgent;
}
} }
/** /**

View file

@ -40,7 +40,7 @@ class TestsAppsPostsController extends AppController {
* *
*/ */
function url_var() { function url_var() {
$this->set('params', $this->params); $this->set('params', $this->request->params);
$this->render('index'); $this->render('index');
} }
@ -49,7 +49,7 @@ class TestsAppsPostsController extends AppController {
* *
*/ */
function post_var() { function post_var() {
$this->set('data', $this->data); $this->set('data', $this->request->data);
$this->render('index'); $this->render('index');
} }

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