git-svn-id: https://svn.cakephp.org/repo/trunk/cake@148 3807eeeb-6ff5-0310-8944-8be069107fe0

This commit is contained in:
pies 2005-05-21 22:40:51 +00:00
parent b2ba766780
commit b5f6dba58e
27 changed files with 479 additions and 849 deletions

View file

@ -1,7 +1,5 @@
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteRule ^$ public/ [L]
#RewriteCond %{REQUEST_URI} !^/cake$
RewriteRule (.*) public/$1 [L]
</IfModule>

View file

@ -38,24 +38,4 @@
*/
define ('DEBUG', 0);
/**
* Page cacheing setting.
*/
define ('CACHE_PAGES', false);
/**
* Cache lifetime in seconds, 0 for debugging, -1 for eternity.
*/
define ('CACHE_PAGES_FOR', -1);
/**
* Set any extra debug options here.
*/
if (DEBUG)
{
error_reporting(E_ALL);
ini_set('error_reporting', E_ALL);
$TIME_START = getmicrotime();
}
?>

View file

@ -30,27 +30,30 @@
*/
/**
* Database configuration array. You can configure multiple connections.
*
* @var array $DATABASE_CONFIG
* Database configuration class.
* You can specify multiple configurations for production, development and testing.
*/
$DATABASE_CONFIG = array(
'devel' => array(
class DATABASE_CONFIG {
function devel () {
return array(
'driver' => 'mysql',
'host' => 'localhost',
'login' => 'login',
'password' => 'password',
'database' => 'database'
),
'login' => 'www',
'password' => '',
'database' => 'project_name'
);
}
'test' => array(
function test () {
return array(
'driver' => 'mysql',
'host' => 'localhost',
'login' => 'login',
'password' => 'password',
'database' => 'database'
),
);
'login' => 'www-test',
'password' => '',
'database' => 'project_name-test'
);
}
}
?>

View file

