Merging fixes and enhancements into trunk

Revision: [2009]
Adding fixes for session errors posted in the google group.
Changed the header for PHP version in the model classes.
Change uses() back to require_once 

Revision: [2008]
Adding reference back to the PHP 4 model

Revision: [2007]
Merging changes from model_php5

Revision: [2006]
Fixing recursive associations, adding whitelist to Model::save

Revision: [2005]
Added fix for error in CakeSession class.
Updated home.thtml

Revision: [2004]
Rearranged  some of the defines moving the most often changed ones to the top of the script

Revision: [2003]
Moved SQL files distributed with the core to app/config/sql/
Removed app/config/routes.php.default
Fixed class_exists check in TextHelper

Revision: [2002]
adding sql directory

Revision: [2001]
Fixed error when cake distribution is installed inside of the DOCUMENT ROOT 

Revision: [2000]
Adding checks for classes that are already loaded so the require() calls will not error

Revision: [1999]
Replacing all require_once() with require()

Revision: [1998]
Moved creation of the Dispatcher object to app/webroot/index.php

Revision: [1997]
Adding session sql file

Revision: [1996]
Revision: [1995]
Fixing session db queries

Revision: [1994]
Change the require_once in bootstrap to require.
Merged changes John made to the CakeSession database methods

Revision: [1993]
Removing some constants that are not needed

Revision: [1992]
Adding fix for Ticket #400

Revision: [1991]
Fixing Ticket #348

Revision: [1990]
Fixing Tickets #397 and #399

Revision: [1989]
Fixed callbacks in JavaScript events and Ajax, fixed Controller::beforeRender so you can set view variables, and fixed Ticket #394

Revision: [1988]
Renamed the $dir param to $direction.
Added default value to the DboSource::order() $direction param.

Revision: [1987]
Adding changes back to the sessions class I reverted in [1984]

git-svn-id: https://svn.cakephp.org/repo/trunk/cake@2010 3807eeeb-6ff5-0310-8944-8be069107fe0
This commit is contained in:
phpnut 2006-02-17 10:12:15 +00:00
parent 818806195f
commit 9a8d5c15fe
32 changed files with 603 additions and 522 deletions

View file

@ -6,4 +6,4 @@
// +---------------------------------------------------------------------------------------------------+ // // +---------------------------------------------------------------------------------------------------+ //
/////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////
0.10.8.1986 0.10.8.2010

View file

@ -58,6 +58,25 @@ define('DEBUG', 1);
* Currently PHP supports LOG_DEBUG * Currently PHP supports LOG_DEBUG
*/ */
define ('LOG_ERROR', 2); define ('LOG_ERROR', 2);
/**
* CakePHP includes 3 types of session saves
* database or file. Set this to your preffered method.
* If you want to use your own save handeler place it in
* app/config/name.php DO NOT USE file or database as the name.
* and use just the name portion below.
*
* Setting this to cake will save files to /cakedistro/tmp directory
* Setting it to php will use the php default save path
* Setting it to database will use the database
*
*
*/
define('CAKE_SESSION_SAVE', 'php');
/**
* Set a random string of used in session.
*
*/
define('CAKE_SESSION_STRING', 'DYhG93b0qyJfIxfs2guVoUubWwvniR2G0FgaC9mi');
/** /**
* Set the name of session cookie * Set the name of session cookie
* *
@ -81,27 +100,6 @@ define('CAKE_SECURITY', 'high');
*/ */
define('CAKE_SESSION_TIMEOUT', '120'); define('CAKE_SESSION_TIMEOUT', '120');
/**
* Set a random string of used in session.
*
*/
define('CAKE_SESSION_STRING', 'DYhG93b0qyJfIxfs2guVoUubWwvniR2G0FgaC9mi');
/**
* CakePHP includes 3 types of session saves
* database or file. Set this to your preffered method.
* If you want to use your own save handeler place it in
* app/config/name.php DO NOT USE file or database as the name.
* and use just the name portion below.
*
* Setting this to cake will save files to /cakedistro/tmp directory
* Setting it to php will use the php default save path
* Setting it to database will use the database
*
*
*/
define('CAKE_SESSION_SAVE', 'php');
/** /**
* Uncomment the define below to use cake built in admin routes. * Uncomment the define below to use cake built in admin routes.
* You can set this value to anything you want. * You can set this value to anything you want.

View file

@ -1,60 +0,0 @@
<?php
/* SVN FILE: $Id:*/
/**
* Short description for file.
*
* In this file, you set up routes to your controllers and their actions.
* Routes are very important mechanism that allows you to freely connect
* different urls to chosen controllers and their actions (functions).
*
* PHP versions 4 and 5
*
* CakePHP : Rapid Development Framework <http://www.cakephp.org/>
* Copyright (c) 2006, 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) 2006, Cake Software Foundation, Inc.
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
* @package cake
* @subpackage cake.cake.app.config
* @since CakePHP v 0.2.9
* @version $Revision$
* @modifiedby $LastChangedBy$
* @lastmodified $Date$
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
*/
/**
* In this file, you set up routes to your controllers and their actions.
* Routes are very important mechanism that allows you to freely connect
* different urls to chosen controllers and their actions (functions).
*
* @package cake
* @subpackage cake.config
*/
/**
* Here we are connecting '/' (base path) to a controller called 'Pages',
* and its action called 'display'. We pass a parameter to select the view file
* to use (in this case, /app/views/pages/home.thtml).
*/
$Route->connect ('/', array('controller'=>'pages', 'action'=>'display', 'home'));
/**
* ...and connect the rest of 'Pages' controller's URLs.
*/
$Route->connect ('/pages/*', array('controller'=>'pages', 'action'=>'display'));
/**
* Then we connect url '/test' to our test controller. This is helpful in
* development.
*/
$Route->connect ('/test', array('controller'=>'tests', 'action'=>'test_all'));
?>

View file

@ -0,0 +1,11 @@
# @copyright Copyright (c) 2006, Cake Software Foundation, Inc.
# @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
# @since CakePHP v 0.10.8.1997
# @version $Revision$
CREATE TABLE cake_sessions (
id varchar(255) NOT NULL default '',
data text,
expires int(11) default NULL,
PRIMARY KEY (id)
);

View file

@ -23,5 +23,5 @@
* @lastmodified $Date$ * @lastmodified $Date$
* @license http://www.opensource.org/licenses/mit-license.php The MIT License * @license http://www.opensource.org/licenses/mit-license.php The MIT License
*/ */
require_once 'webroot'.DIRECTORY_SEPARATOR.'index.php'; require 'webroot'.DIRECTORY_SEPARATOR.'index.php';
?> ?>

View file

