From 134744b5d6ebc2c1a9627278554c8d08bb4f79e5 Mon Sep 17 00:00:00 2001 From: phpnut Date: Sat, 24 Dec 2005 07:56:48 +0000 Subject: [PATCH] Merging: [1613] Fixing Bake (Ticket #5) [1612] Adding new file header [1611] Starting to fix Bake (Ticket #5) [1610] Adding patch for Ticket #63 [1609] Fixing ticket #13 [1608] Fix so only sub classes that have a __destruct() implemented will have it registered [1607] Fixing ticket #130 [1606] Fix for Ticket #190 [1605] Fixing ticket #136 [1604] Fixed would throw error if a action was camelCased in the url or in requestAction() [1603] fixed a few typos in home view git-svn-id: https://svn.cakephp.org/repo/trunk/cake@1614 3807eeeb-6ff5-0310-8944-8be069107fe0 --- cake/config/paths.php | 11 +- cake/dispatcher.php | 15 +- cake/libs/bake.php | 615 ++++++++++++++++++++++ cake/libs/file.php | 15 +- cake/libs/model/dbo/dbo.php | 2 +- cake/libs/model/dbo/dbo_pear.php | 5 + cake/libs/object.php | 20 +- cake/libs/view/helpers/ajax.php | 2 +- cake/libs/view/templates/pages/home.thtml | 2 +- cake/scripts/bake.php | 7 +- 10 files changed, 659 insertions(+), 35 deletions(-) create mode 100644 cake/libs/bake.php diff --git a/cake/config/paths.php b/cake/config/paths.php index 544905547..5b40b290c 100644 --- a/cake/config/paths.php +++ b/cake/config/paths.php @@ -144,17 +144,17 @@ define ('TESTS', ROOT.'tests'.DS); /** * Path to the controller test directory. */ -define ('CONTROLLER_TESTS',TESTS.APP_DIR.'controllers'.DS); +define ('CONTROLLER_TESTS',TESTS.APP_DIR.DS.'controllers'.DS); /** * Path to the helpers test directory. */ -define ('HELPER_TESTS', TESTS.APP_DIR.'helpers'.DS); +define ('HELPER_TESTS', TESTS.APP_DIR.DS.'helpers'.DS); /** * Path to the models' test directory. */ -define ('MODEL_TESTS', TESTS.APP_DIR.'models'.DS); +define ('MODEL_TESTS', TESTS.APP_DIR.DS.'models'.DS); /** * Path to the lib test directory. @@ -191,7 +191,10 @@ if ( (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] =='on' )) { $s ='s'; } -define('FULL_BASE_URL', 'http'.$s.'://'.$_SERVER['HTTP_HOST']); +if (isset($_SERVER['HTTP_HOST'])) +{ + define('FULL_BASE_URL', 'http'.$s.'://'.$_SERVER['HTTP_HOST']); +} /** * Web path to the public images directory. diff --git a/cake/dispatcher.php b/cake/dispatcher.php index 7dfee8463..60692951e 100644 --- a/cake/dispatcher.php +++ b/cake/dispatcher.php @@ -2,22 +2,22 @@ /* SVN FILE: $Id$ */ /** - * Dispatcher takes the URL information, parses it for paramters and + * Dispatcher takes the URL information, parses it for paramters and * tells the involved controllers what to do. - * - * This is the heart of Cake's operation. + * + * This is the heart of Cake's operation. * * PHP versions 4 and 5 * * CakePHP : Rapid Development Framework - * Copyright (c) 2005, Cake Software Foundation, Inc. + * Copyright (c) 2005, Cake Software Foundation, Inc. * 1785 E. Sahara Avenue, Suite 490-204 * Las Vegas, Nevada 89104 * * Licensed under The MIT License * Redistributions of files must retain the above copyright notice. * - * @filesource + * @filesource * @copyright Copyright (c) 2005, Cake Software Foundation, Inc. * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project * @package cake @@ -163,12 +163,12 @@ class Dispatcher extends Object $params['action'] = 'index'; } - if(in_array($params['action'], $classMethods) && strpos($params['action'], '_', 0) === 0) + if((in_array($params['action'], $classMethods) || in_array(strtolower($params['action']), $classMethods)) && strpos($params['action'], '_', 0) === 0) { $privateAction = true; } - if(!in_array($params['action'], $classMethods)) + if(!in_array($params['action'], $classMethods) && !in_array(strtolower($params['action']), $classMethods)) { $missingAction = true; } @@ -384,6 +384,7 @@ class Dispatcher extends Object */ function error404 ($url, $message) { + header("HTTP/1.0 404 Not Found"); $this->error('404', 'Not found', sprintf(ERROR_404, $url, $message)); } } diff --git a/cake/libs/bake.php b/cake/libs/bake.php new file mode 100644 index 000000000..6abfa7087 --- /dev/null +++ b/cake/libs/bake.php @@ -0,0 +1,615 @@ + + * Copyright (c) 2005, Cake Software Foundation, Inc. + * 1785 E. Sahara Avenue, Suite 490-204 + * Las Vegas, Nevada 89104 + * + * Licensed under The MIT License + * Redistributions of files must retain the above copyright notice. + * + * @filesource + * @copyright Copyright (c) 2005, Cake Software Foundation, Inc. + * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project + * @package cake + * @subpackage cake.cake.app.webroot + * @since CakePHP v 0.10.3.1612 + * @version $Revision$ + * @modifiedby $LastChangedBy$ + * @lastmodified $Date$ + * @license http://www.opensource.org/licenses/mit-license.php The MIT License + */ + +/** + * Require needed libraries. + */ +uses('object', 'inflector'); + +/** + * Bake class creates files in configured application directories. This is a + * base class for /scripts/add.php. + * + * @package cake + * @subpackage cake.libs + * @since CakePHP v CakePHP v 0.10.3.1612 + */ +class Bake extends Object +{ + + /** + * Standard input stream (php://stdin). + * + * @var resource + * @access private + */ + var $stdin = null; + + /** + * Standard output stream (php://stdout). + * + * @var resource + * @access private + */ + var $stdout = null; + + /** + * Standard error stream (php://stderr). + * + * @var resource + * @access private + */ + var $stderr = null; + + /** + * Counts actions taken. + * + * @var integer + * @access private + */ + var $actions = null; + + /** + * Decides whether to overwrite existing files without asking. + * + * @var boolean + * @access private + */ + var $dontAsk = false; + + /** + * Returns code template for PHP file generator. + * + * @param string $type + * @return string + * @access private + */ + function template ($type) + { + switch ($type) + { + case 'view': return "%s"; + case 'model': return ""; + case 'action': return "\n\tfunction %s () {\n\t\t\n\t}\n"; + case 'ctrl': return ""; + case 'helper': return ""; + case 'test': return 'abc = new %s (); + } + + // called after the tests + function tearDown() + { + unset($this->abc); + } + +/* + function testFoo () + { + $result = $this->abc->Foo(); + $expected = \'\'; + $this->assertEquals($result, $expected); + } +*/ +} + +?>'; + default: + return false; + } + } + + /** + * Baker's constructor method. Initialises bakery, and starts production. + * + * @param string $type + * @param array $names + * @access public + * @uses Bake::stdin Opens stream for reading. + * @uses Bake::stdout Opens stream for writing. + * @uses Bake::stderr Opens stream for writing. + * @uses Bake::newModel() Depending on the case, can create a new model. + * @uses Bake::newView() Depending on the case, can create a new view. + * @uses Bake::newController() Depending on the case, can create a new controller. + */ + function __construct ($type, $names) + { + $this->stdin = fopen('php://stdin', 'r'); + $this->stdout = fopen('php://stdout', 'w'); + $this->stderr = fopen('php://stderr', 'w'); + + // Output directory name + fwrite($this->stderr, "\n".substr(ROOT,0,strlen(ROOT)-1).":\n".str_repeat('-',strlen(ROOT)+1)."\n"); + + switch ($type) + { + case 'model': + case 'models': + foreach ($names as $model_name) + { + $this->newModel($model_name); + } + break; + + case 'controller': + case 'ctrl': + $controller = array_shift($names); + + $add_actions = array(); + + $controllerPlural = Inflector::pluralize($controller); + + if ($controllerPlural != $controller) + { + fwrite($this->stdout, "I use pluralized Controller names. You entered '$controller'. I can inflect it to '$controllerPlural'. Should I? If no, I will use '$controller'. [y/n/q] "); + $key = trim(fgets($this->stdin)); + } + else + { + $key = 'n'; + } + + if ($key=='q') + { + fwrite($this->stdout, "Quitting.\n"); + exit; + } + elseif ($key=='y') + { + $controller = $controllerPlural; + } + + foreach ($names as $action) + { + $add_actions[] = $action; + $this->newView($controller, $action); + } + + $this->newController($controller, $add_actions); + break; + + case 'view': + case 'views': + $r = null; + foreach ($names as $model_name) + { + if (preg_match('/^([a-z0-9_]+(?:\/[a-z0-9_]+)*)\/([a-z0-9_]+)$/i', $model_name, $r)) + { + $this->newView($r[1], $r[2]); + } + } + break; + } + + if (!$this->actions) + { + fwrite($this->stderr, "Nothing to do, quitting.\n"); + } + } + + /** + * Creates new view in VIEWS/$controller/ directory. + * + * @param string $controller + * @param string $name + * @access private + * @uses Inflector::underscore() Underscores directory's name. + * @uses Bake::createDir() Creates new directory in views dir, named after the controller. + * @uses VIEWS + * @uses Bake::createFile() Creates view file. + * @uses Bake::template() Collects view template. + * @uses Bake::actions Adds one action for each run. + */ + function newView ($controller, $name) + { + $dir = Inflector::underscore($controller); + $path = $dir.DS.strtolower($name).".thtml"; + + $this->createDir(VIEWS.$dir); + $fn = VIEWS.$path; + $this->createFile($fn, sprintf($this->template('view'), "

Edit app".DS."views".DS."{$path} to change this message.

")); + $this->actions++; + } + + /** + * Creates new controller with defined actions, controller's test and + * helper with helper's test. + * + * @param string $name + * @param array $actions + * @access private + * @uses Inflector::pluralize() + * @uses Bake::makeController() + * @uses Bake::makeControllerTest() + * @uses Bake::makeHelper() + * @uses Bake::makeHelperTest() + * @uses Bake::actions Adds one action for each run. + */ + function newController ($name, $actions=array()) + { + $this->makeController($name, $actions); + $this->makeControllerTest($name); + //$this->makeHelper($name); + //$this->makeHelperTest($name); + $this->actions++; + } + + /** + * Creates new controller file with defined actions. + * + * @param string $name + * @param array $actions + * @return boolean + * @access private + * @uses Bake::makeControllerName() CamelCase for controller's name. + * @uses Bake::makeHelperName() CamelCase for helper's name. + * @uses Bake::template() Controller's template. + * @uses Bake::getActions() Actions' templates to be included in the controller. + * @uses Bake::createFile() Creates controller's file. + * @uses Bake::makeControllerFn() Underscored name for controller's filename. + */ + function makeController ($name, $actions) + { + $ctrl = $this->makeControllerName($name); + $helper = $this->makeHelperName($name); + //$body = sprintf($this->template('ctrl'), $ctrl, $helper, join('', $this->getActions($actions))); + $body = sprintf($this->template('ctrl'), $ctrl, 'AppController', join('', $this->getActions($actions))); + return $this->createFile($this->makeControllerFn($name), $body); + } + + /** + * Returns controller's name in CamelCase. + * + * @param string $name + * @return string + * @access private + * @uses Inflector::camelize CamelCase for controller name. + */ + function makeControllerName ($name) + { + return Inflector::camelize($name).'Controller'; + } + + /** + * Returns a name for controller's file, underscored. + * + * @param string $name + * @return string + * @access private + * @uses Inflector::underscore() Underscore for controller's file name. + */ + function makeControllerFn ($name) + { + return CONTROLLERS.Inflector::underscore($name).'_controller.php'; + } + + /** + * Creates new test for a controller. + * + * @param string $name + * @return boolean + * @access private + * @uses CONTROLLER_TESTS + * @uses Inflector::underscore() + * @uses Bake::getTestBody() + * @uses Bake::makeControllerName() + * @uses Bake::createFile() + */ + function makeControllerTest ($name) + { + $fn = CONTROLLER_TESTS.Inflector::underscore($name).'_controller_test.php'; + $body = $this->getTestBody($this->makeControllerName($name)); + + return true; //$this->createFile($fn, $body); // Disable creating tests till later + } + + /** + * Creates new helper. + * + * @param string $name + * @return boolean + * @access private + * @uses Bake::template() + * @uses Bake::makeHelperName() + * @uses Bake::createFile() + * @uses Bake::makeHelperFn() + */ + function makeHelper ($name) + { + $body = sprintf($this->template('helper'), $this->makeHelperName($name)); + + return $this->createFile($this->makeHelperFn($name), $body); + } + + /** + * Returns CamelCase name for a helper. + * + * @param string $name + * @return string + * @access private + * @uses Inflector::camelize() + */ + function makeHelperName ($name) + { + return Inflector::camelize($name).'Helper'; + } + + /** + * Underscores file name for a helper. + * + * @param string $name + * @return string + * @access private + * @uses HELPERS + * @uses Inflector::underscore() + */ + function makeHelperFn ($name) + { + return HELPERS.Inflector::underscore($name).'_helper.php'; + } + + /** + * Creates new test for a helper. + * + * @param string $name + * @return boolean + * @access private + * @uses HELPER_TESTS + * @uses Inflector::underscore() + * @uses Bake::getTestBody() + * @uses Bake::makeHelperName() + * @uses Bake::createFile() + */ + function makeHelperTest ($name) + { + $fn = HELPER_TESTS.Inflector::underscore($name).'_helper_test.php'; + $body = $this->getTestBody($this->makeHelperName($name)); + + return $this->createFile($fn, $body); + } + + /** + * Returns an array of actions' templates. + * + * @param array $as + * @return array + * @access private + * @uses Bake::template() + */ + function getActions ($as) + { + $out = array(); + foreach ($as as $a) + { + $out[] = sprintf($this->template('action'), $a); + } + return $out; + } + + /** + * Returns a test template for given class. + * + * @param string $class + * @return string + * @access private + * @uses Bake::template() + */ + function getTestBody ($class) + { + return sprintf($this->template('test'), $class, $class); + } + + /** + * Creates new model. + * + * @param string $name + * @access private + * @uses Bake::createFile() + * @uses Bake::getModelFn() + * @uses Bake::template() + * @uses Bake::getModelName() + * @uses Bake::makeModelTest() + * @uses Bake::actions + */ + function newModel ($name) + { + $nameSingular = Inflector::singularize($name); + + if ($nameSingular != $name) + { + fwrite($this->stdout, "I use singular Model names. You entered '$name'. I can inflect it to '$nameSingular'. Should I? If no, I will use '$name'. [y/n/q] "); + $key = trim(fgets($this->stdin)); + } + else + { + $key = 'n'; + } + + if ($key=='q') + { + fwrite($this->stdout, "Quitting.\n"); + exit; + } + elseif ($key=='y') + { + $name = $nameSingular; + } + + $this->createFile($this->getModelFn($name), sprintf($this->template('model'), $this->getModelName($name))); + //$this->makeModelTest ($name); + // TODO: Add model test back when I'm less lazy + $this->actions++; + } + + /** + * Returns an underscored filename for a model. + * + * @param string $name + * @return string + * @access private + * @uses MODELS + * @uses Inflector::underscore() + */ + function getModelFn ($name) + { + return MODELS.Inflector::underscore($name).'.php'; + } + + /** + * Creates a test for a given model. + * + * @param string $name + * @return boolean + * @access private + * @uses MODEL_TESTS + * @uses Inflector::underscore() + * @uses Bake::getTestBody() + * @uses Bake::getModelName() + * @uses Bake::createFile() + */ + function makeModelTest ($name) + { + $fn = MODEL_TESTS.Inflector::underscore($name).'_test.php'; + $body = $this->getTestBody($this->getModelName($name)); + + return $this->createFile($fn, $body); + } + + /** + * Returns CamelCased name of a model. + * + * @param string $name + * @return string + * @access private + * @uses Inflector::camelize() + */ + function getModelName ($name) + { + return Inflector::camelize($name); + } + + /** + * Creates a file with given path and contents. + * + * @param string $path + * @param string $contents + * @return boolean + * @access private + * @uses Bake::dontAsk + * @uses Bake::stdin + * @uses Bake::stdout + * @uses Bake::stderr + */ + function createFile ($path, $contents) + { + echo "\nCreating file $path\n"; + $shortPath = str_replace(ROOT,null,$path); + + if (is_file($path) && !$this->dontAsk) + { + fwrite($this->stdout, "File {$shortPath} exists, overwrite? (y/n/q):"); + $key = trim(fgets($this->stdin)); + + if ($key=='q') + { + fwrite($this->stdout, "Quitting.\n"); + exit; + } + elseif ($key=='a') + { + $this->dont_ask = true; + } + elseif ($key=='y') + { + } + else + { + fwrite($this->stdout, "Skip {$shortPath}\n"); + return false; + } + } + + if ($f = fopen($path, 'w')) + { + fwrite($f, $contents); + fclose($f); + fwrite($this->stdout, "Wrote {$shortPath}\n"); + // debug ("Wrote {$path}"); + return true; + } + else + { + fwrite($this->stderr, "Error! Couldn't open {$shortPath} for writing.\n"); + // debug ("Error! Couldn't open {$path} for writing."); + return false; + } + } + + /** + * Creates a directory with given path. + * + * @param string $path + * @return boolean + * @access private + * @uses Bake::stdin + * @uses Bake::stdout + */ + function createDir ($path) + { + if (is_dir($path)) + { + return true; + } + + $shortPath = str_replace(ROOT, null, $path); + + if (mkdir($path)) + { + fwrite($this->stdout, "Created {$shortPath}\n"); + // debug ("Created {$path}"); + return true; + } + else + { + fwrite($this->stderr, "Error! Couldn't create dir {$shortPath}\n"); + // debug ("Error! Couldn't create dir {$path}"); + return false; + } + } + +} +?> \ No newline at end of file diff --git a/cake/libs/file.php b/cake/libs/file.php index 54befdb21..f682f7612 100644 --- a/cake/libs/file.php +++ b/cake/libs/file.php @@ -64,17 +64,18 @@ class File extends Object * @param boolean $create Create file if it does not exist * @return File */ - function File ($path , $create = false ) + function __construct ($path, $create = false) { - $this->folder = new Folder( dirname( realpath($path) ) , $create ); + parent::__construct(); - $this->name = basename( realpath($path) ); + $this->folder = new Folder(dirname($path), $create); + $this->name = basename($path); - if ( !$this->exists() ) + if (!$this->exists()) { - if ( $create === true ) + if ($create === true) { - if ( !$this->create() ) + if (!$this->create()) { return false; } @@ -93,7 +94,7 @@ class File extends Object */ function read () { - return file_get_contents( $this->getFullPath() ); + return file_get_contents($this->getFullPath()); } /** diff --git a/cake/libs/model/dbo/dbo.php b/cake/libs/model/dbo/dbo.php index 61f0709aa..489aedcf3 100644 --- a/cake/libs/model/dbo/dbo.php +++ b/cake/libs/model/dbo/dbo.php @@ -212,7 +212,7 @@ class DBO extends Object * Destructor. Closes connection to the database. * */ - function __destructor() + function __destruct() { $this->close(); } diff --git a/cake/libs/model/dbo/dbo_pear.php b/cake/libs/model/dbo/dbo_pear.php index 31359dc85..1a5ac0346 100644 --- a/cake/libs/model/dbo/dbo_pear.php +++ b/cake/libs/model/dbo/dbo_pear.php @@ -65,6 +65,11 @@ class DBO_Pear extends DBO { $this->config = $config; + if (preg_match('#^pear[-_](.*)$#i', $config['driver'], $res)) + { + $config['driver'] = $res[1]; + } + $dsn = $config['driver'].'://'.$config['login'].':'.$config['password'].'@'.$config['host'].'/'.$config['database']; $options = array( 'debug' => DEBUG-1, diff --git a/cake/libs/object.php b/cake/libs/object.php index ca643cf8c..df30198ff 100644 --- a/cake/libs/object.php +++ b/cake/libs/object.php @@ -10,7 +10,7 @@ * PHP versions 4 and 5 * * CakePHP : Rapid Development Framework - * Copyright (c) 2005, Cake Software Foundation, Inc. + * Copyright (c) 2005, Cake Software Foundation, Inc. * 1785 E. Sahara Avenue, Suite 490-204 * Las Vegas, Nevada 89104 * @@ -64,9 +64,14 @@ class Object */ function Object() { - $args = func_get_args(); - register_shutdown_function(array(&$this, '__destruct')); - call_user_func_array(array(&$this, '__construct'), $args); + $args = func_get_args(); + + if (method_exists($this, '__destruct')) + { + register_shutdown_function(array(&$this, '__destruct')); + } + + call_user_func_array(array(&$this, '__construct'), $args); } /** @@ -76,13 +81,6 @@ class Object { } -/** - * Class destructor, overridden in descendant classes. - */ - function __destruct() - { - } - /** * Object-to-string conversion. * Each class can override this method as necessary. diff --git a/cake/libs/view/helpers/ajax.php b/cake/libs/view/helpers/ajax.php index 98931c481..a4d5835c1 100644 --- a/cake/libs/view/helpers/ajax.php +++ b/cake/libs/view/helpers/ajax.php @@ -232,7 +232,7 @@ class AjaxHelper extends Helper function form($id, $options = null, $html_options = array()) { $html_options['id'] = $id; - return $this->html->formTag(null, "post", $html_options) . + return $this->Html->formTag(null, "post", $html_options) . $this->Javascript->event("$('$id')", "submit", "function(){" . $this->remoteFunction($options) . "; return false;}"); } diff --git a/cake/libs/view/templates/pages/home.thtml b/cake/libs/view/templates/pages/home.thtml index 1290991bc..3fc7e915c 100644 --- a/cake/libs/view/templates/pages/home.thtml +++ b/cake/libs/view/templates/pages/home.thtml @@ -31,7 +31,7 @@

Your database configuration file is

-

Cakeconnected ? ' is able to' : ' is not able to'; ' connect to the database'; ?>.

+

Cakeconnected ? ' is able to ' : ' is not able to ';?>connect to the database.


Take a bite out of CakePHP Beta

diff --git a/cake/scripts/bake.php b/cake/scripts/bake.php index 2580d0428..5a328da43 100644 --- a/cake/scripts/bake.php +++ b/cake/scripts/bake.php @@ -33,10 +33,11 @@ * START-UP */ define ('DS', DIRECTORY_SEPARATOR); -define ('ROOT', dirname(dirname(__FILE__)).DS); +define ('ROOT', dirname(dirname(dirname(__FILE__))).DS); +define ('APP_DIR', 'app'); -require (ROOT.'config'.DS.'paths.php'); -require (LIBS.'basics.php'); +require (ROOT.'cake'.DS.'config'.DS.'paths.php'); +require (ROOT.'cake'.DS.'basics.php'); uses ('bake'); $waste = array_shift($argv);