@ -42,71 +42,73 @@ if( !defined('ROOT') ){
/**
* Path to the application directory.
*/
define ('APP', ROOT.'app/');
define ('APP', ROOT.'app'.DS);
/**
* Path to the application models directory.
*/
define ('MODELS', APP.'models/');
define ('MODELS', APP.'models'.DS);
/**
* Path to the application controllers directory.
*/
define ('CONTROLLERS', APP.'controllers/');
define ('CONTROLLERS', APP.'controllers'.DS);
/**
* Path to the application helpers directory.
*/
define ('HELPERS', APP.'helpers/');
define ('HELPERS', APP.'helpers'.DS);
/**
* Path to the application views directory.
*/
define ('VIEWS', APP.'views/');
define ('VIEWS', APP.'views'.DS);
/**
* Path to the configuration files directory.
*/
define ('CONFIGS', ROOT.'config/');
define ('CONFIGS', ROOT.'config'.DS);
/**
* Path to the libs directory.
*/
define ('LIBS', ROOT.'libs/');
define ('LIBS', ROOT.'libs'.DS);
define ('LOGS', ROOT.'logs'.DS);
define ('MODULES', ROOT.'modules'.DS);
/**
* Path to the public directory.
*/
define ('PUBLIC', ROOT.'public/');
define ('PUBLIC', ROOT.'public'.DS);
/**
* Path to the tests directory.
*/
define ('TESTS', ROOT.'tests/');
define ('TESTS', ROOT.'tests'.DS);
/**
* Path to the vendors directory.
*/
define ('VENDORS', ROOT.'vendors/');
define ('VENDORS', ROOT.'vendors'.DS);
/**
* Path to the controller test directory.
*/
define ('CONTROLLER_TESTS',TESTS.'app/controllers/');
define ('CONTROLLER_TESTS',TESTS.'app'.DS.'controllers'.DS);
/**
* Path to the helpers test directory.
*/
define ('HELPER_TESTS', TESTS.'app/helpers/');
define ('HELPER_TESTS', TESTS.'app'.DS.'helpers'.DS);
/**
* Path to the models test directory.
*/
define ('MODEL_TESTS', TESTS.'app/models/');
define ('MODEL_TESTS', TESTS.'app'.DS.'models'.DS);
/**
* Path to the lib test directory.
*/
define ('LIB_TESTS', TESTS.'libs/')
define ('LIB_TESTS', TESTS.'libs'.DS);
?>

View file

@ -43,8 +43,8 @@ uses('object', 'inflector');
* @subpackage cake.libs
* @since Cake v 0.2.9
*/
class Bake extends Object
{
class Bake extends Object {
/**
* Standard input stream (php://stdin).
*
@ -455,16 +455,16 @@ class %sTest extends TestCase {
if (is_file($path) && !$this->dontAsk) {
fwrite($this->stdout, "File {$path} exists, overwrite? (yNaq) ");
$key = fgets($this->stdin);
$key = trim(fgets($this->stdin));
if (preg_match("/^q$/", $key)) {
if ($key=='q') {
fwrite($this->stdout, "Quitting.\n");
exit;
}
elseif (preg_match("/^a$/", $key)) {
$this->dontAsk = true;
elseif ($key=='a') {
$this->dont_ask = true;
}
elseif (preg_match("/^y$/", $key)) {
elseif ($key=='y') {
}
else {
fwrite($this->stdout, "Skip {$path}\n");

View file

@ -30,20 +30,6 @@
*
*/
/**
* Loads all libs from LIBS directory.
*
* @uses listModules()
* @uses LIBS
*/
function loadLibs () {
foreach (listModules(LIBS) as $lib) {
if ($lib != 'basics') {
include_once (LIBS.$lib.'.php');
}
}
}
/**
* Loads all models.
*
@ -53,8 +39,8 @@ function loadLibs () {
*/
function loadModels () {
require (APP.'app_model.php');
foreach (listModules(MODELS) as $model) {
require (MODELS.$model.'.php');
foreach (listClasses(MODELS) as $model_fn) {
require (MODELS.$model_fn);
}
}
@ -69,97 +55,52 @@ function loadModels () {
function loadControllers () {
require (APP.'app_controller.php');
foreach (listModules(HELPERS) as $helper) {
foreach (listClasses(HELPERS) as $helper) {
require (HELPERS.$helper.'.php');
}
foreach (listModules(CONTROLLERS) as $controller) {
foreach (listClasses(CONTROLLERS) as $controller) {
require (CONTROLLERS.$controller.'.php');
}
}
/**
* Lists all .php files from a given path.
* Loads a controller and it's helper libraries
*
* @param string $name
* @return boolean
*/
function loadController ($name) {
$controller_fn = CONTROLLERS.Inflector::underscore($name).'_controller.php';
$helper_fn = HELPERS.Inflector::underscore($name).'_helper.php';
require(APP.'app_controller.php');
if (file_exists($helper_fn))
require($helper_fn);
return file_exists($controller_fn)? require($controller_fn): false;
}
/**
* Lists PHP files in a specified directory
*
* @param string $path
* @param boolean $sort
* @return array
*/
function listModules($path, $sort=true) {
if ($d = opendir($path)) {
$out = array();
$r = null;
while (false !== ($fn = readdir($d))) {
if (preg_match('#^(.+)\.php$#', $fn, $r)) {
$out[] = $r[1];
}
}
if ($sort || $this->sort) {
sort($out);
}
return $out;
}
else {
return false;
}
function listClasses($path) {
$modules = new Folder($path);
return $modules->find('(.+)\.php');
}
/**
* Loads core config.
*
* @uses $TIME_START
* @uses CONFIGS
* Loads configuration files
*/
function usesConfig () {
global $TIME_START;
require (CONFIGS.'core.php');
}
/**
* Loads database connection identified by $level.
*
* @param string $level
* @uses $DB
* @uses DbFactory::make()
* @uses loadDatabaseConfig()
*/
function usesDatabase ($level='devel') {
global $DB;
$DB = DbFactory::make(loadDatabaseConfig($level));
}
/**
* Loads database configuration identified by $level from CONFIGS/database.php.
*
* @param string $level
* @return mixed
*/
function loadDatabaseConfig ($level='devel') {
if (file_exists(CONFIGS.'database.php'))
require (CONFIGS.'database.php');
if (empty($DATABASE_CONFIG))
return false;
if (empty($DATABASE_CONFIG[$level]))
return false;
if (!is_array($DATABASE_CONFIG[$level]))
return false;
return $DATABASE_CONFIG[$level];
}
/**
* Loads tags configuration from CONFIGS/tags.php.
*
* @uses CONFIGS
*/
function usesTagGenerator () {
require (CONFIGS.'tags.php');
function config () {
$args = func_get_args();
foreach ($args as $arg) {
require_once (CONFIGS.$arg.'.php');
}
}
/**
@ -252,13 +193,15 @@ if (!function_exists('array_combine')) {
function array_combine($a1, $a2) {
$a1 = array_values($a1);
$a2 = array_values($a2);
$c1 = count($a1);
$c2 = count($a2);
if (count($a1) != count($a2)) return false; // different lenghts
if (count($a1) <= 0) return false; // arrays are the same and both are empty
if ($c1 != $c2) return false; // different lenghts
if ($c1 <= 0) return false; // arrays are the same and both are empty
$output = array();
for ($i = 0, $c = count($a1); $i < $c; $i++) {
for ($i = 0; $i < $c1; $i++) {
$output[$a1[$i]] = $a2[$i];
}
@ -267,7 +210,7 @@ if (!function_exists('array_combine')) {
}
/**
* Class used for internal manipulation with recordsets (?).
* Class used for internal manipulation of multiarrays (arrays of arrays)
*
* @package cake
* @subpackage cake.libs
@ -319,13 +262,10 @@ class NeatArray {
* @access public
* @uses NeatArray::value
*/
function cleanup ()
{
function cleanup () {
$out = is_array($this->value)? array(): null;
foreach ($this->value as $k=>$v)
{
if ($v)
{
foreach ($this->value as $k=>$v) {
if ($v) {
$out[$k] = $v;
}
}

View file

@ -402,6 +402,32 @@ class Controller extends Template {
return sprintf(TAG_IMAGE, $url, $alt, $this->parseHtmlOptions($html_options, '', ' '));
}
/**
* Returns a CSS link meta-tag
*
* @param string $path
* @param string $rel
* @param array $html_options
* @return string
*/
function cssTag ($path, $rel='stylesheet', $html_options=null) {
$url = "{$this->base}/css/{$path}.css";
return sprintf(TAG_CSS, $rel, $url, $this->parseHtmlOptions($html_options, '', ' '));
}
/**
* Returns a charset meta-tag
*
* @param string $charset
* @return string
*/
function charsetTag ($charset) {
return sprintf(TAG_CHARSET, $charset);
}
/**
* Enter description here...
*
@ -480,10 +506,10 @@ class Controller extends Template {
$errors = array();
foreach ($objects as $object) {
$errors = array_merge($errors, $object->invalidFields());
$errors = array_merge($errors, $object->invalidFields($object->data));
}
return $this->validation_errors = (count($errors)? $errors: false);
return $this->validationErrors = (count($errors)? $errors: false);
}
/**
@ -494,7 +520,12 @@ class Controller extends Template {
* @return unknown
*/
function tagErrorMsg ($field, $text) {
return $this->tagIsInvalid($field)? sprintf(SHORT_ERROR_MESSAGE, $text): null;
if ($error = $this->tagIsInvalid($field)) {
return sprintf(SHORT_ERROR_MESSAGE, is_array($text)? (empty($text[$error-1])? 'Error in field': $text[$error-1]): $text);
}
else {
return null;
}
}
/**
@ -504,7 +535,7 @@ class Controller extends Template {
* @return unknown
*/
function tagIsInvalid ($field) {
return !empty($this->validation_errors[$field]);
return empty($this->validationErrors[$field])? 0: $this->validationErrors[$field];
}
@ -548,7 +579,7 @@ class Controller extends Template {
*/
function error ($code, $name, $message) {
header ("HTTP/1.0 {$code} {$name}");
print ($this->_do_render(VIEWS.'layouts/error.thtml', array('code'=>$code,'name'=>$name,'message'=>$message)));
print ($this->_render(VIEWS.'layouts/error.thtml', array('code'=>$code,'name'=>$name,'message'=>$message)));
}
}

View file

@ -264,7 +264,7 @@ class DBO extends Object {
}
/**
* Enter description here...
* Returns a single row of results from the _last_ query
*
* @param unknown_type $results
* @param unknown_type $type
@ -275,7 +275,7 @@ class DBO extends Object {
}
/**
* Enter description here...
* Returns a single row of results for a _given_ query
*
* @param unknown_type $sql
* @return unknown
@ -285,7 +285,7 @@ class DBO extends Object {
}
/**
* Enter description here...
* Returns all result rows for a given query
*
* @param unknown_type $sql
* @return unknown

View file

@ -165,166 +165,6 @@ class DBO_AdoDB extends DBO {
*
*/
function lastInsertId () { die('Please implement DBO::lastInsertId() first.'); }
/*
function connect($config) {
if($config) {
$this->config = $config;
if(isset($this->config['driver'])) {
$this->_adodb = NewADOConnection($this->config['driver']);
$adodb =& $this->_adodb;
$this->connected = $adodb->Connect($this->config['host'],$this->config['login'],$this->config['password'],$this->config['database']);
}
}
if(!$this->connected)
die('Could not connect to DB.');
}
function close() {
$adodb =& $this->_adodb;
$adodb->close;
showLog();
$this->_conn = NULL;
$this->connected = NULL;
}
function query($q,$DEBUG=FALSE,$log=TRUE) {
$adodb =& $this->_adodb;
$t = getMicrotime();
if($log){
$this->_result =& $adodb->Execute($q);
$result =& $this->_result;
$this->took = round((getmicrotime()-$t)*1000, 0);
if(!$this->_result && $adodb->ErrorMsg())
$this->error = $adodb->ErrorMsg();
else
$this->error = NULL;
$this->insert_id = $adodb->Insert_ID();
$this->affected = $adodb->Affected_Rows();
$this->num_rows = $result->RecordCount();
$this->_logQuery($q);
if($this->debug || $DEBUG) $this->_showQuery($q);
Return $this->error? FALSE: $this->_result;
}
else {
$this->_result = $adodb->Execute($q);
Return $this->_result;
}
}
function farr() {
$result =& $this->_result;
return $result->FetchRow();
}
//SAME AS ABOVE?
function one($q,$DEBUG=FALSE) {
$result =& $this->_result;
Return $this->query($q,$DEBUG)? $result->FetchRow(): FALSE;
}
function all($q,$DEBUG=FALSE) {
if($this->query($q,$DEBUG)) {
$result = $this->_result;
return $result->GetRows();
} else {
Return FALSE;
}
}
function field($name, $q, $DEBUG=FALSE) {
$data = $this->one($q, $DEBUG);
return empty($data[$name])? false: $data[$name];
}
function tables() {
$adodb =& $this->_adodb;
$tables = $adodb->MetaTables('TABLES');
if (!sizeof($tables)>0) {
trigger_error(ERROR_NO_TABLE_LIST, E_USER_NOTICE);
exit;
}
return $tables;
}
function fields ($table_name) {
return $this->all("DESC {$table_name}");
}
function hasAny($table, $sql) {
$out = $this->one("SELECT COUNT(*) AS count FROM {$table}".($sql? " WHERE {$sql}":""));
return is_array($out)? $out['count']: FALSE;
}
function isConnected() {
Return $this->connected;
}
function lastInsertId() {
Return $this->insert_id;
}
function lastAffected() {
Return $this->affected;
}
function lastNumRows() {
Return $this->num_rows;
}
function lastError() {
return $this->error;
}
function showLog($sorted=FALSE) {
$log = $sorted?
sortByKey($this->_queries_log, 'took', 'desc', SORT_NUMERIC):
$this->_queries_log;
print("<table border=1>\n<tr><th colspan=7>{$this->_queries_cnt} queries took {$this->_queries_time} ms</th></tr>\n");
print("<tr><td>Nr</td><td>Query</td><td>Error</td><td>Affected</td><td>Num. rows</td><td>Took (ms)</td></tr>\n");
foreach($log AS $k=>$i) {
print("<tr><td>".($k+1)."</td><td>{$i['query']}</td><td>{$i['error']}</td><td align='right'>{$i['affected']}</td><td align='right'>{$i['num_rows']}</td><td align='right'>{$i['took']}</td></tr>\n");
}
print("</table>\n");
}
function _logQuery($q) {
$this->_queries_cnt++;
$this->_queries_time += $this->took;
$this->_queries_log[] = array(
'query'=>$q,
'error'=>$this->error,
'affected'=>$this->affected,
'num_rows'=>$this->num_rows,
'took'=>$this->took
);
if ($this->error && function_exists('logError'))
logError("Query: {$q} RETURNS ERROR {$this->error}");
}
function _showQuery($q) {
$error = $this->error;
if ($this->debug || $error) {
print("<p style=\"text-align:left\"><b>Query:</b> {$q} <small>[Aff:{$this->affected} Num:{$this->num_rows} Took:{$this->took}ms]</small>");
if($error) {
print("<br /><span style=\"color:Red;text-align:left\"><b>ERROR:</b> {$this->error}</span>");
}
print('</p>');
}
}
*/
}
?>

View file

@ -1,6 +1,6 @@
<?PHP
//////////////////////////////////////////////////////////////////////////
// + $Id: $
// + $Id$
// +------------------------------------------------------------------+ //
// + Cake <https://developers.nextco.com/cake/> + //
// + Copyright: (c) 2005, Cake Authors/Developers + //
@ -22,9 +22,9 @@
* @author Cake Authors/Developers
* @copyright Copyright (c) 2005, Cake Authors/Developers
* @link https://developers.nextco.com/cake/wiki/Authors Authors/Developers
* @version $Revision: $
* @modifiedby $LastChangedBy: $
* @lastmodified $Date: $
* @version $Revision$
* @modifiedby $LastChangedBy$
* @lastmodified $Date$
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
*/
@ -42,9 +42,10 @@ uses('object');
* @since Cake v 1.0.0.0
*
*/
class DbFactory extends Object {
class DboFactory extends Object {
function make ($config) {
function make ($activeConfig) {
$config = DATABASE_CONFIG::$activeConfig();
// special case for AdoDB -- driver name in the form of 'adodb_drivername'
if (preg_match('#^adodb_(.*)$#i', $config['driver'], $res)) {
@ -57,6 +58,7 @@ class DbFactory extends Object {
else {
$db_driver_class = 'DBO_'.$config['driver'];
$db_driver_fn = LIBS.strtolower($db_driver_class.'.php');
if (file_exists($db_driver_fn)) {
uses(strtolower($db_driver_class));
return new $db_driver_class ($config);

View file

@ -65,6 +65,7 @@ class Dispatcher extends Object {
*
*/
function __construct () {
$this->base = $this->baseUrl();
parent::__construct();
}
@ -77,39 +78,34 @@ class Dispatcher extends Object {
function dispatch ($url) {
global $_POST, $_GET, $_FILES, $_SESSION;
if (CACHE_PAGES) {
$Cache = new Cache($url);
if ($Cache->has()) return print $Cache->restore();
}
$this->base = $this->parseBaseUrl();
$params = $this->parseParams($url);
// if no controller set
// die if no controller set
if (empty($params['controller']))
$this->errorNoController($url);
$controller_class = ucfirst($params['controller']).'Controller';
$ctrl_name = ucfirst($params['controller']);
$ctrl_class = $ctrl_name.'Controller';
// if specified controller class doesn't exist
if (!class_exists($controller_class))
$this->errorUnknownController($url, $controller_class);
if (!loadController($ctrl_name) || !class_exists($ctrl_class))
$this->errorUnknownController($url, $ctrl_name);
$controller = new $controller_class ($this);
$controller = new $ctrl_class ($this);
$controller->cache = &$Cache;
$controller->base = $this->base;
// if action is not set, and the default Controller::index() method doesn't exist
if (empty($params['action'])) {
if (!method_exists($controller, 'index'))
$this->errorNoAction($url);
else
if (method_exists($controller, 'index'))
$params['action'] = 'index';
else
$this->errorNoAction($url);
}
// if the requested action doesn't exist
if (!method_exists($controller, $params['action']))
$this->errorUnknownAction($url, $controller_class, $params['action']);
$this->errorUnknownAction($url, $ctrl_class, $params['action']);
$controller->params = $params;
$controller->action = $params['action'];
@ -122,8 +118,6 @@ class Dispatcher extends Object {
if ($controller->autoRender)
$controller->render();
if (CACHE_PAGES) $Cache->remember(null);
return $params;
}
@ -157,7 +151,7 @@ class Dispatcher extends Object {
*
* @return unknown
*/
function parseBaseUrl () {
function baseUrl () {
global $_SERVER;
//non mod_rewrite use:

View file

@ -126,6 +126,27 @@ class Folder extends Object {
}
}
/**
* Finds all matching files in a directory
*
* @param string $pattern
* @return unknown
*/
function find ($regexp_pattern='.*') {
list($dirs, $files) = $this->ls();
$found = array();
foreach ($files as $file) {
if (preg_match("/^{$regexp_pattern}$/i", $file)) {
$found[] = $file;
}
}
return $found;
}
/**
* Enter description here...
*

16
libs/log.php Normal file
View file

@ -0,0 +1,16 @@
<?PHP
class Log {
function write($type, $msg) {
$out = date('y-m-d H:i:s').' '.ucfirst($type).': '.$msg."\r\n";
$fn = LOGS.$type.'.log';
$log = fopen($fn, 'a+');
fwrite($log, $out);
fclose($log);
}
}
?>

View file

@ -136,7 +136,14 @@ class Model extends Object {
var $validate = array();
/**
* Enter description here...
* Append entries for validation as ('field_name' => '/^perl_compat_regexp$/') that has to match with preg_match()
* validate with Model::validate()
* @var unknown_type
*/
var $validationErrors = null;
/**
* Constructor binds the Model's database table
*
* @param unknown_type $id
*/
@ -149,16 +156,16 @@ class Model extends Object {
$this->id = $id;
$table_name = $this->use_table? $this->use_table: Inflector::tableize(get_class($this));
$this->use_table ($table_name);
$this->useTable ($table_name);
parent::__construct();
$this->create_links();
$this->createLinks();
}
/**
* Enter description here...
*
*/
function create_links () {
function createLinks () {
if (!empty($this->hasMany))
$this->_hasMany = explode(',', $this->hasMany);
@ -178,8 +185,8 @@ class Model extends Object {
function relink () {
foreach ($this->_hasMany as $model) {
$name = Inflector::singularize($model);
$this->$name->clear_links();
$this->$name->link_many_to_one(get_class($this), $this->id);
$this->$name->clearLinks();
$this->$name->linkManyToOne(get_class($this), $this->id);
}
}
@ -189,7 +196,7 @@ class Model extends Object {
* @param unknown_type $model_name
* @param unknown_type $value
*/
function link_many_to_one ($model_name, $value=null) {
function linkManyToOne ($model_name, $value=null) {
$table_name = Inflector::tableize($model_name);
$field_name = Inflector::singularize($table_name).'_id';
$this->_one_to_many[] = array($table_name, $field_name, $value);
@ -199,7 +206,7 @@ class Model extends Object {
* Enter description here...
*
*/
function clear_links () {
function clearLinks () {
$this->_one_to_many = array();
}
@ -208,14 +215,14 @@ class Model extends Object {
*
* @param unknown_type $table_name
*/
function use_table ($table_name) {
function useTable ($table_name) {
if (!in_array($table_name, $this->db->tables())) {
trigger_error (sprintf(ERROR_NO_MODEL_TABLE, get_class($this), $table_name), E_USER_ERROR);
die();
}
else {
$this->table = $table_name;
$this->load_info();
$this->loadInfo();
}
}
@ -228,15 +235,17 @@ class Model extends Object {
* @return unknown
*/
function set ($one, $two=null) {
$this->validationErrors = null;
$data = is_array($one)? $one: array($one=>$two);
foreach ($data as $n => $v) {
if (!$this->has_field($n)) {
/*
if (!$this->hasField($n)) {
DEBUG?
trigger_error(sprintf(ERROR_NO_FIELD_IN_MODEL_DB, $n, $this->table), E_USER_ERROR):
trigger_error('Application error occured, trying to set a field name that doesn\'t exist.', E_USER_WARNING);
}
*/
$n == 'id'? $this->id = $v: $this->data[$n] = $v;
}
@ -248,7 +257,7 @@ class Model extends Object {
*
* @param unknown_type $id
*/
function set_id ($id) {
function setId ($id) {
$this->id = $id;
$this->relink();
}
@ -257,7 +266,7 @@ class Model extends Object {
* Enter description here...
*
*/
function load_info () {
function loadInfo () {
if (empty($this->_table_info))
$this->_table_info = new NeatArray($this->db->fields($this->table));
}
@ -268,7 +277,8 @@ class Model extends Object {
* @param unknown_type $name
* @return unknown
*/
function has_field ($name) {
function hasField ($name) {
if (empty($this->_table_info)) $this->loadInfo();
return $this->_table_info->findIn('name', $name);
}
@ -280,6 +290,7 @@ class Model extends Object {
* @return array of values
*/
function read ($fields=null) {
$this->validationErrors = null;
return $this->id? $this->find("id = '{$this->id}'", $fields): false;
}
@ -302,29 +313,42 @@ class Model extends Object {
}
}
/**
* saves a single field to the db
*
* @param string $name
* @param mixed $value
* @return success
*/
function saveField($name, $value) {
return $this->save(array($name=>$value), false);
}
/**
* saves model data to the db
*
* @param array $data
* @return success
*/
function save ($data=null) {
function save ($data=null, $validate=true) {
if ($data) $this->set($data);
if (!$this->validates())
if ($validate && !$this->validates())
return false;
$fields = $values = array();
foreach ($this->data as $n=>$v) {
if ($this->hasField($n)) {
$fields[] = $n;
$values[] = $this->db->prepare($v);
}
}
if (empty($this->id) && $this->has_field('created')) {
if (empty($this->id) && $this->hasField('created') && !in_array('created', $fields)) {
$fields[] = 'created';
$values[] = date("'Y-m-d H:i:s'");
}
if ($this->has_field('modified')) {
if ($this->hasField('modified') && !in_array('modified', $fields)) {
$fields[] = 'modified';
$values[] = 'NOW()';
}
@ -397,6 +421,17 @@ class Model extends Object {
return $this->id? $this->db->hasAny($this->table, "id = '{$this->id}'"): false;
}
/**
* checks for existance of a record with specified conditions
*
* @return true if such record exists
*/
function hasAny ($sql_conditions=null) {
return $this->db->hasAny($this->table, $sql_conditions);
}
/**
* reads a single row
*
@ -542,7 +577,7 @@ class Model extends Object {
* @return unknown
*/
function validates ($data=null) {
$errors = count($this->invalidFields($data));
$errors = count($this->invalidFields($data? $data: $this->data));
return $errors == 0;
}
@ -567,16 +602,18 @@ class Model extends Object {
if (!isset($this->validate))
return true;
if (is_array($this->validationErrors))
return $this->validationErrors;
$data = ($data? $data: (isset($this->data)? $this->data: array()));
$errors = array();
foreach ($this->validate as $field_name=>$validator) {
if (isset($data[$field_name])) {
if (!preg_match($validator, $data[$field_name]))
if (!isset($data[$field_name]) || !preg_match($validator, $data[$field_name]))
$errors[$field_name] = 1;
}
}
$this->validationErrors = $errors;
return $errors;
}

View file

@ -13,8 +13,11 @@
// + See: http://www.opensource.org/licenses/mit-license.php + //
//////////////////////////////////////////////////////////////////////////
uses('log');
/**
* Purpose: Object
* Allows for __construct to be used in PHP4.
*
* @filesource
* @author Cake Authors/Developers
@ -28,34 +31,62 @@
* @lastmodified $Date$
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
*/
class Object {
/**
* Enter description here...
*
*
* @package cake
* @subpackage cake.libs
* @since Cake v 0.2.9
*
*/
class Object {
/**
* Enter description here...
* A hack to support __construct() on PHP 4
* Hint: descendant classes have no PHP4 class_name() constructors,
* so this one gets called first and calls the top-layer __construct()
* which (if present) should call parent::__construct()
*
* @return Object
*/
function Object() {
$args= func_get_args();
$args = func_get_args();
register_shutdown_function(array(&$this, '__destruct'));
call_user_func_array(array(&$this, '__construct'), $args);
}
/**
* Enter description here...
*
* @param unknown_type $args
* Class constructor, overriden in descendant classes
*/
function __construct($args=NULL) {
function __construct() {
}
/**
* Class destructor, overriden in descendant classes
*/
function __destruct() {
}
/**
* Object-to-string conversion
* Each class can override it as necessary
*
* @return string this class' name
*/
function toString () {
return get_class($this);
}
/**
* API for logging events
*
* @param string $msg
* @param string $type
*/
function log ($msg, LOG_ERROR) {
if (!$this->_log)
$this->_log = new Log ();
switch ($type) {
case LOG_DEBUG:
return $this->_log->write('debug', $msg);
default:
return $this->_log->write('error', $msg);
}
}
}
?>

View file

@ -90,7 +90,7 @@ class Router extends Object {
$names[] = $r[1];
}
elseif (preg_match('/^\*$/', $element, $r)) {
$parsed[] = '/(.*)';
$parsed[] = '(?:\/(.*))?';
}
else {
$parsed[] = '/'.$element;
@ -126,6 +126,7 @@ class Router extends Object {
list($route, $regexp, $names, $defaults) = $route;
if (preg_match($regexp, $url, $r)) {
// $this->log($url.' matched '.$regexp, 'note');
// remove the first element, which is the url
array_shift($r);

View file

@ -108,7 +108,7 @@ class Template extends Object {
*
* @param unknown_type $layout
*/
function set_layout ($layout) {
function setLayout ($layout) {
$this->layout = $layout;
}
@ -120,7 +120,7 @@ class Template extends Object {
* @return unknown
*/
function set($one, $two=null) {
return $this->_set_array(is_array($one)? $one: array($one=>$two));
return $this->_setArray(is_array($one)? $one: array($one=>$two));
}
/**
@ -128,7 +128,7 @@ class Template extends Object {
*
* @param unknown_type $value
*/
function set_title ($value) {
function setTitle ($value) {
$this->_page_title = $value;
}
@ -137,10 +137,10 @@ class Template extends Object {
*
* @param unknown_type $data
*/
function _set_array($data) {
function _setArray($data) {
foreach ($data as $name => $value) {
if ($name == 'title')
$this->set_title ($value);
$this->setTitle ($value);
else
$this->_view_vars[$name] = $value;
}
@ -161,7 +161,7 @@ class Template extends Object {
$this->set('message', $message);
$this->set('time', $time);
$this->render(null,false,VIEWS.'layouts/flash.thtml');
$this->render(null,false,VIEWS.'layouts'.DS.'flash.thtml');
}
/**
@ -175,9 +175,9 @@ class Template extends Object {
$this->autoRender = false;
if (!$action) $action = $this->action;
if ($layout) $this->set_layout($layout);
if ($layout) $this->setLayout($layout);
$view_fn = $file? $file: $this->_get_view_fn($action);
$view_fn = $file? $file: $this->_getViewFn($action);
if (!is_file($view_fn)) {
DEBUG? trigger_error (sprintf(ERROR_NO_VIEW, $action, $view_fn), E_USER_ERROR)
@ -185,17 +185,15 @@ class Template extends Object {
die();
}
$out = $this->_do_render($view_fn, $this->_view_vars, 0);
$out = $this->_render($view_fn, $this->_view_vars, 0);
if ($out !== false) {
if ($this->layout && $this->autoLayout)
$out = $this->render_layout($out);
if (CACHE_PAGES)
$this->cache->append($out);
$out = $this->renderLayout($out);
print $out;
}
else {
$out = $this->_do_render($view_fn, $this->_view_vars, false);
$out = $this->_render($view_fn, $this->_view_vars, false);
trigger_error (sprintf(ERROR_IN_VIEW, $view_fn, $out), E_USER_ERROR);
}
}
@ -206,18 +204,18 @@ class Template extends Object {
* @param unknown_type $content_for_layout
* @return unknown
*/
function render_layout ($content_for_layout) {
$layout_fn = $this->_get_layout_fn();
function renderLayout ($content_for_layout) {
$layout_fn = $this->_getLayoutFn();
$data_for_layout = array_merge($this->_view_vars, array(
'title_for_layout'=>$this->_page_title !== false? $this->_page_title: ucfirst($this->name),
'content_for_layout'=>$content_for_layout));
if (is_file($layout_fn)) {
$out = $this->_do_render($layout_fn, $data_for_layout);
$out = $this->_render($layout_fn, $data_for_layout);
if ($out === false) {
$out = $this->_do_render($layout_fn, $data_for_layout, false);
$out = $this->_render($layout_fn, $data_for_layout, false);
trigger_error (sprintf(ERROR_IN_LAYOUT, $layout_fn, $out), E_USER_ERROR);
return false;
}
@ -236,8 +234,8 @@ class Template extends Object {
*
* @return unknown
*/
function _get_layout_fn() {
return VIEWS."layouts/{$this->layout}.thtml";
function _getLayoutFn() {
return VIEWS."layouts".DS."{$this->layout}.thtml";
}
/**
@ -246,8 +244,8 @@ class Template extends Object {
* @param unknown_type $action
* @return unknown
*/
function _get_view_fn($action) {
return VIEWS.$this->name."/{$action}.thtml";
function _getViewFn($action) {
return VIEWS.$this->name.DS."{$action}.thtml";
}
/**
@ -258,7 +256,7 @@ class Template extends Object {
* @param unknown_type $___play_safe
* @return unknown
*/
function _do_render($___view_fn, $___data_for_view, $___play_safe = true) {
function _render($___view_fn, $___data_for_view, $___play_safe = true) {
extract($___data_for_view, EXTR_SKIP); # load all view variables
$BASE = $this->base;
$params = &$this->params;
@ -281,7 +279,7 @@ class Template extends Object {
* @param unknown_type $length
* @return unknown
*/
function trim_to ($string, $length) {
function trimTo ($string, $length) {
return substr($string, 0, $length).(strlen($string)>$length? '..': null);
}
}

View file

@ -45,20 +45,6 @@
* @lastmodified $Date$
*/
/**
* Enter description here...
*
*/
error_reporting(E_ERROR | E_WARNING | E_PARSE | E_NOTICE |
E_CORE_ERROR | E_CORE_WARNING);
//
//interface Test {
// function run(&$aTestResult);
// function countTestCases();
//}
/**
* Enter description here...
*
@ -304,8 +290,8 @@ class Assert {
/**
* Enter description here...
*
* @param unknown_type $value
* @return unknown
* @param mixed $value
* @return string
*/
function _formatValue ($value) {
@ -325,44 +311,6 @@ class Assert {
return array($valueStr, gettype($value));
}
/**
* Enter description here...
*
* @param unknown_type $value
* @param unknown_type $class
* @return unknown
*/
function _old_formatValue($value, $class="") {
$translateValue = $value;
if (phpversion() >= '4.0.0') {
if (is_object($value)) {
if (method_exists($value, "toString") ) {
$translateValue = $value->toString();
}
else {
$translateValue = serialize($value);
}
}
else if (is_array($value)) {
$translateValue = serialize($value);
}
}
$htmlValue = "<code class=\"$class\">" . htmlspecialchars($translateValue) . "</code>";
if (phpversion() >= '4.0.0') {
if (is_bool($value)) {
$htmlValue = $value ? "<i>true</i>" : "<i>false</i>";
}
elseif (phpversion() >= '4.0.4' && is_null($value)) {
$htmlValue = "<i>null</i>";
}
$htmlValue .= "&nbsp;&nbsp;&nbsp;<span class=\"typeinfo\">";
$htmlValue .= " type:" . gettype($value);
$htmlValue .= is_object($value) ? ", class:" . get_class($value) : "";
$htmlValue .= "</span>";
}
return $htmlValue;
}
/**
* Enter description here...

View file

@ -60,4 +60,10 @@ define('VALID_TAG', '/[^\ ]+/i');
*/
define('VALID_TAGS', '/.+/i');
/**
* Enter description here...
*
*/
define('VALID_YEAR', '/^[12][0-9]{3}$/');
?>

View file

@ -30,33 +30,37 @@
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
*/
/**
* DIRECTORY LAYOUT
*/
require ('../config/paths.php');
session_start();
/**
* Startup
* Get Cake's root directory
*/
require (LIBS.'basics.php');
define ('DS', DIRECTORY_SEPARATOR);
define ('ROOT', substr(__FILE__, 0, strrpos(dirname(__FILE__), DS)+1));
uses ('dispatcher', 'db_factory');
usesConfig();
usesDatabase();
usesTagGenerator();
/**
* Directory layout and basic functions
*/
require (ROOT.'config/core.php');
require (ROOT.'config/paths.php');
require (ROOT.'libs/basics.php');
DEBUG? error_reporting(E_ALL): error_reporting(0);
$TIME_START = getMicrotime();
uses ('folder', 'dispatcher', 'dbo_factory');
config ('tags', 'database');
$DB = DboFactory::make('devel');
loadModels ();
loadControllers ();
session_start();
## RUN THE SCRIPT
$url = empty($_GET['url'])? null: $_GET['url'];
$DISPATCHER = new Dispatcher ();
$DISPATCHER->dispatch($url);
if ($DB) $DB->close();
## CLEANUP
if (DEBUG) echo "<!-- ". round(getMicrotime() - $TIME_START, 2) ."s -->";

View file

@ -33,7 +33,10 @@
/**
* START-UP
*/
require ('../config/paths.php');
define ('DS', DIRECTORY_SEPARATOR);
define ('ROOT', substr(__FILE__, 0, strrpos(dirname(__FILE__), DS)+1));
require (ROOT.'config'.DS.'paths.php');
require (LIBS.'basics.php');
uses ('bake');

View file

@ -1,76 +0,0 @@
<?php
uses ('test', 'dbo_adodb');
class DboAdodbTest extends TestCase {
var $abc;
// constructor of the test suite
function DboAdodbTest ($name) {
$this->TestCase($name);
}
// called before the test functions will be executed
// this function is defined in PHPUnit_TestCase and overwritten
// here
function setUp() {
$this->abc = new DBO_AdoDB (loadDatabaseConfig('test'));
$this->createTemporaryTable();
}
// called after the test functions are executed
// this function is defined in PHPUnit_TestCase and overwritten
// here
function tearDown() {
$this->dropTemporaryTable();
}
function createTemporaryTable () {
$create_sqls = array(
'mysql' => 'CREATE TABLE __test (id INT UNSIGNED PRIMARY KEY, body VARCHAR(255))',
'postgres' => 'CREATE TABLE __test (id serial NOT NULL, body CHARACTER VARYING(255))'
);
$sql = $create_sqls[$this->abc->config['driver']];
return $this->abc->query($sql);
}
function dropTemporaryTable () {
return $this->abc->query("DROP TABLE __test");
}
function testHasImplementation () {
$functions = array(
'connect',
'disconnect',
'execute',
'fetchRow',
'tables',
'fields',
'prepare',
'lastError',
'lastAffected',
'lastNumRows',
'lastInsertId'
);
foreach ($functions as $function) {
$this->assertTrue(method_exists($this->abc, $function));
}
}
function testConnectivity () {
$this->assertTrue($this->abc->connected);
}
function testFields () {
$fields = $this->abc->fields('__test');
$this->assertEquals(count($fields), 2, 'equals');
}
function testTables () {
$this->assertTrue(in_array('__test', $this->abc->tables()));
}
}
?>

View file

@ -1,12 +1,12 @@
<?php
uses ('test', 'db_factory');
uses ('test', 'dbo_factory');
class DbFactoryTest extends TestCase {
class DboFactoryTest extends TestCase {
var $abc;
// constructor of the test suite
function DbFactoryTest($name) {
function DboFactoryTest($name) {
$this->TestCase($name);
}
@ -14,7 +14,7 @@ class DbFactoryTest extends TestCase {
// this function is defined in PHPUnit_TestCase and overwritten
// here
function setUp() {
$this->abc = new DbFactory ();
$this->abc = new DboFactory ();
}
// called after the test functions are executed
@ -26,11 +26,10 @@ class DbFactoryTest extends TestCase {
function testMake () {
$config = loadDatabaseConfig ('test');
$output = $this->abc->make($config);
$output = $this->abc->make('test');
$this->assertTrue(is_object($output));
$config = DATABASE_CONFIG::test();
if (preg_match('#^(adodb)_.*$#i', $config['driver'], $res)) {
$desired_driver_name = $res[1];
}
@ -46,7 +45,7 @@ class DbFactoryTest extends TestCase {
}
// this test expect an E_USER_ERROR to occur during it's run
// disabled until I find a way to assert it happen
// I've disabled it until I find a way to assert it happen
//
// function testBadConfig () {
// $output = $this->abc->make(null);
@ -54,5 +53,4 @@ class DbFactoryTest extends TestCase {
// }
}
?>

View file

@ -1,74 +0,0 @@
<?php
uses ('test', 'dbo_mysql');
class DboMysqlTest extends TestCase {
var $abc;
// constructor of the test suite
function DboMysqlTest($name) {
$this->TestCase($name);
}
// called before the test functions will be executed
// this function is defined in PHPUnit_TestCase and overwritten
// here
function setUp() {
$this->abc = new DBO_MySQL (loadDatabaseConfig('test'));
$this->createTemporaryTable();
}
// called after the test functions are executed
// this function is defined in PHPUnit_TestCase and overwritten
// here
function tearDown() {
$this->dropTemporaryTable();
}
function createTemporaryTable () {
// $sql = "CREATE TABLE __test (id serial NOT NULL, body CHARACTER VARYING(255))"; // postgresql
$sql = "CREATE TABLE __test (id INT UNSIGNED PRIMARY KEY, body VARCHAR(255))"; // mysql
return $this->abc->query($sql);
}
function dropTemporaryTable () {
return $this->abc->query("DROP TABLE __test");
}
function testHasImplementation () {
$functions = array(
'connect',
'disconnect',
'execute',
'fetchRow',
'tables',
'fields',
'prepare',
'lastError',
'lastAffected',
'lastNumRows',
'lastInsertId'
);
foreach ($functions as $function) {
$this->assertTrue(method_exists($this->abc, $function));
}
}
function testConnectivity () {
$this->assertTrue($this->abc->connected);
}
function testFields () {
$fields = $this->abc->fields('__test');
$this->assertEquals(count($fields), 2, 'equals');
}
function testTables () {
$this->assertTrue(in_array('__test', $this->abc->tables()));
}
}
?>

View file

@ -1,74 +0,0 @@
<?php
uses ('test', 'dbo_postgres');
class DBOPostgresTest extends TestCase {
var $abc;
// constructor of the test suite
function DBOPostgresTest($name) {
$this->TestCase($name);
}
// called before the test functions will be executed
// this function is defined in PHPUnit_TestCase and overwritten
// here
function setUp() {
$this->abc = new DBO_Postgres (loadDatabaseConfig('test'));
$this->createTemporaryTable();
}
// called after the test functions are executed
// this function is defined in PHPUnit_TestCase and overwritten
// here
function tearDown() {
$this->dropTemporaryTable();
}
function createTemporaryTable () {
$sql = "CREATE TABLE __test (id serial NOT NULL, body CHARACTER VARYING(255))"; // postgresql
// $sql = "CREATE TABLE __test (id INT UNSIGNED PRIMARY KEY, body VARCHAR(255))"; // mysql
return $this->abc->query($sql);
}
function dropTemporaryTable () {
return $this->abc->query("DROP TABLE __test");
}
function testHasImplementation () {
$functions = array(
'connect',
'disconnect',
'execute',
'fetchRow',
'tables',
'fields',
'prepare',
'lastError',
'lastAffected',
'lastNumRows',
'lastInsertId'
);
foreach ($functions as $function) {
$this->assertTrue(method_exists($this->abc, $function));
}
}
function testConnectivity () {
$this->assertTrue($this->abc->connected);
}
function testFields () {
$fields = $this->abc->fields('__test');
$this->assertEquals(count($fields), 2, 'equals');
}
function testTables () {
$this->assertTrue(in_array('__test', $this->abc->tables()));
}
}
?>

View file

@ -1,6 +1,6 @@
<?php
uses ('test', 'db_factory');
uses ('test', 'dbo_factory');
class DboTest extends TestCase {
var $abc;
@ -14,7 +14,7 @@ class DboTest extends TestCase {
// this function is defined in PHPUnit_TestCase and overwritten
// here
function setUp() {
$this->abc = DbFactory::make(loadDatabaseConfig('test'));
$this->abc = DboFactory::make('test');
$this->createTemporaryTable();
}

View file

@ -48,14 +48,15 @@ class RouterTest extends TestCase {
'/foo/baz/' => array('controller'=>'Foo', 'action'=>'baz'),
'/foo/foo+bar' => array('pass'=>array('foo+bar'), 'controller'=>'Foo', 'action'=>'dodo'),
'/foobar/' => array('controller'=>'Foobar', 'action'=>'bar'),
'/foo/bar/baz' => array('pass'=>array('bar', 'baz'), 'controller'=>'Foo', 'action'=>'dodo'),
'/foo/bar/baz' => array('controller'=>'Foo', 'action'=>'dodo', 'pass'=>array('bar', 'baz')),
'/one/two/three/' => array('controller'=>'one', 'action'=>'two', 'pass'=>array('three')),
'/foo' => array('controller'=>'foo','action'=>null),
'/ruburb' => array('controller'=>'ruburb','action'=>null),
'???' => array()
);
foreach ($tests as $test=>$expected) {
$this->asEq($this->abc->parse($test), $expected);
$tested = $this->abc->parse($test);
$this->asEq($tested, $expected);
}
}