@ -31,9 +31,9 @@
/** /**
* Enter description here... * Enter description here...
*/ */
require_once(CONFIGS.'paths.php'); require(CONFIGS.'paths.php');
require_once(CAKE.'basics.php'); require(CAKE.'basics.php');
require_once(LIBS.'folder.php'); require(LIBS.'folder.php');
require(LIBS.'file.php'); require(LIBS.'file.php');
require(LIBS.'legacy.php'); require(LIBS.'legacy.php');
@ -46,7 +46,7 @@ require(LIBS.'legacy.php');
*/ */
function make_clean_css ($path, $name) function make_clean_css ($path, $name)
{ {
require_once(VENDORS.'csspp'.DS.'csspp.php'); require(VENDORS.'csspp'.DS.'csspp.php');
$data = file_get_contents($path); $data = file_get_contents($path);
$csspp = new csspp(); $csspp = new csspp();

View file

@ -73,5 +73,19 @@ if (!defined('WEBROOT_DIR'))
ini_set('include_path',ini_get('include_path').PATH_SEPARATOR.CAKE_CORE_INCLUDE_PATH.PATH_SEPARATOR.ROOT.DS.APP_DIR.DS); ini_set('include_path',ini_get('include_path').PATH_SEPARATOR.CAKE_CORE_INCLUDE_PATH.PATH_SEPARATOR.ROOT.DS.APP_DIR.DS);
require_once 'cake'.DS.'bootstrap.php'; require 'cake'.DS.'bootstrap.php';
if(isset($_GET['url']) && $_GET['url'] === 'favicon.ico')
{
}
else
{
$Dispatcher= new Dispatcher ();
$Dispatcher->dispatch($url);
}
if (DEBUG)
{
echo "<!-- ". round(getMicrotime() - $TIME_START, 2) ."s -->";
}
?> ?>

View file

@ -65,11 +65,11 @@ function loadModels()
{ {
if(file_exists(APP.'app_model.php')) if(file_exists(APP.'app_model.php'))
{ {
require_once(APP.'app_model.php'); require(APP.'app_model.php');
} }
else else
{ {
require_once(CAKE.'app_model.php'); require(CAKE.'app_model.php');
} }
} }
@ -80,7 +80,7 @@ function loadModels()
foreach (listClasses(MODELS) as $model_fn) foreach (listClasses(MODELS) as $model_fn)
{ {
require_once (MODELS.$model_fn); require (MODELS.$model_fn);
if (phpversion() < 5 && function_exists("overload")) if (phpversion() < 5 && function_exists("overload"))
{ {
list($name) = explode('.', $model_fn); list($name) = explode('.', $model_fn);
@ -104,7 +104,7 @@ function loadPluginModels ($plugin)
{ {
if(file_exists($pluginAppModelFile)) if(file_exists($pluginAppModelFile))
{ {
require_once($pluginAppModelFile); require($pluginAppModelFile);
} }
else else
{ {
@ -121,7 +121,7 @@ function loadPluginModels ($plugin)
foreach (listClasses($pluginModelDir) as $modelFileName) foreach (listClasses($pluginModelDir) as $modelFileName)
{ {
require_once ($pluginModelDir.$modelFileName); require ($pluginModelDir.$modelFileName);
if (phpversion() < 5 && function_exists("overload")) if (phpversion() < 5 && function_exists("overload"))
{ {
list($name) = explode('.', $modelFileName); list($name) = explode('.', $modelFileName);
@ -141,11 +141,11 @@ function loadView ($viewClass)
$file = Inflector::underscore($viewClass).'.php'; $file = Inflector::underscore($viewClass).'.php';
if(file_exists(VIEWS.$file)) if(file_exists(VIEWS.$file))
{ {
return require_once(VIEWS.$file); return require(VIEWS.$file);
} }
elseif(file_exists(LIBS.'view'.DS.$file)) elseif(file_exists(LIBS.'view'.DS.$file))
{ {
return require_once(LIBS.'view'.DS.$file); return require(LIBS.'view'.DS.$file);
} }
else else
{ {
@ -170,17 +170,17 @@ function loadModel($name)
{ {
if(file_exists(APP.'app_model.php')) if(file_exists(APP.'app_model.php'))
{ {
require_once(APP.'app_model.php'); require(APP.'app_model.php');
} }
else else
{ {
require_once(CAKE.'app_model.php'); require(CAKE.'app_model.php');
} }
} }
if(file_exists(MODELS.$name.'.php')) if(file_exists(MODELS.$name.'.php'))
{ {
require_once (MODELS.$name.'.php'); require (MODELS.$name.'.php');
return true; return true;
} }
@ -201,18 +201,18 @@ function loadControllers ()
{ {
if(file_exists(APP.'app_controller.php')) if(file_exists(APP.'app_controller.php'))
{ {
require_once(APP.'app_controller.php'); require(APP.'app_controller.php');
} }
else else
{ {
require_once(CAKE.'app_controller.php'); require(CAKE.'app_controller.php');
} }
} }
foreach (listClasses(CONTROLLERS) as $controller) foreach (listClasses(CONTROLLERS) as $controller)
{ {
if(!class_exists($controller)) if(!class_exists($controller))
{ {
require_once (CONTROLLERS.$controller.'.php'); require (CONTROLLERS.$controller.'.php');
} }
} }
} }
@ -229,11 +229,11 @@ function loadController ($name)
{ {
if(file_exists(APP.'app_controller.php')) if(file_exists(APP.'app_controller.php'))
{ {
require_once(APP.'app_controller.php'); require(APP.'app_controller.php');
} }
else else
{ {
require_once(CAKE.'app_controller.php'); require(CAKE.'app_controller.php');
} }
} }
if($name === null) if($name === null)
@ -255,7 +255,7 @@ function loadController ($name)
{ {
return false; return false;
} }
require_once($controller_fn); require($controller_fn);
return true; return true;
} }
else else
@ -281,7 +281,7 @@ function loadPluginController ($plugin, $controller)
{ {
if(file_exists($pluginAppControllerFile)) if(file_exists($pluginAppControllerFile))
{ {
require_once($pluginAppControllerFile); require($pluginAppControllerFile);
} }
else else
{ {
@ -299,7 +299,7 @@ function loadPluginController ($plugin, $controller)
} }
else else
{ {
require_once($file); require($file);
return true; return true;
} }
} }
@ -396,11 +396,11 @@ function vendor($name)
{ {
if(file_exists(APP.'vendors'.DS.$arg.'.php')) if(file_exists(APP.'vendors'.DS.$arg.'.php'))
{ {
require_once(APP.'vendors'.DS.$arg.'.php'); require(APP.'vendors'.DS.$arg.'.php');
} }
else else
{ {
require_once(VENDORS.$arg.'.php'); require(VENDORS.$arg.'.php');
} }
} }
} }

View file

@ -33,14 +33,17 @@
/** /**
* Configuration, directory layout and standard libraries * Configuration, directory layout and standard libraries
*/ */
require_once 'cake'.DS.'basics.php'; if(!isset($bootstrap))
require_once ROOT.DS.APP_DIR.DS.'config'.DS.'core.php'; {
require_once 'cake'.DS.'config'.DS.'paths.php'; require 'cake'.DS.'basics.php';
require_once LIBS.'object.php'; require 'config'.DS.'core.php';
require_once LIBS.'session.php'; require 'cake'.DS.'config'.DS.'paths.php';
require_once LIBS.'security.php'; }
require_once LIBS.'neat_array.php'; require LIBS.'object.php';
require_once LIBS.'inflector.php'; require LIBS.'session.php';
require LIBS.'security.php';
require LIBS.'neat_array.php';
require LIBS.'inflector.php';
/** /**
* Enter description here... * Enter description here...
@ -101,28 +104,14 @@ else
$TIME_START = getMicrotime(); $TIME_START = getMicrotime();
require_once CAKE.'dispatcher.php'; require CAKE.'dispatcher.php';
require_once LIBS.'model'.DS.'connection_manager.php'; require LIBS.'model'.DS.'connection_manager.php';
config('database'); config('database');
if (class_exists('DATABASE_CONFIG') && !class_exists('AppModel')) if (class_exists('DATABASE_CONFIG') && !class_exists('AppModel'))
{ {
require_once LIBS.'model'.DS.'model.php'; require LIBS.'model'.DS.'model.php';
loadModels(); loadModels();
} }
if(isset($_GET['url']) && $_GET['url'] === 'favicon.ico')
{
}
else
{
$Dispatcher= new Dispatcher ();
$Dispatcher->dispatch($url);
}
if (DEBUG)
{
echo "<!-- ". round(getMicrotime() - $TIME_START, 2) ."s -->";
}
?> ?>

View file

@ -55,7 +55,7 @@ textarea = "<textarea name="data[%s][%s]" %s>%s</textarea>"
checkbox = "<input type="checkbox" name="data[%s][%s]" id="tag_%s" %s/>" checkbox = "<input type="checkbox" name="data[%s][%s]" id="tag_%s" %s/>"
; Tag template for a input type='radio' tag. ; Tag template for a input type='radio' tag.
radio = "<input type="radio" name="data[%s][%s]" id="tag_%s" %s/>" radio = "<input type="radio" name="data[%s][%s]" id="%s" %s />%s"
; Tag template for a select opening tag. ; Tag template for a select opening tag.
selectstart = "<select name="data[%s][%s]" %s>" selectstart = "<select name="data[%s][%s]" %s>"

View file

@ -108,7 +108,10 @@ class Component extends Object
if (is_file($componentFn)) if (is_file($componentFn))
{ {
require_once $componentFn; if(!class_exists($componentCn))
{
require_once $componentFn;
}
if(class_exists($componentCn)===true) if(class_exists($componentCn)===true)
{ {

View file

@ -28,7 +28,6 @@
* @license http://www.opensource.org/licenses/mit-license.php The MIT License * @license http://www.opensource.org/licenses/mit-license.php The MIT License
*/ */
uses('inflector');
uses('controller'.DS.'components'.DS.'acl_base'); uses('controller'.DS.'components'.DS.'acl_base');
uses('controller'.DS.'components'.DS.'dbacl'.DS.'models'.DS.'aclnode'); uses('controller'.DS.'components'.DS.'dbacl'.DS.'models'.DS.'aclnode');
uses('controller'.DS.'components'.DS.'dbacl'.DS.'models'.DS.'aco'); uses('controller'.DS.'components'.DS.'dbacl'.DS.'models'.DS.'aco');

View file

@ -33,7 +33,7 @@
*/ */
if(!class_exists('AppModel')) if(!class_exists('AppModel'))
{ {
require_once(CAKE.'app_model.php'); require(CAKE.'app_model.php');
} }
/** /**
* Short description for file. * Short description for file.

View file

@ -425,6 +425,9 @@ class Controller extends Object
{ {
$viewClass = $this->view.'View'; $viewClass = $this->view.'View';
} }
$this->beforeRender();
$this->_viewClass =& new $viewClass($this); $this->_viewClass =& new $viewClass($this);
if(!empty($this->modelNames)) if(!empty($this->modelNames))
{ {
@ -437,7 +440,6 @@ class Controller extends Object
} }
} }
$this->beforeRender();
$this->autoRender = false; $this->autoRender = false;
return $this->_viewClass->render($action, $layout, $file); return $this->_viewClass->render($action, $layout, $file);
} }

View file

@ -78,12 +78,12 @@ class ConnectionManager extends Object
*/ */
function &getInstance() function &getInstance()
{ {
static $instance = null; static $instance = array();
if($instance == null) if(!isset($instance[0]) || !$instance[0])
{ {
$instance =& new ConnectionManager(); $instance[0] =& new ConnectionManager();
} }
return $instance; return $instance[0];
} }
/** /**
@ -117,18 +117,21 @@ class ConnectionManager extends Object
} }
$tail = 'dbo'.DS.$filename.'.php'; $tail = 'dbo'.DS.$filename.'.php';
if (fileExistsInPath(LIBS.'model'.DS.$tail)) if(!class_exists($classname))
{ {
require_once(LIBS.'model'.DS.$tail); if (fileExistsInPath(LIBS.'model'.DS.$tail))
} {
else if (file_exists(MODELS.$tail)) require(LIBS.'model'.DS.$tail);
{ }
require_once(MODELS.$tail); else if (file_exists(MODELS.$tail))
} {
else require(MODELS.$tail);
{ }
trigger_error('Unable to load model file ' . $filename . '.php', E_USER_ERROR); else
return null; {
trigger_error('Unable to load model file ' . $filename . '.php', E_USER_ERROR);
return null;
}
} }
$_this->_dataSources[$name] =& new $classname($config); $_this->_dataSources[$name] =& new $classname($config);
$_this->_dataSources[$name]->configKeyName = $name; $_this->_dataSources[$name]->configKeyName = $name;

View file

@ -28,12 +28,6 @@
* @license http://www.opensource.org/licenses/mit-license.php The MIT License * @license http://www.opensource.org/licenses/mit-license.php The MIT License
*/ */
/**
* Include DataSource base class
*
*/
uses('model'.DS.'datasources'.DS.'datasource');
/** /**
* DboSource * DboSource
* *
@ -513,11 +507,13 @@ class DboSource extends DataSource
{ {
if (count($row) == 1) if (count($row) == 1)
{ {
$data[$association][] = $row[$association]; $data[$association][] = $row[$association];
} }
else else
{ {
$data[$association][] = $row; $tmp = array_merge($row[$association], $row);
unset($tmp[$association]);
$data[$association][] = $tmp;
} }
} }
} }
@ -916,7 +912,7 @@ class DboSource extends DataSource
{ {
if (!isset($data['conditions'])) if (!isset($data['conditions']))
{ {
$data['conditions'] = ' 1 '; $data['conditions'] = ' 1 = 1 ';
} }
if (!isset($data['fields'])) if (!isset($data['fields']))
{ {
@ -1012,7 +1008,7 @@ class DboSource extends DataSource
{ {
if (trim($conditions) == '') if (trim($conditions) == '')
{ {
$conditions = ' 1'; $conditions = ' 1 = 1';
} }
return $rt.$conditions; return $rt.$conditions;
} }
@ -1073,10 +1069,10 @@ class DboSource extends DataSource
* Returns an ORDER BY clause as a string. * Returns an ORDER BY clause as a string.
* *
* @param string $key Field reference, as a key (i.e. Post.title) * @param string $key Field reference, as a key (i.e. Post.title)
* @param string $dir Direction (ASC or DESC) * @param string $direction Direction (ASC or DESC)
* @return string ORDER BY clause * @return string ORDER BY clause
*/ */
function order ($keys, $dir = '') function order ($keys, $direction = 'ASC')
{ {
if (empty($keys)) if (empty($keys))
{ {
@ -1090,7 +1086,7 @@ class DboSource extends DataSource
if(is_numeric($key)) if(is_numeric($key))
{ {
$key = $value; $key = $value;
$value = null; $value = ' '.$direction;
} }
else else
{ {
@ -1104,10 +1100,14 @@ class DboSource extends DataSource
{ {
if (preg_match('/(?P<direction>\\x20ASC|\\x20DESC)/', $keys, $match)) if (preg_match('/(?P<direction>\\x20ASC|\\x20DESC)/', $keys, $match))
{ {
$dir = $match['direction']; $direction = $match['direction'];
$keys = preg_replace('/'.$match['direction'].'/', '', $keys); $keys = preg_replace('/'.$match['direction'].'/', '', $keys);
} }
return ' ORDER BY '.$this->name($keys).$dir; else
{
$direction = ' '.$direction;
}
return ' ORDER BY '.$this->name($keys).$direction;
} }
} }

View file

@ -31,7 +31,7 @@
/** /**
* Include AdoDB files. * Include AdoDB files.
*/ */
require_once(VENDORS.'adodb'.DS.'adodb.inc.php'); require(VENDORS.'adodb'.DS.'adodb.inc.php');
uses('model'.DS.'datasources'.DS.'dbo_source'); uses('model'.DS.'datasources'.DS.'dbo_source');
/** /**

View file

@ -44,7 +44,7 @@ uses('object');
* Example usage: * Example usage:
* *
* <code> * <code>
* require_once('dbo_mysql.php'); // or 'dbo_postgres.php' * require('dbo_mysql.php'); // or 'dbo_postgres.php'
* *
* // create and connect the object * // create and connect the object
* $db = new DBO_MySQL(array( // or 'DBO_Postgres' * $db = new DBO_MySQL(array( // or 'DBO_Postgres'

View file

@ -283,14 +283,8 @@ class DboMysql extends DboSource
{ {
$data = stripslashes($data); $data = stripslashes($data);
} }
if (version_compare(phpversion(),"4.3.0") == "-1") $data = mysql_real_escape_string($data, $this->connection);
{
$data = mysql_escape_string($data, $this->connection);
}
else
{
$data = mysql_real_escape_string($data, $this->connection);
}
if(!is_numeric($data)) if(!is_numeric($data))
{ {
$return = "'" . $data . "'"; $return = "'" . $data . "'";

View file

@ -35,7 +35,7 @@
*/ */
if (phpversion() < 5) if (phpversion() < 5)
{ {
require_once(LIBS.'model'.DS.'model_php4.php'); require(LIBS.'model'.DS.'model_php4.php');
if (function_exists("overload")) if (function_exists("overload"))
{ {
overload("Model"); overload("Model");
@ -43,6 +43,6 @@ if (phpversion() < 5)
} }
else else
{ {
require_once(LIBS.'model'.DS.'model_php5.php'); require(LIBS.'model'.DS.'model_php5.php');
} }
?> ?>

View file

@ -6,7 +6,7 @@
* *
* DBO-backed object data model, for mapping database tables to Cake objects. * DBO-backed object data model, for mapping database tables to Cake objects.
* *
* PHP versions 4 and 5 * PHP versions 4
* *
* CakePHP : Rapid Development Framework <http://www.cakephp.org/> * CakePHP : Rapid Development Framework <http://www.cakephp.org/>
* Copyright (c) 2006, Cake Software Foundation, Inc. * Copyright (c) 2006, Cake Software Foundation, Inc.
@ -77,7 +77,7 @@ class Model extends Object
var $parent = false; var $parent = false;
/** /**
* Custom database table name * Custom database table name.
* *
* @var string * @var string
* @access public * @access public
@ -85,7 +85,7 @@ class Model extends Object
var $useTable = null; var $useTable = null;
/** /**
* Custom display field name * Custom display field name. Display fields are used by Scaffold, in SELECT boxes' OPTION elements.
* *
* @var string * @var string
* @access public * @access public
@ -147,7 +147,7 @@ class Model extends Object
var $validationErrors = null; var $validationErrors = null;
/** /**
* Prefix for tables in model. * Database table prefix for tables in model.
* *
* @var string * @var string
*/ */
@ -161,7 +161,7 @@ class Model extends Object
var $name = null; var $name = null;
/** /**
* Name of the model. * Name of the current model.
* *
* @var string * @var string
*/ */
@ -182,7 +182,7 @@ class Model extends Object
var $modelToTable = array(); var $modelToTable = array();
/** /**
* List of Foreign Key names to table used tables. Used for associations. * List of Foreign Key names to used tables. Used for associations.
* *
* @var array * @var array
*/ */
@ -203,7 +203,7 @@ class Model extends Object
var $logTransactions = false; var $logTransactions = false;
/** /**
* Whether or not to enable transactions for this model (i.e. begin/commit/rollback) * Whether or not to enable transactions for this model (i.e. BEGIN/COMMIT/ROLLBACK)
* *
* @var boolean * @var boolean
*/ */
@ -238,7 +238,7 @@ class Model extends Object
var $hasAndBelongsToMany = array(); var $hasAndBelongsToMany = array();
/** /**
* recursive assoication depth * Depth of recursive association
* *
* @var int * @var int
*/ */
@ -290,8 +290,8 @@ class Model extends Object
* Constructor. Binds the Model's database table to the object. * Constructor. Binds the Model's database table to the object.
* *
* @param integer $id * @param integer $id
* @param string $table Database table to use. * @param string $table Name of database table to use.
* @param unknown_type $ds DataSource connection object. * @param DataSource $ds DataSource connection object.
*/ */
function __construct ($id=false, $table=null, $ds=null) function __construct ($id=false, $table=null, $ds=null)
{ {
@ -428,6 +428,7 @@ class Model extends Object
* @param string $assoc * @param string $assoc
* @param string $className Class name * @param string $className Class name
* @param string $type Type of assocation * @param string $type Type of assocation
* @todo Is the third parameter in use at the moment? It is not referred to in the method OJ, 30. jan 2006
* @access private * @access private
*/ */
function __constructLinkedModel($assoc, $className, $type) function __constructLinkedModel($assoc, $className, $type)
@ -435,7 +436,7 @@ class Model extends Object
$colKey = Inflector::underscore($className); $colKey = Inflector::underscore($className);
if(ClassRegistry::isKeySet($colKey)) if(ClassRegistry::isKeySet($colKey))
{ {
$this->{$className} =& ClassRegistry::getObject($colKey); $this->{$className} =& ClassRegistry::getObject($colKey);
} }
else else
{ {
@ -448,11 +449,11 @@ class Model extends Object
} }
/** /**
* Build array-based association from string * Build array-based association from string.
* *
* @param string $type "Belongs", "One", "Many", "ManyTo" * @param string $type "Belongs", "One", "Many", "ManyTo"
* @param string $assoc * @param string $assoc
* @param string $model * @todo Is the second parameter in use at the moment? It is not referred to in the method OJ, 30. jan 2006
* @access private * @access private
*/ */
function __generateAssociation ($type, $assoc) function __generateAssociation ($type, $assoc)
@ -604,10 +605,9 @@ class Model extends Object
} }
/** /**
* Returns true if given field name exists in this Model's database table. * Returns true if this Model has given field in its database table.
* Starts by loading the metadata into the private property table_info if that is not already set.
* *
* @param string $name Name of table to look in * @param string $name Name of field to look for
* @return boolean * @return boolean
*/ */
function hasField ($name) function hasField ($name)
@ -624,9 +624,9 @@ class Model extends Object
} }
/** /**
* Initializes the model for writing a new record * Initializes the model for writing a new record.
* *
* @return boolean True on success * @return boolean True
*/ */
function create () function create ()
{ {
@ -646,7 +646,7 @@ class Model extends Object
} }
/** /**
* Deprecated * Deprecated. Use query() instead.
* *
*/ */
function findBySql ($sql) function findBySql ($sql)
@ -691,8 +691,8 @@ class Model extends Object
* Returns contents of a field in a query matching given conditions. * Returns contents of a field in a query matching given conditions.
* *
* @param string $name Name of field to get * @param string $name Name of field to get
* @param string $conditions SQL conditions (defaults to NULL) * @param array $conditions SQL conditions (defaults to NULL)
* @param string $order (defaults to NULL) * @param string $order SQL ORDER BY fragment
* @return field contents * @return field contents
*/ */
function field ($name, $conditions = null, $order = null) function field ($name, $conditions = null, $order = null)
@ -739,14 +739,14 @@ class Model extends Object
/** /**
* Saves model data to the database. * Saves model data to the database.
* By default, validation occurs before save.
* *
* @param array $data Data to save. * @param array $data Data to save.
* @param boolean $validate * @param boolean $validate If set, validation will be done before the save
* @param array $fields * @param array $fieldList List of fields to allow to be written
* @return boolean success * @return boolean success
* @todo Implement $fields param as a whitelist of allowable fields
*/ */
function save ($data = null, $validate = true, $fields = null) function save ($data = null, $validate = true, $fieldList = array())
{ {
if ($data) if ($data)
{ {
@ -760,122 +760,123 @@ class Model extends Object
} }
} }
if($this->beforeSave()) $whitelist = !(empty($fieldList) || count($fieldList) == 0);
if ($validate && !$this->validates())
{ {
if ($validate && !$this->validates()) return false;
}
if(!$this->beforeSave())
{
return false;
}
$fields = $values = array();
$count = 0;
if(count($this->data) > 1)
{
$weHaveMulti = true;
$joined = false;
}
else
{
$weHaveMulti = false;
}
foreach ($this->data as $n => $v)
{
if(isset($weHaveMulti) && $count > 0 && count($this->hasAndBelongsToMany) > 0)
{ {
return false; $joined[] = $v;
} }
$fields = $values = array(); else
$count = 0; {
foreach ($v as $x => $y)
{
if ($this->hasField($x) && ($whitelist && in_array($x, $fieldList) || !$whitelist))
{
$fields[] = $x;
$values[] = $y;
if(count($this->data) > 1) if($x == $this->primaryKey && !is_numeric($y))
{ {
$weHaveMulti = true; $newID = $y;
$joined = false; }
} }
else }
{ $count++;
$weHaveMulti = false; }
} }
foreach ($this->data as $n => $v) if (empty($this->id) && $this->hasField('created') && !in_array('created', $fields) && ($whitelist && in_array('created', $fieldList) || !$whitelist))
{ {
if(isset($weHaveMulti) && $count > 0 && count($this->hasAndBelongsToMany) > 0) $fields[] = 'created';
{ $values[] = date('Y-m-d H:i:s');
$joined[] = $v; }
} if ($this->hasField('modified') && !in_array('modified', $fields) && ($whitelist && in_array('modified', $fieldList) || !$whitelist))
else {
{ $fields[] = 'modified';
foreach ($v as $x => $y) $values[] = date('Y-m-d H:i:s');
{ }
if ($this->hasField($x)) if ($this->hasField('updated') && !in_array('updated', $fields) && ($whitelist && in_array('updated', $fieldList) || !$whitelist))
{ {
$fields[] = $x; $fields[] = 'updated';
$values[] = $y; $values[] = date('Y-m-d H:i:s');
}
if($x == $this->primaryKey && !is_numeric($y)) if(!$this->exists())
{ {
$newID = $y; $this->id = false;
} }
}
}
$count++;
}
}
if (empty($this->id) && $this->hasField('created') && !in_array('created', $fields)) if(count($fields))
{ {
$fields[] = 'created'; if(!empty($this->id))
$values[] = date('Y-m-d H:i:s'); {
} if ($this->db->update($this, $fields, $values))
if ($this->hasField('modified') && !in_array('modified', $fields)) {
{ if(!empty($joined))
$fields[] = 'modified'; {
$values[] = date('Y-m-d H:i:s'); $this->__saveMulti($joined, $this->id);
} }
if ($this->hasField('updated') && !in_array('updated', $fields)) $this->afterSave();
{ $this->data = false;
$fields[] = 'updated'; return true;
$values[] = date('Y-m-d H:i:s'); }
} else
{
return $this->hasAny($this->escapeField($this->primaryKey).' = '.$this->db->value($this->id));
}
}
else
{
if($this->db->create($this, $fields, $values))
{
$this->__insertID = $this->db->lastInsertId($this->table, $this->primaryKey);
$this->id = $this->__insertID;
if(!$this->exists()) if(!$this->id > 0 && isset($newID))
{ {
$this->id = false; $this->__insertID = $newID;
} $this->id = $newID;
}
if(count($fields)) if(!empty($joined))
{ {
if(!empty($this->id)) $this->__saveMulti($joined, $this->id);
{ }
if ($this->db->update($this, $fields, $values))
{
if(!empty($joined))
{
$this->__saveMulti($joined, $this->id);
}
$this->afterSave();
$this->data = false;
return true;
}
else
{
return $this->hasAny($this->escapeField($this->primaryKey).' = '.$this->db->value($this->id));
}
}
else
{
if($this->db->create($this, $fields, $values))
{
$this->__insertID = $this->db->lastInsertId($this->table, $this->primaryKey);
$this->id = $this->__insertID;
if(!$this->id > 0 && isset($newID)) $this->afterSave();
{ $this->data = false;
$this->__insertID = $newID; return true;
$this->id = $newID; }
} else
{
if(!empty($joined)) return false;
{ }
$this->__saveMulti($joined, $this->id); }
}
$this->afterSave();
$this->data = false;
return true;
}
else
{
return false;
}
}
}
else
{
return false;
}
} }
else else
{ {
@ -949,10 +950,10 @@ class Model extends Object
/** /**
* Removes record for given id. If no id is given, the current id is used. Returns true on success. * Removes record for given id. If no id is given, the current id is used. Returns true on success.
* *
* @param mixed $id Id of database record to delete * @param mixed $id Id of record to delete
* @return boolean True on success * @return boolean True on success
*/ */
function del ($id = null) function del ($id = null, $cascade = false)
{ {
if ($id) if ($id)
{ {
@ -963,6 +964,11 @@ class Model extends Object
{ {
if ($this->id && $this->db->delete($this)) if ($this->id && $this->db->delete($this))
{ {
//$this->__deleteJoins($id);
if ($cascade)
{
//$this->__deleteMulti($id);
}
$this->afterDelete(); $this->afterDelete();
$this->id = false; $this->id = false;
return true; return true;
@ -972,6 +978,42 @@ class Model extends Object
return false; return false;
} }
/**
* Cascades model deletes to hasMany relationships.
*
* @param string $id
* @return null
* @access private
*/
function __deleteMulti ($id)
{
foreach ($this->hasMany as $assoc => $data)
{
$model =& $this->{$data['className']};
$field = $model->escapeField($data['foreignKey']);
$records = $model->findAll($field.'='.$id);
foreach($records as $record)
{
}
}
}
/**
* Cascades model deletes to HABTM join keys.
*
* @param string $id
* @return null
* @access private
*/
function __deleteJoins ($id)
{
foreach ($this->hasAndBelongsToMany as $assoc => $data)
{
}
}
/** /**
* Returns true if a record with set id exists. * Returns true if a record with set id exists.
* *
@ -994,6 +1036,7 @@ class Model extends Object
/** /**
* Returns true if a record that meets given conditions exists * Returns true if a record that meets given conditions exists
* *
* @param array $conditions SQL conditions array
* @return boolean True if such a record exists * @return boolean True if such a record exists
*/ */
function hasAny ($conditions = null) function hasAny ($conditions = null)
@ -1003,11 +1046,13 @@ class Model extends Object
/** /**
* Return a single row as a resultset array. * Return a single row as a resultset array.
* By using the $recursive parameter, the call can access further "levels of association" than
* the ones this model is directly associated to.
* *
* @param string $conditions SQL conditions * @param array $conditions SQL conditions array
* @param mixed $fields Either a single string of a field name, or an array of field names * @param mixed $fields Either a single string of a field name, or an array of field names
* @param string $order SQL ORDER BY conditions (e.g. "price DESC" or "name ASC") * @param string $order SQL ORDER BY conditions (e.g. "price DESC" or "name ASC")
* @param int $recursize The number of levels deep to fetch associated records * @param int $recursive The number of levels deep to fetch associated records
* @return array Array of records * @return array Array of records
*/ */
function find ($conditions = null, $fields = null, $order = null, $recursive = null) function find ($conditions = null, $fields = null, $order = null, $recursive = null)
@ -1022,13 +1067,15 @@ class Model extends Object
/** /**
* Returns a resultset array with specified fields from database matching given conditions. * Returns a resultset array with specified fields from database matching given conditions.
* By using the $recursive parameter, the call can access further "levels of association" than
* the ones this model is directly associated to.
* *
* @param mixed $conditions SQL conditions as a string or as an array('field'=>'value',...) * @param mixed $conditions SQL conditions as a string or as an array('field'=>'value',...)
* @param mixed $fields Either a single string of a field name, or an array of field names * @param mixed $fields Either a single string of a field name, or an array of field names
* @param string $order SQL ORDER BY conditions (e.g. "price DESC" or "name ASC") * @param string $order SQL ORDER BY conditions (e.g. "price DESC" or "name ASC")
* @param int $limit SQL LIMIT clause, for calculating items per page * @param int $limit SQL LIMIT clause, for calculating items per page.
* @param int $page Page number * @param int $page Page number, for accessing paged data
* @param int $recursize The number of levels deep to fetch associated records * @param int $recursive The number of levels deep to fetch associated records
* @return array Array of records * @return array Array of records
*/ */
function findAll ($conditions = null, $fields = null, $order = null, $limit = 50, $page = 1, $recursive = null) function findAll ($conditions = null, $fields = null, $order = null, $limit = 50, $page = 1, $recursive = null)
@ -1061,7 +1108,7 @@ class Model extends Object
} }
/** /**
* Runs a direct query against the bound DataSource, and returns the result * Runs a direct query against the bound DataSource, and returns the result.
* *
* @param string $data Query data * @param string $data Query data
* @return array * @return array
@ -1089,9 +1136,10 @@ class Model extends Object
/** /**
* Returns number of rows matching given SQL condition. * Returns number of rows matching given SQL condition.
* *
* @param string $conditions SQL conditions (WHERE clause conditions) * @param array $conditions SQL conditions array for findAll
* @param int $recursize The number of levels deep to fetch associated records * @param int $recursize The number of levels deep to fetch associated records
* @return int Number of matching rows * @return int Number of matching rows
* @see Model::findAll
*/ */
function findCount ($conditions = null, $recursive = 0) function findCount ($conditions = null, $recursive = 0)
{ {
@ -1105,12 +1153,12 @@ class Model extends Object
/** /**
* Special findAll variation for tables joined to themselves. * Special findAll variation for tables joined to themselves.
* The table needs fields id and parent_id to work. * The table needs the fields id and parent_id to work.
* *
* @param array $conditions Conditions for the findAll() call * @param array $conditions Conditions for the findAll() call
* @param array $fields Fields for the findAll() call * @param array $fields Fields for the findAll() call
* @param string $sort SQL ORDER BY statement * @param string $sort SQL ORDER BY statement
* @return unknown * @return array
* @todo Perhaps create a Component with this logic * @todo Perhaps create a Component with this logic
*/ */
function findAllThreaded ($conditions=null, $fields=null, $sort=null) function findAllThreaded ($conditions=null, $fields=null, $sort=null)
@ -1125,6 +1173,7 @@ class Model extends Object
* @param string $root NULL or id for root node of operation * @param string $root NULL or id for root node of operation
* @return array * @return array
* @access private * @access private
* @see findAllThreaded
*/ */
function __doThread ($data, $root) function __doThread ($data, $root)
{ {
@ -1154,7 +1203,7 @@ class Model extends Object
* which is useful when creating paged lists. * which is useful when creating paged lists.
* *
* @param string $conditions SQL conditions for matching rows * @param string $conditions SQL conditions for matching rows
* @param unknown_type $field * @param string $field Field name (parameter for findAll)
* @param unknown_type $value * @param unknown_type $value
* @return array Array with keys "prev" and "next" that holds the id's * @return array Array with keys "prev" and "next" that holds the id's
*/ */
@ -1179,7 +1228,7 @@ class Model extends Object
} }
/** /**
* Returns a resultset for given SQL statement. * Returns a resultset for given SQL statement. Generic SQL queries should be made with this method.
* *
* @param string $sql SQL statement * @param string $sql SQL statement
* @return array Resultset * @return array Resultset
@ -1191,7 +1240,7 @@ class Model extends Object
} }
/** /**
* Returns true if all fields pass validation. * Returns true if all fields pass validation, otherwise false.
* *
* @param array $data POST data * @param array $data POST data
* @return boolean True if there are no errors * @return boolean True if there are no errors
@ -1254,7 +1303,7 @@ class Model extends Object
} }
/** /**
* This function determines whether or not a string is a foreign key * Returns true if given field name is a foreign key in this Model.
* *
* @param string $field Returns true if the input string ends in "_id" * @param string $field Returns true if the input string ends in "_id"
* @return True if the field is a foreign key listed in the belongsTo array. * @return True if the field is a foreign key listed in the belongsTo array.
@ -1284,7 +1333,7 @@ class Model extends Object
} }
/** /**
* Returns a resultset array with specified fields from database matching given conditions. * Returns a resultset array with specified fields from database matching given conditions. Method can be used to generate option lists for SELECT elements.
* *
* @param mixed $conditions SQL conditions as a string or as an array('field'=>'value',...) * @param mixed $conditions SQL conditions as a string or as an array('field'=>'value',...)
* @param mixed $fields Either a single string of a field name, or an array of field names * @param mixed $fields Either a single string of a field name, or an array of field names
@ -1313,7 +1362,7 @@ class Model extends Object
} }
/** /**
* Escapes the field name and prepends the model name * Escapes the field name and prepends the model name. Escaping will be done according to the current database driver's rules.
* *
* @param unknown_type $field * @param unknown_type $field
* @return string The name of the escaped field for this Model (i.e. id becomes `Post`.`id`). * @return string The name of the escaped field for this Model (i.e. id becomes `Post`.`id`).
@ -1350,7 +1399,7 @@ class Model extends Object
} }
/** /**
* Gets the ID of the last record this Model inserted * Returns the ID of the last record this Model inserted
* *
* @return mixed * @return mixed
*/ */
@ -1360,7 +1409,7 @@ class Model extends Object
} }
/** /**
* Gets the ID of the last record this Model inserted * Returns the ID of the last record this Model inserted
* *
* @return mixed * @return mixed
*/ */
@ -1370,7 +1419,7 @@ class Model extends Object
} }
/** /**
* Gets the number of rows returned from the last query * Returns the number of rows returned from the last query
* *
* @return int * @return int
*/ */
@ -1381,7 +1430,7 @@ class Model extends Object
} }
/** /**
* Gets the number of rows affected by the last query * Returns the number of rows affected by the last query
* *
* @return int * @return int
*/ */
@ -1409,7 +1458,6 @@ class Model extends Object
{ {
$this->tablePrefix = $this->db->config['prefix']; $this->tablePrefix = $this->db->config['prefix'];
} }
if(empty($this->db) || $this->db == null || !is_object($this->db)) if(empty($this->db) || $this->db == null || !is_object($this->db))
{ {
return $this->cakeError('missingConnection',array(array('className' => $this->name))); return $this->cakeError('missingConnection',array(array('className' => $this->name)));
@ -1428,7 +1476,7 @@ class Model extends Object
} }
/** /**
* After find callback * After find callback. Can be used to modify any results returned by find and findAll.
* *
* @param mixed $results The results of the find operation * @param mixed $results The results of the find operation
* @return mixed Result of the find operation * @return mixed Result of the find operation

View file

@ -6,7 +6,7 @@
* *
* DBO-backed object data model, for mapping database tables to Cake objects. * DBO-backed object data model, for mapping database tables to Cake objects.
* *
* PHP versions 4 and 5 * PHP versions 5
* *
* CakePHP : Rapid Development Framework <http://www.cakephp.org/> * CakePHP : Rapid Development Framework <http://www.cakephp.org/>
* Copyright (c) 2006, Cake Software Foundation, Inc. * Copyright (c) 2006, Cake Software Foundation, Inc.
@ -739,11 +739,10 @@ class Model extends Object
* *
* @param array $data Data to save. * @param array $data Data to save.
* @param boolean $validate If set, validation will be done before the save * @param boolean $validate If set, validation will be done before the save
* @param array $fields * @param array $fieldList List of fields to allow to be written
* @return boolean success * @return boolean success
* @todo Implement $fields param as a whitelist of allowable fields
*/ */
function save ($data = null, $validate = true, $fields = null) function save ($data = null, $validate = true, $fieldList = array())
{ {
if ($data) if ($data)
{ {
@ -756,122 +755,124 @@ class Model extends Object
$this->set($data); $this->set($data);
} }
} }
if($this->beforeSave())
$whitelist = !(empty($fieldList) || count($fieldList) == 0);
if ($validate && !$this->validates())
{ {
if ($validate && !$this->validates()) return false;
}
if(!$this->beforeSave())
{
return false;
}
$fields = $values = array();
$count = 0;
if(count($this->data) > 1)
{
$weHaveMulti = true;
$joined = false;
}
else
{
$weHaveMulti = false;
}
foreach ($this->data as $n => $v)
{
if(isset($weHaveMulti) && $count > 0 && count($this->hasAndBelongsToMany) > 0)
{ {
return false; $joined[] = $v;
} }
$fields = $values = array(); else
$count = 0; {
foreach ($v as $x => $y)
{
if ($this->hasField($x) && ($whitelist && in_array($x, $fieldList) || !$whitelist))
{
$fields[] = $x;
$values[] = $y;
if(count($this->data) > 1) if($x == $this->primaryKey && !is_numeric($y))
{ {
$weHaveMulti = true; $newID = $y;
$joined = false; }
} }
else }
{ $count++;
$weHaveMulti = false; }
} }
foreach ($this->data as $n => $v) if (empty($this->id) && $this->hasField('created') && !in_array('created', $fields) && ($whitelist && in_array('created', $fieldList) || !$whitelist))
{ {
if(isset($weHaveMulti) && $count > 0 && count($this->hasAndBelongsToMany) > 0) $fields[] = 'created';
{ $values[] = date('Y-m-d H:i:s');
$joined[] = $v; }
} if ($this->hasField('modified') && !in_array('modified', $fields) && ($whitelist && in_array('modified', $fieldList) || !$whitelist))
else {
{ $fields[] = 'modified';
foreach ($v as $x => $y) $values[] = date('Y-m-d H:i:s');
{ }
if ($this->hasField($x)) if ($this->hasField('updated') && !in_array('updated', $fields) && ($whitelist && in_array('updated', $fieldList) || !$whitelist))
{ {
$fields[] = $x; $fields[] = 'updated';
$values[] = $y; $values[] = date('Y-m-d H:i:s');
}
if($x == $this->primaryKey && !is_numeric($y)) if(!$this->exists())
{ {
$newID = $y; $this->id = false;
} }
}
}
$count++;
}
}
if (empty($this->id) && $this->hasField('created') && !in_array('created', $fields)) if(count($fields))
{ {
$fields[] = 'created'; if(!empty($this->id))
$values[] = date('Y-m-d H:i:s'); {
} if ($this->db->update($this, $fields, $values))
if ($this->hasField('modified') && !in_array('modified', $fields)) {
{ if(!empty($joined))
$fields[] = 'modified'; {
$values[] = date('Y-m-d H:i:s'); $this->__saveMulti($joined, $this->id);
} }
if ($this->hasField('updated') && !in_array('updated', $fields)) $this->afterSave();
{ $this->data = false;
$fields[] = 'updated'; return true;
$values[] = date('Y-m-d H:i:s'); }
} else
{
return $this->hasAny($this->escapeField($this->primaryKey).' = '.$this->db->value($this->id));
}
}
else
{
if($this->db->create($this, $fields, $values))
{
$this->__insertID = $this->db->lastInsertId($this->table, $this->primaryKey);
$this->id = $this->__insertID;
if(!$this->exists()) if(!$this->id > 0 && isset($newID))
{ {
$this->id = false; $this->__insertID = $newID;
} $this->id = $newID;
}
if(count($fields)) if(!empty($joined))
{ {
if(!empty($this->id)) $this->__saveMulti($joined, $this->id);
{ }
if ($this->db->update($this, $fields, $values))
{
if(!empty($joined))
{
$this->__saveMulti($joined, $this->id);
}
$this->afterSave();
$this->data = false;
return true;
}
else
{
return $this->hasAny($this->escapeField($this->primaryKey).' = '.$this->db->value($this->id));
}
}
else
{
if($this->db->create($this, $fields, $values))
{
$this->__insertID = $this->db->lastInsertId($this->table, $this->primaryKey);
$this->id = $this->__insertID;
if(!$this->id > 0 && isset($newID)) $this->afterSave();
{ $this->data = false;
$this->__insertID = $newID; return true;
$this->id = $newID; }
} else
{
if(!empty($joined)) return false;
{ }
$this->__saveMulti($joined, $this->id); }
}
$this->afterSave();
$this->data = false;
return true;
}
else
{
return false;
}
}
}
else
{
return false;
}
} }
else else
{ {
@ -948,7 +949,7 @@ class Model extends Object
* @param mixed $id Id of record to delete * @param mixed $id Id of record to delete
* @return boolean True on success * @return boolean True on success
*/ */
function del ($id = null) function del ($id = null, $cascade = false)
{ {
if ($id) if ($id)
{ {
@ -959,6 +960,11 @@ class Model extends Object
{ {
if ($this->id && $this->db->delete($this)) if ($this->id && $this->db->delete($this))
{ {
//$this->__deleteJoins($id);
if ($cascade)
{
//$this->__deleteMulti($id);
}
$this->afterDelete(); $this->afterDelete();
$this->id = false; $this->id = false;
return true; return true;
@ -968,6 +974,42 @@ class Model extends Object
return false; return false;
} }
/**
* Cascades model deletes to hasMany relationships.
*
* @param string $id
* @return null
* @access private
*/
function __deleteMulti ($id)
{
foreach ($this->hasMany as $assoc => $data)
{
$model =& $this->{$data['className']};
$field = $model->escapeField($data['foreignKey']);
$records = $model->findAll($field.'='.$id);
foreach($records as $record)
{
}
}
}
/**
* Cascades model deletes to HABTM join keys.
*
* @param string $id
* @return null
* @access private
*/
function __deleteJoins ($id)
{
foreach ($this->hasAndBelongsToMany as $assoc => $data)
{
}
}
/** /**
* Returns true if a record with set id exists. * Returns true if a record with set id exists.
* *

View file

@ -129,13 +129,21 @@ class CakeSession extends Object
$this->time = time(); $this->time = time();
$this->sessionTime = $this->time + (Security::inactiveMins() * CAKE_SESSION_TIMEOUT); $this->sessionTime = $this->time + (Security::inactiveMins() * CAKE_SESSION_TIMEOUT);
$this->security = CAKE_SECURITY; $this->security = CAKE_SECURITY;
session_write_close();
if (!isset($_SESSION)) if (!isset($_SESSION))
{ {
$this->_initSession(); $this->_initSession();
$this->_begin();
} }
session_cache_limiter("must-revalidate");
session_start();
if (!isset($_SESSION))
{
$this->_begin();
}
$this->_checkValid(); $this->_checkValid();
parent::__construct(); parent::__construct();
} }
@ -274,8 +282,6 @@ class CakeSession extends Object
*/ */
function _begin() function _begin()
{ {
session_cache_limiter("must-revalidate");
session_start();
header('P3P: CP="NOI ADM DEV PSAi COM NAV OUR OTRo STP IND DEM"'); header('P3P: CP="NOI ADM DEV PSAi COM NAV OUR OTRo STP IND DEM"');
} }
@ -286,10 +292,7 @@ class CakeSession extends Object
*/ */
function _close() function _close()
{ {
echo "<pre>"; return true;
echo "CakeSession::_close() Not Implemented Yet";
echo "</pre>";
die();
} }
/** /**
@ -297,13 +300,13 @@ class CakeSession extends Object
* *
* @access private * @access private
*/ */
function _destroy() function _destroy($key)
{ {
echo "<pre>"; $db =& ConnectionManager::getDataSource('default');
echo "CakeSession::_destroy() Not Implemented Yet"; $db->execute("DELETE FROM ".$db->name('cake_sessions')." WHERE ".$db->name('id')." = ".$db->value($key));
echo "</pre>"; return true;
die();
} }
/** /**
* Private helper method to destroy invalid sessions. * Private helper method to destroy invalid sessions.
* *
@ -331,12 +334,11 @@ class CakeSession extends Object
* *
* @access private * @access private
*/ */
function _gc() function _gc($expires)
{ {
echo "<pre>"; $db =& ConnectionManager::getDataSource('default');
echo "CakeSession::_gc() Not Implemented Yet"; $db->execute("DELETE FROM ".$db->name('cake_sessions')." WHERE ".$db->name('expires')." < " . $db->value(time()));
echo "</pre>"; return true;
die();
} }
/** /**
@ -346,11 +348,6 @@ class CakeSession extends Object
*/ */
function _initSession() function _initSession()
{ {
if (function_exists('session_write_close'))
{
session_write_close();
}
switch ($this->security) switch ($this->security)
{ {
case 'high': case 'high':
@ -409,7 +406,7 @@ class CakeSession extends Object
$config = CONFIGS.CAKE_SESSION_SAVE.'.php'; $config = CONFIGS.CAKE_SESSION_SAVE.'.php';
if(is_file($config)) if(is_file($config))
{ {
require_once($config); require($config);
} }
else else
{ {
@ -465,10 +462,7 @@ class CakeSession extends Object
*/ */
function _open() function _open()
{ {
echo "<pre>"; return true;
echo "CakeSession::_open() Not Implemented Yet";
echo "</pre>";
die();
} }
/** /**
@ -477,12 +471,20 @@ class CakeSession extends Object
* @access private * @access private
* *
*/ */
function _read() function _read($key)
{ {
echo "<pre>"; $db =& ConnectionManager::getDataSource('default');
echo "CakeSession::_read() Not Implemented Yet";
echo "</pre>"; $row = $db->query("SELECT ".$db->name('data')." FROM ".$db->name('cake_sessions')." WHERE ".$db->name('id')." = ".$db->value($key));
die();
if ($row && $row[0]['cake_sessions']['data'])
{
return $row[0]['cake_sessions']['data'];
}
else
{
return false;
}
} }
/** /**
@ -543,7 +545,7 @@ class CakeSession extends Object
{ {
$names = array($name); $names = array($name);
} }
$expression = $expression = "\$_SESSION"; $expression = "\$_SESSION";
foreach($names as $item) foreach($names as $item)
{ {
@ -578,12 +580,40 @@ class CakeSession extends Object
* *
* @access private * @access private
*/ */
function _write() function _write($key, $value)
{ {
echo "<pre>"; $db =& ConnectionManager::getDataSource('default');
echo "CakeSession::_write() Not Implemented Yet";
echo "</pre>"; switch (CAKE_SECURITY) {
die(); case 'high':
$factor = 10;
break;
case 'medium':
$factor = 100;
break;
case 'low':
$factor = 300;
break;
default:
$factor = 10;
break;
}
$expires = time() + CAKE_SESSION_TIMEOUT * $factor;
$row = $db->query("SELECT COUNT(*) AS count FROM ".$db->name('cake_sessions')." WHERE ".$db->name('id')." = ".$db->value($key));
if($row[0][0]['count'] > 0)
{
$db->execute("UPDATE ".$db->name('cake_sessions')." SET ".$db->name('data')." = ".$db->value($value).", ".$db->name('expires')." = ".$db->name($expires)." WHERE ".$db->name('id')." = ".$db->value($key));
}
else
{
$db->execute("INSERT INTO ".$db->name('cake_sessions')." (".$db->name('data').",".$db->name('expires').",".$db->name('id').") VALUES (".$db->value($value).", ".$db->value($expires).", ".$db->value($key).")");
}
return true;
} }
} }
?> ?>

View file

@ -189,7 +189,7 @@ class AjaxHelper extends Helper
if (isset($options['id'])) if (isset($options['id']))
{ {
$htmlOptions['onclick'] = ' return false;'; $htmlOptions['onclick'] = ' return false;';
return $this->Html->link($title, $href, $htmlOptions) . $this->Javascript->event("$('{$options['id']}')", "click", "function() {" . $this->remoteFunction($options) . "; return true; }"); return $this->Html->link($title, $href, $htmlOptions) . $this->Javascript->event("$('{$options['id']}')", "click", $this->remoteFunction($options));
} }
else else
{ {
@ -208,7 +208,7 @@ class AjaxHelper extends Helper
} }
if (isset($html_options['id'])) if (isset($html_options['id']))
{ {
return $this->Html->link($title, $href, $html_options) . $this->Javascript->event("$('{$html_options['id']}')", "click", "function() {" . $this->remoteFunction($options) . "; return true; }"); return $this->Html->link($title, $href, $html_options) . $this->Javascript->event("$('{$html_options['id']}')", "click", $this->remoteFunction($options));
} }
else else
{ {
@ -322,7 +322,7 @@ class AjaxHelper extends Helper
} }
$options['url'] = $action; $options['url'] = $action;
return $this->Html->formTag($htmlOptions['action'], $type, $htmlOptions) . $this->Javascript->event("$('".$htmlOptions['id']."')", "submit", "function(){" . $this->remoteFunction($options) . ";}"); return $this->Html->formTag($htmlOptions['action'], $type, $htmlOptions) . $this->Javascript->event("$('".$htmlOptions['id']."')", "submit", $this->remoteFunction($options));
} }
/** /**
@ -331,25 +331,32 @@ class AjaxHelper extends Helper
* Returns a button input tag that will submit form using XMLHttpRequest in the background instead of regular * Returns a button input tag that will submit form using XMLHttpRequest in the background instead of regular
* reloading POST arrangement. <i>options</i> argument is the same as in <i>form_remote_tag</i> * reloading POST arrangement. <i>options</i> argument is the same as in <i>form_remote_tag</i>
* *
* @param string $name Input button name * @param string $title Input button title
* @param string $value Input button value
* @param array $options Callback options * @param array $options Callback options
* @return string Ajaxed input button * @return string Ajaxed input button
*/ */
function submit ($name, $value, $options = array()) function submit ($title = 'Submit', $options = array())
{ {
$htmlOptions = $this->__getHtmlOptions($options); $htmlOptions = $this->__getHtmlOptions($options);
$htmlOptions['type'] = 'button'; if (!isset($htmlOptions['type']))
$htmlOptions['name'] = $name; {
$htmlOptions['value'] = $value; $htmlOptions['type'] = 'submit';
}
$htmlOptions['value'] = $title;
if (!isset($options['with'])) if (!isset($options['with']))
{ {
$options['with'] = 'Form.serialize(this.form)'; $options['with'] = 'Form.serialize(Event.element(event).form)';
} }
$htmlOptions['onclick'] = $this->remoteFunction($options) . "; return false;"; if(!isset($htmlOptions['id']))
return $this->Html->tag('input', $htmlOptions); {
$htmlOptions['id'] = 'submit'.intval(rand());
}
$htmlOptions['onclick'] = "return false;";
return $this->Html->submit($title, $htmlOptions) .
$this->Javascript->event('$("'.$htmlOptions['id'].'")', 'click', $this->remoteFunction($options));
} }
/** /**
@ -558,7 +565,7 @@ class AjaxHelper extends Helper
} }
if (isset($options['callback'])) if (isset($options['callback']))
{ {
$options['callback'] = 'function(form) {'.$options['callback'].'}'; $options['callback'] = 'function(form, value) {'.$options['callback'].'}';
} }
$options = $this->_optionsToString($options, array('okText', 'cancelText', 'savingText', 'formId', 'externalControl', 'highlightcolor', 'highlightendcolor', 'savingClassName', 'formClassName', 'loadTextURL', 'loadingText')); $options = $this->_optionsToString($options, array('okText', 'cancelText', 'savingText', 'formId', 'externalControl', 'highlightcolor', 'highlightendcolor', 'savingClassName', 'formClassName', 'loadTextURL', 'loadingText'));
@ -597,7 +604,7 @@ class AjaxHelper extends Helper
} }
/** /**
* Private helper function for Javascript. * Private helper function for Javascript.
* *
*/ */
function __optionsForAjax ($options = array()) function __optionsForAjax ($options = array())

View file

@ -255,7 +255,7 @@ class HtmlHelper extends Helper
{ {
$this->setFormTag($fieldName); $this->setFormTag($fieldName);
if (empty($htmlAttributes['value'])) if (!isset($htmlAttributes['value']))
{ {
$htmlAttributes['value'] = $this->tagValue($fieldName); $htmlAttributes['value'] = $this->tagValue($fieldName);
} }
@ -502,7 +502,7 @@ class HtmlHelper extends Helper
$opt_value==$value? $options_here['checked'] = 'checked': null; $opt_value==$value? $options_here['checked'] = 'checked': null;
$parsed_options = $this->parseHtmlOptions(array_merge($htmlAttributes, $options_here), null, '', ' '); $parsed_options = $this->parseHtmlOptions(array_merge($htmlAttributes, $options_here), null, '', ' ');
$individual_tag_name = "{$this->field}_{$opt_value}"; $individual_tag_name = "{$this->field}_{$opt_value}";
$out[] = sprintf($this->tags['radio'], $individual_tag_name, $this->model, $this->field, $individual_tag_name, $parsed_options, $opt_title); $out[] = sprintf($this->tags['radio'], $this->model, $this->field, $individual_tag_name, $parsed_options, $opt_title);
} }
$out = join($inbetween, $out); $out = join($inbetween, $out);
@ -1403,7 +1403,7 @@ class HtmlHelper extends Helper
$mins[$minCount] = sprintf('%02d', $minCount); $mins[$minCount] = sprintf('%02d', $minCount);
} }
$option = $this->selectTag($tagName.'_min', $mins, $minValue, $select_attr, $option = $this->selectTag($tagName.'_min', $mins, $minValue, $select_attr,
$optionAttr); $optionAttr);
return $option; return $option;
} }

View file

@ -136,7 +136,7 @@ class JavascriptHelper extends Helper
$useCapture = "false"; $useCapture = "false";
} }
$b = "Event.observe($object, '$event', $observer, $useCapture);"; $b = "Event.observe($object, '$event', function(event){ $observer }, $useCapture);";
if($this->_cacheEvents === true) if($this->_cacheEvents === true)
{ {
$this->_cachedEvents[] = $b; $this->_cachedEvents[] = $b;

View file

@ -32,11 +32,14 @@
* Included libraries. * Included libraries.
* *
*/ */
if(!class_exists('Flay') || !class_exists('Html')) if(!class_exists('Flay'))
{ {
uses('flay', DS.'view'.DS.'helpers'.DS.'html'); uses('flay');
}
if(!class_exists('Html'))
{
uses(DS.'view'.DS.'helpers'.DS.'html');
} }
/** /**
* Text helper library. * Text helper library.

View file

@ -35,10 +35,8 @@
<p style="background:#DBA941;padding:4px;font-size: 16px;">Cake<?php echo $connected->connected ? ' is able to' : ' is not able to';?> connect to the database.</p> <p style="background:#DBA941;padding:4px;font-size: 16px;">Cake<?php echo $connected->connected ? ' is able to' : ' is not able to';?> connect to the database.</p>
<br /> <br />
<?php endif; ?> <?php endif; ?>
<h1>Take a bite out of Cake<em>PHP</em> Beta</h1> <h1>Cake<em>PHP</em></h1>
<p>
More content will be added...
</p>
<p>If you plan to upgrade from an older version, you may also want to read the <a href="http://cakephp.org/pages/changelog">changelog</a></p> <p>If you plan to upgrade from an older version, you may also want to read the <a href="http://cakephp.org/pages/changelog">changelog</a></p>
<h2>Editing <em>this Page</em></h2> <h2>Editing <em>this Page</em></h2>

View file

@ -687,7 +687,7 @@ class View extends Object
} }
if (is_file($helperFn)) if (is_file($helperFn))
{ {
require_once $helperFn; require $helperFn;
} }
else else
{ {

View file

@ -51,10 +51,10 @@ define ('APP_DIR', 'app');
* *
*/ */
define ('DEBUG', 1); define ('DEBUG', 1);
require_once (ROOT.'cake'.DS.'basics.php'); require (ROOT.'cake'.DS.'basics.php');
require_once (ROOT.'cake'.DS.'config'.DS.'paths.php'); require (ROOT.'cake'.DS.'config'.DS.'paths.php');
require_once (CONFIGS.'core.php'); require (CONFIGS.'core.php');
require_once (CONFIGS.'database.php'); require (CONFIGS.'database.php');
uses ('neat_array'); uses ('neat_array');
uses ('object'); uses ('object');
uses ('session'); uses ('session');
@ -62,7 +62,7 @@ uses ('security');
uses ('model'.DS.'connection_manager'); uses ('model'.DS.'connection_manager');
uses ('model'.DS.'datasources'.DS.'dbo_source'); uses ('model'.DS.'datasources'.DS.'dbo_source');
uses ('model'.DS.'model'); uses ('model'.DS.'model');
require_once(CAKE.'app_model.php'); require(CAKE.'app_model.php');
uses ('controller'.DS.'components'.DS.'acl'); uses ('controller'.DS.'components'.DS.'acl');
uses ('controller'.DS.'components'.DS.'dbacl'.DS.'models'.DS.'aclnode'); uses ('controller'.DS.'components'.DS.'dbacl'.DS.'models'.DS.'aclnode');
uses ('controller'.DS.'components'.DS.'dbacl'.DS.'models'.DS.'aco'); uses ('controller'.DS.'components'.DS.'dbacl'.DS.'models'.DS.'aco');

View file

@ -48,10 +48,10 @@ if (!defined('CAKE_CORE_INCLUDE_PATH'))
ini_set('include_path',ini_get('include_path').PATH_SEPARATOR.CAKE_CORE_INCLUDE_PATH.PATH_SEPARATOR.ROOT.DS.APP_DIR.DS); ini_set('include_path',ini_get('include_path').PATH_SEPARATOR.CAKE_CORE_INCLUDE_PATH.PATH_SEPARATOR.ROOT.DS.APP_DIR.DS);
require_once 'cake'.DS.'basics.php'; require 'cake'.DS.'basics.php';
require_once 'config'.DS.'core.php'; require 'config'.DS.'core.php';
require_once 'cake'.DS.'config'.DS.'paths.php'; require 'cake'.DS.'config'.DS.'paths.php';
$bootstrap = true;
$uri = setUri(); $uri = setUri();
@ -62,7 +62,7 @@ $uri = setUri();
if ($uri === '/' || $uri === '/index.php') if ($uri === '/' || $uri === '/index.php')
{ {
$_GET['url'] = '/'; $_GET['url'] = '/';
require_once ROOT.APP_DIR.DS.WEBROOT_DIR.DS.'index.php'; require ROOT.APP_DIR.DS.WEBROOT_DIR.DS.'index.php';
} }
else else
{ {
@ -79,6 +79,6 @@ else
$_GET['url'] = $path; $_GET['url'] = $path;
require_once ROOT.APP_DIR.DS.WEBROOT_DIR.DS.'index.php'; require ROOT.APP_DIR.DS.WEBROOT_DIR.DS.'index.php';
} }
?> ?>