Renaming branched version directory

git-svn-id: https://svn.cakephp.org/repo/branches/1.1.x.x@3085 3807eeeb-6ff5-0310-8944-8be069107fe0
This commit is contained in:
phpnut 2006-06-14 18:02:37 +00:00
parent e5c074a0dc
commit 9d19dee879
45 changed files with 2935 additions and 2406 deletions

View file

@ -6,4 +6,4 @@
// +---------------------------------------------------------------------------------------------------+ // // +---------------------------------------------------------------------------------------------------+ //
/////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////
1.1.2.2955 1.1.4.3083

View file

@ -17,11 +17,11 @@ background:#003d4c;
a{ a{
color:#003d4c; color:#003d4c;
text-decoration:none; text-decoration:underline;
} }
a:hover{ a:hover{
color:#003d4c; color:#003d4c;
text-decoration:underline; text-decoration:none;
} }
a img{ a img{
@ -77,6 +77,7 @@ padding:0 2em;
#container{ #container{
text-align:left; text-align:left;
margin-left:0px; margin-left:0px;
min-width: 960px;
} }
#header{ #header{
@ -164,24 +165,24 @@ background:url(images/nav_item_bg.gif) no-repeat bottom left;
} }
#footer { #footer {
color: #fff; color: #fff;
background-color: #003d4c; background-color: #003d4c;
padding: 4px 10px; padding: 4px 10px;
text-align: right; text-align: right;
} }
#footer a{ #footer a{
color: #fff; color: #fff;
} }
.left { .left {
float:left; float:left;
} }
.right { .right {
float:right; float:right;
} }
.clear { .clear {
clear:both; clear:both;
height: 0px; height: 0px;
line-height: 0px; line-height: 0px;
} }
@ -189,9 +190,8 @@ background:url(images/nav_item_bg.gif) no-repeat bottom left;
table { table {
width: 100%; width: 100%;
border: 0px; border: 1px solid #003d4c;
color:#333; color:#333;
border: 1px solid #ccc;
background-color: #fff; background-color: #fff;
clear:both; clear:both;
padding: 0; padding: 0;
@ -205,7 +205,7 @@ th {
border-right: 1px solid #003d4c; border-right: 1px solid #003d4c;
border-bottom: 1px solid #003d4c; border-bottom: 1px solid #003d4c;
text-align: center; text-align: center;
padding:2px; padding:1px;
} }
table tr td { table tr td {
border-right: 1px solid #ccc; border-right: 1px solid #ccc;
@ -240,29 +240,35 @@ dd {
vertical-align:top; vertical-align:top;
} }
/* scaffold buttons */ /* notices and errors */
p.error, error_message {
color: #e32000;
font-size: 18px;
background-color: #fff;
margin: 8px 4px;
}
p.error em {
font-size: 18px;
color: #003d4c;
}
.notice { .notice {
color: #DB8101; color: #656565;
background-color: #ddd; font-size: 14px;
display: block; background-color: #f4f4f4;
padding: 1em; padding: 4px;
display:block;
} }
.tip { .tip {
color: #DB8101; color: #e32000;
background-color: #ddd; background-color: #ddd;
display: block;
padding: 1em;
} }
/* action links */ /* action links */
ul.actions { ul.actions {
float:left; float:left;
margin-left: 10px; margin-left: 10px;
width: 200px; width: 200px;
}
li {
list-style-image: url("images/arrow.gif");
} }

View file

@ -129,12 +129,6 @@ form div label.labelCheckbox, form div label.labelRadio {
form div fieldset label.labelCheckbox, form div fieldset label.labelRadio { form div fieldset label.labelCheckbox, form div fieldset label.labelRadio {
margin: 0px 0px 5px 0px; margin: 0px 0px 5px 0px;
} }
p.error {
color: #DB8101;
background-color: #DBA941;
font-size: 14px;
padding: 1em;
}
form div input, form div select, form div textarea { form div input, form div select, form div textarea {
padding: 1px 3px; padding: 1px 3px;

View file

@ -129,6 +129,8 @@
} else { } else {
return false; return false;
} }
} else {
return true;
} }
} }
/** /**
@ -165,14 +167,14 @@
require(CAKE . 'app_controller.php'); require(CAKE . 'app_controller.php');
} }
} }
$loadedControllers=array(); $loadedControllers = array();
foreach($paths->controllerPaths as $path) { foreach($paths->controllerPaths as $path) {
foreach(listClasses($path)as $controller) { foreach(listClasses($path) as $controller) {
if (file_exists($path . $controller . '.php')) { if (file_exists($path . $controller . '.php')) {
if (!key_exists($controller, $loadedControllers)) { if (!key_exists($controller, $loadedControllers)) {
require($path . $controller . '.php'); require($path . $controller . '.php');
$loadedControllers[$controller]=$controller; $loadedControllers[$controller] = $controller;
} }
} }
} }
@ -252,13 +254,126 @@
if (file_exists($file)) { if (file_exists($file)) {
require($file); require($file);
return true; return true;
} elseif (file_exists(APP . 'plugins' . DS . $plugin . DS . 'controllers' . DS . $plugin . '_controller.php')) } elseif (file_exists(APP . 'plugins' . DS . $plugin . DS . 'controllers' . DS . $plugin . '_controller.php')) {
{
require(APP . 'plugins' . DS . $plugin . DS . 'controllers' . DS . $plugin . '_controller.php'); require(APP . 'plugins' . DS . $plugin . DS . 'controllers' . DS . $plugin . '_controller.php');
return true; return true;
} else { } else {
return false; return false;
} }
} else {
return true;
}
}
/**
* Loads a helper
*
* @param string $name Name of helper
* @return boolean Success
*/
function loadHelper($name) {
$paths = Configure::getInstance();
if ($name === null) {
return true;
}
if (!class_exists($name . 'Helper')) {
$name=Inflector::underscore($name);
foreach($paths->helperPaths as $path) {
if (file_exists($path . $name . '.php')) {
require($path . $name . '.php');
return true;
}
}
if ($helper_fn = fileExistsInPath(LIBS . 'view' . DS . 'helpers' . DS . $name . '.php')) {
if (file_exists($helper_fn)) {
require($helper_fn);
return true;
} else {
return false;
}
}
} else {
return true;
}
}
/**
* Loads a plugin's helper
*
* @param string $plugin Name of plugin
* @param string $helper Name of helper to load
* @return boolean Success
*/
function loadPluginHelper($plugin, $helper) {
if (!class_exists($helper . 'Helper')) {
$helper = Inflector::underscore($helper);
$file = APP . 'plugins' . DS . $plugin . DS . 'views' . DS . 'helpers' . DS . $helper . '.php';
if (file_exists($file)) {
require($file);
return true;
} else {
return false;
}
} else {
return true;
}
}
/**
* Loads a component
*
* @param string $name Name of component
* @return boolean Success
*/
function loadComponent($name) {
$paths = Configure::getInstance();
if ($name === null) {
return true;
}
if (!class_exists($name . 'Component')) {
$name=Inflector::underscore($name);
foreach($paths->componentPaths as $path) {
if (file_exists($path . $name . '.php')) {
require($path . $name . '.php');
return true;
}
}
if ($component_fn = fileExistsInPath(LIBS . 'controller' . DS . 'components' . DS . $name . '.php')) {
if (file_exists($component_fn)) {
require($component_fn);
return true;
} else {
return false;
}
}
} else {
return true;
}
}
/**
* Loads a plugin's component
*
* @param string $plugin Name of plugin
* @param string $helper Name of component to load
* @return boolean Success
*/
function loadPluginComponent($plugin, $component) {
if (!class_exists($component . 'Component')) {
$component = Inflector::underscore($component);
$file = APP . 'plugins' . DS . $plugin . DS . 'controllers' . DS . 'components' . DS . $component . '.php';
if (file_exists($file)) {
require($file);
return true;
} else {
return false;
}
} else {
return true;
} }
} }
/** /**
@ -344,7 +459,7 @@
*/ */
function debug($var = false, $showHtml = false) { function debug($var = false, $showHtml = false) {
if (DEBUG) { if (DEBUG) {
print "\n<pre>\n"; print "\n<pre class=\"cake_debug\">\n";
ob_start(); ob_start();
print_r($var); print_r($var);
$var = ob_get_clean(); $var = ob_get_clean();
@ -362,7 +477,7 @@
*/ */
if (!function_exists('getMicrotime')) { if (!function_exists('getMicrotime')) {
function getMicrotime() { function getMicrotime() {
list($usec, $sec)=explode(" ", microtime()); list($usec, $sec) = explode(" ", microtime());
return ((float)$usec + (float)$sec); return ((float)$usec + (float)$sec);
} }
} }
@ -886,7 +1001,7 @@
if (!is_dir($path)) { if (!is_dir($path)) {
return chmod($path, $mode); return chmod($path, $mode);
} }
$di = opendir($path); $dir = opendir($path);
while($file = readdir($dir)) { while($file = readdir($dir)) {
if ($file != '.' && $file != '..') { if ($file != '.' && $file != '..') {
@ -911,4 +1026,24 @@
return false; return false;
} }
} }
/**
* removed the plugin name from the base url
*
* @param string $base
* @param string $plugin
* @return base url with plugin name removed if present
*/
function strip_plugin($base, $plugin){
if ($plugin != null) {
$base = preg_replace('/' . $plugin . '/', '', $base);
$base = str_replace('//', '', $base);
$pos1 = strrpos($base, '/');
$char = strlen($base) - 1;
if ($pos1 == $char) {
$base = substr($base, 0, $char);
}
}
return $base;
}
?> ?>

View file

@ -105,6 +105,9 @@ blockend = "</div>"
; Tag template for a CSS link tag. ; Tag template for a CSS link tag.
css = "<link rel="%s" type="text/css" href="%s" %s/>" css = "<link rel="%s" type="text/css" href="%s" %s/>"
; Tag template for a CSS tag block.
style = "<style type="text/css"%s>%s</style>"
; Tag template for a charset meta-tag. ; Tag template for a charset meta-tag.
charset = "<meta http-equiv="Content-Type" content="text/html; charset=%s" />" charset = "<meta http-equiv="Content-Type" content="text/html; charset=%s" />"

View file

@ -89,10 +89,7 @@ class Dispatcher extends Object {
if(!class_exists($ctrlClass)) { if(!class_exists($ctrlClass)) {
if (!loadController($ctrlName)) { if (!loadController($ctrlName)) {
$plugin = $ctrlName;
$pluginName = Inflector::camelize($params['action']); $pluginName = Inflector::camelize($params['action']);
$pluginClass = $pluginName.'Controller';
if (!loadPluginController(Inflector::underscore($ctrlName), $pluginName)) { if (!loadPluginController(Inflector::underscore($ctrlName), $pluginName)) {
if(preg_match('/([\\.]+)/', $ctrlName)) { if(preg_match('/([\\.]+)/', $ctrlName)) {
return $this->cakeError('error404', array( return $this->cakeError('error404', array(
@ -104,28 +101,33 @@ class Dispatcher extends Object {
$missingController = true; $missingController = true;
} }
} else { } else {
$ctrlClass = $pluginClass; $params['plugin'] = Inflector::underscore($ctrlName);
$oldAction = $params['action'];
$params = $this->_restructureParams($params);
$plugin = Inflector::underscore($ctrlName);
$this->plugin = $plugin;
loadPluginModels($plugin);
$this->base = $this->base.'/'.Inflector::underscore($ctrlName);
if(empty($params['controller']) || !class_exists($pluginClass)) {
$params['controller'] = Inflector::underscore($ctrlName);
$ctrlClass = $ctrlName.'Controller';
if (!is_null($params['action'])) {
array_unshift($params['pass'], $params['action']);
}
$params['action'] = $oldAction;
}
} }
} }
} }
} }
if(isset($params['plugin'])){
$plugin = $params['plugin'];
$pluginName = Inflector::camelize($params['action']);
$pluginClass = $pluginName.'Controller';
$ctrlClass = $pluginClass;
$oldAction = $params['action'];
$params = $this->_restructureParams($params);
$this->plugin = $plugin;
loadPluginModels($plugin);
$this->base = $this->base.'/'.Inflector::underscore($ctrlName);
if(empty($params['controller']) || !class_exists($pluginClass)) {
$params['controller'] = Inflector::underscore($ctrlName);
$ctrlClass = $ctrlName.'Controller';
if (!is_null($params['action'])) {
array_unshift($params['pass'], $params['action']);
}
$params['action'] = $oldAction;
}
}
if(defined('CAKE_ADMIN')) { if(defined('CAKE_ADMIN')) {
if(isset($params[CAKE_ADMIN])) { if(isset($params[CAKE_ADMIN])) {
$this->admin = '/'.CAKE_ADMIN ; $this->admin = '/'.CAKE_ADMIN ;

View file

@ -34,7 +34,7 @@
* @package cake * @package cake
* @subpackage cake.cake.libs * @subpackage cake.cake.libs
*/ */
class Configure extends Object{ class Configure extends Object {
/** /**
* Hold array with paths to view files * Hold array with paths to view files
* *
@ -56,6 +56,20 @@ class Configure extends Object{
* @access public * @access public
*/ */
var $modelPaths = array(); var $modelPaths = array();
/**
* Enter description here...
*
* @var array
* @access public
*/
var $helperPaths = array();
/**
* Enter description here...
*
* @var array
* @access public
*/
var $componentPaths = array();
/** /**
* Return a singleton instance of Configure. * Return a singleton instance of Configure.
* *
@ -81,7 +95,7 @@ class Configure extends Object{
$_this->modelPaths[] = MODELS; $_this->modelPaths[] = MODELS;
if (isset($modelPaths)) { if (isset($modelPaths)) {
foreach($modelPaths as $value) { foreach($modelPaths as $value) {
$this->modelPaths[] = $value; $_this->modelPaths[] = $value;
} }
} }
} }
@ -97,7 +111,7 @@ class Configure extends Object{
$_this->viewPaths[] = VIEWS . 'errors' . DS; $_this->viewPaths[] = VIEWS . 'errors' . DS;
if (isset($viewPaths)) { if (isset($viewPaths)) {
foreach($viewPaths as $value) { foreach($viewPaths as $value) {
$this->viewPaths[] = $value; $_this->viewPaths[] = $value;
} }
} }
} }
@ -112,7 +126,37 @@ class Configure extends Object{
$_this->controllerPaths[] = CONTROLLERS; $_this->controllerPaths[] = CONTROLLERS;
if (isset($controllerPaths)) { if (isset($controllerPaths)) {
foreach($controllerPaths as $value) { foreach($controllerPaths as $value) {
$this->controllerPaths[] = $value; $_this->controllerPaths[] = $value;
}
}
}
/**
* Sets the var helperPaths
*
* @param array $helperPaths
* @access private
*/
function __buildHelperPaths($helperPaths) {
$_this =& Configure::getInstance();
$_this->helperPaths[] = HELPERS;
if (isset($helperPaths)) {
foreach($helperPaths as $value) {
$_this->helperPaths[] = $value;
}
}
}
/**
* Sets the var componentPaths
*
* @param array $componentPaths
* @access private
*/
function __buildComponentPaths($componentPaths) {
$_this =& Configure::getInstance();
$_this->componentPaths[] = COMPONENTS;
if (isset($componentPaths)) {
foreach($componentPaths as $value) {
$_this->componentPaths[] = $value;
} }
} }
} }
@ -124,14 +168,19 @@ class Configure extends Object{
* @access private * @access private
*/ */
function __loadBootstrap() { function __loadBootstrap() {
$_this =&Configure::getInstance(); $_this =& Configure::getInstance();
$modelPaths =null; $modelPaths = null;
$viewPaths =null; $viewPaths = null;
$controllerPaths=null; $controllerPaths = null;
$helperPaths = null;
$componentPaths = null;
require APP_PATH . 'config' . DS . 'bootstrap.php'; require APP_PATH . 'config' . DS . 'bootstrap.php';
$_this->__buildModelPaths($modelPaths); $_this->__buildModelPaths($modelPaths);
$_this->__buildViewPaths($viewPaths); $_this->__buildViewPaths($viewPaths);
$_this->__buildControllerPaths($controllerPaths); $_this->__buildControllerPaths($controllerPaths);
$_this->__buildHelperPaths($helperPaths);
$_this->__buildComponentPaths($componentPaths);
} }
} }
?> ?>

View file

@ -1,6 +1,5 @@
<?php <?php
/* SVN FILE: $Id$ */ /* SVN FILE: $Id$ */
/** /**
* *
* *
@ -25,53 +24,47 @@
* @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
*/ */
/** /**
* *
* *
* @package cake * @package cake
* @subpackage cake.cake.libs.controller * @subpackage cake.cake.libs.controller
*/ */
class Component extends Object{ class Component extends Object {
/** /**
* Enter description here... * Enter description here...
* *
* @var unknown_type * @var unknown_type
*/ */
var $components = array(); var $components = array();
/** /**
* Enter description here... * Enter description here...
* *
* @var unknown_type * @var unknown_type
*/ */
var $controller = null; var $controller = null;
/** /**
* Constructor * Constructor
* *
* @return Component * @return Component
*/ */
function Component(&$controller) { function __construct(&$controller) {
$this->controller=&$controller; $this->controller =& $controller;
if ($this->controller->components !== false) {
$loaded = array();
$loaded = $this->_loadComponents($loaded, $this->controller->components);
if ($this->controller->components !== false) { foreach(array_keys($loaded)as $component) {
$loaded=array(); $tempComponent =& $loaded[$component];
$loaded=$this->_loadComponents($loaded, $this->controller->components); if (isset($tempComponent->components) && is_array($tempComponent->components)) {
foreach($tempComponent->components as $subComponent) {
foreach(array_keys($loaded)as $component) { $this->controller->{$component}->{$subComponent} =& $loaded[$subComponent];
$tempComponent = &$loaded[$component]; }
if (isset($tempComponent->components) && is_array($tempComponent->components)) {
foreach($tempComponent->components as $subComponent) {
$this->controller->{$component}->{$subComponent}= &$loaded[$subComponent];
}
}
} }
} }
} }
}
/** /**
* Enter description here... * Enter description here...
* *
@ -79,61 +72,48 @@ class Component extends Object{
* @param unknown_type $components * @param unknown_type $components
* @return unknown * @return unknown
*/ */
function &_loadComponents(&$loaded, $components) { function &_loadComponents(&$loaded, $components) {
foreach($components as $component) { foreach($components as $component) {
if (in_array($component, array_keys($loaded)) !== true) { $componentCn = $component . 'Component';
$componentFn=Inflector::underscore($component) . '.php';
if (file_exists( if (in_array($component, array_keys($loaded)) !== true) {
APP . 'plugins' . DS . $this->controller->plugin . DS . 'controllers' . DS . 'components' . DS . $componentFn)) { if (!class_exists($componentCn)) {
$componentFn = APP . 'plugins' . DS . $this->controller->plugin . DS . 'controllers' . DS if (is_null($this->controller->plugin) || !loadPluginComponent($this->controller->plugin, $component)) {
. 'components' . DS . $componentFn; if (!loadComponent($component)) {
} else if(file_exists(COMPONENTS . $componentFn)) { return $this->cakeError('missingComponentFile', array(array(
$componentFn = COMPONENTS . $componentFn; 'className' => $this->controller->name,
} else if($componentFn 'component' => $component,
= fileExistsInPath(LIBS . 'controller' . DS . 'components' . DS . $componentFn)) { 'file' => Inflector::underscore($componentCn) . '.php',
} 'base' => $this->controller->base
)));
}
}
$componentCn=$component . 'Component'; if (!class_exists($componentCn)) {
$componentFn = Inflector::underscore($component) . '.php';
if (is_file($componentFn)) { return $this->cakeError('missingComponentClass', array(array(
if (!class_exists($componentCn)) { 'className' => $this->controller->name,
require_once $componentFn; 'component' => $component,
} 'file' => $componentFn,
'base' => $this->controller->base
if (class_exists($componentCn) === true) { )));
if ($componentCn == 'SessionComponent') { }
$param = $this->controller->base . '/';
} else {
$param = null;
}
$this->controller->{$component}=&new $componentCn($param);
$loaded[$component] =&$this->controller->{$component};
if (isset($this->controller->{$component}->components)
&& is_array($this->controller->{$component}->components)) {
$loaded = &$this->_loadComponents($loaded,
$this->controller->{$component}->components);
}
} else {
return $this->cakeError('missingComponentClass',
array(array('className' => $this->controller->name,
'component' => $component,
'file' => $componentFn,
'base' => $this->controller->base)));
}
} else {
return $this->cakeError('missingComponentFile',
array(array('className' => $this->controller->name,
'component' => $component,
'file' => $componentFn,
'base' => $this->controller->base)));
}
} }
}
return $loaded; if ($componentCn == 'SessionComponent') {
} $param = $this->controller->base . '/';
} else {
$param = null;
}
$this->controller->{$component} =& new $componentCn($param);
$loaded[$component] =& $this->controller->{$component};
if (isset($this->controller->{$component}->components) && is_array($this->controller->{$component}->components)) {
$loaded =& $this->_loadComponents($loaded, $this->controller->{$component}->components);
}
}
}
return $loaded;
}
} }
?> ?>

View file

@ -36,110 +36,102 @@
* @package cake * @package cake
* @subpackage cake.cake.libs.controller.components * @subpackage cake.cake.libs.controller.components
*/ */
class AclComponent extends Object{ class AclComponent extends Object {
var $_instance = null;
var $controller = true; var $_instance = null;
var $controller = true;
/** /**
* Constructor. Will return an instance of the correct ACL class. * Constructor. Will return an instance of the correct ACL class.
* *
*/ */
function __construct() { function __construct() {
$this->getACL(); $this->getACL();
} }
/** /**
* Static function used to gain an instance of the correct ACL class. * Static function used to gain an instance of the correct ACL class.
* *
* @return MyACL * @return MyACL
*/ */
function &getACL() { function &getACL() {
if ($this->_instance == null) { if ($this->_instance == null) {
uses('controller' . DS . 'components' . DS . ACL_FILENAME); uses('controller' . DS . 'components' . DS . ACL_FILENAME);
$classname =ACL_CLASSNAME; $classname = ACL_CLASSNAME;
$this->_instance=new $classname; $this->_instance = new $classname;
} }
return $this->_instance;
}
return $this->_instance;
}
/** /**
* Empty class defintion, to be overridden in subclasses. * Empty class defintion, to be overridden in subclasses.
* *
*/ */
function _initACL() { function _initACL() {
} }
/** /**
* Pass-thru function for ACL check instance. * Pass-thru function for ACL check instance.
* *
* @return boolean * @return boolean
*/ */
function check($aro, $aco, $action = "*") { function check($aro, $aco, $action = "*") {
return $this->_instance->check($aro, $aco, $action); return $this->_instance->check($aro, $aco, $action);
} }
/** /**
* Pass-thru function for ACL allow instance. * Pass-thru function for ACL allow instance.
* *
* @return boolean * @return boolean
*/ */
function allow($aro, $aco, $action = "*") { function allow($aro, $aco, $action = "*") {
return $this->_instance->allow($aro, $aco, $action); return $this->_instance->allow($aro, $aco, $action);
} }
/** /**
* Pass-thru function for ACL deny instance. * Pass-thru function for ACL deny instance.
* *
* @return boolean * @return boolean
*/ */
function deny($aro, $aco, $action = "*") { function deny($aro, $aco, $action = "*") {
return $this->_instance->deny($aro, $aco, $action); return $this->_instance->deny($aro, $aco, $action);
} }
/** /**
* Pass-thru function for ACL inherit instance. * Pass-thru function for ACL inherit instance.
* *
* @return boolean * @return boolean
*/ */
function inherit($aro, $aco, $action = "*") { function inherit($aro, $aco, $action = "*") {
return $this->_instance->inherit($aro, $aco, $action); return $this->_instance->inherit($aro, $aco, $action);
} }
/** /**
* Pass-thru function for ACL grant instance. * Pass-thru function for ACL grant instance.
* *
* @return boolean * @return boolean
*/ */
function grant($aro, $aco, $action = "*") { function grant($aro, $aco, $action = "*") {
return $this->_instance->grant($aro, $aco, $action); return $this->_instance->grant($aro, $aco, $action);
} }
/** /**
* Pass-thru function for ACL grant instance. * Pass-thru function for ACL grant instance.
* *
* @return boolean * @return boolean
*/ */
function revoke($aro, $aco, $action = "*") { function revoke($aro, $aco, $action = "*") {
return $this->_instance->revoke($aro, $aco, $action); return $this->_instance->revoke($aro, $aco, $action);
} }
/** /**
* Pass-thru function for ACL getAro instance. * Pass-thru function for ACL getAro instance.
* *
* @return Aro * @return Aro
*/ */
function getAro($id) { function getAro($id) {
return $this->_instance->getAro($id); return $this->_instance->getAro($id);
} }
/** /**
* Pass-thru function for ACL getAco instance. * Pass-thru function for ACL getAco instance.
* *
* @return Aco * @return Aco
*/ */
function getAco($id) { function getAco($id) {
return $this->_instance->getAco($id); return $this->_instance->getAco($id);
} }
} }
?> ?>

View file

@ -29,7 +29,6 @@
*/ */
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');
uses('controller' . DS . 'components' . DS . 'dbacl' . DS . 'models' . DS . 'acoaction'); uses('controller' . DS . 'components' . DS . 'dbacl' . DS . 'models' . DS . 'acoaction');
@ -43,15 +42,14 @@ uses('controller' . DS . 'components' . DS . 'dbacl' . DS . 'models' . DS . 'aro
* @subpackage cake.cake.libs.controller.components.dbacl * @subpackage cake.cake.libs.controller.components.dbacl
*/ */
class DB_ACL extends AclBase{ class DB_ACL extends AclBase {
/** /**
* Enter description here... * Enter description here...
* *
*/ */
function __construct() { function __construct() {
} }
/** /**
* Enter description here... * Enter description here...
* *
@ -60,200 +58,193 @@ class DB_ACL extends AclBase{
* @param unknown_type $action * @param unknown_type $action
* @return unknown * @return unknown
*/ */
function check($aro, $aco, $action = "*") { function check($aro, $aco, $action = "*") {
$Perms=new ArosAco(); $Perms = new ArosAco();
$Aro =new Aro(); $Aro = new Aro();
$Aco =new Aco(); $Aco = new Aco();
if ($aro == null || $aco == null) { if ($aro == null || $aco == null) {
return false; return false;
} }
$permKeys =$this->_getAcoKeys($Perms->loadInfo()); $permKeys = $this->_getAcoKeys($Perms->loadInfo());
$aroPath =$Aro->getPath($aro); $aroPath = $Aro->getPath($aro);
$tmpAcoPath=$Aco->getPath($aco); $tmpAcoPath = $Aco->getPath($aco);
$acoPath=array();
if ($action != '*' && !in_array('_' . $action, $permKeys)) { if ($tmpAcoPath === null) {
trigger_error('ACO permissions key "' . $action . '" does not exist in DB_ACL::check()', return false;
E_USER_NOTICE); }
return false;
}
foreach($tmpAcoPath as $a) { $acoPath = array();
$acoPath[] = $a['Aco']['id'];
}
for($i = count($aroPath) - 1; $i >= 0; $i--) { if ($action != '*' && !in_array('_' . $action, $permKeys)) {
$perms = $Perms->findAll(array('ArosAco.aro_id' => $aroPath[$i]['Aro']['id'], trigger_error('ACO permissions key "' . $action . '" does not exist in DB_ACL::check()', E_USER_NOTICE);
'ArosAco.aco_id' => $acoPath), null, return false;
'Aco.lft asc'); }
if ($perms == null || count($perms) == 0) { foreach($tmpAcoPath as $a) {
continue; $acoPath[] = $a['Aco']['id'];
} else { }
foreach($perms as $perm) {
if ($action == '*') { for($i = count($aroPath) - 1; $i >= 0; $i--) {
// ARO must be cleared for ALL ACO actions $perms = $Perms->findAll(array(
foreach($permKeys as $key) { 'ArosAco.aro_id' => $aroPath[$i]['Aro']['id'],
if (isset($perm['ArosAco'])) { 'ArosAco.aco_id' => $acoPath), null,
if ($perm['ArosAco'][$key] != 1) { 'Aco.lft asc'
return false; );
}
} if ($perms == null || count($perms) == 0) {
continue;
} else {
foreach($perms as $perm) {
if ($action == '*') {
// ARO must be cleared for ALL ACO actions
foreach($permKeys as $key) {
if (isset($perm['ArosAco'])) {
if ($perm['ArosAco'][$key] != 1) {
return false;
} }
}
}
return true;
} else {
switch($perm['ArosAco']['_' . $action]) {
case -1:
return false;
case 0:
continue;
break;
case 1:
return true; return true;
} else { break;
switch($perm['ArosAco']['_' . $action]) }
{ }
case -1: return false;
case 0:
continue;
break;
case 1: return true;
}
}
}
} }
} }
}
return false; return false;
} }
/** /**
* Allow * Allow
* *
* @return boolean * @return boolean
*/ */
function allow($aro, $aco, $action = "*", $value = 1) { function allow($aro, $aco, $action = "*", $value = 1) {
$Perms =new ArosAco(); $Perms = new ArosAco();
$perms =$this->getAclLink($aro, $aco); $perms = $this->getAclLink($aro, $aco);
$permKeys=$this->_getAcoKeys($Perms->loadInfo()); $permKeys = $this->_getAcoKeys($Perms->loadInfo());
$save=array(); $save = array();
if ($perms == false) { if ($perms == false) {
trigger_error('DB_ACL::allow() - Invalid node', E_USER_WARNING); trigger_error('DB_ACL::allow() - Invalid node', E_USER_WARNING);
return false;
}
if (isset($perms[0])) {
$save = $perms[0]['ArosAco'];
}
if ($action == "*") {
$permKeys = $this->_getAcoKeys($Perms->loadInfo());
foreach($permKeys as $key) {
$save[$key] = $value;
}
} else {
if (in_array('_' . $action, $permKeys)) {
$save['_' . $action] = $value;
} else {
trigger_error('DB_ACL::allow() - Invalid ACO action', E_USER_WARNING);
return false; return false;
} }
}
if (isset($perms[0])) { $save['aro_id'] = $perms['aro'];
$save = $perms[0]['ArosAco']; $save['aco_id'] = $perms['aco'];
}
if ($action == "*") {
$permKeys=$this->_getAcoKeys($Perms->loadInfo());
foreach($permKeys as $key) {
$save[$key] = $value;
}
} else {
if (in_array('_' . $action, $permKeys)) {
$save['_' . $action] = $value;
} else {
trigger_error('DB_ACL::allow() - Invalid ACO action', E_USER_WARNING);
return false;
}
}
$save['aro_id']=$perms['aro'];
$save['aco_id']=$perms['aco'];
if ($perms['link'] != null && count($perms['link']) > 0) {
$save['id'] = $perms['link'][0]['ArosAco']['id'];
}
return $Perms->save(array('ArosAco' => $save));
}
if ($perms['link'] != null && count($perms['link']) > 0) {
$save['id'] = $perms['link'][0]['ArosAco']['id'];
}
return $Perms->save(array('ArosAco' => $save));
}
/** /**
* Deny * Deny
* *
* @return boolean * @return boolean
*/ */
function deny($aro, $aco, $action = "*") { function deny($aro, $aco, $action = "*") {
return $this->allow($aro, $aco, $action, -1); return $this->allow($aro, $aco, $action, -1);
} }
/** /**
* Inherit * Inherit
* *
* @return boolean * @return boolean
*/ */
function inherit($aro, $aco, $action = "*") { function inherit($aro, $aco, $action = "*") {
return $this->allow($aro, $aco, $action, 0); return $this->allow($aro, $aco, $action, 0);
} }
/** /**
* Allow alias * Allow alias
* *
* @return boolean * @return boolean
*/ */
function grant($aro, $aco, $action = "*") { function grant($aro, $aco, $action = "*") {
return $this->allow($aro, $aco, $action); return $this->allow($aro, $aco, $action);
} }
/** /**
* Deny alias * Deny alias
* *
* @return boolean * @return boolean
*/ */
function revoke($aro, $aco, $action = "*") { function revoke($aro, $aco, $action = "*") {
return $this->deny($aro, $aco, $action); return $this->deny($aro, $aco, $action);
} }
/** /**
* Get an ARO object from the given id or alias * Get an ARO object from the given id or alias
* *
* @param mixed $id * @param mixed $id
* @return Aro * @return Aro
*/ */
function getAro($id = null) { function getAro($id = null) {
return $this->__getObject($id, 'Aro'); return $this->__getObject($id, 'Aro');
} }
/** /**
* Get an ACO object from the given id or alias * Get an ACO object from the given id or alias
* *
* @param mixed $id * @param mixed $id
* @return Aco * @return Aco
*/ */
function getAco($id = null) { function getAco($id = null) {
return $this->__getObject($id, 'Aco'); return $this->__getObject($id, 'Aco');
} }
/** /**
* Privaate method * Private method
* *
*/ */
function __getObject($id = null, $object) { function __getObject($id = null, $object) {
if ($id == null) { if ($id == null) {
trigger_error('Null id provided in DB_ACL::get' . $object, E_USER_WARNING); trigger_error('Null id provided in DB_ACL::get' . $object, E_USER_WARNING);
return null; return null;
} }
$obj=new $object; $obj = new $object;
if (is_numeric($id)) { if (is_numeric($id)) {
$key='user_id'; $key = 'user_id';
if ($object == 'Aco') {
$key = 'object_id';
}
if ($object == 'Aco') { $conditions = array($object . '.' . $key => $id);
$key = 'object_id'; } else {
} $conditions = array($object . '.alias' => $id);
}
$conditions=array($object . '.' . $key => $id);
} else {
$conditions = array($object . '.alias' => $id);
}
$tmp =$obj->find($conditions);
$obj->id=$tmp[$object]['id'];
return $obj;
}
$tmp = $obj->find($conditions);
$obj->id = $tmp[$object]['id'];
return $obj;
}
/** /**
* Get an array of access-control links between the given Aro and Aco * Get an array of access-control links between the given Aro and Aco
* *
@ -261,45 +252,47 @@ class DB_ACL extends AclBase{
* @param mixed $aco * @param mixed $aco
* @return array * @return array
*/ */
function getAclLink($aro, $aco) { function getAclLink($aro, $aco) {
$Aro =new Aro(); $Aro = new Aro();
$Aco =new Aco(); $Aco = new Aco();
$Link =new ArosAco(); $Link = new ArosAco();
$obj=array(); $obj = array();
$obj['Aro']=$Aro->find($Aro->_resolveID($aro)); $obj['Aro'] = $Aro->find($Aro->_resolveID($aro));
$obj['Aco']=$Aco->find($Aco->_resolveID($aco)); $obj['Aco'] = $Aco->find($Aco->_resolveID($aco));
$obj['Aro']=$obj['Aro']['Aro']; $obj['Aro'] = $obj['Aro']['Aro'];
$obj['Aco']=$obj['Aco']['Aco']; $obj['Aco'] = $obj['Aco']['Aco'];
if ($obj['Aro'] == null || count($obj['Aro']) == 0 || $obj['Aco'] == null || count($obj['Aco']) == 0) if ($obj['Aro'] == null || count($obj['Aro']) == 0 || $obj['Aco'] == null || count($obj['Aco']) == 0) {
{ return false;
return false; }
}
return array('aro' => $obj['Aro']['id'],
'aco' => $obj['Aco']['id'],
'link' => $Link->findAll(array('ArosAco.aro_id' => $obj['Aro']['id'],
'ArosAco.aco_id' => $obj['Aco']['id'])));
}
return array(
'aro' => $obj['Aro']['id'],
'aco' => $obj['Aco']['id'],
'link' => $Link->findAll(array(
'ArosAco.aro_id' => $obj['Aro']['id'],
'ArosAco.aco_id' => $obj['Aco']['id']
))
);
}
/** /**
* Enter description here... * Enter description here...
* *
* @param unknown_type $keys * @param unknown_type $keys
* @return unknown * @return unknown
*/ */
function _getAcoKeys($keys) { function _getAcoKeys($keys) {
$newKeys=array(); $newKeys = array();
$keys=$keys->value; $keys = $keys->value;
foreach($keys as $key) { foreach($keys as $key) {
if ($key['name'] != 'id' && $key['name'] != 'aro_id' && $key['name'] != 'aco_id') { if ($key['name'] != 'id' && $key['name'] != 'aro_id' && $key['name'] != 'aco_id') {
$newKeys[] = $key['name']; $newKeys[] = $key['name'];
} }
} }
return $newKeys;
return $newKeys; }
}
} }
?> ?>

View file

@ -69,10 +69,12 @@ class AclNode extends AppModel {
$parent = $parent[$class]; $parent = $parent[$class];
$this->_syncTable(1, $parent['lft'], $parent['lft']); $this->_syncTable(1, $parent['lft'], $parent['lft']);
} }
$return = $this->save(array($class => array($secondary_id => $link_id, $return = $this->save(array($class => array(
'alias' => $alias, $secondary_id => $link_id,
'lft' => $parent['lft'] + 1, 'alias' => $alias,
'rght' => $parent['lft'] + 2))); 'lft' => $parent['lft'] + 1,
'rght' => $parent['lft'] + 2
)));
$this->id = $this->getLastInsertID(); $this->id = $this->getLastInsertID();
return $return; return $return;
} }
@ -103,10 +105,8 @@ class AclNode extends AppModel {
$object = $object[$class]; $object = $object[$class];
$parent = $this->getParent($id); $parent = $this->getParent($id);
if (($parent == null && $parent_id == null) if (($parent == null && $parent_id == null) || ($parent_id == $parent[$class][$secondary_id] && $parent_id != null) || ($parent_id == $parent[$class]['alias'] && $parent_id != null)) {
|| ($parent_id == $parent[$class][$secondary_id] && $parent_id != null) return false;
|| ($parent_id == $parent[$class]['alias'] && $parent_id != null)) {
return false;
} }
if ($parent_id == null) { if ($parent_id == null) {
@ -245,4 +245,5 @@ class AclNode extends AppModel {
return $vars; return $vars;
} }
} }
?> ?>

View file

@ -43,7 +43,7 @@ if (!class_exists('AppModel')) {
* @subpackage cake.cake.libs.controller.components.dbacl.models * @subpackage cake.cake.libs.controller.components.dbacl.models
* *
*/ */
class AcoAction extends AppModel{ class AcoAction extends AppModel {
/** /**
* Enter description here... * Enter description here...
* *

View file

@ -37,7 +37,7 @@
* @subpackage cake.cake.libs.controller.components.dbacl.models * @subpackage cake.cake.libs.controller.components.dbacl.models
* *
*/ */
class Aro extends AclNode{ class Aro extends AclNode {
/** /**
* Enter description here... * Enter description here...

View file

@ -37,8 +37,13 @@
* @subpackage cake.cake.libs.controller.components.dbacl.models * @subpackage cake.cake.libs.controller.components.dbacl.models
*/ */
class ArosAco extends AppModel{ class ArosAco extends AppModel {
/**
* Enter description here...
*
* @var unknown_type
*/
var $cacheQueries = false;
/** /**
* Enter description here... * Enter description here...
* *

View file

@ -38,12 +38,17 @@ uses('controller/components/acl_base');
*/ */
class INI_ACL extends AclBase{ class INI_ACL extends AclBase{
/**
* Array with configuration, parsed from ini file
*/
var $config = null;
/** /**
* The constructor must be overridden, as AclBase is abstract. * The constructor must be overridden, as AclBase is abstract.
* *
*/ */
function __construct() { function __construct() {
} }
/** /**
* Main ACL check function. Checks to see if the ARO (access request object) has access to the ACO (access control object). * Main ACL check function. Checks to see if the ARO (access request object) has access to the ACO (access control object).
@ -53,63 +58,66 @@ class INI_ACL extends AclBase{
* @param string $aco * @param string $aco
* @return boolean * @return boolean
*/ */
function check($aro, $aco, $aco_action = null) { function check($aro, $aco, $aco_action = null) {
$aclConfig=$this->readConfigFile(CONFIGS . 'acl.ini.php'); if ($this->config == null) {
$this->config = $this->readConfigFile(CONFIGS . 'acl.ini.php');
}
$aclConfig = $this->config;
//First, if the user is specifically denied, then DENY //First, if the user is specifically denied, then DENY
if (isset($aclConfig[$aro]['deny'])) { if (isset($aclConfig[$aro]['deny'])) {
$userDenies=$this->arrayTrim(explode(",", $aclConfig[$aro]['deny'])); $userDenies = $this->arrayTrim(explode(",", $aclConfig[$aro]['deny']));
if (array_search($aco, $userDenies)) { if (array_search($aco, $userDenies)) {
//echo "User Denied!"; //echo "User Denied!";
return false; return false;
}
}
//Second, if the user is specifically allowed, then ALLOW
if (isset($aclConfig[$aro]['allow'])) {
$userAllows = $this->arrayTrim(explode(",", $aclConfig[$aro]['allow']));
if (array_search($aco, $userAllows)) {
//echo "User Allowed!";
return true;
}
}
//Check group permissions
if (isset($aclConfig[$aro]['groups'])) {
$userGroups = $this->arrayTrim(explode(",", $aclConfig[$aro]['groups']));
foreach($userGroups as $group) {
//If such a group exists,
if (array_key_exists($group, $aclConfig)) {
//If the group is specifically denied, then DENY
if (isset($aclConfig[$group]['deny'])) {
$groupDenies=$this->arrayTrim(explode(",", $aclConfig[$group]['deny']));
if (array_search($aco, $groupDenies)) {
//echo("Group Denied!");
return false;
}
}
//If the group is specifically allowed, then ALLOW
if (isset($aclConfig[$group]['allow'])) {
$groupAllows = $this->arrayTrim(explode(",", $aclConfig[$group]['allow']));
if (array_search($aco, $groupAllows)) {
//echo("Group Allowed!");
return true;
}
}
} }
} }
}
//Second, if the user is specifically allowed, then ALLOW //Default, DENY
if (isset($aclConfig[$aro]['allow'])) { //echo("DEFAULT: DENY.");
$userAllows=$this->arrayTrim(explode(",", $aclConfig[$aro]['allow'])); return false;
}
if (array_search($aco, $userAllows)) {
//echo "User Allowed!";
return true;
}
}
//Check group permissions
if (isset($aclConfig[$aro]['groups'])) {
$userGroups=$this->arrayTrim(explode(",", $aclConfig[$aro]['groups']));
foreach($userGroups as $group) {
//If such a group exists,
if (array_key_exists($group, $aclConfig)) {
//If the group is specifically denied, then DENY
if (isset($aclConfig[$group]['deny'])) {
$groupDenies=$this->arrayTrim(explode(",", $aclConfig[$group]['deny']));
if (array_search($aco, $groupDenies)) {
//echo("Group Denied!");
return false;
}
}
//If the group is specifically allowed, then ALLOW
if (isset($aclConfig[$group]['allow'])) {
$groupAllows=$this->arrayTrim(explode(",", $aclConfig[$group]['allow']));
if (array_search($aco, $groupAllows)) {
//echo("Group Allowed!");
return true;
}
}
}
}
}
//Default, DENY
//echo("DEFAULT: DENY.");
return false;
}
/** /**
* Parses an INI file and returns an array that reflects the INI file's section structure. Double-quote friendly. * Parses an INI file and returns an array that reflects the INI file's section structure. Double-quote friendly.
@ -117,42 +125,42 @@ class INI_ACL extends AclBase{
* @param string $fileName * @param string $fileName
* @return array * @return array
*/ */
function readConfigFile($fileName) { function readConfigFile($fileName) {
$fileLineArray=file($fileName); $fileLineArray = file($fileName);
foreach($fileLineArray as $fileLine) { foreach($fileLineArray as $fileLine) {
$dataLine = trim($fileLine); $dataLine = trim($fileLine);
$firstChar=substr($dataLine, 0, 1); $firstChar = substr($dataLine, 0, 1);
if ($firstChar != ';' && $dataLine != '') { if ($firstChar != ';' && $dataLine != '') {
if ($firstChar == '[' && substr($dataLine, -1, 1) == ']') { if ($firstChar == '[' && substr($dataLine, -1, 1) == ']') {
$sectionName = preg_replace('/[\[\]]/', '', $dataLine); $sectionName = preg_replace('/[\[\]]/', '', $dataLine);
} else { } else {
$delimiter=strpos($dataLine, '='); $delimiter = strpos($dataLine, '=');
if ($delimiter > 0) { if ($delimiter > 0) {
$key =strtolower(trim(substr($dataLine, 0, $delimiter))); $key = strtolower(trim(substr($dataLine, 0, $delimiter)));
$value=trim(substr($dataLine, $delimiter + 1)); $value = trim(substr($dataLine, $delimiter + 1));
if (substr($value, 0, 1) == '"' && substr($value, -1) == '"') { if (substr($value, 0, 1) == '"' && substr($value, -1) == '"') {
$value = substr($value, 1, -1); $value = substr($value, 1, -1);
} }
$iniSetting[$sectionName][$key]=stripcslashes($value); $iniSetting[$sectionName][$key]=stripcslashes($value);
} else { } else {
if (!isset($sectionName)) { if (!isset($sectionName)) {
$sectionName = ''; $sectionName = '';
} }
$iniSetting[$sectionName][strtolower(trim($dataLine))]=''; $iniSetting[$sectionName][strtolower(trim($dataLine))]='';
} }
} }
} else { } else {
} }
} }
return $iniSetting; return $iniSetting;
} }
/** /**
* Removes trailing spaces on all array elements (to prepare for searching) * Removes trailing spaces on all array elements (to prepare for searching)
@ -160,16 +168,16 @@ class INI_ACL extends AclBase{
* @param array $array * @param array $array
* @return array * @return array
*/ */
function arrayTrim($array) { function arrayTrim($array) {
foreach($array as $element) { foreach($array as $element) {
$element = trim($element); $element = trim($element);
} }
//Adding this element keeps array_search from returning 0: //Adding this element keeps array_search from returning 0:
//0 is the first key, which may be correct, but 0 is interpreted as false. //0 is the first key, which may be correct, but 0 is interpreted as false.
//Adding this element makes all the keys be positive integers. //Adding this element makes all the keys be positive integers.
array_unshift($array, ""); array_unshift($array, "");
return $array; return $array;
} }
} }
?> ?>

View file

@ -29,8 +29,8 @@
*/ */
if (!defined('REQUEST_MOBILE_UA')) { if (!defined('REQUEST_MOBILE_UA')) {
define('REQUEST_MOBILE_UA', define('REQUEST_MOBILE_UA',
'(AvantGo|BlackBerry|DoCoMo|NetFront|Nokia|PalmOS|PalmSource|portalmmm|Plucker|ReqwirelessWeb|SonyEricsson|Symbian|UP\.Browser|Windows CE|Xiino)'); '(AvantGo|BlackBerry|DoCoMo|NetFront|Nokia|PalmOS|PalmSource|portalmmm|Plucker|ReqwirelessWeb|SonyEricsson|Symbian|UP\.Browser|Windows CE|Xiino)');
} }
/** /**
@ -41,159 +41,143 @@ if (!defined('REQUEST_MOBILE_UA')) {
* *
*/ */
class RequestHandlerComponent extends Object{ class RequestHandlerComponent extends Object{
var $controller = true; var $controller = true;
var $ajaxLayout = 'ajax'; var $ajaxLayout = 'ajax';
var $disableStartup = false; var $disableStartup = false;
var $__requestContent = array('js' => 'text/javascript', var $__requestContent = array(
'css' => 'text/css', 'js' => 'text/javascript',
'html' => 'text/html', 'css' => 'text/css',
'form' => 'application/x-www-form-urlencoded', 'html' => 'text/html',
'file' => 'multipart/form-data', 'form' => 'application/x-www-form-urlencoded',
'xhtml' => array('application/xhtml+xml', 'file' => 'multipart/form-data',
'application/xhtml', 'xhtml' => array('application/xhtml+xml', 'application/xhtml', 'text/xhtml'),
'text/xhtml'), 'xml' => array('application/xml', 'text/xml'),
'xml' => array('application/xml', 'rss' => 'application/rss+xml',
'text/xml'), 'atom' => 'application/atom+xml'
'rss' => 'application/rss+xml', );
'atom' => 'application/atom+xml');
var $__acceptTypes = array(); var $__acceptTypes = array();
function __construct() { function __construct() {
$this->__acceptTypes=explode(',', env('HTTP_ACCEPT')); $this->__acceptTypes = explode(',', env('HTTP_ACCEPT'));
foreach($this->__acceptTypes as $i => $type) {
if (strpos($type, ';')) {
$type =explode(';', $type);
$this->__acceptTypes[$i]=$type[0];
}
}
parent::__construct();
}
foreach($this->__acceptTypes as $i => $type) {
if (strpos($type, ';')) {
$type = explode(';', $type);
$this->__acceptTypes[$i] = $type[0];
}
}
parent::__construct();
}
/** /**
* Startup * Startup
* *
* @param object A reference to the controller * @param object A reference to the controller
* @return null * @return null
*/ */
function startup(&$controller) { function startup(&$controller) {
if ($this->disableStartup) { if ($this->disableStartup) {
return; return;
} }
$this->setAjax($controller);
$this->setAjax($controller); }
}
/** /**
* Sets a controller's layout based on whether or not the current call is Ajax * Sets a controller's layout based on whether or not the current call is Ajax
* *
* @param object The controller object * @param object The controller object
* @return null * @return null
*/ */
function setAjax(&$controller) { function setAjax(&$controller) {
if ($this->isAjax()) { if ($this->isAjax()) {
$controller->layout=$this->ajaxLayout; $controller->layout=$this->ajaxLayout;
// Add UTF-8 header for IE6 on XPsp2 bug
header ('Content-Type: text/html; charset=UTF-8');
}
}
// Add UTF-8 header for IE6 on XPsp2 bug
header ('Content-Type: text/html; charset=UTF-8');
}
}
/** /**
* Returns true if the current call is from Ajax, false otherwise * Returns true if the current call is from Ajax, false otherwise
* *
* @return bool True if call is Ajax * @return bool True if call is Ajax
*/ */
function isAjax() { function isAjax() {
if (env('HTTP_X_REQUESTED_WITH') != null) { if (env('HTTP_X_REQUESTED_WITH') != null) {
return env('HTTP_X_REQUESTED_WITH') == "XMLHttpRequest"; return env('HTTP_X_REQUESTED_WITH') == "XMLHttpRequest";
} else { } else {
return false; return false;
} }
} }
/** /**
* Returns true if the current call accepts an XML response, false otherwise * Returns true if the current call accepts an XML response, false otherwise
* *
* @return bool True if client accepts an XML response * @return bool True if client accepts an XML response
*/ */
function isXml() { function isXml() {
return $this->accepts('xml'); return $this->accepts('xml');
} }
/** /**
* Returns true if the current call accepts an RSS response, false otherwise * Returns true if the current call accepts an RSS response, false otherwise
* *
* @return bool True if client accepts an RSS response * @return bool True if client accepts an RSS response
*/ */
function isRss() { function isRss() {
return $this->accepts('rss'); return $this->accepts('rss');
} }
/** /**
* Returns true if the current call accepts an RSS response, false otherwise * Returns true if the current call accepts an RSS response, false otherwise
* *
* @return bool True if client accepts an RSS response * @return bool True if client accepts an RSS response
*/ */
function isAtom() { function isAtom() {
return $this->accepts('atom'); return $this->accepts('atom');
} }
/** /**
* Returns true if the current call a POST request * Returns true if the current call a POST request
* *
* @return bool True if call is a POST * @return bool True if call is a POST
*/ */
function isPost() { function isPost() {
return (strtolower(env('REQUEST_METHOD')) == 'post'); return (strtolower(env('REQUEST_METHOD')) == 'post');
} }
/** /**
* Returns true if the current call a PUT request * Returns true if the current call a PUT request
* *
* @return bool True if call is a PUT * @return bool True if call is a PUT
*/ */
function isPut() { function isPut() {
return (strtolower(env('REQUEST_METHOD')) == 'put'); return (strtolower(env('REQUEST_METHOD')) == 'put');
} }
/** /**
* Returns true if the current call a GET request * Returns true if the current call a GET request
* *
* @return bool True if call is a GET * @return bool True if call is a GET
*/ */
function isGet() { function isGet() {
return (strtolower(env('REQUEST_METHOD')) == 'get'); return (strtolower(env('REQUEST_METHOD')) == 'get');
} }
/** /**
* Returns true if the current call a DELETE request * Returns true if the current call a DELETE request
* *
* @return bool True if call is a DELETE * @return bool True if call is a DELETE
*/ */
function isDelete() { function isDelete() {
return (strtolower(env('REQUEST_METHOD')) == 'delete'); return (strtolower(env('REQUEST_METHOD')) == 'delete');
} }
/** /**
* Gets Prototype version if call is Ajax, otherwise empty string. * Gets Prototype version if call is Ajax, otherwise empty string.
* The Prototype library sets a special "Prototype version" HTTP header. * The Prototype library sets a special "Prototype version" HTTP header.
* *
* @return string Prototype version of component making Ajax call * @return string Prototype version of component making Ajax call
*/ */
function getAjaxVersion() { function getAjaxVersion() {
if (env('HTTP_X_PROTOTYPE_VERSION') != null) { if (env('HTTP_X_PROTOTYPE_VERSION') != null) {
return env('HTTP_X_PROTOTYPE_VERSION'); return env('HTTP_X_PROTOTYPE_VERSION');
} }
return false;
return false; }
}
/** /**
* Adds/sets the Content-type(s) for the given name * Adds/sets the Content-type(s) for the given name
* *
@ -201,109 +185,96 @@ class RequestHandlerComponent extends Object{
* @param mixed $type The Content-type or array of Content-types assigned to the name * @param mixed $type The Content-type or array of Content-types assigned to the name
* @return void * @return void
*/ */
function setContent($name, $type) { function setContent($name, $type) {
$this->__requestContent[$name]=$type; $this->__requestContent[$name] = $type;
} }
/** /**
* Gets the server name from which this request was referred * Gets the server name from which this request was referred
* *
* @return string Server address * @return string Server address
*/ */
function getReferrer() { function getReferrer() {
if (env('HTTP_HOST') != null) { if (env('HTTP_HOST') != null) {
$sess_host = env('HTTP_HOST'); $sess_host = env('HTTP_HOST');
} }
if (env('HTTP_X_FORWARDED_HOST') != null) {
$sess_host = env('HTTP_X_FORWARDED_HOST');
}
return trim(preg_replace('/:.*/', '', $sess_host));
}
if (env('HTTP_X_FORWARDED_HOST') != null) {
$sess_host = env('HTTP_X_FORWARDED_HOST');
}
return trim(preg_replace('/:.*/', '', $sess_host));
}
/** /**
* Gets remote client IP * Gets remote client IP
* *
* @return string Client IP address * @return string Client IP address
*/ */
function getClientIP() { function getClientIP() {
if (env('HTTP_X_FORWARDED_FOR') != null) { if (env('HTTP_X_FORWARDED_FOR') != null) {
$ipaddr = preg_replace('/,.*/', '', env('HTTP_X_FORWARDED_FOR')); $ipaddr = preg_replace('/,.*/', '', env('HTTP_X_FORWARDED_FOR'));
} else { } else {
if (env('HTTP_CLIENT_IP') != null) { if (env('HTTP_CLIENT_IP') != null) {
$ipaddr = env('HTTP_CLIENT_IP'); $ipaddr = env('HTTP_CLIENT_IP');
} else { } else {
$ipaddr = env('REMOTE_ADDR'); $ipaddr = env('REMOTE_ADDR');
} }
} }
if (env('HTTP_CLIENTADDRESS') != null) { if (env('HTTP_CLIENTADDRESS') != null) {
$tmpipaddr=env('HTTP_CLIENTADDRESS'); $tmpipaddr = env('HTTP_CLIENTADDRESS');
if (!empty($tmpipaddr)) {
$ipaddr = preg_replace('/,.*/', '', $tmpipaddr);
}
}
return trim($ipaddr);
}
if (!empty($tmpipaddr)) {
$ipaddr = preg_replace('/,.*/', '', $tmpipaddr);
}
}
return trim($ipaddr);
}
/** /**
* Returns true if user agent string matches a mobile web browser * Returns true if user agent string matches a mobile web browser
* *
* @return bool True if user agent is a mobile web browser * @return bool True if user agent is a mobile web browser
*/ */
function isMobile() { function isMobile() {
return (preg_match('/' . REQUEST_MOBILE_UA . '/i', env('HTTP_USER_AGENT')) > 0); return (preg_match('/' . REQUEST_MOBILE_UA . '/i', env('HTTP_USER_AGENT')) > 0);
} }
/** /**
* Strips extra whitespace from output * Strips extra whitespace from output
* *
* @param string $str * @param string $str
*/ */
function stripWhitespace($str) { function stripWhitespace($str) {
$r=preg_replace('/[\n\r\t]+/', '', $str); $r = preg_replace('/[\n\r\t]+/', '', $str);
return preg_replace('/\s{2,}/', ' ', $r); return preg_replace('/\s{2,}/', ' ', $r);
} }
/** /**
* Strips image tags from output * Strips image tags from output
* *
* @param string $str * @param string $str
*/ */
function stripImages($str) { function stripImages($str) {
$str=preg_replace('/(<a[^>]*>)(<img[^>]+alt=")([^"]*)("[^>]*>)(<\/a>)/i', '$1$3$5<br />', $str); $str = preg_replace('/(<a[^>]*>)(<img[^>]+alt=")([^"]*)("[^>]*>)(<\/a>)/i', '$1$3$5<br />', $str);
$str=preg_replace('/(<img[^>]+alt=")([^"]*)("[^>]*>)/i', '$2<br />', $str); $str = preg_replace('/(<img[^>]+alt=")([^"]*)("[^>]*>)/i', '$2<br />', $str);
$str=preg_replace('/<img[^>]*>/i', '', $str); $str = preg_replace('/<img[^>]*>/i', '', $str);
return $str; return $str;
} }
/** /**
* Strips scripts and stylesheets from output * Strips scripts and stylesheets from output
* *
* @param string $str * @param string $str
*/ */
function stripScripts($str) { function stripScripts($str) {
return preg_replace( return preg_replace('/(<link[^>]+rel="[^"]*stylesheet"[^>]*>|<img[^>]*>|style="[^"]*")|<script[^>]*>.*?<\/script>|<style[^>]*>.*?<\/style>|<!--.*?-->/i', '', $str);
'/(<link[^>]+rel="[^"]*stylesheet"[^>]*>|<img[^>]*>|style="[^"]*")|<script[^>]*>.*?<\/script>|<style[^>]*>.*?<\/style>|<!--.*?-->/i', }
'',
$str);
}
/** /**
* Strips extra whitespace, images, scripts and stylesheets from output * Strips extra whitespace, images, scripts and stylesheets from output
* *
* @param string $str * @param string $str
*/ */
function stripAll($str) { function stripAll($str) {
$str=$this->stripWhitespace($str); $str = $this->stripWhitespace($str);
$str=$this->stripImages($str); $str = $this->stripImages($str);
$str=$this->stripScripts($str); $str = $this->stripScripts($str);
return $str; return $str;
} }
/** /**
* Strips the specified tags from output * Strips the specified tags from output
* *
@ -312,17 +283,16 @@ class RequestHandlerComponent extends Object{
* @param string $tag * @param string $tag
* @param string ... * @param string ...
*/ */
function stripTags() { function stripTags() {
$params=params(func_get_args()); $params = params(func_get_args());
$str =$params[0]; $str = $params[0];
for($i = 1; $i < count($params); $i++) { for($i = 1; $i < count($params); $i++) {
$str = preg_replace('/<' . $params[$i] . '[^>]*>/i', '', $str); $str = preg_replace('/<' . $params[$i] . '[^>]*>/i', '', $str);
$str =preg_replace('/<\/' . $params[$i] . '[^>]*>/i', '', $str); $str = preg_replace('/<\/' . $params[$i] . '[^>]*>/i', '', $str);
} }
return $str;
return $str; }
}
/** /**
* Determines which content types the client accepts * Determines which content types the client accepts
@ -335,43 +305,41 @@ class RequestHandlerComponent extends Object{
* if the client accepts one or more elements in the array. * if the client accepts one or more elements in the array.
* @access public * @access public
*/ */
function accepts($type = null) { function accepts($type = null) {
if ($type == null) { if ($type == null) {
return $this->__acceptTypes; return $this->__acceptTypes;
} else if(is_array($type)) { } else if(is_array($type)) {
foreach($type as $t) { foreach($type as $t) {
if ($this->accepts($t) == true) { if ($this->accepts($t) == true) {
return true; return true;
}
} }
}
return false;
} else if(is_string($type)) {
// If client only accepts */*, then assume default HTML browser
if ($type == 'html' && $this->__acceptTypes === array('*/*')) {
return true;
}
if (!in_array($type, array_keys($this->__requestContent))) {
return false; return false;
} else if(is_string($type)) { }
// If client only accepts */*, then assume default HTML browser
if ($type == 'html' && $this->__acceptTypes === array('*/*')) { $content = $this->__requestContent[$type];
return true;
if (is_array($content)) {
foreach($content as $c) {
if (in_array($c, $this->__acceptTypes)) {
return true;
}
} }
} else {
if (!in_array($type, array_keys($this->__requestContent))) { if (in_array($content, $this->__acceptTypes)) {
return false; return true;
} }
}
$content=$this->__requestContent[$type]; }
}
if (is_array($content)) {
foreach($content as $c) {
if (in_array($c, $this->__acceptTypes)) {
return true;
}
}
} else {
if (in_array($content, $this->__acceptTypes)) {
return true;
}
}
}
}
/** /**
* Determines which content types the client prefers * Determines which content types the client prefers
* *
@ -379,10 +347,11 @@ class RequestHandlerComponent extends Object{
* @returns mixed * @returns mixed
* @access public * @access public
*/ */
function prefers($type = null) { function prefers($type = null) {
if ($type == null) { if ($type == null) {
return $this->accepts(null); return $this->accepts(null);
} }
} }
} }
?> ?>

View file

@ -43,11 +43,23 @@ class SessionComponent extends Object{
* Enter description here... * Enter description here...
* *
*/ */
function __construct($base = null) { function __construct($base = null) {
$this->CakeSession=new CakeSession($base); $this->CakeSession = new CakeSession($base);
parent::__construct(); parent::__construct();
} }
/**
* Startup method. Copies controller data locally for rendering flash messages.
*
*/
function startup(&$controller) {
$this->base = $controller->base;
$this->webroot = $controller->webroot;
$this->here = $controller->here;
$this->params = $controller->params;
$this->action = $controller->action;
$this->data = $controller->data;
$this->plugin = $controller->plugin;
}
/** /**
* Enter description here... * Enter description here...
* *
@ -57,10 +69,9 @@ class SessionComponent extends Object{
* @param unknown_type $value * @param unknown_type $value
* @return unknown * @return unknown
*/ */
function write($name, $value) { function write($name, $value) {
return $this->CakeSession->writeSessionVar($name, $value); return $this->CakeSession->writeSessionVar($name, $value);
} }
/** /**
* Enter description here... * Enter description here...
* *
@ -70,10 +81,9 @@ class SessionComponent extends Object{
* @param unknown_type $name * @param unknown_type $name
* @return unknown * @return unknown
*/ */
function read($name = null) { function read($name = null) {
return $this->CakeSession->readSessionVar($name); return $this->CakeSession->readSessionVar($name);
} }
/** /**
* Enter description here... * Enter description here...
* *
@ -82,19 +92,17 @@ class SessionComponent extends Object{
* @param unknown_type $name * @param unknown_type $name
* @return unknown * @return unknown
*/ */
function del($name) { function del($name) {
return $this->CakeSession->delSessionVar($name); return $this->CakeSession->delSessionVar($name);
} }
/** /**
* Enter description here... * Enter description here...
* @param unknown_type $name * @param unknown_type $name
* @return unknown * @return unknown
*/ */
function delete($name) { function delete($name) {
return $this->del($name); return $this->del($name);
} }
/** /**
* Enter description here... * Enter description here...
* *
@ -103,10 +111,9 @@ class SessionComponent extends Object{
* @param unknown_type $name * @param unknown_type $name
* @return unknown * @return unknown
*/ */
function check($name) { function check($name) {
return $this->CakeSession->checkSessionVar($name); return $this->CakeSession->checkSessionVar($name);
} }
/** /**
* Enter description here... * Enter description here...
* *
@ -114,10 +121,9 @@ class SessionComponent extends Object{
* *
* @return string Last session error * @return string Last session error
*/ */
function error() { function error() {
return $this->CakeSession->getLastError(); return $this->CakeSession->getLastError();
} }
/** /**
* Enter description here... * Enter description here...
* *
@ -129,38 +135,43 @@ class SessionComponent extends Object{
* @param string $key Message key, default is 'flash' * @param string $key Message key, default is 'flash'
* @return string Last session error * @return string Last session error
*/ */
function setFlash($flashMessage, $layout = 'default', $params = array(), $key = 'flash') { function setFlash($flashMessage, $layout = 'default', $params = array(), $key = 'flash') {
if ($layout == 'default') { if ($layout == 'default') {
$out = '<div id="' . $key . 'Message" class="message">' . $flashMessage . '</div>'; $out = '<div id="' . $key . 'Message" class="message">' . $flashMessage . '</div>';
} else if($layout == '' || $layout == null) { } else if($layout == '' || $layout == null) {
$out = $flashMessage; $out = $flashMessage;
} else { } else {
$ctrl =null; $ctrl = null;
$view =new View($ctrl); $view = new View($ctrl);
$view->layout =$layout; $view->base = $this->base;
$view->pageTitle=''; $view->webroot = $this->webroot;
$view->_viewVars=$params; $view->here = $this->here;
$out =$view->renderLayout($flashMessage); $view->params = $this->params;
} $view->action = $this->action;
$view->data = $this->data;
$this->write('Message.' . $key, $out); $view->plugin = $this->plugin;
} $view->helpers = array('Html');
$view->layout = $layout;
$view->pageTitle = '';
$view->_viewVars = $params;
$out = $view->renderLayout($flashMessage);
}
$this->write('Message.' . $key, $out);
}
/** /**
* Use like this. $this->Session->flash(); * Use like this. $this->Session->flash();
* *
* @param string $key Optional message key * @param string $key Optional message key
* @return null * @return null
*/ */
function flash($key = 'flash') { function flash($key = 'flash') {
if ($this->check('Message.' . $key)) { if ($this->check('Message.' . $key)) {
e($this->read('Message.' . $key)); e($this->read('Message.' . $key));
$this->del('Message.' . $key); $this->del('Message.' . $key);
} else { } else {
return false; return false;
} }
} }
/** /**
* Enter description here... * Enter description here...
* *
@ -169,10 +180,9 @@ class SessionComponent extends Object{
* *
* @return boolean * @return boolean
*/ */
function renew() { function renew() {
$this->CakeSession->renew(); $this->CakeSession->renew();
} }
/** /**
* Enter description here... * Enter description here...
* *
@ -182,10 +192,9 @@ class SessionComponent extends Object{
* *
* @return boolean * @return boolean
*/ */
function valid() { function valid() {
return $this->CakeSession->isValid(); return $this->CakeSession->isValid();
} }
/** /**
* Enter description here... * Enter description here...
* *
@ -193,8 +202,9 @@ class SessionComponent extends Object{
* Used to destroy Sessions * Used to destroy Sessions
* *
*/ */
function destroy() { function destroy() {
$this->CakeSession->destroyInvalid(); $this->CakeSession->destroyInvalid();
} }
} }
?> ?>

View file

@ -54,6 +54,12 @@ class Controller extends Object{
* @var string Current URL * @var string Current URL
*/ */
var $here = null; var $here = null;
/**
* The webroot of the application
*
* @var string
*/
var $webroot = null;
/** /**
* Action to be performed. * Action to be performed.
* *
@ -75,6 +81,20 @@ class Controller extends Object{
* @access protected * @access protected
*/ */
var $helpers = array('Html'); var $helpers = array('Html');
/**
* Parameters received in the current request, i.e. GET and POST data
*
* @var array
* @access public
*/
var $params = array();
/**
* POST'ed model data
*
* @var array
* @access public
*/
var $data = array();
/** /**
* Enter description here... * Enter description here...
* *
@ -186,40 +206,38 @@ class Controller extends Object{
*/ */
function __construct() { function __construct() {
if ($this->name === null) { if ($this->name === null) {
$r=null; $r = null;
if (!preg_match('/(.*)Controller/i', get_class($this), $r)) { if (!preg_match('/(.*)Controller/i', get_class($this), $r)) {
die ("Controller::__construct() : Can't get or parse my own class name, exiting."); die ("Controller::__construct() : Can't get or parse my own class name, exiting.");
} }
$this->name=$r[1]; $this->name = $r[1];
} }
if ($this->viewPath == null) { if ($this->viewPath == null) {
$this->viewPath = Inflector::underscore($this->name); $this->viewPath = Inflector::underscore($this->name);
} }
$this->modelClass=ucwords(Inflector::singularize($this->name)); $this->modelClass = ucwords(Inflector::singularize($this->name));
$this->modelKey =Inflector::underscore($this->modelClass); $this->modelKey = Inflector::underscore($this->modelClass);
if (!defined('AUTO_SESSION') || AUTO_SESSION == true) { if (!defined('AUTO_SESSION') || AUTO_SESSION == true) {
$this->components[] = 'Session'; $this->components[] = 'Session';
} }
if (is_subclass_of($this, 'AppController')) { if (is_subclass_of($this, 'AppController')) {
$appVars=get_class_vars('AppController'); $appVars = get_class_vars('AppController');
foreach(array('components', foreach(array('components', 'helpers', 'uses') as $var) {
'helpers', if (isset($appVars[$var]) && !empty($appVars[$var]) && is_array($this->{$var})) {
'uses')as $var) { $diff = array_diff($appVars[$var], $this->{$var});
if (isset($appVars[$var]) && !empty($appVars[$var]) && is_array($this->{$var})) { $this->{$var} = array_merge($this->{$var}, $diff);
$diff =array_diff($appVars[$var], $this->{$var});
$this->{$var}=array_merge($this->{$var}, $diff);
}
} }
}
} }
if (!empty($this->components)) { if (!empty($this->components)) {
$component = &new Component($this); $component = &new Component($this);
} }
parent::__construct(); parent::__construct();
} }
@ -255,7 +273,7 @@ class Controller extends Object{
} else { } else {
$this->_persist($this->modelClass . 'registry', true, $object, 'registry'); $this->_persist($this->modelClass . 'registry', true, $object, 'registry');
$this->_persist($this->modelClass, true, $object); $this->_persist($this->modelClass, true, $object);
$this->modelNames[]=$this->modelClass; $this->modelNames[] = $this->modelClass;
return true; return true;
} }
} elseif ($this->uses === false) { } elseif ($this->uses === false) {
@ -306,11 +324,12 @@ class Controller extends Object{
function redirect($url, $status = null) { function redirect($url, $status = null) {
$this->autoRender = false; $this->autoRender = false;
$pos = strpos($url, '://'); $pos = strpos($url, '://');
$base = strip_plugin($this->base, $this->plugin);
if ($pos === false) { if ($pos === false) {
if (strpos($url, '/') !== 0) { if (strpos($url, '/') !== 0) {
$url = '/' . $url; $url = '/' . $url;
} }
$url = $this->base . $url; $url = $base . $url;
} }
if (function_exists('session_write_close')) { if (function_exists('session_write_close')) {
@ -318,45 +337,47 @@ class Controller extends Object{
} }
if ($status != null) { if ($status != null) {
$codes = array(100 => "HTTP/1.1 100 Continue", $codes = array(
101 => "HTTP/1.1 101 Switching Protocols", 100 => "HTTP/1.1 100 Continue",
200 => "HTTP/1.1 200 OK", 101 => "HTTP/1.1 101 Switching Protocols",
201 => "HTTP/1.1 201 Created", 200 => "HTTP/1.1 200 OK",
202 => "HTTP/1.1 202 Accepted", 201 => "HTTP/1.1 201 Created",
203 => "HTTP/1.1 203 Non-Authoritative Information", 202 => "HTTP/1.1 202 Accepted",
204 => "HTTP/1.1 204 No Content", 203 => "HTTP/1.1 203 Non-Authoritative Information",
205 => "HTTP/1.1 205 Reset Content", 204 => "HTTP/1.1 204 No Content",
206 => "HTTP/1.1 206 Partial Content", 205 => "HTTP/1.1 205 Reset Content",
300 => "HTTP/1.1 300 Multiple Choices", 206 => "HTTP/1.1 206 Partial Content",
301 => "HTTP/1.1 301 Moved Permanently", 300 => "HTTP/1.1 300 Multiple Choices",
302 => "HTTP/1.1 302 Found", 301 => "HTTP/1.1 301 Moved Permanently",
303 => "HTTP/1.1 303 See Other", 302 => "HTTP/1.1 302 Found",
304 => "HTTP/1.1 304 Not Modified", 303 => "HTTP/1.1 303 See Other",
305 => "HTTP/1.1 305 Use Proxy", 304 => "HTTP/1.1 304 Not Modified",
307 => "HTTP/1.1 307 Temporary Redirect", 305 => "HTTP/1.1 305 Use Proxy",
400 => "HTTP/1.1 400 Bad Request", 307 => "HTTP/1.1 307 Temporary Redirect",
401 => "HTTP/1.1 401 Unauthorized", 400 => "HTTP/1.1 400 Bad Request",
402 => "HTTP/1.1 402 Payment Required", 401 => "HTTP/1.1 401 Unauthorized",
403 => "HTTP/1.1 403 Forbidden", 402 => "HTTP/1.1 402 Payment Required",
404 => "HTTP/1.1 404 Not Found", 403 => "HTTP/1.1 403 Forbidden",
405 => "HTTP/1.1 405 Method Not Allowed", 404 => "HTTP/1.1 404 Not Found",
406 => "HTTP/1.1 406 Not Acceptable", 405 => "HTTP/1.1 405 Method Not Allowed",
407 => "HTTP/1.1 407 Proxy Authentication Required", 406 => "HTTP/1.1 406 Not Acceptable",
408 => "HTTP/1.1 408 Request Time-out", 407 => "HTTP/1.1 407 Proxy Authentication Required",
409 => "HTTP/1.1 409 Conflict", 408 => "HTTP/1.1 408 Request Time-out",
410 => "HTTP/1.1 410 Gone", 409 => "HTTP/1.1 409 Conflict",
411 => "HTTP/1.1 411 Length Required", 410 => "HTTP/1.1 410 Gone",
412 => "HTTP/1.1 412 Precondition Failed", 411 => "HTTP/1.1 411 Length Required",
413 => "HTTP/1.1 413 Request Entity Too Large", 412 => "HTTP/1.1 412 Precondition Failed",
414 => "HTTP/1.1 414 Request-URI Too Large", 413 => "HTTP/1.1 413 Request Entity Too Large",
415 => "HTTP/1.1 415 Unsupported Media Type", 414 => "HTTP/1.1 414 Request-URI Too Large",
416 => "HTTP/1.1 416 Requested range not satisfiable", 415 => "HTTP/1.1 415 Unsupported Media Type",
417 => "HTTP/1.1 417 Expectation Failed", 416 => "HTTP/1.1 416 Requested range not satisfiable",
500 => "HTTP/1.1 500 Internal Server Error", 417 => "HTTP/1.1 417 Expectation Failed",
501 => "HTTP/1.1 501 Not Implemented", 500 => "HTTP/1.1 500 Internal Server Error",
502 => "HTTP/1.1 502 Bad Gateway", 501 => "HTTP/1.1 501 Not Implemented",
503 => "HTTP/1.1 503 Service Unavailable", 502 => "HTTP/1.1 502 Bad Gateway",
504 => "HTTP/1.1 504 Gateway Time-out"); 503 => "HTTP/1.1 503 Service Unavailable",
504 => "HTTP/1.1 504 Gateway Time-out"
);
if (isset($codes[$status])) { if (isset($codes[$status])) {
header($codes[$status]); header($codes[$status]);
@ -439,16 +460,11 @@ class Controller extends Object{
* @return unknown * @return unknown
*/ */
function render($action = null, $layout = null, $file = null) { function render($action = null, $layout = null, $file = null) {
$viewClass=$this->view; $viewClass = $this->view;
if ($this->view != 'View' && !class_exists($viewClass)) { if ($this->view != 'View') {
$viewClass = $this->view . 'View'; $viewClass = $this->view . 'View';
loadView($this->view); loadView($this->view);
} }
if ($this->view != 'View') {
$viewClass = $this->view . 'View';
}
$this->beforeRender(); $this->beforeRender();
$this->_viewClass =& new $viewClass($this); $this->_viewClass =& new $viewClass($this);
@ -459,7 +475,7 @@ class Controller extends Object{
} }
} }
} }
$this->autoRender=false; $this->autoRender = false;
return $this->_viewClass->render($action, $layout, $file); return $this->_viewClass->render($action, $layout, $file);
} }
/** /**
@ -472,6 +488,7 @@ class Controller extends Object{
function referer($default = null, $local = false) { function referer($default = null, $local = false) {
$ref = env('HTTP_REFERER'); $ref = env('HTTP_REFERER');
$base = FULL_BASE_URL . $this->webroot; $base = FULL_BASE_URL . $this->webroot;
if ($ref != null && (defined(FULL_BASE_URL) || FULL_BASE_URL)) { if ($ref != null && (defined(FULL_BASE_URL) || FULL_BASE_URL)) {
if (strpos($ref, $base) === 0) { if (strpos($ref, $base) === 0) {
return substr($ref, strlen($base) - 1); return substr($ref, strlen($base) - 1);
@ -545,15 +562,15 @@ class Controller extends Object{
* @param unknown_type $time * @param unknown_type $time
*/ */
function flashOut($message, $url, $pause = 1) { function flashOut($message, $url, $pause = 1) {
$this->autoRender=false; $this->autoRender = false;
$this->autoLayout=false; $this->autoLayout = false;
$this->set('url', $url); $this->set('url', $url);
$this->set('message', $message); $this->set('message', $message);
$this->set('pause', $pause); $this->set('pause', $pause);
$this->set('page_title', $message); $this->set('page_title', $message);
if (file_exists(VIEWS . 'layouts' . DS . 'flash.thtml')) { if (file_exists(VIEWS . 'layouts' . DS . 'flash.thtml')) {
$flash = VIEWS . 'layouts' . DS . 'flash.thtml'; $flash = VIEWS . 'layouts' . DS . 'flash.thtml';
} elseif($flash = fileExistsInPath(LIBS . 'view' . DS . 'templates' . DS . "layouts" . DS . 'flash.thtml')) { } elseif($flash = fileExistsInPath(LIBS . 'view' . DS . 'templates' . DS . "layouts" . DS . 'flash.thtml')) {
} }
$this->render(null, false, $flash); $this->render(null, false, $flash);
@ -587,7 +604,7 @@ class Controller extends Object{
$fieldNames[$tabl['name']]['prompt'] = Inflector::humanize($niceName); $fieldNames[$tabl['name']]['prompt'] = Inflector::humanize($niceName);
$fieldNames[$tabl['name']]['model'] = $fkNames[1]; $fieldNames[$tabl['name']]['model'] = $fkNames[1];
$fieldNames[$tabl['name']]['modelKey'] = $this->{$model}->tableToModel[$fieldNames[$tabl['name']]['table']]; $fieldNames[$tabl['name']]['modelKey'] = $this->{$model}->tableToModel[$fieldNames[$tabl['name']]['table']];
$fieldNames[$tabl['name']]['controller']=Inflector::pluralize($this->{$model}->tableToModel[$fkNames[0]]); $fieldNames[$tabl['name']]['controller'] = Inflector::pluralize($this->{$model}->tableToModel[$fkNames[0]]);
$fieldNames[$tabl['name']]['foreignKey'] = true; $fieldNames[$tabl['name']]['foreignKey'] = true;
} else if('created' != $tabl['name'] && 'updated' != $tabl['name']) { } else if('created' != $tabl['name'] && 'updated' != $tabl['name']) {
@ -597,8 +614,8 @@ class Controller extends Object{
} else if('updated' == $tabl['name']) { } else if('updated' == $tabl['name']) {
$fieldNames[$tabl['name']]['prompt'] = 'Modified'; $fieldNames[$tabl['name']]['prompt'] = 'Modified';
} }
$fieldNames[$tabl['name']]['tagName']=$model . '/' . $tabl['name']; $fieldNames[$tabl['name']]['tagName'] = $model . '/' . $tabl['name'];
$validationFields=$objRegistryModel->validate; $validationFields = $objRegistryModel->validate;
if (isset($validationFields[$tabl['name']])) { if (isset($validationFields[$tabl['name']])) {
if (VALID_NOT_EMPTY == $validationFields[$tabl['name']]) { if (VALID_NOT_EMPTY == $validationFields[$tabl['name']]) {
@ -618,7 +635,7 @@ class Controller extends Object{
switch($type) { switch($type) {
case "text": case "text":
$fieldNames[$tabl['name']]['type']='area'; $fieldNames[$tabl['name']]['type'] = 'area';
break; break;
case "string": case "string":
if (isset($fieldNames[$tabl['name']]['foreignKey'])) { if (isset($fieldNames[$tabl['name']]['foreignKey'])) {
@ -673,7 +690,7 @@ class Controller extends Object{
} }
} }
} }
$fieldNames[$tabl['name']]['selected']=$data[$model][$tabl['name']]; $fieldNames[$tabl['name']]['selected'] = $data[$model][$tabl['name']];
} }
} else { } else {
$fieldNames[$tabl['name']]['type'] = 'input'; $fieldNames[$tabl['name']]['type'] = 'input';
@ -681,7 +698,7 @@ class Controller extends Object{
break; break;
case "enum": case "enum":
$fieldNames[$tabl['name']]['type']='select'; $fieldNames[$tabl['name']]['type'] = 'select';
$fieldNames[$tabl['name']]['options'] = array(); $fieldNames[$tabl['name']]['options'] = array();
$enumValues = split(',', $fieldLength); $enumValues = split(',', $fieldLength);
@ -864,4 +881,5 @@ class Controller extends Object{
return false; return false;
} }
} }
?> ?>

View file

@ -103,7 +103,7 @@ class File extends Object{
* @return boolean Success * @return boolean Success
*/ */
function write($data, $mode = 'w') { function write($data, $mode = 'w') {
$fil = $this->getFullPath(); $file = $this->getFullPath();
if (!($handle = fopen($file, $mode))) { if (!($handle = fopen($file, $mode))) {
print ("[File] Could not open $file with mode $mode!"); print ("[File] Could not open $file with mode $mode!");
return false; return false;

View file

@ -47,139 +47,148 @@ class ConnectionManager extends Object{
* @var class:Connections * @var class:Connections
* @access public * @access public
*/ */
var $config = null; var $config = null;
/** /**
* Holds instances DataSource objects * Holds instances DataSource objects
* *
* @var array * @var array
* @access private * @access private
*/ */
var $_dataSources = array(); var $_dataSources = array();
/** /**
* Contains a list of all file and class names used in Connection settings * Contains a list of all file and class names used in Connection settings
* *
* @var array * @var array
* @access private * @access private
*/ */
var $_connectionsEnum = array(); var $_connectionsEnum = array();
/** /**
* Constructor. * Constructor.
* *
*/ */
function __construct() { function __construct() {
if (class_exists('DATABASE_CONFIG')) { if (class_exists('DATABASE_CONFIG')) {
$this->config = new DATABASE_CONFIG(); $this->config = new DATABASE_CONFIG();
} }
} }
/** /**
* Gets a reference to the ConnectionManger object instance * Gets a reference to the ConnectionManger object instance
* *
* @return object * @return object
*/ */
function &getInstance() { function &getInstance() {
static $instance = array(); static $instance = array();
if (!isset($instance[0]) || !$instance[0]) { if (!isset($instance[0]) || !$instance[0]) {
$instance[0] = &new ConnectionManager(); $instance[0] = &new ConnectionManager();
} }
return $instance[0];
}
return $instance[0];
}
/** /**
* Gets a reference to a DataSource object * Gets a reference to a DataSource object
* *
* @param string $name The name of the DataSource, as defined in app/config/connections * @param string $name The name of the DataSource, as defined in app/config/connections
* @return object * @return object
*/ */
function &getDataSource($name) { function &getDataSource($name) {
$_this=&ConnectionManager::getInstance(); $_this =& ConnectionManager::getInstance();
if (in_array($name, array_keys($_this->_dataSources))) { if (in_array($name, array_keys($_this->_dataSources))) {
return $_this->_dataSources[$name]; return $_this->_dataSources[$name];
} }
$connections=$_this->enumConnectionObjects(); $connections = $_this->enumConnectionObjects();
if (in_array($name, array_keys($connections))) {
$conn = $connections[$name];
$class = $conn['classname'];
$_this->loadDataSource($name);
$_this->_dataSources[$name] =& new $class($_this->config->{$name});
$_this->_dataSources[$name]->configKeyName = $name;
} else {
trigger_error("ConnectionManager::getDataSource - Non-existent data source {$name}", E_USER_ERROR);
return null;
}
if (in_array($name, array_keys($connections))) { return $_this->_dataSources[$name];
$conn =$connections[$name]; }
$class=$conn['classname']; /**
$_this->loadDataSource($name); * Gets a DataSource name from an object reference
$_this->_dataSources[$name] =&new $class($_this->config->{$name}); *
$_this->_dataSources[$name]->configKeyName=$name; * @param object $source
} else { * @return string
trigger_error("ConnectionManager::getDataSource - Non-existent data source {$name}", */
E_USER_ERROR); function getSourceName(&$source) {
return null; $_this =& ConnectionManager::getInstance();
}
return $_this->_dataSources[$name];
}
$names = array_keys($_this->_dataSources);
for ($i = 0; $i < count($names); $i++) {
if ($_this->_dataSources[$names[$i]] === $source) {
return $names[$i];
}
}
return null;
}
/** /**
* Loads the DataSource class for the given connection name * Loads the DataSource class for the given connection name
* *
* @param string $connName The name of the connection, as defined in Connections config * @param string $connName The name of the connection, as defined in Connections config
* @return boolean True on success, false on failure or if the class is already loaded * @return boolean True on success, false on failure or if the class is already loaded
*/ */
function loadDataSource($connName) { function loadDataSource($connName) {
$_this =&ConnectionManager::getInstance();
$connections=$_this->enumConnectionObjects();
$conn =$connections[$connName];
if (class_exists($conn['classname'])) { $_this =& ConnectionManager::getInstance();
return false; $connections = $_this->enumConnectionObjects();
} $conn = $connections[$connName];
if (fileExistsInPath(LIBS . 'model' . DS . $conn['filename'] . '.php')) { if (class_exists($conn['classname'])) {
require (LIBS . 'model' . DS . $conn['filename'] . '.php'); return false;
} else if(file_exists(MODELS . $conn['filename'] . '.php')) { }
require (MODELS . $conn['filename'] . '.php');
} else {
trigger_error('Unable to load DataSource file ' . $conn['filename'] . '.php', E_USER_ERROR);
return null;
}
}
if (fileExistsInPath(LIBS . 'model' . DS . $conn['filename'] . '.php')) {
require (LIBS . 'model' . DS . $conn['filename'] . '.php');
} else if(file_exists(MODELS . $conn['filename'] . '.php')) {
require (MODELS . 'datasources' . DS . $conn['filename'] . '.php');
} else {
trigger_error('Unable to load DataSource file ' . $conn['filename'] . '.php', E_USER_ERROR);
return null;
}
}
/** /**
* Gets a list of class and file names associated with the user-defined DataSource connections * Gets a list of class and file names associated with the user-defined DataSource connections
* *
* @return array An associative array of elements where the key is the connection name * @return array An associative array of elements where the key is the connection name
* (as defined in Connections), and the value is an array with keys 'filename' and 'classname'. * (as defined in Connections), and the value is an array with keys 'filename' and 'classname'.
*/ */
function enumConnectionObjects() { function enumConnectionObjects() {
$_this=&ConnectionManager::getInstance(); $_this =& ConnectionManager::getInstance();
if (!empty($_this->_connectionsEnum)) { if (!empty($_this->_connectionsEnum)) {
return $_this->_connectionsEnum; return $_this->_connectionsEnum;
} }
$connections = get_object_vars($_this->config);
$connections=get_object_vars($_this->config); if ($connections != null) {
if ($connections != null) { foreach($connections as $name => $config) {
foreach($connections as $name => $config) {
if (isset($config['driver']) && $config['driver'] != null && $config['driver'] != '') {
$filename='dbo_' . $config['driver'];
$classname=Inflector::camelize(strtolower('DBO_' . $config['driver']));
} else {
$filename=$config['datasource'] . '_source';
$classname=Inflector::camelize(strtolower($config['datasource'] . '_source'));
}
// TODO 2.0: Change 'dbo' to $config['datasource'] if (!isset($config['datasource'])) {
$filename='dbo' . DS . $filename; $config['datasource'] = 'dbo';
$_this->_connectionsEnum[$name]=array('filename' => $filename,
'classname' => $classname);
} }
return $this->_connectionsEnum; if (isset($config['driver']) && $config['driver'] != null && !empty($config['driver'])) {
} else { $filename = $config['datasource'] . DS . $config['datasource'] . '_' . $config['driver'];
$this->cakeError('missingConnection', array(array('className' => 'ConnectionManager'))); $classname = Inflector::camelize(strtolower($config['datasource'] . '_' . $config['driver']));
} } else {
} $filename = $config['datasource'] . '_source';
$classname = Inflector::camelize(strtolower($config['datasource'] . '_source'));
}
$_this->_connectionsEnum[$name] = array('filename' => $filename, 'classname' => $classname);
}
return $this->_connectionsEnum;
} else {
$this->cakeError('missingConnection', array(array('className' => 'ConnectionManager')));
}
}
} }
?> ?>

View file

@ -222,18 +222,18 @@ class DataSource extends Object{
*/ */
function __cacheDescription($object, $data = null) { function __cacheDescription($object, $data = null) {
if (DEBUG > 0) { if (DEBUG > 0) {
$expires = "+10 seconds"; $expires = "+15 seconds";
} else { } else {
$expires = "+999 days"; $expires = "+999 days";
} }
if ($data !== null) { if ($data !== null) {
$this->__descriptions[$object]=&$data; $this->__descriptions[$object] =& $data;
$cache = serialize($data); $cache = serialize($data);
} else { } else {
$cache = null; $cache = null;
} }
$new = cache('models' . DS . strtolower(get_class($this)) . '_' . $object, $cache, $expires); $new = cache('models' . DS . ConnectionManager::getSourceName($this) . '_' . $object, $cache, $expires);
if ($new != null) { if ($new != null) {
$new = unserialize($new); $new = unserialize($new);
@ -276,10 +276,10 @@ class DataSource extends Object{
if (isset($this->__descriptions[$model->table])) { if (isset($this->__descriptions[$model->table])) {
return $this->__descriptions[$model->table]; return $this->__descriptions[$model->table];
} }
$cache=$this->__cacheDescription($model->table); $cache = $this->__cacheDescription($model->tablePrefix.$model->table);
if ($cache !== null) { if ($cache !== null) {
$this->__descriptions[$model->table]=&$cache; $this->__descriptions[$model->table] =& $cache;
return $cache; return $cache;
} }
return null; return null;
@ -355,11 +355,11 @@ class DataSource extends Object{
* @param unknown_type $assocData * @param unknown_type $assocData
* @param Model $model * @param Model $model
* @param Model $linkModel * @param Model $linkModel
* @param unknown_type $index * @param array $stack
* @return unknown * @return unknown
*/ */
function insertQueryData($query, $data, $association, $assocData, &$model, &$linkModel, $index) { function insertQueryData($query, $data, $association, $assocData, &$model, &$linkModel, $stack) {
$keys=array('{$__cakeID__$}', '{$__cakeForeignKey__$}'); $keys = array('{$__cakeID__$}', '{$__cakeForeignKey__$}');
foreach($keys as $key) { foreach($keys as $key) {
$val = null; $val = null;
@ -367,10 +367,22 @@ class DataSource extends Object{
if (strpos($query, $key) !== false) { if (strpos($query, $key) !== false) {
switch($key) { switch($key) {
case '{$__cakeID__$}': case '{$__cakeID__$}':
if (isset($data[$index][$model->name])) { if (isset($data[$model->name]) || isset($data[$association])) {
if (isset($data[$index][$model->name][$model->primaryKey])) { if (isset($data[$model->name][$model->primaryKey])) {
$val = $data[$index][$model->name][$model->primaryKey]; $val = $data[$model->name][$model->primaryKey];
} else { } elseif (isset($data[$association][$model->primaryKey])) {
$val = $data[$association][$model->primaryKey];
}
} else {
$found = false;
foreach (array_reverse($stack) as $assoc) {
if (isset($data[$assoc]) && isset($data[$assoc][$model->primaryKey])) {
$val = $data[$assoc][$model->primaryKey];
$found = true;
break;
}
}
if (!$found) {
$val = ''; $val = '';
} }
} }
@ -380,10 +392,24 @@ class DataSource extends Object{
foreach($model->$name as $assocName => $assoc) { foreach($model->$name as $assocName => $assoc) {
if ($assocName === $association) { if ($assocName === $association) {
if (isset($assoc['foreignKey'])) { if (isset($assoc['foreignKey'])) {
$foreignKey=$assoc['foreignKey']; $foreignKey = $assoc['foreignKey'];
if (isset($data[$index][$model->name][$foreignKey])) { if (isset($data[$model->name][$foreignKey])) {
$val = $data[$index][$model->name][$foreignKey]; $val = $data[$model->name][$foreignKey];
} elseif (isset($data[$association][$foreignKey])) {
$val = $data[$association][$foreignKey];
} else {
$found = false;
foreach (array_reverse($stack) as $assoc) {
if (isset($data[$assoc]) && isset($data[$assoc][$model->primaryKey])) {
$val = $data[$assoc][$model->primaryKey];
$found = true;
break;
}
}
if (!$found) {
$val = '';
}
} }
} }
break 3; break 3;
@ -442,13 +468,6 @@ class DataSource extends Object{
} }
return $data; return $data;
} }
/**
* To-be-overridden in subclasses.
*
*/
function buildSchemaQuery($schema) {
die ("Implement in DBO");
}
/** /**
* Closes the current datasource. * Closes the current datasource.
* *

View file

@ -129,7 +129,7 @@ class DboSource extends DataSource {
} }
if (DEBUG > 0) { if (DEBUG > 0) {
$expires = "+10 seconds"; $expires = "+30 seconds";
} else { } else {
$expires = "+999 days"; $expires = "+999 days";
} }
@ -137,7 +137,7 @@ class DboSource extends DataSource {
if ($data != null) { if ($data != null) {
$data = serialize($data); $data = serialize($data);
} }
$filename = strtolower(get_class($this)) . '_' . $this->config['database'] . '_list'; $filename = ConnectionManager::getSourceName($this) . '_' . $this->config['database'] . '_list';
$new = cache('models' . DS . $filename, $data, $expires); $new = cache('models' . DS . $filename, $data, $expires);
if ($new != null) { if ($new != null) {
@ -345,7 +345,7 @@ class DboSource extends DataSource {
} else { } else {
$text = 'query'; $text = 'query';
} }
print ("<table border = \"0\">\n<caption>{$this->_queriesCnt} {$text} took {$this->_queriesTime} ms</caption>\n"); print ("<table id=\"cakeSqlLog\" border = \"0\">\n<caption>{$this->_queriesCnt} {$text} took {$this->_queriesTime} ms</caption>\n");
print ("<thead>\n<tr><th>Nr</th><th>Query</th><th>Error</th><th>Affected</th><th>Num. rows</th><th>Took (ms)</th></tr>\n</thead>\n<tbody>\n"); print ("<thead>\n<tr><th>Nr</th><th>Query</th><th>Error</th><th>Affected</th><th>Num. rows</th><th>Took (ms)</th></tr>\n</thead>\n<tbody>\n");
foreach($log as $k => $i) { foreach($log as $k => $i) {
@ -481,7 +481,7 @@ class DboSource extends DataSource {
} }
foreach($model->__associations as $type) { foreach($model->__associations as $type) {
foreach($model->{$type}as $assoc => $assocData) { foreach($model->{$type} as $assoc => $assocData) {
if ($model->recursive > -1) { if ($model->recursive > -1) {
$linkModel =& $model->{$assocData['className']}; $linkModel =& $model->{$assocData['className']};
@ -500,21 +500,21 @@ class DboSource extends DataSource {
} }
} }
// Build final query SQL // Build final query SQL
$query = $this->generateAssociationQuery($model, $null, null, null, null, $queryData, false, $null); $query = $this->generateAssociationQuery($model, $null, null, null, null, $queryData, false, $null);
$resultSet = $this->fetchAll($query, $model->cacheQueries, $model->name); $resultSet = $this->fetchAll($query, $model->cacheQueries, $model->name);
$filtered = $this->__filterResults($resultSet, $model); $filtered = $this->__filterResults($resultSet, $model);
if ($model->recursive > 0) { if ($model->recursive > 0) {
foreach($model->__associations as $type) { foreach($model->__associations as $type) {
foreach($model->{$type}as $assoc => $assocData) { foreach($model->{$type} as $assoc => $assocData) {
$db = null; $db = null;
$linkModel =& $model->{$assocData['className']}; $linkModel =& $model->{$assocData['className']};
if (!in_array($type . '/' . $assoc, $linkedModels)) { if (!in_array($type . '/' . $assoc, $linkedModels)) {
if ($model->useDbConfig == $linkModel->useDbConfig) { if ($model->useDbConfig == $linkModel->useDbConfig) {
$db =& $this; $db =& $this;
} else { } else {
$db =& ConnectionManager::getDataSource($linkModel->useDbConfig); $db =& ConnectionManager::getDataSource($linkModel->useDbConfig);
} }
} elseif($model->recursive > 1 && ($type == 'belongsTo' || $type == 'hasOne')) { } elseif($model->recursive > 1 && ($type == 'belongsTo' || $type == 'hasOne')) {
// Do recursive joins on belongsTo and hasOne relationships // Do recursive joins on belongsTo and hasOne relationships
@ -524,7 +524,8 @@ class DboSource extends DataSource {
} }
if (isset($db) && $db != null) { if (isset($db) && $db != null) {
$db->queryAssociation($model, $linkModel, $type, $assoc, $assocData, $array, true, $resultSet, $model->recursive - 1); $stack = array($assoc);
$db->queryAssociation($model, $linkModel, $type, $assoc, $assocData, $array, true, $resultSet, $model->recursive - 1, $stack);
unset($db); unset($db);
} }
} }
@ -546,26 +547,34 @@ class DboSource extends DataSource {
* @return unknown * @return unknown
*/ */
function __filterResults(&$results, &$model, $filtered = array()) { function __filterResults(&$results, &$model, $filtered = array()) {
$filtering = array(); $filtering = array();
$associations = am($model->belongsTo, $model->hasOne, $model->hasMany, $model->hasAndBelongsToMany); $associations = am($model->belongsTo, $model->hasOne, $model->hasMany, $model->hasAndBelongsToMany);
$count = count($results); $count = count($results);
for($i = 0; $i < $count; $i++) { for($i = 0; $i < $count; $i++) {
if (is_array($results[$i])) { if (is_array($results[$i])) {
$keys = array_keys($results[$i]); $keys = array_keys($results[$i]);
$count2 = count($keys); $count2 = count($keys);
for($j = 0; $j < $count2; $j++) { for($j = 0; $j < $count2; $j++) {
$key = $keys[$j];
if ($model->name != $key && !in_array($key, $filtered)) { $key = $keys[$j];
if (isset($associations[$key])) {
$className = $associations[$key]['className'];
} else {
$className = $key;
}
if ($model->name != $className && !in_array($key, $filtered)) {
if (!in_array($key, $filtering)) { if (!in_array($key, $filtering)) {
$filtering[] = $key; $filtering[] = $key;
} }
if (isset($model->{$key}) && is_object($model->{$key})) { if (isset($model->{$className}) && is_object($model->{$className})) {
$data = $model->{$key}->afterFind(array(array($key => $results[$i][$key]))); $data = $model->{$className}->afterFind(array(array($key => $results[$i][$key])));
} else { } else {
$data = $model->{$associations[$key]['className']}->afterFind(array(array($key => $results[$i][$key]))); $data = $model->{$className}->afterFind(array(array($key => $results[$i][$key])));
} }
$results[$i][$key] = $data[0][$key]; $results[$i][$key] = $data[0][$key];
} }
@ -586,8 +595,9 @@ class DboSource extends DataSource {
* @param unknown_type $external * @param unknown_type $external
* @param unknown_type $resultSet * @param unknown_type $resultSet
* @param integer $recursive Number of levels of association * @param integer $recursive Number of levels of association
* @param array $stack
*/ */
function queryAssociation(&$model, &$linkModel, $type, $association, $assocData, &$queryData, $external = false, &$resultSet, $recursive) { function queryAssociation(&$model, &$linkModel, $type, $association, $assocData, &$queryData, $external = false, &$resultSet, $recursive, $stack) {
$query = $this->generateAssociationQuery($model, $linkModel, $type, $association, $assocData, $queryData, $external, $resultSet); $query = $this->generateAssociationQuery($model, $linkModel, $type, $association, $assocData, $queryData, $external, $resultSet);
if ($query) { if ($query) {
@ -601,20 +611,24 @@ class DboSource extends DataSource {
} }
return null; return null;
} }
$count = count($resultSet);
$count = count($resultSet);
for($i = 0; $i < $count; $i++) { for($i = 0; $i < $count; $i++) {
$row =& $resultSet[$i]; $row =& $resultSet[$i];
$q = $this->insertQueryData($query, $resultSet, $association, $assocData, $model, $linkModel, $i); $q = $this->insertQueryData($query, $resultSet[$i], $association, $assocData, $model, $linkModel, $stack);
$fetch = $this->fetchAll($q, $model->cacheQueries, $model->name); $fetch = $this->fetchAll($q, $model->cacheQueries, $model->name);
if (!empty($fetch) && is_array($fetch)) { if (!empty($fetch) && is_array($fetch)) {
if ($recursive > 0) { if ($recursive > 0) {
foreach($linkModel->__associations as $type1) { foreach($linkModel->__associations as $type1) {
foreach($linkModel->{$type1}as $assoc1 => $assocData1) { foreach($linkModel->{$type1} as $assoc1 => $assocData1) {
$deepModel =& $linkModel->{$assocData1['className']}; $deepModel =& $linkModel->{$assocData1['className']};
if ($deepModel->name != $model->name) { if ($deepModel->name != $model->name) {
$this->queryAssociation($linkModel, $deepModel, $type1, $assoc1, $assocData1, $queryData, true, $fetch, $recursive - 1); $tmpStack = $stack;
$tmpStack[] = $assoc1;
$this->queryAssociation($linkModel, $deepModel, $type1, $assoc1, $assocData1, $queryData, true, $fetch, $recursive - 1, $tmpStack);
} }
} }
} }
@ -637,6 +651,7 @@ class DboSource extends DataSource {
* @param unknown_type $type * @param unknown_type $type
*/ */
function __mergeAssociation(&$data, $merge, $association, $type) { function __mergeAssociation(&$data, $merge, $association, $type) {
if (isset($merge[0]) && !isset($merge[0][$association])) { if (isset($merge[0]) && !isset($merge[0][$association])) {
$association = Inflector::pluralize($association); $association = Inflector::pluralize($association);
} }
@ -711,7 +726,7 @@ class DboSource extends DataSource {
$sql = $queryData['selfJoin'][0]; $sql = $queryData['selfJoin'][0];
$sql .= ' ' . join(' ', $queryData['joins']); $sql .= ' ' . join(' ', $queryData['joins']);
$sql .= $this->conditions($queryData['conditions']) . ' ' . $this->order($queryData['order']); $sql .= $this->conditions($queryData['conditions']) . ' ' . $this->order($queryData['order']);
$sql .= ' ' . $this->limit($queryData['limit']); $sql .= ' ' . $this->limit($queryData['limit'], $queryData['offset']);
$result = preg_replace('/FROM/', $replace, $sql); $result = preg_replace('/FROM/', $replace, $sql);
return $result; return $result;
} }
@ -730,8 +745,11 @@ class DboSource extends DataSource {
* @return unknown * @return unknown
*/ */
function generateAssociationQuery(&$model, &$linkModel, $type, $association = null, $assocData = array(), &$queryData, $external = false, &$resultSet) { function generateAssociationQuery(&$model, &$linkModel, $type, $association = null, $assocData = array(), &$queryData, $external = false, &$resultSet) {
$this->__scrubQueryData($queryData); $this->__scrubQueryData($queryData);
$this->__scrubQueryData($assocData);
$joinedOnSelf = false; $joinedOnSelf = false;
if ($linkModel == null) { if ($linkModel == null) {
if (array_key_exists('selfJoin', $queryData)) { if (array_key_exists('selfJoin', $queryData)) {
return $this->generateSelfAssociationQuery($model, $linkModel, $type, $association, $assocData, $queryData, $external, $resultSet); return $this->generateSelfAssociationQuery($model, $linkModel, $type, $association, $assocData, $queryData, $external, $resultSet);
@ -746,7 +764,7 @@ class DboSource extends DataSource {
$sql = 'SELECT '; $sql = 'SELECT ';
if ($this->goofyLimit) { if ($this->goofyLimit) {
$sql .= $this->limit($queryData['limit']); $sql .= $this->limit($queryData['limit'], $queryData['offset']);
} }
$sql .= ' ' . join(', ', $this->fields($model, $model->name, $queryData['fields'])) . $joinFields . ' FROM '; $sql .= ' ' . join(', ', $this->fields($model, $model->name, $queryData['fields'])) . $joinFields . ' FROM ';
$sql .= $this->fullTableName($model) . ' ' . $this->alias; $sql .= $this->fullTableName($model) . ' ' . $this->alias;
@ -754,7 +772,7 @@ class DboSource extends DataSource {
$sql .= $this->conditions($queryData['conditions']) . ' ' . $this->order($queryData['order']); $sql .= $this->conditions($queryData['conditions']) . ' ' . $this->order($queryData['order']);
if (!$this->goofyLimit) { if (!$this->goofyLimit) {
$sql .= ' ' . $this->limit($queryData['limit']); $sql .= ' ' . $this->limit($queryData['limit'], $queryData['offset']);
} }
} }
return $sql; return $sql;
@ -779,7 +797,7 @@ class DboSource extends DataSource {
$limit = ''; $limit = '';
if (isset($queryData['limit']) && !empty($queryData['limit'])) { if (isset($queryData['limit']) && !empty($queryData['limit'])) {
$limit = $this->limit($queryData['limit']); $limit = $this->limit($queryData['limit'], $queryData['offset']);
} }
$sql = 'SELECT '; $sql = 'SELECT ';
@ -851,7 +869,7 @@ class DboSource extends DataSource {
if ($external) { if ($external) {
$limit = ''; $limit = '';
if (isset($assocData['limit'])) { if (isset($assocData['limit'])) {
$limit = $this->limit($assocData['limit']); $limit = $this->limit($assocData['limit'], $queryData['offset']);
} }
if (!isset($assocData['fields'])) { if (!isset($assocData['fields'])) {
@ -905,9 +923,18 @@ class DboSource extends DataSource {
if (isset($assocData['conditions']) && !empty($assocData['conditions'])) { if (isset($assocData['conditions']) && !empty($assocData['conditions'])) {
if (is_array($queryData['conditions'])) { if (is_array($queryData['conditions'])) {
$queryData['conditions'] = array_merge($assocData['conditions'], $queryData['conditions']); $queryData['conditions'] = array_merge((array)$assocData['conditions'], $queryData['conditions']);
} else { } else {
$queryData['conditions'] = $assocData['conditions']; if (!empty($queryData['conditions'])){
$queryData['conditions'] = array($queryData['conditions']);
if (is_array($assocData['conditions'])){
array_merge($queryData['conditions'],$assocData['conditions']);
} else {
$queryData['conditions'][] = $assocData['conditions'];
}
} else {
$queryData['conditions'] = $assocData['conditions'];
}
} }
} }
@ -925,7 +952,7 @@ class DboSource extends DataSource {
$limit = ''; $limit = '';
if (isset($assocData['limit'])) { if (isset($assocData['limit'])) {
$limit = $this->limit($assocData['limit']); $limit = $this->limit($assocData['limit'], $queryData['offset']);
} }
$conditions = $assocData['conditions']; $conditions = $assocData['conditions'];
@ -966,7 +993,7 @@ class DboSource extends DataSource {
$limit = ''; $limit = '';
if (isset($assocData['limit'])) { if (isset($assocData['limit'])) {
$limit = $this->limit($assocData['limit']); $limit = $this->limit($assocData['limit'], $queryData['offset']);
} }
$sql = 'SELECT '; $sql = 'SELECT ';
@ -1005,8 +1032,13 @@ class DboSource extends DataSource {
function update(&$model, $fields = array(), $values = array()) { function update(&$model, $fields = array(), $values = array()) {
$updates = array(); $updates = array();
$combined = array_combine($fields, $values); $combined = array_combine($fields, $values);
foreach($combined as $field => $value) { foreach($combined as $field => $value) {
$updates[] = $this->name($field) . ' = ' . $this->value($value, $model->getColumnType($field)); if ($value === null) {
$updates[] = $this->name($field) . ' = NULL';
} else {
$updates[] = $this->name($field) . ' = ' . $this->value($value, $model->getColumnType($field));
}
} }
$sql = 'UPDATE ' . $this->fullTableName($model); $sql = 'UPDATE ' . $this->fullTableName($model);
$sql .= ' SET ' . join(',', $updates); $sql .= ' SET ' . join(',', $updates);
@ -1091,6 +1123,10 @@ class DboSource extends DataSource {
if (!isset($data['limit'])) { if (!isset($data['limit'])) {
$data['limit'] = ''; $data['limit'] = '';
} }
if (!isset($data['offset'])) {
$data['offset'] = null;
}
} }
/** /**
* Generates the fields list of an SQL query. * Generates the fields list of an SQL query.
@ -1193,30 +1229,34 @@ class DboSource extends DataSource {
} }
function conditionKeysToString($conditions) { function conditionKeysToString($conditions) {
$data = null;
$out = array(); $out = array();
$operator = null;
$bool = array('and', 'or', 'and not', 'or not', 'xor', '||', '&&'); $bool = array('and', 'or', 'and not', 'or not', 'xor', '||', '&&');
foreach($conditions as $key => $value) { foreach($conditions as $key => $value) {
if (in_array(strtolower(trim($key)), $bool)) { if (in_array(strtolower(trim($key)), $bool)) {
$out[] = '(' . join(') ' . $key . ' (', $this->conditionKeysToString($value)) . ')'; $out[] = '(' . join(') ' . $key . ' (', $this->conditionKeysToString($value)) . ')';
} else { } else {
if (is_array($value)) { if (is_array($value) && !empty($value)) {
$data = $this->name($key) . ' IN (';
foreach($value as $valElement) { $keys = array_keys($value);
$data .= $this->value($valElement) . ', '; if ($keys[0] === 0) {
$data = $this->name($key) . ' IN (';
foreach($value as $valElement) {
$data .= $this->value($valElement) . ', ';
}
$data[strlen($data) - 2] = ')';
} else {
$out[] = '(' . join(') AND (', $this->conditionKeysToString($value)) . ')';
} }
$data[strlen($data) - 2] = ')';
} elseif(is_numeric($key)) { } elseif(is_numeric($key)) {
$data = ' ' . $value; $data = ' ' . $value;
} elseif($value === null) { } elseif($value === null) {
$data = $this->name($key) . ' = NULL'; $data = $this->name($key) . ' = NULL';
} elseif($value === '') { } elseif($value === '') {
$data = $this->name($key) . " = ''"; $data = $this->name($key) . " = ''";
} elseif(preg_match( } elseif(preg_match('/^([a-z]*\\([a-z0-9]*\\)\\x20?|(?:like\\x20)|(?:or\\x20)|(?:between\\x20)|(?:regexp\\x20)|[<> = !]{1,3}\\x20?)?(.*)/i', $value, $match)) {
'/^([a-z]*\\([a-z0-9]*\\)\\x20?|(?:like\\x20)|(?:or\\x20)|(?:between\\x20)|(?:regexp\\x20)|[<> = !]{1,3}\\x20?)?(.*)/i', $value, $match)) {
if (preg_match('/(\\x20[\\w]*\\x20)/', $key, $regs)) { if (preg_match('/(\\x20[\\w]*\\x20)/', $key, $regs)) {
$clause = $regs['1']; $clause = $regs['1'];
$key = preg_replace('/' . $regs['1'] . '/', '', $key); $key = preg_replace('/' . $regs['1'] . '/', '', $key);
@ -1228,7 +1268,7 @@ class DboSource extends DataSource {
if (strpos($match['2'], '-!') === 0) { if (strpos($match['2'], '-!') === 0) {
$match['2'] = str_replace('-!', '', $match['2']); $match['2'] = str_replace('-!', '', $match['2']);
$data = $this->name($key) . ' ' . $match['1'] . ' ' . $match['2']; $data = $this->name($key) . ' ' . $match['1'] . ' ' . $match['2'];
} else { } else {
if ($match['2'] != '' && !is_numeric($match['2'])) { if ($match['2'] != '' && !is_numeric($match['2'])) {
$match['2'] = $this->value($match['2']); $match['2'] = $this->value($match['2']);
@ -1238,7 +1278,9 @@ class DboSource extends DataSource {
} }
} }
$out[] = $operator . $data; if ($data != null) {
$out[] = $data;
}
} }
} }
return $out; return $out;
@ -1370,8 +1412,14 @@ class DboSource extends DataSource {
if ($this->fullDebug) { if ($this->fullDebug) {
$this->showLog(); $this->showLog();
} }
$this->_conn = NULL; $this->disconnect();
$this->connected = false; }
/**
* To-be-overridden in subclasses.
*
*/
function buildSchemaQuery($schema) {
die ("Implement in DBO");
} }
/** /**
* Destructor. Closes connection to the database. * Destructor. Closes connection to the database.
@ -1392,7 +1440,8 @@ class DboSource extends DataSource {
* @return boolean True if the table has a matching record, else false * @return boolean True if the table has a matching record, else false
*/ */
function hasAny($model, $sql) { function hasAny($model, $sql) {
$out = $this->one("SELECT COUNT(*) " . $this->alias . "count FROM " . $this->fullTableName($model) . ($sql ? ' ' . $sql : '')); $sql = $this->conditions($sql);
$out = $this->one("SELECT COUNT(*) " . $this->alias . "count FROM " . $this->fullTableName($model) . ' ' . ($sql ? ' ' . $sql : 'WHERE 1 = 1'));
if (is_array($out)) { if (is_array($out)) {
return $out[0]['count']; return $out[0]['count'];

View file

@ -0,0 +1,452 @@
<?php
/* SVN FILE: $Id$ */
/**
* MySQLi layer for DBO
*
* Long description for file
*
* 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.libs.model.dbo
* @since CakePHP v 1.1.4.2974
* @version $Revision$
* @modifiedby $LastChangedBy$
* @lastmodified $Date$
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
*/
/**
* Include DBO.
*/
uses('model'.DS.'datasources'.DS.'dbo_source');
/**
* Short description for class.
*
* Long description for class
*
* @package cake
* @subpackage cake.cake.libs.model.dbo
*/
class DboMysqli extends DboSource {
/**
* Enter description here...
*
* @var unknown_type
*/
var $description = "Mysqli DBO Driver";
/**
* Enter description here...
*
* @var unknown_type
*/
var $startQuote = "`";
/**
* Enter description here...
*
* @var unknown_type
*/
var $endQuote = "`";
/**
* Base configuration settings for Mysqli driver
*
* @var array
*/
var $_baseConfig = array('persistent' => true,
'host' => 'localhost',
'login' => 'root',
'password' => '',
'database' => 'cake',
'port' => '3306',
'connect' => 'mysqli_pconnect');
/**
* Mysqli column definition
*
* @var array
*/
var $columns = array('primary_key' => array('name' => 'int(11) DEFAULT NULL auto_increment'),
'string' => array('name' => 'varchar', 'limit' => '255'),
'text' => array('name' => 'text'),
'integer' => array('name' => 'int', 'limit' => '11', 'formatter' => 'intval'),
'float' => array('name' => 'float', 'formatter' => 'floatval'),
'datetime' => array('name' => 'datetime', 'format' => 'Y-m-d H:i:s', 'formatter' => 'date'),
'timestamp' => array('name' => 'timestamp', 'format' => 'Y-m-d H:i:s', 'formatter' => 'date'),
'time' => array('name' => 'time', 'format' => 'H:i:s', 'formatter' => 'date'),
'date' => array('name' => 'date', 'format' => 'Y-m-d', 'formatter' => 'date'),
'binary' => array('name' => 'blob'),
'boolean' => array('name' => 'tinyint', 'limit' => '1'));
/**
* Connects to the database using options in the given configuration array.
*
* @return boolean True if the database could be connected, else false
*/
function connect() {
$config = $this->config;
$connect = $config['connect'];
$this->connected = false;
if (!$config['persistent']) {
$this->connection = mysqli_connect($config['host'], $config['login'], $config['password'], true);
} else {
$this->connection = $connect($config['host'], $config['login'], $config['password']);
}
if (mysqli_select_db($this->connection, $config['database'])) {
$this->connected = true;
}
return $this->connected;
}
/**
* Disconnects from database.
*
* @return boolean True if the database could be disconnected, else false
*/
function disconnect() {
$this->connected = !@mysqli_close($this->connection);
return !$this->connected;
}
/**
* Executes given SQL statement.
*
* @param string $sql SQL statement
* @return resource Result resource identifier
* @access protected
*/
function _execute($sql) {
return mysqli_query($this->connection, $sql);
}
/**
* Returns a row from given resultset as an array .
*
* @param bool $assoc Associative array only, or both?
* @return array The fetched row as an array
*/
function fetchRow($assoc = false) {
if(is_resource($this->_result)) {
$this->resultSet($this->_result);
$resultRow = $this->fetchResult();
return $resultRow;
} else {
return null;
}
}
/**
* Returns an array of sources (tables) in the database.
*
* @return array Array of tablenames in the database
*/
function listSources() {
$cache = parent::listSources();
if ($cache != null) {
return $cache;
}
$result = $this->_execute('SHOW TABLES FROM ' . $this->config['database'] . ';');
if (!$result) {
return array();
} else {
$tables = array();
while ($line = mysqli_fetch_array($result)) {
$tables[] = $line[0];
}
parent::listSources($tables);
return $tables;
}
}
/**
* Returns an array of the fields in given table name.
*
* @param string $tableName Name of database table to inspect
* @return array Fields in table. Keys are name and type
*/
function describe(&$model) {
$cache = parent::describe($model);
if ($cache != null) {
return $cache;
}
$fields = false;
$cols = $this->_execute('DESCRIBE ' . $this->fullTableName($model));
foreach ($cols as $column) {
$colKey = array_keys($column);
if (isset($column[$colKey[0]]) && !isset($column[0])) {
$column[0] = $column[$colKey[0]];
}
if (isset($column[0])) {
$fields[] = array('name' => $column[0]['Field'], 'type' => $this->column($column[0]['Type']), 'null' => $column[0]['Null']);
}
}
$this->__cacheDescription($model->tablePrefix.$model->table, $fields);
return $fields;
}
/**
* Returns a quoted name of $data for use in an SQL statement.
*
* @param string $data Name (table.field) to be prepared for use in an SQL statement
* @return string Quoted for MySQL
*/
function name($data) {
if ($data == '*') {
return '*';
}
$pos = strpos($data, '`');
if ($pos === false) {
$data = '`'. str_replace('.', '`.`', $data) .'`';
}
return $data;
}
/**
* Returns a quoted and escaped string of $data for use in an SQL statement.
*
* @param string $data String to be prepared for use in an SQL statement
* @param string $column The column into which this data will be inserted
* @param boolean $safe Whether or not numeric data should be handled automagically if no column data is provided
* @return string Quoted and escaped data
*/
function value($data, $column = null, $safe = false) {
$parent = parent::value($data, $column, $safe);
if ($parent != null) {
return $parent;
}
if ($data === null) {
return 'NULL';
}
if($data == '') {
return "''";
}
switch ($column) {
case 'boolean':
$data = $this->boolean((bool)$data);
break;
default:
if (ini_get('magic_quotes_gpc') == 1) {
$data = stripslashes($data);
}
$data = mysqli_real_escape_string($this->connection, $data);
break;
}
return "'" . $data . "'";
}
/**
* Begin a transaction
*
* @param unknown_type $model
* @return boolean True on success, false on fail
* (i.e. if the database/model does not support transactions).
*/
function begin(&$model) {
if (parent::begin($model)) {
if ($this->execute('START TRANSACTION')) {
$this->__transactionStarted = true;
return true;
}
}
return false;
}
/**
* Commit a transaction
*
* @param unknown_type $model
* @return boolean True on success, false on fail
* (i.e. if the database/model does not support transactions,
* or a transaction has not started).
*/
function commit(&$model) {
if (parent::commit($model)) {
$this->__transactionStarted;
return $this->execute('COMMIT');
}
return false;
}
/**
* Rollback a transaction
*
* @param unknown_type $model
* @return boolean True on success, false on fail
* (i.e. if the database/model does not support transactions,
* or a transaction has not started).
*/
function rollback(&$model) {
if (parent::rollback($model)) {
return $this->execute('ROLLBACK');
}
return false;
}
/**
* Returns a formatted error message from previous database operation.
*
* @return string Error message with error number
*/
function lastError() {
if (mysqli_errno($this->connection)) {
return mysqli_errno($this->connection).': '.mysqli_error($this->connection);
}
return null;
}
/**
* Returns number of affected rows in previous database operation. If no previous operation exists,
* this returns false.
*
* @return int Number of affected rows
*/
function lastAffected() {
if ($this->_result) {
return mysqli_affected_rows($this->connection);
}
return null;
}
/**
* Returns number of rows in previous resultset. If no previous resultset exists,
* this returns false.
*
* @return int Number of rows in resultset
*/
function lastNumRows() {
if ($this->_result and is_resource($this->_result)) {
return @mysqli_num_rows($this->_result);
}
return null;
}
/**
* Returns the ID generated from the previous INSERT operation.
*
* @param unknown_type $source
* @return in
*/
function lastInsertId($source = null) {
$id = mysqli_insert_id($this->connection);
if ($id) {
return $id;
}
$data = $this->fetchAll('SELECT LAST_INSERT_ID() as id From '.$source);
if ($data && isset($data[0]['id'])) {
return $data[0]['id'];
}
}
/**
* Converts database-layer column types to basic types
*
* @param string $real Real database-layer column type (i.e. "varchar(255)")
* @return string Abstract column type (i.e. "string")
*/
function column($real) {
if (is_array($real)) {
$col = $real['name'];
if (isset($real['limit']))
{
$col .= '('.$real['limit'].')';
}
return $col;
}
$col = r(')', '', $real);
$limit = null;
@list($col, $limit) = explode('(', $col);
if (in_array($col, array('date', 'time', 'datetime', 'timestamp'))) {
return $col;
}
if ($col == 'tinyint' && $limit == '1') {
return 'boolean';
}
if (strpos($col, 'int') !== false) {
return 'integer';
}
if (strpos($col, 'char') !== false || $col == 'tinytext') {
return 'string';
}
if (strpos($col, 'text') !== false) {
return 'text';
}
if (strpos($col, 'blob') !== false) {
return 'binary';
}
if (in_array($col, array('float', 'double', 'decimal'))) {
return 'float';
}
if (strpos($col, 'enum') !== false) {
return "enum($limit)";
}
return 'text';
}
/**
* Enter description here...
*
* @param unknown_type $results
*/
function resultSet(&$results) {
$this->results =& $results;
$this->map = array();
$num_fields = mysqli_num_fields($results);
$index = 0;
$j = 0;
while ($j < $num_fields) {
$column = mysqli_fetch_field($results,$j);
if (!empty($column->table)) {
$this->map[$index++] = array($column->table, $column->name);
} else {
$this->map[$index++] = array(0, $column->name);
}
$j++;
}
}
/**
* Fetches the next row from the current result set
*
* @return unknown
*/
function fetchResult() {
if ($row = mysqli_fetch_row($this->results)) {
$resultRow = array();
$i = 0;
foreach ($row as $index => $field) {
list($table, $column) = $this->map[$index];
$resultRow[$table][$column] = $row[$index];
$i++;
}
return $resultRow;
} else {
return false;
}
}
/**
* Enter description here...
*
* @param unknown_type $schema
* @return unknown
*/
function buildSchemaQuery($schema) {
$search = array('{AUTOINCREMENT}', '{PRIMARY}', '{UNSIGNED}', '{FULLTEXT}',
'{FULLTEXT_MYSQL}', '{BOOLEAN}', '{UTF_8}');
$replace = array('int(11) not null auto_increment', 'primary key', 'unsigned',
'FULLTEXT', 'FULLTEXT', 'enum (\'true\', \'false\') NOT NULL default \'true\'',
'/*!40100 CHARACTER SET utf8 COLLATE utf8_unicode_ci */');
$query = trim(r($search, $replace, $schema));
return $query;
}
}
?>

View file

@ -48,31 +48,33 @@ class DboOdbc extends DboSource{
* *
* @var string * @var string
*/ */
var $description = "ODBC DBO Driver"; var $description = "ODBC DBO Driver";
/** /**
* Table/column starting quote * Table/column starting quote
* *
* @var string * @var string
*/ */
var $startQuote = "`"; var $startQuote = "`";
/** /**
* Table/column end quote * Table/column end quote
* *
* @var string * @var string
*/ */
var $endQuote = "`"; var $endQuote = "`";
/** /**
* Driver base configuration * Driver base configuration
* *
* @var array * @var array
*/ */
var $_baseConfig = array('persistent' => true, var $_baseConfig = array('persistent' => true,
'login' => 'root', 'login' => 'root',
'password' => '', 'password' => '',
'database' => 'cake'); 'database' => 'cake',
'connect' => 'odbc_pconnect'
);
/** /**
* Enter description here... * Enter description here...
@ -80,47 +82,47 @@ class DboOdbc extends DboSource{
* @var unknown_type * @var unknown_type
*/ */
var $columns = array(); var $columns = array();
// var $columns = array('primary_key' => array('name' => 'int(11) DEFAULT NULL auto_increment'), // var $columns = array('primary_key' => array('name' => 'int(11) DEFAULT NULL auto_increment'),
// 'string' => array('name' => 'varchar', 'limit' => '255'), // 'string' => array('name' => 'varchar', 'limit' => '255'),
// 'text' => array('name' => 'text'), // 'text' => array('name' => 'text'),
// 'integer' => array('name' => 'int', 'limit' => '11'), // 'integer' => array('name' => 'int', 'limit' => '11'),
// 'float' => array('name' => 'float'), // 'float' => array('name' => 'float'),
// 'datetime' => array('name' => 'datetime', 'format' => 'Y-m-d h:i:s', 'formatter' => 'date'), // 'datetime' => array('name' => 'datetime', 'format' => 'Y-m-d h:i:s', 'formatter' => 'date'),
// 'timestamp' => array('name' => 'datetime', 'format' => 'Y-m-d h:i:s', 'formatter' => 'date'), // 'timestamp' => array('name' => 'datetime', 'format' => 'Y-m-d h:i:s', 'formatter' => 'date'),
// 'time' => array('name' => 'time', 'format' => 'h:i:s', 'formatter' => 'date'), // 'time' => array('name' => 'time', 'format' => 'h:i:s', 'formatter' => 'date'),
// 'date' => array('name' => 'date', 'format' => 'Y-m-d', 'formatter' => 'date'), // 'date' => array('name' => 'date', 'format' => 'Y-m-d', 'formatter' => 'date'),
// 'binary' => array('name' => 'blob'), // 'binary' => array('name' => 'blob'),
// 'boolean' => array('name' => 'tinyint', 'limit' => '1')); // 'boolean' => array('name' => 'tinyint', 'limit' => '1'));
/** /**
* Connects to the database using options in the given configuration array. * Connects to the database using options in the given configuration array.
* *
* @return boolean True if the database could be connected, else false * @return boolean True if the database could be connected, else false
*/ */
function connect() { function connect() {
$config =$this->config; $config = $this->config;
$connect =$config['connect']; $connect = $config['connect'];
$this->connected =false; $this->connected = false;
$this->connection=$connect($config['database'], $config['login'], $config['password']); $this->connection = $connect($config['database'], $config['login'], $config['password']);
if ($this->connection) { if ($this->connection) {
$this->connected = true; $this->connected = true;
} }
return $this->connected; return $this->connected;
} }
/** /**
* Disconnects from database. * Disconnects from database.
* *
* @return boolean True if the database could be disconnected, else false * @return boolean True if the database could be disconnected, else false
*/ */
function disconnect() { function disconnect() {
return@odbc_close($this->connection); return@odbc_close($this->connection);
} }
/** /**
* Executes given SQL statement. * Executes given SQL statement.
@ -129,9 +131,9 @@ class DboOdbc extends DboSource{
* @return resource Result resource identifier * @return resource Result resource identifier
* @access protected * @access protected
*/ */
function _execute($sql) { function _execute($sql) {
return odbc_exec($this->connection, $sql); return odbc_exec($this->connection, $sql);
} }
/** /**
* Returns a row from given resultset as an array . * Returns a row from given resultset as an array .
@ -139,87 +141,98 @@ class DboOdbc extends DboSource{
* @param bool $assoc Associative array only, or both? * @param bool $assoc Associative array only, or both?
* @return array The fetched row as an array * @return array The fetched row as an array
*/ */
function fetchRow($assoc = false) { function fetchRow($assoc = false) {
if (is_resource($this->_result)) { if (is_resource($this->_result)) {
$this->resultSet($this->_result); $this->resultSet($this->_result);
$resultRow=$this->fetchResult(); $resultRow = $this->fetchResult();
return $resultRow; return $resultRow;
} else { } else {
return null; return null;
} }
} }
/** /**
* Returns an array of sources (tables) in the database. * Returns an array of sources (tables) in the database.
* *
* @return array Array of tablenames in the database * @return array Array of tablenames in the database
*/ */
function listSources() { function listSources() {
$result=odbc_tables($this->connection);
if (!$result) { $cache = parent::listSources();
return array(); if ($cache != null) {
} else { return $cache;
$tables=array(); }
while($line = odbc_fetch_array($result)) { /*$result = odbc_tables($this->connection);
$tables[] = strtolower($line['TABLE_NAME']); if (function_exists('odbc_fetch_row')) {
} echo 'GOOD';
} else {
echo 'BAD';
}*/
return $tables; $result = odbc_tables($this->connection);
}
}
$tables = array();
while (odbc_fetch_row($result)) {
array_push($tables, odbc_result($result, "TABLE_NAME"));
}
foreach( $tables as $t ) {
echo "$t\n";
}
parent::listSources($tables);
return $tables;
}
/** /**
* Returns an array of the fields in given table name. * Returns an array of the fields in given table name.
* *
* @param Model $model Model object to describe * @param Model $model Model object to describe
* @return array Fields in table. Keys are name and type * @return array Fields in table. Keys are name and type
*/ */
function &describe(&$model) { function &describe(&$model) {
$cache=parent::describe($model); $cache=parent::describe($model);
if ($cache != null) { if ($cache != null) {
return $cache; return $cache;
} }
$fields=array(); $fields=array();
$sql='SELECT * FROM ' . $this->fullTableName($model) . ' LIMIT 1'; $sql='SELECT * FROM ' . $this->fullTableName($model) . ' LIMIT 1';
$result=odbc_exec($this->connection, $sql); $result=odbc_exec($this->connection, $sql);
$count=odbc_num_fields($result); $count=odbc_num_fields($result);
for($i = 1; $i <= $count; $i++) { for($i = 1; $i <= $count; $i++) {
$cols[$i - 1] = odbc_field_name($result, $i); $cols[$i - 1] = odbc_field_name($result, $i);
} }
foreach($cols as $column) { foreach($cols as $column) {
$type $type
= odbc_field_type( = odbc_field_type(
odbc_exec($this->connection, "SELECT " . $column . " FROM " . $this->fullTableName($model)), odbc_exec($this->connection, "SELECT " . $column . " FROM " . $this->fullTableName($model)),
1); 1);
array_push($fields, array('name' => $column, array_push($fields, array('name' => $column,
'type' => $type)); 'type' => $type));
} }
$this->__cacheDescription($model->tablePrefix . $model->table, $fields); $this->__cacheDescription($model->tablePrefix . $model->table, $fields);
return $fields; return $fields;
} }
function name($data) { function name($data) {
if ($data == '*') { if ($data == '*') {
return '*'; return '*';
} }
$pos=strpos($data, '`'); $pos=strpos($data, '`');
if ($pos === false) { if ($pos === false) {
$data = '' . str_replace('.', '.', $data) . ''; $data = '' . str_replace('.', '.', $data) . '';
//$data = '`'. str_replace('.', '`.`', $data) .'`'; //$data = '`'. str_replace('.', '`.`', $data) .'`';
} }
return $data; return $data;
} }
/** /**
* Returns a quoted and escaped string of $data for use in an SQL statement. * Returns a quoted and escaped string of $data for use in an SQL statement.
@ -229,30 +242,30 @@ class DboOdbc extends DboSource{
* @return string Quoted and escaped * @return string Quoted and escaped
* @todo Add logic that formats/escapes data based on column type * @todo Add logic that formats/escapes data based on column type
*/ */
function value($data, $column = null) { function value($data, $column = null) {
$parent=parent::value($data, $column); $parent=parent::value($data, $column);
if ($parent != null) { if ($parent != null) {
return $parent; return $parent;
} }
if ($data === null) { if ($data === null) {
return 'NULL'; return 'NULL';
} }
if (ini_get('magic_quotes_gpc') == 1) { if (ini_get('magic_quotes_gpc') == 1) {
$data = stripslashes($data); $data = stripslashes($data);
} }
// $data = mysql_real_escape_string($data, $this->connection); // $data = mysql_real_escape_string($data, $this->connection);
if (!is_numeric($data)) { if (!is_numeric($data)) {
$return = "'" . $data . "'"; $return = "'" . $data . "'";
} else { } else {
$return = $data; $return = $data;
} }
return $return; return $return;
} }
/** /**
* Not sure about this one, MySQL needs it but does ODBC? Safer just to leave it * Not sure about this one, MySQL needs it but does ODBC? Safer just to leave it
@ -261,21 +274,21 @@ class DboOdbc extends DboSource{
* @param mixed $data Value to be translated * @param mixed $data Value to be translated
* @return mixed Converted boolean value * @return mixed Converted boolean value
*/ */
function boolean($data) { function boolean($data) {
if ($data === true || $data === false) { if ($data === true || $data === false) {
if ($data === true) { if ($data === true) {
return 1; return 1;
} }
return 0; return 0;
} else { } else {
if (intval($data !== 0)) { if (intval($data !== 0)) {
return true; return true;
} }
return false; return false;
} }
} }
/** /**
* Begin a transaction * Begin a transaction
@ -284,16 +297,16 @@ class DboOdbc extends DboSource{
* @return boolean True on success, false on fail * @return boolean True on success, false on fail
* (i.e. if the database/model does not support transactions). * (i.e. if the database/model does not support transactions).
*/ */
function begin(&$model) { function begin(&$model) {
if (parent::begin($model)) { if (parent::begin($model)) {
if (odbc_autocommit($this->connection, false)) { if (odbc_autocommit($this->connection, false)) {
$this->__transactionStarted=true; $this->__transactionStarted=true;
return true; return true;
} }
} }
return false; return false;
} }
/** /**
* Commit a transaction * Commit a transaction
@ -303,16 +316,16 @@ class DboOdbc extends DboSource{
* (i.e. if the database/model does not support transactions, * (i.e. if the database/model does not support transactions,
* or a transaction has not started). * or a transaction has not started).
*/ */
function commit(&$model) { function commit(&$model) {
if (parent::commit($model)) { if (parent::commit($model)) {
if (odbc_commit($this->connection)) { if (odbc_commit($this->connection)) {
$this->__transactionStarted=false; $this->__transactionStarted=false;
return true; return true;
} }
} }
return false; return false;
} }
/** /**
* Rollback a transaction * Rollback a transaction
@ -322,27 +335,27 @@ class DboOdbc extends DboSource{
* (i.e. if the database/model does not support transactions, * (i.e. if the database/model does not support transactions,
* or a transaction has not started). * or a transaction has not started).
*/ */
function rollback(&$model) { function rollback(&$model) {
if (parent::rollback($model)) { if (parent::rollback($model)) {
$this->__transactionStarted=false; $this->__transactionStarted=false;
return odbc_rollback($this->connection); return odbc_rollback($this->connection);
} }
return false; return false;
} }
/** /**
* Returns a formatted error message from previous database operation. * Returns a formatted error message from previous database operation.
* *
* @return string Error message with error number * @return string Error message with error number
*/ */
function lastError() { function lastError() {
if (odbc_error($this->connection)) { if (odbc_error($this->connection)) {
return odbc_error($this->connection) . ': ' . odbc_errormsg($this->connection); return odbc_error($this->connection) . ': ' . odbc_errormsg($this->connection);
} }
return null; return null;
} }
/** /**
* Returns number of affected rows in previous database operation. If no previous operation exists, * Returns number of affected rows in previous database operation. If no previous operation exists,
@ -350,13 +363,13 @@ class DboOdbc extends DboSource{
* *
* @return int Number of affected rows * @return int Number of affected rows
*/ */
function lastAffected() { function lastAffected() {
if ($this->_result) { if ($this->_result) {
return null; return null;
} }
return null; return null;
} }
/** /**
* Returns number of rows in previous resultset. If no previous resultset exists, * Returns number of rows in previous resultset. If no previous resultset exists,
@ -364,13 +377,13 @@ class DboOdbc extends DboSource{
* *
* @return int Number of rows in resultset * @return int Number of rows in resultset
*/ */
function lastNumRows() { function lastNumRows() {
if ($this->_result) { if ($this->_result) {
return@odbc_num_rows($this->_result); return@odbc_num_rows($this->_result);
} }
return null; return null;
} }
/** /**
* Returns the ID generated from the previous INSERT operation. * Returns the ID generated from the previous INSERT operation.
@ -378,101 +391,101 @@ class DboOdbc extends DboSource{
* @param unknown_type $source * @param unknown_type $source
* @return int * @return int
*/ */
function lastInsertId($source = null) { function lastInsertId($source = null) {
$result=$this->fetchAll('SELECT @@IDENTITY'); $result=$this->fetchAll('SELECT @@IDENTITY');
return $result[0]; return $result[0];
} }
/** /**
* Enter description here... * Enter description here...
* *
* @param string $real Real database-layer column type (i.e. "varchar(255)") * @param string $real Real database-layer column type (i.e. "varchar(255)")
*/ */
function column($real) { function column($real) {
if (is_array($real)) { if (is_array($real)) {
$col=$real['name']; $col=$real['name'];
if (isset($real['limit'])) { if (isset($real['limit'])) {
$col .= '(' . $real['limit'] . ')'; $col .= '(' . $real['limit'] . ')';
} }
return $col; return $col;
} }
return $real; return $real;
} }
/** /**
* Enter description here... * Enter description here...
* *
* @param unknown_type $results * @param unknown_type $results
*/ */
function resultSet(&$results) { function resultSet(&$results) {
$this->results=&$results; $this->results=&$results;
$this->map=array(); $this->map=array();
$num_fields =odbc_num_fields($results); $num_fields =odbc_num_fields($results);
$index =0; $index =0;
$j =0; $j =0;
while($j < $num_fields) { while($j < $num_fields) {
$column = odbc_fetch_array($results, $j); $column = odbc_fetch_array($results, $j);
if (!empty($column->table)) { if (!empty($column->table)) {
$this->map[$index++] = array($column->table, $this->map[$index++] = array($column->table,
$column->name); $column->name);
} else { } else {
echo array(0, echo array(0,
$column->name); $column->name);
$this->map[$index++]=array(0, $this->map[$index++]=array(0,
$column->name); $column->name);
} }
$j++; $j++;
} }
} }
/** /**
* Fetches the next row from the current result set * Fetches the next row from the current result set
* *
* @return unknown * @return unknown
*/ */
function fetchResult() { function fetchResult() {
if ($row = odbc_fetch_row($this->results)) { if ($row = odbc_fetch_row($this->results)) {
$resultRow=array(); $resultRow=array();
$i=0; $i=0;
foreach($row as $index => $field) { foreach($row as $index => $field) {
list($table, $column) = $this->map[$index]; list($table, $column) = $this->map[$index];
$resultRow[$table][$column]=$row[$index]; $resultRow[$table][$column]=$row[$index];
$i++; $i++;
} }
return $resultRow; return $resultRow;
} else { } else {
return false; return false;
} }
} }
function buildSchemaQuery($schema) { function buildSchemaQuery($schema) {
$search=array('{AUTOINCREMENT}', $search=array('{AUTOINCREMENT}',
'{PRIMARY}', '{PRIMARY}',
'{UNSIGNED}', '{UNSIGNED}',
'{FULLTEXT}', '{FULLTEXT}',
'{FULLTEXT_MYSQL}', '{FULLTEXT_MYSQL}',
'{BOOLEAN}', '{BOOLEAN}',
'{UTF_8}'); '{UTF_8}');
$replace=array('int(11) not null auto_increment', $replace=array('int(11) not null auto_increment',
'primary key', 'primary key',
'unsigned', 'unsigned',
'FULLTEXT', 'FULLTEXT',
'FULLTEXT', 'FULLTEXT',
'enum (\'true\', \'false\') NOT NULL default \'true\'', 'enum (\'true\', \'false\') NOT NULL default \'true\'',
'/*!40100 CHARACTER SET utf8 COLLATE utf8_unicode_ci */'); '/*!40100 CHARACTER SET utf8 COLLATE utf8_unicode_ci */');
$query=trim(str_replace($search, $replace, $schema)); $query=trim(str_replace($search, $replace, $schema));
return $query; return $query;
} }
} }
?> ?>

View file

@ -359,7 +359,6 @@ class Model extends Object{
$return = $db->query($method, $params, $this); $return = $db->query($method, $params, $this);
return true; return true;
} }
/** /**
* Bind model associations on the fly. * Bind model associations on the fly.
* *
@ -386,7 +385,6 @@ class Model extends Object{
} }
return true; return true;
} }
/** /**
* Turn off associations on the fly. * Turn off associations on the fly.
* *
@ -404,7 +402,6 @@ class Model extends Object{
} }
return true; return true;
} }
/** /**
* Private helper method to create a set of associations. * Private helper method to create a set of associations.
* *
@ -418,14 +415,14 @@ class Model extends Object{
if (!is_array($this->{$type})) { if (!is_array($this->{$type})) {
$this->{$type} = explode(',', $this->{$type}); $this->{$type} = explode(',', $this->{$type});
foreach($this->{$type}as $i => $className) { foreach($this->{$type} as $i => $className) {
$className = trim($className); $className = trim($className);
unset ($this->{$type}[$i]); unset ($this->{$type}[$i]);
$this->{$type}[$className] = array(); $this->{$type}[$className] = array();
} }
} }
foreach($this->{$type}as $assoc => $value) { foreach($this->{$type} as $assoc => $value) {
if (is_numeric($assoc)) { if (is_numeric($assoc)) {
unset ($this->{$type}[$assoc]); unset ($this->{$type}[$assoc]);
$assoc = $value; $assoc = $value;
@ -458,16 +455,15 @@ 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 {
$this->{$className} = new $className(); $this->{$className} =& new $className();
} }
$this->alias[$assoc] = $this->{$className}->table; $this->alias[$assoc] = $this->{$className}->table;
$this->tableToModel[$this->{$className}->table] = $className; $this->tableToModel[$this->{$className}->table] = $className;
$this->modelToTable[$className] = $this->{$className}->table; $this->modelToTable[$className] = $this->{$className}->table;
} }
/** /**
* Build array-based association from string. * Build array-based association from string.
* *
@ -524,7 +520,6 @@ class Model extends Object{
} }
} }
} }
/** /**
* Sets a custom table for your controller class. Used by your controller to select a database table. * Sets a custom table for your controller class. Used by your controller to select a database table.
* *
@ -558,7 +553,6 @@ class Model extends Object{
$this->loadInfo(); $this->loadInfo();
} }
} }
/** /**
* This function does two things: 1) it scans the array $one for the primary key, * This function does two things: 1) it scans the array $one for the primary key,
* and if that's found, it sets the current id to the value of $one[id]. * and if that's found, it sets the current id to the value of $one[id].
@ -602,7 +596,6 @@ class Model extends Object{
} }
return $data; return $data;
} }
/** /**
* Returns an array of table metadata (column names and types) from the database. * Returns an array of table metadata (column names and types) from the database.
* *
@ -616,7 +609,6 @@ class Model extends Object{
} }
return $this->_tableInfo; return $this->_tableInfo;
} }
/** /**
* Returns an associative array of field names and column types. * Returns an associative array of field names and column types.
* *
@ -633,7 +625,6 @@ class Model extends Object{
} }
return $cols; return $cols;
} }
/** /**
* Returns the column type of a column in the model * Returns the column type of a column in the model
* *
@ -653,7 +644,6 @@ class Model extends Object{
} }
return null; return null;
} }
/** /**
* Returns true if this Model has given field in its database table. * Returns true if this Model has given field in its database table.
* *
@ -670,7 +660,6 @@ class Model extends Object{
} }
return null; return null;
} }
/** /**
* Initializes the model for writing a new record. * Initializes the model for writing a new record.
* *
@ -682,7 +671,6 @@ class Model extends Object{
$this->data = array(); $this->data = array();
return true; return true;
} }
/** /**
* Deprecated * Deprecated
* *
@ -690,7 +678,6 @@ class Model extends Object{
function setId($id) { function setId($id) {
$this->id = $id; $this->id = $id;
} }
/** /**
* Deprecated. Use query() instead. * Deprecated. Use query() instead.
* *
@ -698,7 +685,6 @@ class Model extends Object{
function findBySql($sql) { function findBySql($sql) {
return $this->query($sql); return $this->query($sql);
} }
/** /**
* Returns a list of fields from the database * Returns a list of fields from the database
* *
@ -710,13 +696,13 @@ class Model extends Object{
$this->validationErrors = array(); $this->validationErrors = array();
if ($id != null) { if ($id != null) {
$this->id = $id; $this->id = $id;
} }
$id = $this->id; $id = $this->id;
if (is_array($this->id)) { if (is_array($this->id)) {
$id = $this->id[0]; $id = $this->id[0];
} }
if ($this->id !== null && $this->id !== false) { if ($this->id !== null && $this->id !== false) {
@ -727,7 +713,6 @@ class Model extends Object{
return false; return false;
} }
} }
/** /**
* Returns contents of a field in a query matching given conditions. * Returns contents of a field in a query matching given conditions.
* *
@ -762,7 +747,6 @@ class Model extends Object{
return false; return false;
} }
} }
/** /**
* Saves a single field to the database. * Saves a single field to the database.
* *
@ -774,7 +758,6 @@ class Model extends Object{
function saveField($name, $value, $validate = false) { function saveField($name, $value, $validate = false) {
return $this->save(array($this->name => array($name => $value)), $validate); return $this->save(array($this->name => array($name => $value)), $validate);
} }
/** /**
* Saves model data to the database. * Saves model data to the database.
* By default, validation occurs before save. * By default, validation occurs before save.
@ -838,69 +821,66 @@ class Model extends Object{
} }
if (empty($this->id) && $this->hasField('created') && !in_array('created', $fields) && ($whitelist && in_array('created', $fieldList) || !$whitelist)) { if (empty($this->id) && $this->hasField('created') && !in_array('created', $fields) && ($whitelist && in_array('created', $fieldList) || !$whitelist)) {
$fields[] = 'created'; $fields[] = 'created';
$values[] = date('Y-m-d H:i:s'); $values[] = date('Y-m-d H:i:s');
} }
if ($this->hasField('modified') if ($this->hasField('modified') && !in_array('modified', $fields) && ($whitelist && in_array('modified', $fieldList) || !$whitelist)) {
&& !in_array('modified', $fields) && ($whitelist && in_array('modified', $fieldList) || !$whitelist)) { $fields[] = 'modified';
$fields[] = 'modified'; $values[] = date('Y-m-d H:i:s');
$values[] = date('Y-m-d H:i:s');
} }
if ($this->hasField('updated') if ($this->hasField('updated') && !in_array('updated', $fields) && ($whitelist && in_array('updated', $fieldList) || !$whitelist)) {
&& !in_array('updated', $fields) && ($whitelist && in_array('updated', $fieldList) || !$whitelist)) { $fields[] = 'updated';
$fields[] = 'updated'; $values[] = date('Y-m-d H:i:s');
$values[] = date('Y-m-d H:i:s');
} }
if (!$this->exists()) { if (!$this->exists()) {
$this->id = false; $this->id = false;
} }
if (count($fields)) { if (count($fields)) {
if (!empty($this->id)) { if (!empty($this->id)) {
if ($db->update($this, $fields, $values)) { if ($db->update($this, $fields, $values)) {
if (!empty($joined)) { if (!empty($joined)) {
$this->__saveMulti($joined, $this->id); $this->__saveMulti($joined, $this->id);
}
$this->afterSave();
$this->data = false;
$this->_clearCache();
return true;
} else {
return false;
} }
$this->afterSave();
$this->data = false;
$this->_clearCache();
return true;
} else { } else {
if ($db->create($this, $fields, $values)) { return false;
$this->__insertID = $db->lastInsertId($this->table, $this->primaryKey);
if (!$this->__insertID && $newID != null) {
$this->__insertID = $newID;
$this->id = $newID;
} else {
$this->id = $this->__insertID;
}
if (!empty($joined)) {
$this->__saveMulti($joined, $this->id);
}
$this->afterSave();
$this->data = false;
$this->_clearCache();
$this->validationErrors = array();
return true;
} else {
return false;
}
} }
} else {
if ($db->create($this, $fields, $values)) {
$this->__insertID = $db->lastInsertId($this->table, $this->primaryKey);
if (!$this->__insertID && $newID != null) {
$this->__insertID = $newID;
$this->id = $newID;
} else {
$this->id = $this->__insertID;
}
if (!empty($joined)) {
$this->__saveMulti($joined, $this->id);
}
$this->afterSave();
$this->data = false;
$this->_clearCache();
$this->validationErrors = array();
return true;
} else {
return false;
}
}
} else { } else {
return false; return false;
} }
} }
/** /**
* Saves model hasAndBelongsToMany data to the database. * Saves model hasAndBelongsToMany data to the database.
* *
@ -913,48 +893,48 @@ class Model extends Object{
$db =& ConnectionManager::getDataSource($this->useDbConfig); $db =& ConnectionManager::getDataSource($this->useDbConfig);
foreach($joined as $x => $y) { foreach($joined as $x => $y) {
foreach($y as $assoc => $value) { foreach($y as $assoc => $value) {
$joinTable[] = $this->hasAndBelongsToMany[$assoc]['joinTable']; $joinTable[] = $this->hasAndBelongsToMany[$assoc]['joinTable'];
$mainKey[] = $this->hasAndBelongsToMany[$assoc]['foreignKey']; $mainKey[] = $this->hasAndBelongsToMany[$assoc]['foreignKey'];
$keys[] = $this->hasAndBelongsToMany[$assoc]['foreignKey']; $keys[] = $this->hasAndBelongsToMany[$assoc]['foreignKey'];
$keys[] = $this->hasAndBelongsToMany[$assoc]['associationForeignKey']; $keys[] = $this->hasAndBelongsToMany[$assoc]['associationForeignKey'];
$fields[] = join(',', $keys); $fields[] = join(',', $keys);
unset($keys); unset($keys);
foreach($value as $update) { foreach($value as $update) {
if (!empty($update)) { if (!empty($update)) {
$values[] = $db->value($id, $this->getColumnType($this->primaryKey)); $values[] = $db->value($id, $this->getColumnType($this->primaryKey));
$values[] = $db->value($update); $values[] = $db->value($update);
$values = join(',', $values); $values = join(',', $values);
$newValues[] = "({$values})"; $newValues[] = "({$values})";
unset ($values); unset ($values);
}
}
if (!empty($newValues)) {
$newValue[] = $newValues;
unset($newValues);
} }
} }
if (!empty($newValues)) {
$newValue[] = $newValues;
unset($newValues);
}
}
} }
$total = count($joinTable); $total = count($joinTable);
for($count = 0; $count < $total; $count++) { for($count = 0; $count < $total; $count++) {
$db =& ConnectionManager::getDataSource($this->useDbConfig); $db =& ConnectionManager::getDataSource($this->useDbConfig);
$db->execute("DELETE FROM {$joinTable[$count]} WHERE {$mainKey[$count]} = '{$id}'"); $table = $db->name($db->fullTableName($joinTable[$count]));
$db->execute("DELETE FROM {$table} WHERE {$mainKey[$count]} = '{$id}'");
if (!empty($newValue[$count])) { if (!empty($newValue[$count])) {
$secondCount = count($newValue[$count]); $secondCount = count($newValue[$count]);
for($x = 0; $x < $secondCount; $x++) { for($x = 0; $x < $secondCount; $x++) {
$db->execute("INSERT INTO {$joinTable[$count]} ({$fields[$count]}) VALUES {$newValue[$count][$x]}"); $db->execute("INSERT INTO {$table} ({$fields[$count]}) VALUES {$newValue[$count][$x]}");
}
} }
}
} }
} }
/** /**
* Synonym for del(). * Synonym for del().
* *
@ -962,10 +942,9 @@ class Model extends Object{
* @see function del * @see function del
* @return boolean True on success * @return boolean True on success
*/ */
function remove($id = null) { function remove($id = null, $cascade = true) {
return $this->del($id); return $this->del($id, $cascade);
} }
/** /**
* 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.
* *
@ -974,28 +953,27 @@ class Model extends Object{
*/ */
function del($id = null, $cascade = true) { function del($id = null, $cascade = true) {
if ($id) { if ($id) {
$this->id = $id; $this->id = $id;
} }
$id = $this->id; $id = $this->id;
if ($this->beforeDelete()) { if ($this->beforeDelete()) {
$db =& ConnectionManager::getDataSource($this->useDbConfig); $db =& ConnectionManager::getDataSource($this->useDbConfig);
if ($this->id && $db->delete($this)) { if ($this->id && $db->delete($this)) {
$this->_deleteMulti($id); $this->_deleteMulti($id);
$this->_deleteHasMany($id, $cascade); $this->_deleteHasMany($id, $cascade);
$this->_deleteHasOne($id, $cascade); $this->_deleteHasOne($id, $cascade);
$this->afterDelete(); $this->afterDelete();
$this->_clearCache(); $this->_clearCache();
$this->id = false; $this->id = false;
return true; return true;
} }
} }
return false; return false;
} }
/** /**
* Alias for del() * Alias for del()
* *
@ -1005,7 +983,6 @@ class Model extends Object{
function delete($id = null, $cascade = true) { function delete($id = null, $cascade = true) {
return $this->del($id, $cascade); return $this->del($id, $cascade);
} }
/** /**
* Cascades model deletes to hasMany relationships. * Cascades model deletes to hasMany relationships.
* *
@ -1027,7 +1004,6 @@ class Model extends Object{
} }
} }
} }
/** /**
* Cascades model deletes to hasOne relationships. * Cascades model deletes to hasOne relationships.
* *
@ -1037,19 +1013,18 @@ class Model extends Object{
*/ */
function _deleteHasOne($id, $cascade) { function _deleteHasOne($id, $cascade) {
foreach($this->hasOne as $assoc => $data) { foreach($this->hasOne as $assoc => $data) {
if ($data['dependent'] === true && $cascade === true) { if ($data['dependent'] === true && $cascade === true) {
$model =& $this->{$data['className']}; $model =& $this->{$data['className']};
$field = $model->escapeField($data['foreignKey']); $field = $model->escapeField($data['foreignKey']);
$model->recursive = 0; $model->recursive = 0;
$records = $model->findAll("$field = '$id'", $model->primaryKey, null, null); $records = $model->findAll("$field = '$id'", $model->primaryKey, null, null);
foreach($records as $record) { foreach($records as $record) {
$model->del($record[$data['className']][$model->primaryKey]); $model->del($record[$data['className']][$model->primaryKey]);
}
} }
}
} }
} }
/** /**
* Cascades model deletes to HABTM join keys. * Cascades model deletes to HABTM join keys.
* *
@ -1059,13 +1034,10 @@ class Model extends Object{
*/ */
function _deleteMulti($id) { function _deleteMulti($id) {
$db =& ConnectionManager::getDataSource($this->useDbConfig); $db =& ConnectionManager::getDataSource($this->useDbConfig);
foreach($this->hasAndBelongsToMany as $assoc => $data) { foreach($this->hasAndBelongsToMany as $assoc => $data) {
$db->execute("DELETE FROM " . $db->name($data['joinTable']) . " WHERE " $db->execute("DELETE FROM " . $db->name($db->fullTableName($data['joinTable'])) . " WHERE " . $db->name($data['foreignKey']) . " = '{$id}'");
. $db->name($data['foreignKey']) . " = '{$id}'");
} }
} }
/** /**
* Returns true if a record with set id exists. * Returns true if a record with set id exists.
* *
@ -1073,19 +1045,17 @@ class Model extends Object{
*/ */
function exists() { function exists() {
if ($this->id) { if ($this->id) {
$id = $this->id; $id = $this->id;
if (is_array($id)) { if (is_array($id)) {
$id = $id[0]; $id = $id[0];
} }
$db =& ConnectionManager::getDataSource($this->useDbConfig); $db =& ConnectionManager::getDataSource($this->useDbConfig);
return $db->hasAny($this, $db->conditions(array($this->primaryKey => $id))); return $db->hasAny($this, array($this->primaryKey => $id));
} }
return false; return false;
} }
/** /**
* Returns true if a record that meets given conditions exists * Returns true if a record that meets given conditions exists
* *
@ -1095,7 +1065,6 @@ class Model extends Object{
function hasAny($conditions = null) { function hasAny($conditions = null) {
return ($this->findCount($conditions) != false); return ($this->findCount($conditions) != false);
} }
/** /**
* 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 * By using the $recursive parameter, the call can access further "levels of association" than
@ -1111,12 +1080,11 @@ class Model extends Object{
$data = $this->findAll($conditions, $fields, $order, 1, null, $recursive); $data = $this->findAll($conditions, $fields, $order, 1, null, $recursive);
if (empty($data[0])) { if (empty($data[0])) {
return false; return false;
} }
return $data[0]; return $data[0];
} }
/** /**
* 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 * By using the $recursive parameter, the call can access further "levels of association" than
@ -1131,45 +1099,41 @@ class Model extends Object{
* @return array Array of records * @return array Array of records
*/ */
function findAll($conditions = null, $fields = null, $order = null, $limit = null, $page = 1, $recursive = null) { function findAll($conditions = null, $fields = null, $order = null, $limit = null, $page = 1, $recursive = null) {
$db =& ConnectionManager::getDataSource($this->useDbConfig); $db =& ConnectionManager::getDataSource($this->useDbConfig);
$this->id = $this->getID(); $this->id = $this->getID();
$offset = 0; $offset = null;
if ($page > 1) { if ($page > 1 && $limit != null) {
$offset = ($page - 1) * $limit; $offset = ($page - 1) * $limit;
} }
$limit_str = '';
if ($limit) {
$limit_str = $db->limit($limit, $offset);
}
if ($order == null) { if ($order == null) {
$order = array(); $order = array();
} else { } else {
$order = array($order); $order = array($order);
} }
$queryData = array('conditions' => $conditions, $queryData = array('conditions' => $conditions,
'fields' => $fields, 'fields' => $fields,
'joins' => array(), 'joins' => array(),
'limit' => $limit_str, 'limit' => $limit,
'order' => $order); 'offset' => $offset,
'order' => $order
);
if (!$this->beforeFind($queryData)) { if (!$this->beforeFind($queryData)) {
return null; return null;
} }
$return = $this->afterFind($db->read($this, $queryData, $recursive)); $return = $this->afterFind($db->read($this, $queryData, $recursive));
if (isset($this->__backAssociation)) { if (isset($this->__backAssociation)) {
$this->__resetAssociations(); $this->__resetAssociations();
} }
return $return; return $return;
} }
/** /**
* Method is called only when bindTo<ModelName>() is used. * Method is called only when bindTo<ModelName>() is used.
* This resets the association arrays for the model back * This resets the association arrays for the model back
@ -1180,15 +1144,14 @@ class Model extends Object{
*/ */
function __resetAssociations() { function __resetAssociations() {
foreach($this->__associations as $type) { foreach($this->__associations as $type) {
if (isset($this->__backAssociation[$type])) { if (isset($this->__backAssociation[$type])) {
$this->{$type} = $this->__backAssociation[$type]; $this->{$type} = $this->__backAssociation[$type];
} }
} }
unset ($this->__backAssociation); unset ($this->__backAssociation);
return true; return true;
} }
/** /**
* Runs a direct query against the bound DataSource, and returns the result. * Runs a direct query against the bound DataSource, and returns the result.
* *
@ -1200,20 +1163,19 @@ class Model extends Object{
$data = $db->fetchAll($data, $this->cacheQueries); $data = $db->fetchAll($data, $this->cacheQueries);
foreach($data as $key => $value) { foreach($data as $key => $value) {
foreach($this->tableToModel as $key1 => $value1) { foreach($this->tableToModel as $key1 => $value1) {
if (isset($data[$key][$key1])) { if (isset($data[$key][$key1])) {
$newData[$key][$value1] = $data[$key][$key1]; $newData[$key][$value1] = $data[$key][$key1];
}
} }
}
} }
if (!empty($newData)) { if (!empty($newData)) {
return $newData; return $newData;
} }
return $data; return $data;
} }
/** /**
* Returns number of rows matching given SQL condition. * Returns number of rows matching given SQL condition.
* *
@ -1231,7 +1193,6 @@ class Model extends Object{
return false; return false;
} }
/** /**
* Special findAll variation for tables joined to themselves. * Special findAll variation for tables joined to themselves.
* The table needs the fields id and parent_id to work. * The table needs the fields id and parent_id to work.
@ -1245,7 +1206,6 @@ class Model extends Object{
function findAllThreaded($conditions = null, $fields = null, $sort = null) { function findAllThreaded($conditions = null, $fields = null, $sort = null) {
return $this->__doThread(Model::findAll($conditions, $fields, $sort), null); return $this->__doThread(Model::findAll($conditions, $fields, $sort), null);
} }
/** /**
* Private, recursive helper method for findAllThreaded. * Private, recursive helper method for findAllThreaded.
* *
@ -1260,23 +1220,21 @@ class Model extends Object{
$sizeOf = sizeof($data); $sizeOf = sizeof($data);
for($ii = 0; $ii < $sizeOf; $ii++) { for($ii = 0; $ii < $sizeOf; $ii++) {
if (($data[$ii][$this->name]['parent_id'] == $root) if (($data[$ii][$this->name]['parent_id'] == $root) || (($root === null) && ($data[$ii][$this->name]['parent_id'] == '0'))) {
|| (($root === null) && ($data[$ii][$this->name]['parent_id'] == '0'))) { $tmp = $data[$ii];
$tmp = $data[$ii];
if (isset($data[$ii][$this->name][$this->primaryKey])) { if (isset($data[$ii][$this->name][$this->primaryKey])) {
$tmp['children'] = $this->__doThread($data, $data[$ii][$this->name][$this->primaryKey]); $tmp['children'] = $this->__doThread($data, $data[$ii][$this->name][$this->primaryKey]);
} else { } else {
$tmp['children'] = null; $tmp['children'] = null;
}
$out[] = $tmp;
} }
$out[] = $tmp;
}
} }
return $out; return $out;
} }
/** /**
* Returns an array with keys "prev" and "next" that holds the id's of neighbouring data, * Returns an array with keys "prev" and "next" that holds the id's of neighbouring data,
* which is useful when creating paged lists. * which is useful when creating paged lists.
@ -1306,7 +1264,6 @@ class Model extends Object{
return array('prev' => $prev, 'next' => $next); return array('prev' => $prev, 'next' => $next);
} }
/** /**
* Returns a resultset for given SQL statement. Generic SQL queries should be made with this method. * Returns a resultset for given SQL statement. Generic SQL queries should be made with this method.
* *
@ -1318,22 +1275,16 @@ class Model extends Object{
$db =& ConnectionManager::getDataSource($this->useDbConfig); $db =& ConnectionManager::getDataSource($this->useDbConfig);
return call_user_func_array(array(&$db, 'query'), $params); return call_user_func_array(array(&$db, 'query'), $params);
} }
/** /**
* Returns true if all fields pass validation, otherwise false. * 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
*/ */
function validates($data = null) { function validates($data = array()) {
if ($data == null) {
$data = $this->data;
}
$errors = $this->invalidFields($data); $errors = $this->invalidFields($data);
return count($errors) == 0; return count($errors) == 0;
} }
/** /**
* Returns an array of invalid fields. * Returns an array of invalid fields.
* *
@ -1341,6 +1292,10 @@ class Model extends Object{
* @return array Array of invalid fields * @return array Array of invalid fields
*/ */
function invalidFields($data = array()) { function invalidFields($data = array()) {
if (empty($data)) {
$data = $this->data;
}
if (!$this->beforeValidate()) { if (!$this->beforeValidate()) {
return false; return false;
} }
@ -1349,10 +1304,9 @@ class Model extends Object{
return true; return true;
} }
if (!empty($data)){ if (!empty($data)) {
$data = $data; $data = $data;
} } elseif (isset($this->data)) {
elseif (isset($this->data)){
$data = $this->data; $data = $this->data;
} }
@ -1367,7 +1321,6 @@ class Model extends Object{
} }
return $this->validationErrors; return $this->validationErrors;
} }
/** /**
* Sets a field as invalid * Sets a field as invalid
* *
@ -1378,10 +1331,8 @@ class Model extends Object{
if (!is_array($this->validationErrors)) { if (!is_array($this->validationErrors)) {
$this->validationErrors = array(); $this->validationErrors = array();
} }
$this->validationErrors[$field] = 1; $this->validationErrors[$field] = 1;
} }
/** /**
* Returns true if given field name is a foreign key in this Model. * Returns true if given field name is a foreign key in this Model.
* *
@ -1396,10 +1347,8 @@ class Model extends Object{
$foreignKeys[] = $data['foreignKey']; $foreignKeys[] = $data['foreignKey'];
} }
} }
return (bool)(in_array($field, $foreignKeys)); return (bool)(in_array($field, $foreignKeys));
} }
/** /**
* Gets the display field for this model * Gets the display field for this model
* *
@ -1408,7 +1357,6 @@ class Model extends Object{
function getDisplayField() { function getDisplayField() {
return $this->displayField; return $this->displayField;
} }
/** /**
* 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. * Method can be used to generate option lists for SELECT elements.
@ -1423,10 +1371,10 @@ class Model extends Object{
function generateList($conditions = null, $order = null, $limit = null, $keyPath = null, $valuePath = null) { function generateList($conditions = null, $order = null, $limit = null, $keyPath = null, $valuePath = null) {
$db =& ConnectionManager::getDataSource($this->useDbConfig); $db =& ConnectionManager::getDataSource($this->useDbConfig);
if ($keyPath == null && $valuePath == null) { if ($keyPath == null && $valuePath == null && $this->hasField($this->displayField)) {
$fields = array($this->primaryKey, $this->displayField); $fields = array($this->primaryKey, $this->displayField);
} else { } else {
$fields = '*'; $fields = null;
} }
$result = $this->findAll($conditions, $fields, $order, $limit, 1, 0); $result = $this->findAll($conditions, $fields, $order, $limit, 1, 0);
@ -1447,7 +1395,6 @@ class Model extends Object{
return $return; return $return;
} }
} }
/** /**
* Escapes the field name and prepends the model name. Escaping will be done according to the current database driver's rules. * Escapes the field name and prepends the model name. Escaping will be done according to the current database driver's rules.
* *
@ -1458,7 +1405,6 @@ class Model extends Object{
$db =& ConnectionManager::getDataSource($this->useDbConfig); $db =& ConnectionManager::getDataSource($this->useDbConfig);
return $db->name($this->name) . '.' . $db->name($field); return $db->name($this->name) . '.' . $db->name($field);
} }
/** /**
* Returns the current record's ID * Returns the current record's ID
* *
@ -1484,7 +1430,6 @@ class Model extends Object{
return false; return false;
} }
/** /**
* Returns the ID of the last record this Model inserted * Returns the ID of the last record this Model inserted
* *
@ -1493,7 +1438,6 @@ class Model extends Object{
function getLastInsertID() { function getLastInsertID() {
return $this->getInsertID(); return $this->getInsertID();
} }
/** /**
* Returns the ID of the last record this Model inserted * Returns the ID of the last record this Model inserted
* *
@ -1502,7 +1446,6 @@ class Model extends Object{
function getInsertID() { function getInsertID() {
return $this->__insertID; return $this->__insertID;
} }
/** /**
* Returns the number of rows returned from the last query * Returns the number of rows returned from the last query
* *
@ -1513,7 +1456,6 @@ class Model extends Object{
$db =& ConnectionManager::getDataSource($this->useDbConfig); $db =& ConnectionManager::getDataSource($this->useDbConfig);
return $db->lastNumRows(); return $db->lastNumRows();
} }
/** /**
* Returns the number of rows affected by the last query * Returns the number of rows affected by the last query
* *
@ -1524,7 +1466,6 @@ class Model extends Object{
$db =& ConnectionManager::getDataSource($this->useDbConfig); $db =& ConnectionManager::getDataSource($this->useDbConfig);
return $db->lastAffected(); return $db->lastAffected();
} }
/** /**
* Sets the DataSource to which this model is bound * Sets the DataSource to which this model is bound
* *
@ -1546,7 +1487,6 @@ class Model extends Object{
return $this->cakeError('missingConnection', array(array('className' => $this->name))); return $this->cakeError('missingConnection', array(array('className' => $this->name)));
} }
} }
/** /**
* Before find callback * Before find callback
* *
@ -1556,7 +1496,6 @@ class Model extends Object{
function beforeFind(&$queryData) { function beforeFind(&$queryData) {
return true; return true;
} }
/** /**
* After find callback. Can be used to modify any results returned by find and findAll. * After find callback. Can be used to modify any results returned by find and findAll.
* *
@ -1566,7 +1505,6 @@ class Model extends Object{
function afterFind($results) { function afterFind($results) {
return $results; return $results;
} }
/** /**
* Before save callback * Before save callback
* *
@ -1575,7 +1513,6 @@ class Model extends Object{
function beforeSave() { function beforeSave() {
return true; return true;
} }
/** /**
* After save callback * After save callback
* *
@ -1584,7 +1521,6 @@ class Model extends Object{
function afterSave() { function afterSave() {
return true; return true;
} }
/** /**
* Before delete callback * Before delete callback
* *
@ -1593,7 +1529,6 @@ class Model extends Object{
function beforeDelete() { function beforeDelete() {
return true; return true;
} }
/** /**
* After delete callback * After delete callback
* *
@ -1602,7 +1537,6 @@ class Model extends Object{
function afterDelete() { function afterDelete() {
return true; return true;
} }
/** /**
* Before validate callback * Before validate callback
* *
@ -1611,7 +1545,6 @@ class Model extends Object{
function beforeValidate() { function beforeValidate() {
return true; return true;
} }
/** /**
* Private method. Clears cache for this model * Private method. Clears cache for this model
* *
@ -1640,7 +1573,6 @@ class Model extends Object{
//Will use for query cache deleting //Will use for query cache deleting
} }
} }
/** /**
* Called when serializing a model * Called when serializing a model
* *

View file

@ -341,7 +341,6 @@ class Model extends Object{
} }
} }
} }
/** /**
* Handles custom method calls, like findBy<field> for DB models, * Handles custom method calls, like findBy<field> for DB models,
* and custom RPC calls for remote data sources * and custom RPC calls for remote data sources
@ -355,7 +354,6 @@ class Model extends Object{
$db =& ConnectionManager::getDataSource($this->useDbConfig); $db =& ConnectionManager::getDataSource($this->useDbConfig);
return $db->query($method, $params, $this); return $db->query($method, $params, $this);
} }
/** /**
* Bind model associations on the fly. * Bind model associations on the fly.
* *
@ -382,7 +380,6 @@ class Model extends Object{
} }
return true; return true;
} }
/** /**
* Turn off associations on the fly. * Turn off associations on the fly.
* *
@ -400,7 +397,6 @@ class Model extends Object{
} }
return true; return true;
} }
/** /**
* Private helper method to create a set of associations. * Private helper method to create a set of associations.
* *
@ -414,14 +410,14 @@ class Model extends Object{
if (!is_array($this->{$type})) { if (!is_array($this->{$type})) {
$this->{$type} = explode(',', $this->{$type}); $this->{$type} = explode(',', $this->{$type});
foreach($this->{$type}as $i => $className) { foreach($this->{$type} as $i => $className) {
$className = trim($className); $className = trim($className);
unset ($this->{$type}[$i]); unset ($this->{$type}[$i]);
$this->{$type}[$className] = array(); $this->{$type}[$className] = array();
} }
} }
foreach($this->{$type}as $assoc => $value) { foreach($this->{$type} as $assoc => $value) {
if (is_numeric($assoc)) { if (is_numeric($assoc)) {
unset ($this->{$type}[$assoc]); unset ($this->{$type}[$assoc]);
$assoc = $value; $assoc = $value;
@ -442,7 +438,6 @@ class Model extends Object{
$this->__generateAssociation($type); $this->__generateAssociation($type);
} }
} }
/** /**
* Private helper method to create associated models of given class. * Private helper method to create associated models of given class.
* @param string $assoc * @param string $assoc
@ -463,7 +458,6 @@ class Model extends Object{
$this->tableToModel[$this->{$className}->table] = $className; $this->tableToModel[$this->{$className}->table] = $className;
$this->modelToTable[$className] = $this->{$className}->table; $this->modelToTable[$className] = $this->{$className}->table;
} }
/** /**
* Build array-based association from string. * Build array-based association from string.
* *
@ -520,7 +514,6 @@ class Model extends Object{
} }
} }
} }
/** /**
* Sets a custom table for your controller class. Used by your controller to select a database table. * Sets a custom table for your controller class. Used by your controller to select a database table.
* *
@ -554,7 +547,6 @@ class Model extends Object{
$this->loadInfo(); $this->loadInfo();
} }
} }
/** /**
* This function does two things: 1) it scans the array $one for the primary key, * This function does two things: 1) it scans the array $one for the primary key,
* and if that's found, it sets the current id to the value of $one[id]. * and if that's found, it sets the current id to the value of $one[id].
@ -598,7 +590,6 @@ class Model extends Object{
} }
return $data; return $data;
} }
/** /**
* Returns an array of table metadata (column names and types) from the database. * Returns an array of table metadata (column names and types) from the database.
* *
@ -612,7 +603,6 @@ class Model extends Object{
} }
return $this->_tableInfo; return $this->_tableInfo;
} }
/** /**
* Returns an associative array of field names and column types. * Returns an associative array of field names and column types.
* *
@ -629,7 +619,6 @@ class Model extends Object{
} }
return $cols; return $cols;
} }
/** /**
* Returns the column type of a column in the model * Returns the column type of a column in the model
* *
@ -649,7 +638,6 @@ class Model extends Object{
} }
return null; return null;
} }
/** /**
* Returns true if this Model has given field in its database table. * Returns true if this Model has given field in its database table.
* *
@ -666,7 +654,6 @@ class Model extends Object{
} }
return null; return null;
} }
/** /**
* Initializes the model for writing a new record. * Initializes the model for writing a new record.
* *
@ -678,7 +665,6 @@ class Model extends Object{
$this->data = array(); $this->data = array();
return true; return true;
} }
/** /**
* Deprecated * Deprecated
* *
@ -686,7 +672,6 @@ class Model extends Object{
function setId($id) { function setId($id) {
$this->id = $id; $this->id = $id;
} }
/** /**
* Deprecated. Use query() instead. * Deprecated. Use query() instead.
* *
@ -694,7 +679,6 @@ class Model extends Object{
function findBySql($sql) { function findBySql($sql) {
return $this->query($sql); return $this->query($sql);
} }
/** /**
* Returns a list of fields from the database * Returns a list of fields from the database
* *
@ -706,13 +690,13 @@ class Model extends Object{
$this->validationErrors = array(); $this->validationErrors = array();
if ($id != null) { if ($id != null) {
$this->id = $id; $this->id = $id;
} }
$id = $this->id; $id = $this->id;
if (is_array($this->id)) { if (is_array($this->id)) {
$id = $this->id[0]; $id = $this->id[0];
} }
if ($this->id !== null && $this->id !== false) { if ($this->id !== null && $this->id !== false) {
@ -834,69 +818,66 @@ class Model extends Object{
} }
if (empty($this->id) && $this->hasField('created') && !in_array('created', $fields) && ($whitelist && in_array('created', $fieldList) || !$whitelist)) { if (empty($this->id) && $this->hasField('created') && !in_array('created', $fields) && ($whitelist && in_array('created', $fieldList) || !$whitelist)) {
$fields[] = 'created'; $fields[] = 'created';
$values[] = date('Y-m-d H:i:s'); $values[] = date('Y-m-d H:i:s');
} }
if ($this->hasField('modified') if ($this->hasField('modified') && !in_array('modified', $fields) && ($whitelist && in_array('modified', $fieldList) || !$whitelist)) {
&& !in_array('modified', $fields) && ($whitelist && in_array('modified', $fieldList) || !$whitelist)) { $fields[] = 'modified';
$fields[] = 'modified'; $values[] = date('Y-m-d H:i:s');
$values[] = date('Y-m-d H:i:s');
} }
if ($this->hasField('updated') if ($this->hasField('updated') && !in_array('updated', $fields) && ($whitelist && in_array('updated', $fieldList) || !$whitelist)) {
&& !in_array('updated', $fields) && ($whitelist && in_array('updated', $fieldList) || !$whitelist)) { $fields[] = 'updated';
$fields[] = 'updated'; $values[] = date('Y-m-d H:i:s');
$values[] = date('Y-m-d H:i:s');
} }
if (!$this->exists()) { if (!$this->exists()) {
$this->id = false; $this->id = false;
} }
if (count($fields)) { if (count($fields)) {
if (!empty($this->id)) { if (!empty($this->id)) {
if ($db->update($this, $fields, $values)) { if ($db->update($this, $fields, $values)) {
if (!empty($joined)) { if (!empty($joined)) {
$this->__saveMulti($joined, $this->id); $this->__saveMulti($joined, $this->id);
}
$this->afterSave();
$this->data = false;
$this->_clearCache();
return true;
} else {
return false;
} }
$this->afterSave();
$this->data = false;
$this->_clearCache();
return true;
} else { } else {
if ($db->create($this, $fields, $values)) { return false;
$this->__insertID = $db->lastInsertId($this->table, $this->primaryKey);
if (!$this->__insertID && $newID != null) {
$this->__insertID = $newID;
$this->id = $newID;
} else {
$this->id = $this->__insertID;
}
if (!empty($joined)) {
$this->__saveMulti($joined, $this->id);
}
$this->afterSave();
$this->data = false;
$this->_clearCache();
$this->validationErrors = array();
return true;
} else {
return false;
}
} }
} else {
if ($db->create($this, $fields, $values)) {
$this->__insertID = $db->lastInsertId($this->table, $this->primaryKey);
if (!$this->__insertID && $newID != null) {
$this->__insertID = $newID;
$this->id = $newID;
} else {
$this->id = $this->__insertID;
}
if (!empty($joined)) {
$this->__saveMulti($joined, $this->id);
}
$this->afterSave();
$this->data = false;
$this->_clearCache();
$this->validationErrors = array();
return true;
} else {
return false;
}
}
} else { } else {
return false; return false;
} }
} }
/** /**
* Saves model hasAndBelongsToMany data to the database. * Saves model hasAndBelongsToMany data to the database.
* *
@ -909,48 +890,48 @@ class Model extends Object{
$db =& ConnectionManager::getDataSource($this->useDbConfig); $db =& ConnectionManager::getDataSource($this->useDbConfig);
foreach($joined as $x => $y) { foreach($joined as $x => $y) {
foreach($y as $assoc => $value) { foreach($y as $assoc => $value) {
$joinTable[] = $this->hasAndBelongsToMany[$assoc]['joinTable']; $joinTable[] = $this->hasAndBelongsToMany[$assoc]['joinTable'];
$mainKey[] = $this->hasAndBelongsToMany[$assoc]['foreignKey']; $mainKey[] = $this->hasAndBelongsToMany[$assoc]['foreignKey'];
$keys[] = $this->hasAndBelongsToMany[$assoc]['foreignKey']; $keys[] = $this->hasAndBelongsToMany[$assoc]['foreignKey'];
$keys[] = $this->hasAndBelongsToMany[$assoc]['associationForeignKey']; $keys[] = $this->hasAndBelongsToMany[$assoc]['associationForeignKey'];
$fields[] = join(',', $keys); $fields[] = join(',', $keys);
unset($keys); unset($keys);
foreach($value as $update) { foreach($value as $update) {
if (!empty($update)) { if (!empty($update)) {
$values[] = $db->value($id, $this->getColumnType($this->primaryKey)); $values[] = $db->value($id, $this->getColumnType($this->primaryKey));
$values[] = $db->value($update); $values[] = $db->value($update);
$values = join(',', $values); $values = join(',', $values);
$newValues[] = "({$values})"; $newValues[] = "({$values})";
unset ($values); unset ($values);
}
}
if (!empty($newValues)) {
$newValue[] = $newValues;
unset($newValues);
} }
} }
if (!empty($newValues)) {
$newValue[] = $newValues;
unset($newValues);
}
}
} }
$total = count($joinTable); $total = count($joinTable);
for($count = 0; $count < $total; $count++) { for($count = 0; $count < $total; $count++) {
$db =& ConnectionManager::getDataSource($this->useDbConfig); $db =& ConnectionManager::getDataSource($this->useDbConfig);
$db->execute("DELETE FROM {$joinTable[$count]} WHERE {$mainKey[$count]} = '{$id}'"); $table = $db->name($db->fullTableName($joinTable[$count]));
$db->execute("DELETE FROM {$table} WHERE {$mainKey[$count]} = '{$id}'");
if (!empty($newValue[$count])) { if (!empty($newValue[$count])) {
$secondCount = count($newValue[$count]); $secondCount = count($newValue[$count]);
for($x = 0; $x < $secondCount; $x++) { for($x = 0; $x < $secondCount; $x++) {
$db->execute("INSERT INTO {$joinTable[$count]} ({$fields[$count]}) VALUES {$newValue[$count][$x]}"); $db->execute("INSERT INTO {$table} ({$fields[$count]}) VALUES {$newValue[$count][$x]}");
}
} }
}
} }
} }
/** /**
* Synonym for del(). * Synonym for del().
* *
@ -958,10 +939,9 @@ class Model extends Object{
* @see function del * @see function del
* @return boolean True on success * @return boolean True on success
*/ */
function remove($id = null) { function remove($id = null, $cascade = true) {
return $this->del($id); return $this->del($id, $cascade);
} }
/** /**
* 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.
* *
@ -970,28 +950,27 @@ class Model extends Object{
*/ */
function del($id = null, $cascade = true) { function del($id = null, $cascade = true) {
if ($id) { if ($id) {
$this->id = $id; $this->id = $id;
} }
$id = $this->id; $id = $this->id;
if ($this->beforeDelete()) { if ($this->beforeDelete()) {
$db =& ConnectionManager::getDataSource($this->useDbConfig); $db =& ConnectionManager::getDataSource($this->useDbConfig);
if ($this->id && $db->delete($this)) { if ($this->id && $db->delete($this)) {
$this->_deleteMulti($id); $this->_deleteMulti($id);
$this->_deleteHasMany($id, $cascade); $this->_deleteHasMany($id, $cascade);
$this->_deleteHasOne($id, $cascade); $this->_deleteHasOne($id, $cascade);
$this->afterDelete(); $this->afterDelete();
$this->_clearCache(); $this->_clearCache();
$this->id = false; $this->id = false;
return true; return true;
} }
} }
return false; return false;
} }
/** /**
* Alias for del() * Alias for del()
* *
@ -1001,7 +980,6 @@ class Model extends Object{
function delete($id = null, $cascade = true) { function delete($id = null, $cascade = true) {
return $this->del($id, $cascade); return $this->del($id, $cascade);
} }
/** /**
* Cascades model deletes to hasMany relationships. * Cascades model deletes to hasMany relationships.
* *
@ -1011,19 +989,18 @@ class Model extends Object{
*/ */
function _deleteHasMany($id, $cascade) { function _deleteHasMany($id, $cascade) {
foreach($this->hasMany as $assoc => $data) { foreach($this->hasMany as $assoc => $data) {
if ($data['dependent'] === true && $cascade === true) { if ($data['dependent'] === true && $cascade === true) {
$model =& $this->{$data['className']}; $model =& $this->{$data['className']};
$field = $model->escapeField($data['foreignKey']); $field = $model->escapeField($data['foreignKey']);
$model->recursive = 0; $model->recursive = 0;
$records = $model->findAll("$field = '$id'", $model->primaryKey, null, null); $records = $model->findAll("$field = '$id'", $model->primaryKey, null, null);
foreach($records as $record) { foreach($records as $record) {
$model->del($record[$data['className']][$model->primaryKey]); $model->del($record[$data['className']][$model->primaryKey]);
}
} }
}
} }
} }
/** /**
* Cascades model deletes to hasOne relationships. * Cascades model deletes to hasOne relationships.
* *
@ -1033,19 +1010,18 @@ class Model extends Object{
*/ */
function _deleteHasOne($id, $cascade) { function _deleteHasOne($id, $cascade) {
foreach($this->hasOne as $assoc => $data) { foreach($this->hasOne as $assoc => $data) {
if ($data['dependent'] === true && $cascade === true) { if ($data['dependent'] === true && $cascade === true) {
$model =& $this->{$data['className']}; $model =& $this->{$data['className']};
$field = $model->escapeField($data['foreignKey']); $field = $model->escapeField($data['foreignKey']);
$model->recursive = 0; $model->recursive = 0;
$records = $model->findAll("$field = '$id'", $model->primaryKey, null, null); $records = $model->findAll("$field = '$id'", $model->primaryKey, null, null);
foreach($records as $record) { foreach($records as $record) {
$model->del($record[$data['className']][$model->primaryKey]); $model->del($record[$data['className']][$model->primaryKey]);
}
} }
}
} }
} }
/** /**
* Cascades model deletes to HABTM join keys. * Cascades model deletes to HABTM join keys.
* *
@ -1055,13 +1031,10 @@ class Model extends Object{
*/ */
function _deleteMulti($id) { function _deleteMulti($id) {
$db =& ConnectionManager::getDataSource($this->useDbConfig); $db =& ConnectionManager::getDataSource($this->useDbConfig);
foreach($this->hasAndBelongsToMany as $assoc => $data) { foreach($this->hasAndBelongsToMany as $assoc => $data) {
$db->execute("DELETE FROM " . $db->name($data['joinTable']) . " WHERE " $db->execute("DELETE FROM " . $db->name($db->fullTableName($data['joinTable'])) . " WHERE " . $db->name($data['foreignKey']) . " = '{$id}'");
. $db->name($data['foreignKey']) . " = '{$id}'");
} }
} }
/** /**
* Returns true if a record with set id exists. * Returns true if a record with set id exists.
* *
@ -1069,19 +1042,17 @@ class Model extends Object{
*/ */
function exists() { function exists() {
if ($this->id) { if ($this->id) {
$id = $this->id; $id = $this->id;
if (is_array($id)) { if (is_array($id)) {
$id = $id[0]; $id = $id[0];
} }
$db =& ConnectionManager::getDataSource($this->useDbConfig); $db =& ConnectionManager::getDataSource($this->useDbConfig);
return $db->hasAny($this, $db->conditions(array($this->primaryKey => $id))); return $db->hasAny($this, array($this->primaryKey => $id));
} }
return false; return false;
} }
/** /**
* Returns true if a record that meets given conditions exists * Returns true if a record that meets given conditions exists
* *
@ -1091,7 +1062,6 @@ class Model extends Object{
function hasAny($conditions = null) { function hasAny($conditions = null) {
return ($this->findCount($conditions) != false); return ($this->findCount($conditions) != false);
} }
/** /**
* 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 * By using the $recursive parameter, the call can access further "levels of association" than
@ -1107,12 +1077,11 @@ class Model extends Object{
$data = $this->findAll($conditions, $fields, $order, 1, null, $recursive); $data = $this->findAll($conditions, $fields, $order, 1, null, $recursive);
if (empty($data[0])) { if (empty($data[0])) {
return false; return false;
} }
return $data[0]; return $data[0];
} }
/** /**
* 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 * By using the $recursive parameter, the call can access further "levels of association" than
@ -1127,45 +1096,41 @@ class Model extends Object{
* @return array Array of records * @return array Array of records
*/ */
function findAll($conditions = null, $fields = null, $order = null, $limit = null, $page = 1, $recursive = null) { function findAll($conditions = null, $fields = null, $order = null, $limit = null, $page = 1, $recursive = null) {
$db =& ConnectionManager::getDataSource($this->useDbConfig); $db =& ConnectionManager::getDataSource($this->useDbConfig);
$this->id = $this->getID(); $this->id = $this->getID();
$offset = 0; $offset = null;
if ($page > 1) { if ($page > 1 && $limit != null) {
$offset = ($page - 1) * $limit; $offset = ($page - 1) * $limit;
} }
$limit_str = '';
if ($limit) {
$limit_str = $db->limit($limit, $offset);
}
if ($order == null) { if ($order == null) {
$order = array(); $order = array();
} else { } else {
$order = array($order); $order = array($order);
} }
$queryData = array('conditions' => $conditions, $queryData = array('conditions' => $conditions,
'fields' => $fields, 'fields' => $fields,
'joins' => array(), 'joins' => array(),
'limit' => $limit_str, 'limit' => $limit,
'order' => $order); 'offset' => $offset,
'order' => $order
);
if (!$this->beforeFind($queryData)) { if (!$this->beforeFind($queryData)) {
return null; return null;
} }
$return = $this->afterFind($db->read($this, $queryData, $recursive)); $return = $this->afterFind($db->read($this, $queryData, $recursive));
if (isset($this->__backAssociation)) { if (isset($this->__backAssociation)) {
$this->__resetAssociations(); $this->__resetAssociations();
} }
return $return; return $return;
} }
/** /**
* Method is called only when bindTo<ModelName>() is used. * Method is called only when bindTo<ModelName>() is used.
* This resets the association arrays for the model back * This resets the association arrays for the model back
@ -1176,15 +1141,14 @@ class Model extends Object{
*/ */
function __resetAssociations() { function __resetAssociations() {
foreach($this->__associations as $type) { foreach($this->__associations as $type) {
if (isset($this->__backAssociation[$type])) { if (isset($this->__backAssociation[$type])) {
$this->{$type} = $this->__backAssociation[$type]; $this->{$type} = $this->__backAssociation[$type];
} }
} }
unset ($this->__backAssociation); unset ($this->__backAssociation);
return true; return true;
} }
/** /**
* Runs a direct query against the bound DataSource, and returns the result. * Runs a direct query against the bound DataSource, and returns the result.
* *
@ -1196,20 +1160,19 @@ class Model extends Object{
$data = $db->fetchAll($data, $this->cacheQueries); $data = $db->fetchAll($data, $this->cacheQueries);
foreach($data as $key => $value) { foreach($data as $key => $value) {
foreach($this->tableToModel as $key1 => $value1) { foreach($this->tableToModel as $key1 => $value1) {
if (isset($data[$key][$key1])) { if (isset($data[$key][$key1])) {
$newData[$key][$value1] = $data[$key][$key1]; $newData[$key][$value1] = $data[$key][$key1];
}
} }
}
} }
if (!empty($newData)) { if (!empty($newData)) {
return $newData; return $newData;
} }
return $data; return $data;
} }
/** /**
* Returns number of rows matching given SQL condition. * Returns number of rows matching given SQL condition.
* *
@ -1222,12 +1185,11 @@ class Model extends Object{
list($data) = $this->findAll($conditions, 'COUNT(*) AS count', null, null, 1, $recursive); list($data) = $this->findAll($conditions, 'COUNT(*) AS count', null, null, 1, $recursive);
if (isset($data[0]['count'])) { if (isset($data[0]['count'])) {
return $data[0]['count']; return $data[0]['count'];
} }
return false; return false;
} }
/** /**
* Special findAll variation for tables joined to themselves. * Special findAll variation for tables joined to themselves.
* The table needs the fields id and parent_id to work. * The table needs the fields id and parent_id to work.
@ -1241,7 +1203,6 @@ class Model extends Object{
function findAllThreaded($conditions = null, $fields = null, $sort = null) { function findAllThreaded($conditions = null, $fields = null, $sort = null) {
return $this->__doThread(Model::findAll($conditions, $fields, $sort), null); return $this->__doThread(Model::findAll($conditions, $fields, $sort), null);
} }
/** /**
* Private, recursive helper method for findAllThreaded. * Private, recursive helper method for findAllThreaded.
* *
@ -1256,23 +1217,21 @@ class Model extends Object{
$sizeOf = sizeof($data); $sizeOf = sizeof($data);
for($ii = 0; $ii < $sizeOf; $ii++) { for($ii = 0; $ii < $sizeOf; $ii++) {
if (($data[$ii][$this->name]['parent_id'] == $root) if (($data[$ii][$this->name]['parent_id'] == $root) || (($root === null) && ($data[$ii][$this->name]['parent_id'] == '0'))) {
|| (($root === null) && ($data[$ii][$this->name]['parent_id'] == '0'))) { $tmp = $data[$ii];
$tmp = $data[$ii];
if (isset($data[$ii][$this->name][$this->primaryKey])) { if (isset($data[$ii][$this->name][$this->primaryKey])) {
$tmp['children'] = $this->__doThread($data, $data[$ii][$this->name][$this->primaryKey]); $tmp['children'] = $this->__doThread($data, $data[$ii][$this->name][$this->primaryKey]);
} else { } else {
$tmp['children'] = null; $tmp['children'] = null;
}
$out[] = $tmp;
} }
$out[] = $tmp;
}
} }
return $out; return $out;
} }
/** /**
* Returns an array with keys "prev" and "next" that holds the id's of neighbouring data, * Returns an array with keys "prev" and "next" that holds the id's of neighbouring data,
* which is useful when creating paged lists. * which is useful when creating paged lists.
@ -1293,16 +1252,15 @@ class Model extends Object{
@list($next) = Model::findAll($conditions . $field . ' > ' . $db->value($value), $field, $field . ' ASC', 1, null, 0); @list($next) = Model::findAll($conditions . $field . ' > ' . $db->value($value), $field, $field . ' ASC', 1, null, 0);
if (!isset($prev)) { if (!isset($prev)) {
$prev = null; $prev = null;
} }
if (!isset($next)) { if (!isset($next)) {
$next = null; $next = null;
} }
return array('prev' => $prev, 'next' => $next); return array('prev' => $prev, 'next' => $next);
} }
/** /**
* Returns a resultset for given SQL statement. Generic SQL queries should be made with this method. * Returns a resultset for given SQL statement. Generic SQL queries should be made with this method.
* *
@ -1314,22 +1272,16 @@ class Model extends Object{
$db =& ConnectionManager::getDataSource($this->useDbConfig); $db =& ConnectionManager::getDataSource($this->useDbConfig);
return call_user_func_array(array(&$db, 'query'), $params); return call_user_func_array(array(&$db, 'query'), $params);
} }
/** /**
* Returns true if all fields pass validation, otherwise false. * 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
*/ */
function validates($data = null) { function validates($data = array()) {
if ($data == null) {
$data = $this->data;
}
$errors = $this->invalidFields($data); $errors = $this->invalidFields($data);
return count($errors) == 0; return count($errors) == 0;
} }
/** /**
* Returns an array of invalid fields. * Returns an array of invalid fields.
* *
@ -1337,6 +1289,10 @@ class Model extends Object{
* @return array Array of invalid fields * @return array Array of invalid fields
*/ */
function invalidFields($data = array()) { function invalidFields($data = array()) {
if (empty($data)) {
$data = $this->data;
}
if (!$this->beforeValidate()) { if (!$this->beforeValidate()) {
return false; return false;
} }
@ -1345,10 +1301,9 @@ class Model extends Object{
return true; return true;
} }
if (!empty($data)){ if (!empty($data)) {
$data = $data; $data = $data;
} } elseif (isset($this->data)) {
elseif (isset($this->data)){
$data = $this->data; $data = $this->data;
} }
@ -1363,7 +1318,6 @@ class Model extends Object{
} }
return $this->validationErrors; return $this->validationErrors;
} }
/** /**
* Sets a field as invalid * Sets a field as invalid
* *
@ -1374,10 +1328,8 @@ class Model extends Object{
if (!is_array($this->validationErrors)) { if (!is_array($this->validationErrors)) {
$this->validationErrors = array(); $this->validationErrors = array();
} }
$this->validationErrors[$field] = 1; $this->validationErrors[$field] = 1;
} }
/** /**
* Returns true if given field name is a foreign key in this Model. * Returns true if given field name is a foreign key in this Model.
* *
@ -1392,10 +1344,8 @@ class Model extends Object{
$foreignKeys[] = $data['foreignKey']; $foreignKeys[] = $data['foreignKey'];
} }
} }
return (bool)(in_array($field, $foreignKeys)); return (bool)(in_array($field, $foreignKeys));
} }
/** /**
* Gets the display field for this model * Gets the display field for this model
* *
@ -1404,7 +1354,6 @@ class Model extends Object{
function getDisplayField() { function getDisplayField() {
return $this->displayField; return $this->displayField;
} }
/** /**
* 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. * Method can be used to generate option lists for SELECT elements.
@ -1419,10 +1368,10 @@ class Model extends Object{
function generateList($conditions = null, $order = null, $limit = null, $keyPath = null, $valuePath = null) { function generateList($conditions = null, $order = null, $limit = null, $keyPath = null, $valuePath = null) {
$db =& ConnectionManager::getDataSource($this->useDbConfig); $db =& ConnectionManager::getDataSource($this->useDbConfig);
if ($keyPath == null && $valuePath == null) { if ($keyPath == null && $valuePath == null && $this->hasField($this->displayField)) {
$fields = array($this->primaryKey, $this->displayField); $fields = array($this->primaryKey, $this->displayField);
} else { } else {
$fields = '*'; $fields = null;
} }
$result = $this->findAll($conditions, $fields, $order, $limit, 1, 0); $result = $this->findAll($conditions, $fields, $order, $limit, 1, 0);
@ -1443,7 +1392,6 @@ class Model extends Object{
return $return; return $return;
} }
} }
/** /**
* Escapes the field name and prepends the model name. Escaping will be done according to the current database driver's rules. * Escapes the field name and prepends the model name. Escaping will be done according to the current database driver's rules.
* *
@ -1454,7 +1402,6 @@ class Model extends Object{
$db =& ConnectionManager::getDataSource($this->useDbConfig); $db =& ConnectionManager::getDataSource($this->useDbConfig);
return $db->name($this->name) . '.' . $db->name($field); return $db->name($this->name) . '.' . $db->name($field);
} }
/** /**
* Returns the current record's ID * Returns the current record's ID
* *
@ -1480,7 +1427,6 @@ class Model extends Object{
return false; return false;
} }
/** /**
* Returns the ID of the last record this Model inserted * Returns the ID of the last record this Model inserted
* *
@ -1489,7 +1435,6 @@ class Model extends Object{
function getLastInsertID() { function getLastInsertID() {
return $this->getInsertID(); return $this->getInsertID();
} }
/** /**
* Returns the ID of the last record this Model inserted * Returns the ID of the last record this Model inserted
* *
@ -1498,7 +1443,6 @@ class Model extends Object{
function getInsertID() { function getInsertID() {
return $this->__insertID; return $this->__insertID;
} }
/** /**
* Returns the number of rows returned from the last query * Returns the number of rows returned from the last query
* *
@ -1509,7 +1453,6 @@ class Model extends Object{
$db =& ConnectionManager::getDataSource($this->useDbConfig); $db =& ConnectionManager::getDataSource($this->useDbConfig);
return $db->lastNumRows(); return $db->lastNumRows();
} }
/** /**
* Returns the number of rows affected by the last query * Returns the number of rows affected by the last query
* *
@ -1520,7 +1463,6 @@ class Model extends Object{
$db =& ConnectionManager::getDataSource($this->useDbConfig); $db =& ConnectionManager::getDataSource($this->useDbConfig);
return $db->lastAffected(); return $db->lastAffected();
} }
/** /**
* Sets the DataSource to which this model is bound * Sets the DataSource to which this model is bound
* *
@ -1542,7 +1484,6 @@ class Model extends Object{
return $this->cakeError('missingConnection', array(array('className' => $this->name))); return $this->cakeError('missingConnection', array(array('className' => $this->name)));
} }
} }
/** /**
* Before find callback * Before find callback
* *
@ -1552,7 +1493,6 @@ class Model extends Object{
function beforeFind(&$queryData) { function beforeFind(&$queryData) {
return true; return true;
} }
/** /**
* After find callback. Can be used to modify any results returned by find and findAll. * After find callback. Can be used to modify any results returned by find and findAll.
* *
@ -1562,7 +1502,6 @@ class Model extends Object{
function afterFind($results) { function afterFind($results) {
return $results; return $results;
} }
/** /**
* Before save callback * Before save callback
* *
@ -1571,7 +1510,6 @@ class Model extends Object{
function beforeSave() { function beforeSave() {
return true; return true;
} }
/** /**
* After save callback * After save callback
* *
@ -1580,7 +1518,6 @@ class Model extends Object{
function afterSave() { function afterSave() {
return true; return true;
} }
/** /**
* Before delete callback * Before delete callback
* *
@ -1589,7 +1526,6 @@ class Model extends Object{
function beforeDelete() { function beforeDelete() {
return true; return true;
} }
/** /**
* After delete callback * After delete callback
* *
@ -1598,7 +1534,6 @@ class Model extends Object{
function afterDelete() { function afterDelete() {
return true; return true;
} }
/** /**
* Before validate callback * Before validate callback
* *
@ -1607,7 +1542,6 @@ class Model extends Object{
function beforeValidate() { function beforeValidate() {
return true; return true;
} }
/** /**
* Private method. Clears cache for this model * Private method. Clears cache for this model
* *
@ -1636,7 +1570,6 @@ class Model extends Object{
//Will use for query cache deleting //Will use for query cache deleting
} }
} }
/** /**
* Called when serializing a model * Called when serializing a model
* *

View file

@ -84,12 +84,15 @@ class Object{
function requestAction($url, $extra = array()) { function requestAction($url, $extra = array()) {
if (!empty($url)) { if (!empty($url)) {
$dispatcher =& new Dispatcher(); $dispatcher =& new Dispatcher();
if(isset($this->plugin)){
$extra['plugin'] = $this->plugin;
}
if (in_array('return', $extra)) { if (in_array('return', $extra)) {
$extra['return'] = 0; $extra['return'] = 0;
$extra['bare'] = 1; $extra['bare'] = 1;
ob_start(); ob_start();
$out=$dispatcher->dispatch($url, $extra); $out = $dispatcher->dispatch($url, $extra);
$out=ob_get_clean(); $out = ob_get_clean();
return $out; return $out;
} else { } else {
$extra['return'] = 1; $extra['return'] = 1;

View file

@ -426,8 +426,8 @@ class CakeSession extends Object{
$table = $db->fullTableName(CAKE_SESSION_TABLE); $table = $db->fullTableName(CAKE_SESSION_TABLE);
$row = $db->query("SELECT " . $db->name($table.'.data') . " FROM " . $db->name($table) . " WHERE " . $db->name($table.'.id') . " = " . $db->value($key), false); $row = $db->query("SELECT " . $db->name($table.'.data') . " FROM " . $db->name($table) . " WHERE " . $db->name($table.'.id') . " = " . $db->value($key), false);
if ($row && $row[0][$table]['data']) { if ($row && $row[0][CAKE_SESSION_TABLE]['data']) {
return $row[0][$table]['data']; return $row[0][CAKE_SESSION_TABLE]['data'];
} else { } else {
return false; return false;
} }
@ -527,7 +527,7 @@ class CakeSession extends Object{
$factor = 10; $factor = 10;
break; break;
case 'medium': case 'medium':
$facto = 100; $factor = 100;
break; break;
case 'low': case 'low':
$factor = 300; $factor = 300;
@ -538,17 +538,17 @@ class CakeSession extends Object{
} }
$expires = time() + CAKE_SESSION_TIMEOUT * $factor; $expires = time() + CAKE_SESSION_TIMEOUT * $factor;
$row = $db->query("SELECT COUNT(id) AS count FROM " . $db->name($table) . " WHERE " $row = $db->query("SELECT COUNT(id) AS count FROM " . $db->name($table) . " WHERE "
. $db->name($table.'.id') . " = " . $db->name('id') . " = "
. $db->value($key), false); . $db->value($key), false);
if ($row[0][0]['count'] > 0) { if ($row[0][0]['count'] > 0) {
$db->execute("UPDATE " . $db->name($table) . " SET " . $db->name('data') . " = " $db->execute("UPDATE " . $db->name($table) . " SET " . $db->name('data') . " = "
. $db->value($value) . ", " . $db->name($table.'.expires') . " = " . $db->value($value) . ", " . $db->name('expires') . " = "
. $db->value($expires) . " WHERE " . $db->name($table.'.id') . " = " . $db->value($expires) . " WHERE " . $db->name('id') . " = "
. $db->value($key)); . $db->value($key));
} else { } else {
$db->execute("INSERT INTO " . $db->name($table) . " (" . $db->name('data') . "," $db->execute("INSERT INTO " . $db->name($table) . " (" . $db->name('data') . ","
. $db->name($table.'.expires') . "," . $db->name($table.'.id') . $db->name('expires') . "," . $db->name('id')
. ") VALUES (" . $db->value($value) . ", " . $db->value($expires) . ", " . ") VALUES (" . $db->value($value) . ", " . $db->value($expires) . ", "
. $db->value($key) . ")"); . $db->value($key) . ")");
} }

View file

@ -36,14 +36,7 @@
* @package cake * @package cake
* @subpackage cake.cake.libs.view * @subpackage cake.cake.libs.view
*/ */
class Helper extends Object{ class Helper extends Object {
/*************************************************************************
* Public variables
*************************************************************************/
/**#@+
* @access public
*/
/** /**
* Holds tag templates. * Holds tag templates.
@ -51,35 +44,22 @@ class Helper extends Object{
* @access public * @access public
* @var array * @var array
*/ */
var $tags = array(); var $tags = array();
/**#@-*/
/*************************************************************************
* Public methods
*************************************************************************/
/**#@+
* @access public
*/
/** /**
* Parses tag templates into $this->tags. * Parses tag templates into $this->tags.
* *
* @return void * @return void
*/ */
function loadConfig() { function loadConfig() {
$config=fileExistsInPath(CAKE . 'config' . DS . 'tags.ini.php'); $config = fileExistsInPath(CAKE . 'config' . DS . 'tags.ini.php');
$cakeConfig=$this->readConfigFile($config); $cakeConfig = $this->readConfigFile($config);
if (file_exists(APP . 'config' . DS . 'tags.ini.php')) {
$appConfig=$this->readConfigFile(APP . 'config' . DS . 'tags.ini.php');
$cakeConfig=array_merge($cakeConfig, $appConfig);
}
return $cakeConfig;
}
if (file_exists(APP . 'config' . DS . 'tags.ini.php')) {
$appConfig = $this->readConfigFile(APP . 'config' . DS . 'tags.ini.php');
$cakeConfig = am($cakeConfig, $appConfig);
}
return $cakeConfig;
}
/** /**
* Decides whether to output or return a string. * Decides whether to output or return a string.
* *
@ -92,15 +72,14 @@ class Helper extends Object{
* @return mixed Either string or boolean value, depends on AUTO_OUTPUT * @return mixed Either string or boolean value, depends on AUTO_OUTPUT
* and $return. * and $return.
*/ */
function output($str, $return = false) { function output($str, $return = false) {
if (AUTO_OUTPUT && $return === false) { if (AUTO_OUTPUT && $return === false) {
echo $str; echo $str;
return true; return true;
} else { } else {
return $str; return $str;
} }
} }
/** /**
* Assigns values to tag templates. * Assigns values to tag templates.
* *
@ -111,49 +90,49 @@ class Helper extends Object{
* @param array $values Values to be inserted into tag. * @param array $values Values to be inserted into tag.
* @return string Tag with inserted values. * @return string Tag with inserted values.
*/ */
function assign($keyName, $values) { function assign($keyName, $values) {
return str_replace('%%' . array_keys($values) . '%%', array_values($values), $this->tags[$keyName]); return str_replace('%%' . array_keys($values) . '%%', array_values($values), $this->tags[$keyName]);
} }
/** /**
* Returns an array of settings in given INI file. * Returns an array of settings in given INI file.
* *
* @param string $fileName * @param string $fileName
* @return array * @return array
*/ */
function readConfigFile($fileName) { function readConfigFile($fileName) {
$fileLineArray=file($fileName); $fileLineArray = file($fileName);
foreach($fileLineArray as $fileLine) { foreach($fileLineArray as $fileLine) {
$dataLine = trim($fileLine); $dataLine = trim($fileLine);
$firstChar=substr($dataLine, 0, 1); $firstChar = substr($dataLine, 0, 1);
if ($firstChar != ';' && $dataLine != '') { if ($firstChar != ';' && $dataLine != '') {
if ($firstChar == '[' && substr($dataLine, -1, 1) == ']') { if ($firstChar == '[' && substr($dataLine, -1, 1) == ']') {
// [section block] we might use this later do not know for sure // [section block] we might use this later do not know for sure
// this could be used to add a key with the section block name // this could be used to add a key with the section block name
// but it adds another array level // but it adds another array level
} else {
$delimiter=strpos($dataLine, '=');
if ($delimiter > 0) {
$key =strtolower(trim(substr($dataLine, 0, $delimiter)));
$value=trim(substr($dataLine, $delimiter + 1));
if (substr($value, 0, 1) == '"' && substr($value, -1) == '"') {
$value = substr($value, 1, -1);
}
$iniSetting[$key]=stripcslashes($value);
} else {
$iniSetting[strtolower(trim($dataLine))] = '';
}
}
} else { } else {
} $delimiter = strpos($dataLine, '=');
}
return $iniSetting; if ($delimiter > 0) {
} $key = strtolower(trim(substr($dataLine, 0, $delimiter)));
$value = trim(substr($dataLine, $delimiter + 1));
if (substr($value, 0, 1) == '"' && substr($value, -1) == '"') {
$value = substr($value, 1, -1);
}
$iniSetting[$key] = stripcslashes($value);
} else {
$iniSetting[strtolower(trim($dataLine))] = '';
}
}
} else {
}
}
return $iniSetting;
}
/** /**
* After render callback. Overridden in subclasses. * After render callback. Overridden in subclasses.
* *
@ -161,7 +140,6 @@ class Helper extends Object{
*/ */
function afterRender() { function afterRender() {
} }
/**#@-*/
} }
?> ?>

View file

@ -654,8 +654,8 @@ class AjaxHelper extends Helper {
case 'requestHeaders': case 'requestHeaders':
$keys = array(); $keys = array();
foreach ($value as $key => $val) { foreach ($value as $key => $val) {
$keys[] = '"' . $key . '"'; $keys[] = "'" . $key . "'";
$keys[] = '"' . $val . '"'; $keys[] = "'" . $val . "'";
} }
$js_options['requestHeaders'] = '[' . join(', ', $keys) . ']'; $js_options['requestHeaders'] = '[' . join(', ', $keys) . ']';
break; break;
@ -762,13 +762,18 @@ class AjaxHelper extends Helper {
function afterRender() { function afterRender() {
if (env('HTTP_X_UPDATE') != null && count($this->__ajaxBuffer) > 0) { if (env('HTTP_X_UPDATE') != null && count($this->__ajaxBuffer) > 0) {
$data = array(); $data = array();
$divs = explode(' ', env('HTTP_X_UPDATE'));
foreach ($this->__ajaxBuffer as $key => $val) { foreach ($this->__ajaxBuffer as $key => $val) {
$data[] = $key . ':"' . rawurlencode($val) . '"'; if (in_array($key, $divs)) {
$data[] = $key . ':"' . rawurlencode($val) . '"';
}
} }
$out = 'var __ajaxUpdater__ = {' . join(', ', $data) . '};' . "\n"; $out = 'var __ajaxUpdater__ = {' . join(', ', $data) . '};' . "\n";
$out .= 'for (n in __ajaxUpdater__) { if (typeof __ajaxUpdater__[n] == "string" && $(n)) Element.update($(n), unescape(__ajaxUpdater__[n])); }'; $out .= 'for (n in __ajaxUpdater__) { if (typeof __ajaxUpdater__[n] == "string" && $(n)) Element.update($(n), unescape(__ajaxUpdater__[n])); }';
@ob_end_clean();
e($this->Javascript->codeBlock($out)); e($this->Javascript->codeBlock($out));
exit(); exit();
} }

View file

@ -1,6 +1,5 @@
<?php <?php
/* SVN FILE: $Id$ */ /* SVN FILE: $Id$ */
/** /**
* Automatic generation of HTML FORMs from given data. * Automatic generation of HTML FORMs from given data.
* *
@ -27,27 +26,22 @@
* @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
*/ */
/** /**
* Tag template for a div with a class attribute. * Tag template for a div with a class attribute.
*/ */
define('TAG_DIV', '<div class="%s">%s</div>'); define('TAG_DIV', '<div class="%s">%s</div>');
/** /**
* Tag template for a paragraph with a class attribute. * Tag template for a paragraph with a class attribute.
*/ */
define('TAG_P_CLASS', '<p class="%s">%s</p>'); define('TAG_P_CLASS', '<p class="%s">%s</p>');
/** /**
* Tag template for a label with a for attribute. * Tag template for a label with a for attribute.
*/ */
define('TAG_LABEL', '<label for="%s">%s</label>'); define('TAG_LABEL', '<label for="%s">%s</label>');
/** /**
* Tag template for a fieldset with a legend tag inside. * Tag template for a fieldset with a legend tag inside.
*/ */
define('TAG_FIELDSET', '<fieldset><legend>%s</legend>%s</label>'); define('TAG_FIELDSET', '<fieldset><legend>%s</legend>%s</label>');
/** /**
* Form helper library. * Form helper library.
* *
@ -65,7 +59,6 @@ class FormHelper extends Helper{
*/ */
function FormHelper() { function FormHelper() {
} }
/** /**
* Returns a formatted error message for given FORM field, NULL if no errors. * Returns a formatted error message for given FORM field, NULL if no errors.
* *
@ -82,7 +75,6 @@ class FormHelper extends Helper{
return false; return false;
} }
} }
/** /**
* Returns a formatted LABEL element for HTML FORMs. * Returns a formatted LABEL element for HTML FORMs.
* *
@ -93,7 +85,6 @@ class FormHelper extends Helper{
function labelTag($tagName, $text) { function labelTag($tagName, $text) {
return sprintf(TAG_LABEL, strtolower(str_replace('/', '_', $tagName)), $text); return sprintf(TAG_LABEL, strtolower(str_replace('/', '_', $tagName)), $text);
} }
/** /**
* Returns a formatted DIV tag for HTML FORMs. * Returns a formatted DIV tag for HTML FORMs.
* *
@ -104,7 +95,6 @@ class FormHelper extends Helper{
function divTag($class, $text) { function divTag($class, $text) {
return sprintf(TAG_DIV, $class, $text); return sprintf(TAG_DIV, $class, $text);
} }
/** /**
* Returns a formatted P tag with class for HTML FORMs. * Returns a formatted P tag with class for HTML FORMs.
* *
@ -115,7 +105,6 @@ class FormHelper extends Helper{
function pTag($class, $text) { function pTag($class, $text) {
return sprintf(TAG_P_CLASS, $class, $text); return sprintf(TAG_P_CLASS, $class, $text);
} }
/** /**
* Returns a formatted INPUT tag for HTML FORMs. * Returns a formatted INPUT tag for HTML FORMs.
* *
@ -127,32 +116,25 @@ class FormHelper extends Helper{
* @param array $htmlOptions HTML options array. * @param array $htmlOptions HTML options array.
* @return string The formatted INPUT element, with a label and wrapped in a div. * @return string The formatted INPUT element, with a label and wrapped in a div.
*/ */
function generateInputDiv($tagName, $prompt, $required = false, $errorMsg = null, $size = 20, function generateInputDiv($tagName, $prompt, $required = false, $errorMsg = null, $size = 20, $htmlOptions = null) {
$htmlOptions = null) {
$htmlOptions['id'] = strtolower(str_replace('/', '_', $tagName)); $htmlOptions['id'] = strtolower(str_replace('/', '_', $tagName));
$htmlAttributes = $htmlOptions; $htmlAttributes = $htmlOptions;
$htmlAttributes['size'] = $size; $htmlAttributes['size'] = $size;
$str = $this->Html->input($tagName, $htmlAttributes); $str = $this->Html->input($tagName, $htmlAttributes);
$strLabel = $this->labelTag($tagName, $prompt); $strLabel = $this->labelTag($tagName, $prompt);
$divClass = "optional"; $divClass = "optional";
if ($required) { if ($required) {
$divClass = "required"; $divClass = "required";
} }
$strError = "";
$strError = ""; // initialize the error to empty.
if ($this->isFieldError($tagName)) { if ($this->isFieldError($tagName)) {
// if it was an error that occured, then add the error message, and append " error" to the div tag.
$strError = $this->pTag('error', $errorMsg); $strError = $this->pTag('error', $errorMsg);
$divClass = sprintf("%s error", $divClass); $divClass = sprintf("%s error", $divClass);
} }
$divTagInside = sprintf("%s %s %s", $strError, $strLabel, $str); $divTagInside = sprintf("%s %s %s", $strError, $strLabel, $str);
return $this->divTag($divClass, $divTagInside); return $this->divTag($divClass, $divTagInside);
} }
/** /**
* Returns a formatted CHECKBOX tag inside a DIV for HTML FORMs. * Returns a formatted CHECKBOX tag inside a DIV for HTML FORMs.
* *
@ -163,32 +145,24 @@ class FormHelper extends Helper{
* @param array $htmlOptions HTML options array. * @param array $htmlOptions HTML options array.
* @return string The formatted checkbox div * @return string The formatted checkbox div
*/ */
function generateCheckboxDiv($tagName, $prompt, $required = false, $errorMsg = null, $htmlOptions = null) function generateCheckboxDiv($tagName, $prompt, $required = false, $errorMsg = null, $htmlOptions = null) {
{ $htmlOptions['class'] = "inputCheckbox";
$htmlOptions['class']="inputCheckbox"; $htmlOptions['id'] = strtolower(str_replace('/', '_', $tagName));
$htmlOptions['id'] =strtolower(str_replace('/', '_', $tagName)); $str = $this->Html->checkbox($tagName, null, $htmlOptions);
; $strLabel = $this->labelTag($tagName, $prompt);
$str =$this->Html->checkbox($tagName, null, $htmlOptions); $divClass = "optional";
$strLabel =$this->labelTag($tagName, $prompt); if ($required) {
$divClass = "required";
$divClass ="optional"; }
$strError = "";
if ($required)
$divClass="required";
$strError=""; // initialize the error to empty.
if ($this->isFieldError($tagName)) { if ($this->isFieldError($tagName)) {
// if it was an error that occured, then add the error message, and append " error" to the div tag. $strError = $this->pTag('error', $errorMsg);
$strError=$this->pTag('error', $errorMsg); $divClass = sprintf("%s error", $divClass);
$divClass=sprintf("%s error", $divClass);
} }
$divTagInside = sprintf("%s %s %s", $strError, $strLabel, $str);
$divTagInside=sprintf("%s %s %s", $strError, $strLabel, $str);
return $this->divTag($divClass, $divTagInside); return $this->divTag($divClass, $divTagInside);
} }
/** /**
* Returns a formatted date option element for HTML FORMs. * Returns a formatted date option element for HTML FORMs.
* *
@ -201,34 +175,24 @@ class FormHelper extends Helper{
* @param array $htmlOptions HTML options array * @param array $htmlOptions HTML options array
* @return string Date option wrapped in a div. * @return string Date option wrapped in a div.
*/ */
function generateDate($tagName, $prompt, $required = false, $errorMsg = null, $size = 20, $htmlOptions = function generateDate($tagName, $prompt, $required = false, $errorMsg = null, $size = 20, $htmlOptions = null, $selected = null) {
null,
$selected = null) {
$htmlOptions['id']=strtolower(str_replace('/', '_', $tagName)); $htmlOptions['id']=strtolower(str_replace('/', '_', $tagName));
; $str = $this->Html->dateTimeOptionTag($tagName, 'MDY', 'NONE', $selected, $htmlOptions);
$str =$this->Html->dateTimeOptionTag($tagName, 'MDY', 'NONE', $selected, $htmlOptions); $strLabel = $this->labelTag($tagName, $prompt);
$strLabel =$this->labelTag($tagName, $prompt); $divClass = "optional";
if ($required) {
$divClass ="optional"; $divClass = "required";
}
if ($required) $strError = "";
$divClass="required";
$strError=""; // initialize the error to empty.
if ($this->isFieldError($tagName)) { if ($this->isFieldError($tagName)) {
// if it was an error that occured, then add the error message, and append " error" to the div tag. $strError = $this->pTag('error', $errorMsg);
$strError=$this->pTag('error', $errorMsg); $divClass = sprintf("%s error", $divClass);
$divClass=sprintf("%s error", $divClass);
} }
$divTagInside = sprintf("%s %s %s", $strError, $strLabel, $str);
$divTagInside=sprintf("%s %s %s", $strError, $strLabel, $str); $requiredDiv = $this->divTag($divClass, $divTagInside);
$requiredDiv =$this->divTag($divClass, $divTagInside);
return $this->divTag("date", $requiredDiv); return $this->divTag("date", $requiredDiv);
} }
/** /**
* Returns a formatted datetime option element for HTML FORMs. * Returns a formatted datetime option element for HTML FORMs.
* *
@ -242,33 +206,24 @@ class FormHelper extends Helper{
* @param array $selected Selected index in the dateTimeOption tag. * @param array $selected Selected index in the dateTimeOption tag.
* @return string The formatted datetime option element wrapped in a div. * @return string The formatted datetime option element wrapped in a div.
*/ */
function generateDateTime($tagName, $prompt, $required = false, $errorMsg = null, $size = 20, function generateDateTime($tagName, $prompt, $required = false, $errorMsg = null, $size = 20, $htmlOptions = null, $selected = null) {
$htmlOptions = null, $selected = null) {
$htmlOptions['id']=strtolower(str_replace('/', '_', $tagName)); $htmlOptions['id']=strtolower(str_replace('/', '_', $tagName));
; $str = $this->Html->dateTimeOptionTag($tagName, 'MDY', '12', $selected, $htmlOptions);
$str =$this->Html->dateTimeOptionTag($tagName, 'MDY', '12', $selected, $htmlOptions); $strLabel = $this->labelTag($tagName, $prompt);
$strLabel =$this->labelTag($tagName, $prompt); $divClass = "optional";
if ($required) {
$divClass ="optional"; $divClass = "required";
}
if ($required) $strError = "";
$divClass="required";
$strError=""; // initialize the error to empty.
if ($this->isFieldError($tagName)) { if ($this->isFieldError($tagName)) {
// if it was an error that occured, then add the error message, and append " error" to the div tag. $strError = $this->pTag('error', $errorMsg);
$strError=$this->pTag('error', $errorMsg); $divClass = sprintf("%s error", $divClass);
$divClass=sprintf("%s error", $divClass);
} }
$divTagInside = sprintf("%s %s %s", $strError, $strLabel, $str);
$divTagInside=sprintf("%s %s %s", $strError, $strLabel, $str); $requiredDiv = $this->divTag($divClass, $divTagInside);
$requiredDiv =$this->divTag($divClass, $divTagInside);
return $this->divTag("date", $requiredDiv); return $this->divTag("date", $requiredDiv);
} }
/** /**
* Returns a formatted TEXTAREA inside a DIV for use with HTML forms. * Returns a formatted TEXTAREA inside a DIV for use with HTML forms.
* *
@ -281,33 +236,27 @@ class FormHelper extends Helper{
* @param array $htmlOptions HTML options array. * @param array $htmlOptions HTML options array.
* @return string The formatted TEXTAREA element, wrapped in a div. * @return string The formatted TEXTAREA element, wrapped in a div.
*/ */
function generateAreaDiv($tagName, $prompt, $required = false, $errorMsg = null, $cols = 60, $rows = 10, function generateAreaDiv($tagName, $prompt, $required = false, $errorMsg = null, $cols = 60, $rows = 10, $htmlOptions = null) {
$htmlOptions = null) { $htmlOptions['id'] = strtolower(str_replace('/', '_', $tagName));
$htmlOptions['id'] =strtolower(str_replace('/', '_', $tagName)); $htmlAttributes = $htmlOptions;
$htmlAttributes =$htmlOptions; $htmlAttributes['cols'] = $cols;
$htmlAttributes['cols']=$cols; $htmlAttributes['rows'] = $rows;
$htmlAttributes['rows']=$rows; $str = $this->Html->textarea($tagName, $htmlAttributes);
$str =$this->Html->textarea($tagName, $htmlAttributes); $strLabel = $this->labelTag($tagName, $prompt);
$strLabel =$this->labelTag($tagName, $prompt); $divClass = "optional";
$divClass ="optional"; if ($required) {
$divClass="required";
if ($required) }
$divClass="required"; $strError = "";
$strError=""; // initialize the error to empty.
if ($this->isFieldError($tagName)) { if ($this->isFieldError($tagName)) {
// if it was an error that occured, then add the error message, and append " error" to the div tag. $strError = $this->pTag('error', $errorMsg);
$strError=$this->pTag('error', $errorMsg); $divClass = sprintf("%s error", $divClass);
$divClass=sprintf("%s error", $divClass);
} }
$divTagInside = sprintf("%s %s %s", $strError, $strLabel, $str);
$divTagInside=sprintf("%s %s %s", $strError, $strLabel, $str);
return $this->divTag($divClass, $divTagInside); return $this->divTag($divClass, $divTagInside);
} }
/** /**
* Returns a formatted SELECT tag for HTML FORMs. * Returns a formatted SELECT tag for HTML FORMs.
* *
@ -321,31 +270,24 @@ class FormHelper extends Helper{
* @param string $errorMsg Text that will appear if an error has occurred * @param string $errorMsg Text that will appear if an error has occurred
* @return string The formatted INPUT element, wrapped in a div * @return string The formatted INPUT element, wrapped in a div
*/ */
function generateSelectDiv($tagName, $prompt, $options, $selected = null, $selectAttr = null, function generateSelectDiv($tagName, $prompt, $options, $selected = null, $selectAttr = null, $optionAttr = null, $required = false, $errorMsg = null) {
$optionAttr = null, $required = false, $errorMsg = null) { $selectAttr['id'] = strtolower(str_replace('/', '_', $tagName));
$selectAttr['id']=strtolower(str_replace('/', '_', $tagName)); $str = $this->Html->selectTag($tagName, $options, $selected, $selectAttr, $optionAttr);
$str =$this->Html->selectTag($tagName, $options, $selected, $selectAttr, $optionAttr); $strLabel = $this->labelTag($tagName, $prompt);
$strLabel =$this->labelTag($tagName, $prompt); $divClass = "optional";
$divClass ="optional";
if ($required) { if ($required) {
$divClass = "required"; $divClass = "required";
} }
$strError = "";
$strError=""; // initialize the error to empty.
if ($this->isFieldError($tagName)) { if ($this->isFieldError($tagName)) {
// if it was an error that occured, then add the error message, and append " error" to the div tag. $strError=$this->pTag('error', $errorMsg);
$strError=$this->pTag('error', $errorMsg); $divClass=sprintf("%s error", $divClass);
$divClass=sprintf("%s error", $divClass);
} }
$divTagInside = sprintf("%s %s %s", $strError, $strLabel, $str);
$divTagInside=sprintf("%s %s %s", $strError, $strLabel, $str);
return $this->divTag($divClass, $divTagInside); return $this->divTag($divClass, $divTagInside);
} }
/** /**
* Returns a formatted submit widget for HTML FORMs. * Returns a formatted submit widget for HTML FORMs.
* *
@ -356,7 +298,6 @@ class FormHelper extends Helper{
function generateSubmitDiv($displayText, $htmlOptions = null) { function generateSubmitDiv($displayText, $htmlOptions = null) {
return $this->divTag('submit', $this->Html->submitTag($displayText, $htmlOptions)); return $this->divTag('submit', $this->Html->submitTag($displayText, $htmlOptions));
} }
/** /**
* Generates a form to go onto a HtmlHelper object. * Generates a form to go onto a HtmlHelper object.
* *
@ -365,142 +306,109 @@ class FormHelper extends Helper{
* @return string The completed form specified by the $fields parameter * @return string The completed form specified by the $fields parameter
*/ */
function generateFields($fields, $readOnly = false) { function generateFields($fields, $readOnly = false) {
$strFormFields=''; $strFormFields = '';
foreach($fields as $field) { foreach($fields as $field) {
if (isset($field['type'])) { if (isset($field['type'])) {
if (!isset($field['required'])) {
$field['required'] = false;
}
if (!isset($field['errorMsg'])) { if (!isset($field['required'])) {
$field['errorMsg'] = null; $field['required'] = false;
}
if (!isset($field['htmlOptions'])) {
$field['htmlOptions'] = array();
}
if ($readOnly) {
$field['htmlOptions']['READONLY'] = "readonly";
}
switch($field['type'])
{
case "input":
if (!isset($field['size'])) {
$field['size'] = 40;
}
$strFormFields=
$strFormFields . $this->generateInputDiv($field['tagName'], $field['prompt'],
$field['required'],
$field['errorMsg'], $field['size'],
$field['htmlOptions']);
break;
case "checkbox":
$strFormFields=
$strFormFields . $this->generateCheckboxDiv($field['tagName'], $field['prompt'],
$field['required'],
$field['errorMsg'],
$field['htmlOptions']);
break;
case "select":
case "selectMultiple":
if ("selectMultiple" == $field['type']) {
$field['selectAttr']['multiple']='multiple';
$field['selectAttr']['class'] ='selectMultiple';
}
if (!isset($field['selected'])) {
$field['selected'] = null;
}
if (!isset($field['selectAttr'])) {
$field['selectAttr'] = null;
}
if (!isset($field['optionsAttr'])) {
$field['optionsAttr'] = null;
}
if ($readOnly) {
$field['selectAttr']['DISABLED'] = true;
}
if (!isset($field['options'])) {
$field['options'] = null;
}
$strFormFields=
$strFormFields . $this->generateSelectDiv($field['tagName'], $field['prompt'],
$field['options'],
$field['selected'],
$field['selectAttr'],
$field['optionsAttr'],
$field['required'],
$field['errorMsg']);
break;
case "area":
if (!isset($field['rows'])) {
$field['rows'] = 10;
}
if (!isset($field['cols'])) {
$field['cols'] = 60;
}
$strFormFields=
$strFormFields . $this->generateAreaDiv($field['tagName'], $field['prompt'],
$field['required'],
$field['errorMsg'], $field['cols'],
$field['rows'],
$field['htmlOptions']);
break;
case "fieldset":
$strFieldsetFields=$this->generateFields($field['fields']);
$strFieldSet =sprintf('
<fieldset><legend>%s</legend><div class="notes"><h4>%s</h4><p class="last">%s</p></div>%s</fieldset>', $field['legend'], $field['noteHeading'], $field['note'],
$strFieldsetFields);
$strFormFields =$strFormFields . $strFieldSet;
break;
case "hidden":
$strFormFields=$strFormFields . $this->Html->hiddenTag($field['tagName']);
break;
case "date":
if (!isset($field['selected'])) {
$field['selected'] = null;
}
$strFormFields=
$strFormFields . $this->generateDate($field['tagName'], $field['prompt'], null,
null, null, null, $field['selected']);
break;
case "datetime":
if (!isset($field['selected'])) {
$field['selected'] = null;
}
$strFormFields=$strFormFields
. $this->generateDateTime($field['tagName'], $field['prompt'], '', '', '', '',
$field['selected']);
break;
default: break;
}
} }
}
if (!isset($field['errorMsg'])) {
$field['errorMsg'] = null;
}
if (!isset($field['htmlOptions'])) {
$field['htmlOptions'] = array();
}
if ($readOnly) {
$field['htmlOptions']['READONLY'] = "readonly";
}
switch($field['type']) {
case "input":
if (!isset($field['size'])) {
$field['size'] = 40;
}
$strFormFields = $strFormFields . $this->generateInputDiv($field['tagName'], $field['prompt'],
$field['required'], $field['errorMsg'], $field['size'], $field['htmlOptions']);
break;
case "checkbox":
$strFormFields = $strFormFields . $this->generateCheckboxDiv($field['tagName'], $field['prompt'],
$field['required'], $field['errorMsg'], $field['htmlOptions']);
break;
case "select":
case "selectMultiple":
if ("selectMultiple" == $field['type']) {
$field['selectAttr']['multiple'] = 'multiple';
$field['selectAttr']['class'] = 'selectMultiple';
}
if (!isset($field['selected'])) {
$field['selected'] = null;
}
if (!isset($field['selectAttr'])) {
$field['selectAttr'] = null;
}
if (!isset($field['optionsAttr'])) {
$field['optionsAttr'] = null;
}
if ($readOnly) {
$field['selectAttr']['DISABLED'] = true;
}
if (!isset($field['options'])) {
$field['options'] = null;
}
$strFormFields = $strFormFields . $this->generateSelectDiv($field['tagName'], $field['prompt'], $field['options'],
$field['selected'], $field['selectAttr'], $field['optionsAttr'], $field['required'], $field['errorMsg']);
break;
case "area":
if (!isset($field['rows'])) {
$field['rows'] = 10;
}
if (!isset($field['cols'])) {
$field['cols'] = 60;
}
$strFormFields = $strFormFields . $this->generateAreaDiv($field['tagName'], $field['prompt'],
$field['required'], $field['errorMsg'], $field['cols'], $field['rows'], $field['htmlOptions']);
break;
case "fieldset":
$strFieldsetFields = $this->generateFields($field['fields']);
$strFieldSet = sprintf(' <fieldset><legend>%s</legend><div class="notes"><h4>%s</h4><p class="last">%s</p></div>%s</fieldset>',
$field['legend'], $field['noteHeading'], $field['note'], $strFieldsetFields);
$strFormFields = $strFormFields . $strFieldSet;
break;
case "hidden":
if(!isset($field['value'])){
$field['value'] = null;
}
$strFormFields = $strFormFields . $this->Html->hiddenTag($field['tagName'], $field['value']);
break;
case "date":
if (!isset($field['selected'])) {
$field['selected'] = null;
}
$strFormFields = $strFormFields . $this->generateDate($field['tagName'], $field['prompt'], null,
null, null, null, $field['selected']);
break;
case "datetime":
if (!isset($field['selected'])) {
$field['selected'] = null;
}
$strFormFields = $strFormFields . $this->generateDateTime($field['tagName'], $field['prompt'], '', '', '', '', $field['selected']);
break;
default:
break;
}
}
}
return $strFormFields; return $strFormFields;
} }
} }

View file

@ -129,18 +129,7 @@ class HtmlHelper extends Helper {
* @return mixed Either string or boolean value, depends on AUTO_OUTPUT and $return. * @return mixed Either string or boolean value, depends on AUTO_OUTPUT and $return.
*/ */
function url($url = null, $return = false) { function url($url = null, $return = false) {
$base = $this->base; $base = strip_plugin($this->base, $this->plugin);
if ($this->plugin != null) {
$base = preg_replace('/' . $this->plugin . '/', '', $this->base);
$base = str_replace('//', '', $base);
$pos1 = strrpos($base, '/');
$char = strlen($base) - 1;
if ($pos1 == $char) {
$base = substr($base, 0, $char);
}
}
if (empty($url)) { if (empty($url)) {
return $this->here; return $this->here;
} elseif($url{0} == '/') { } elseif($url{0} == '/') {
@ -148,7 +137,8 @@ class HtmlHelper extends Helper {
} else { } else {
$output = $base . '/' . strtolower($this->params['controller']) . '/' . $url; $output = $base . '/' . strtolower($this->params['controller']) . '/' . $url;
} }
return $this->output(preg_replace('/&([^a])/', '&amp;\1', $output), $return);
return $this->output($output, $return);
} }
/** /**
* Creates an HTML link. * Creates an HTML link.
@ -210,7 +200,10 @@ class HtmlHelper extends Helper {
function password($fieldName, $htmlAttributes = null, $return = false) { function password($fieldName, $htmlAttributes = null, $return = false) {
$this->setFormTag($fieldName); $this->setFormTag($fieldName);
if (!isset($htmlAttributes['value'])) { if (!isset($htmlAttributes['value'])) {
$htmlAttributes['value'] = $this->tagValue($fieldName); $htmlAttributes['value'] = $this->tagValue($fieldName);
}
if (!isset($htmlAttributes['id'])) {
$htmlAttributes['id'] = $this->model . Inflector::camelize($this->field);
} }
if ($this->tagIsInvalid($this->model, $this->field)) { if ($this->tagIsInvalid($this->model, $this->field)) {
@ -237,6 +230,9 @@ class HtmlHelper extends Helper {
$value = $htmlAttributes['value']; $value = $htmlAttributes['value'];
unset($htmlAttributes['value']); unset($htmlAttributes['value']);
} }
if (!isset($htmlAttributes['id'])) {
$htmlAttributes['id'] = $this->model . Inflector::camelize($this->field);
}
if ($this->tagIsInvalid($this->model, $this->field)) { if ($this->tagIsInvalid($this->model, $this->field)) {
if (isset($htmlAttributes['class']) && trim($htmlAttributes['class']) != "") { if (isset($htmlAttributes['class']) && trim($htmlAttributes['class']) != "") {
@ -272,6 +268,9 @@ class HtmlHelper extends Helper {
$htmlAttributes['checked'] = $value ? 'checked' : null; $htmlAttributes['checked'] = $value ? 'checked' : null;
$htmlAttributes['value'] = 1; $htmlAttributes['value'] = 1;
} }
if (!isset($htmlAttributes['id'])) {
$htmlAttributes['id'] = $this->model . Inflector::camelize($this->field);
}
$output = $this->hidden($fieldName, array('value' => $notCheckedValue), true); $output = $this->hidden($fieldName, array('value' => $notCheckedValue), true);
$output .= sprintf($this->tags['checkbox'], $this->model, $this->field, $this->_parseAttributes($htmlAttributes, null, '', ' ')); $output .= sprintf($this->tags['checkbox'], $this->model, $this->field, $this->_parseAttributes($htmlAttributes, null, '', ' '));
return $this->output($output, $return); return $this->output($output, $return);
@ -287,7 +286,11 @@ class HtmlHelper extends Helper {
*/ */
function css($path, $rel = 'stylesheet', $htmlAttributes = null, $return = false) { function css($path, $rel = 'stylesheet', $htmlAttributes = null, $return = false) {
$url = "{$this->webroot}" . (COMPRESS_CSS ? 'c' : '') . CSS_URL . $this->themeWeb . $path . ".css"; $url = "{$this->webroot}" . (COMPRESS_CSS ? 'c' : '') . CSS_URL . $this->themeWeb . $path . ".css";
return $this->output(sprintf($this->tags['css'], $rel, $url, $this->parseHtmlOptions($htmlAttributes, null, '', ' ')), $return); if ($rel == 'import') {
return $this->output(sprintf($this->tags['style'], $this->parseHtmlOptions($htmlAttributes, null, '', ' '), '@import url(' . $url . ');'), $return);
} else {
return $this->output(sprintf($this->tags['css'], $rel, $url, $this->parseHtmlOptions($htmlAttributes, null, '', ' ')), $return);
}
} }
/** /**
* Creates file input widget. * Creates file input widget.
@ -300,6 +303,9 @@ class HtmlHelper extends Helper {
function file($fieldName, $htmlAttributes = null, $return = false) { function file($fieldName, $htmlAttributes = null, $return = false) {
if (strpos($fieldName, '/')) { if (strpos($fieldName, '/')) {
$this->setFormTag($fieldName); $this->setFormTag($fieldName);
if (!isset($htmlAttributes['id'])) {
$htmlAttributes['id'] = $this->model . Inflector::camelize($this->field);
}
return $this->output(sprintf($this->tags['file'], $this->model, $this->field, $this->_parseAttributes($htmlAttributes, null, '', ' ')), $return); return $this->output(sprintf($this->tags['file'], $this->model, $this->field, $this->_parseAttributes($htmlAttributes, null, '', ' ')), $return);
} }
return $this->output(sprintf($this->tags['file_no_model'], $fieldName, $this->_parseAttributes($htmlAttributes, null, '', ' ')), $return); return $this->output(sprintf($this->tags['file_no_model'], $fieldName, $this->_parseAttributes($htmlAttributes, null, '', ' ')), $return);
@ -340,6 +346,9 @@ class HtmlHelper extends Helper {
if (!isset($htmlAttributes['value'])) { if (!isset($htmlAttributes['value'])) {
$htmlAttributes['value'] = $this->tagValue($fieldName); $htmlAttributes['value'] = $this->tagValue($fieldName);
} }
if (!isset($htmlAttributes['id'])) {
$htmlAttributes['id'] = $this->model . Inflector::camelize($this->field);
}
return $this->output(sprintf($this->tags['hidden'], $this->model, $this->field, $this->_parseAttributes($htmlAttributes, null, ' ', ' ')), $return); return $this->output(sprintf($this->tags['hidden'], $this->model, $this->field, $this->_parseAttributes($htmlAttributes, null, ' ', ' ')), $return);
} }
/** /**
@ -400,9 +409,11 @@ class HtmlHelper extends Helper {
* @return mixed Either string or boolean value, depends on AUTO_OUTPUT and $return. * @return mixed Either string or boolean value, depends on AUTO_OUTPUT and $return.
*/ */
function radio($fieldName, $options, $inbetween = null, $htmlAttributes = array(), $return = false) { function radio($fieldName, $options, $inbetween = null, $htmlAttributes = array(), $return = false) {
$this->setFormTag($fieldName); $this->setFormTag($fieldName);
$value = isset($htmlAttributes['value']) ? $htmlAttributes['value'] : $this->tagValue($fieldName); $value = isset($htmlAttributes['value']) ? $htmlAttributes['value'] : $this->tagValue($fieldName);
$out = array(); $out = array();
foreach($options as $optValue => $optTitle) { foreach($options as $optValue => $optTitle) {
$optionsHere = array('value' => $optValue); $optionsHere = array('value' => $optValue);
$optValue == $value ? $optionsHere['checked'] = 'checked' : null; $optValue == $value ? $optionsHere['checked'] = 'checked' : null;
@ -799,48 +810,47 @@ class HtmlHelper extends Helper {
function selectTag($fieldName, $optionElements, $selected = null, $selectAttr = null, $optionAttr = null, $showEmpty = true, $return = false) { function selectTag($fieldName, $optionElements, $selected = null, $selectAttr = null, $optionAttr = null, $showEmpty = true, $return = false) {
$this->setFormTag($fieldName); $this->setFormTag($fieldName);
if ($this->tagIsInvalid($this->model, $this->field)) { if ($this->tagIsInvalid($this->model, $this->field)) {
if (isset($selectAttr['class']) && trim($selectAttr['class']) != "") { if (isset($selectAttr['class']) && trim($selectAttr['class']) != "") {
$selectAttr['class'] .= ' form_error'; $selectAttr['class'] .= ' form_error';
} else { } else {
$selectAttr['class'] = 'form_error'; $selectAttr['class'] = 'form_error';
} }
}
if (!isset($selectAttr['id'])) {
$selectAttr['id'] = $this->model . Inflector::camelize($this->field);
} }
if (!is_array($optionElements)) { if (!is_array($optionElements)) {
return null; return null;
} }
if (!isset($selected)) { if (!isset($selected)) {
$selected = $this->tagValue($fieldName); $selected = $this->tagValue($fieldName);
} }
if (isset($selectAttr) && array_key_exists("multiple", $selectAttr)) { if (isset($selectAttr) && array_key_exists("multiple", $selectAttr)) {
$select[] = sprintf($this->tags['selectmultiplestart'], $this->model, $this->field, $select[] = sprintf($this->tags['selectmultiplestart'], $this->model, $this->field, $this->parseHtmlOptions($selectAttr));
$this->parseHtmlOptions($selectAttr));
} else { } else {
$select[] = sprintf($this->tags['selectstart'], $this->model, $this->field, $select[] = sprintf($this->tags['selectstart'], $this->model, $this->field, $this->parseHtmlOptions($selectAttr));
$this->parseHtmlOptions($selectAttr));
} }
if ($showEmpty == true) { if ($showEmpty == true) {
$select[] = sprintf($this->tags['selectempty'], $this->parseHtmlOptions($optionAttr)); $select[] = sprintf($this->tags['selectempty'], $this->parseHtmlOptions($optionAttr));
} }
foreach($optionElements as $name => $title) { foreach($optionElements as $name => $title) {
$optionsHere = $optionAttr; $optionsHere = $optionAttr;
if (($selected !== null) && ($selected == $name)) { if (($selected !== null) && ($selected == $name)) {
$optionsHere['selected'] = 'selected'; $optionsHere['selected'] = 'selected';
} else if(is_array($selected) && array_key_exists($name, $selected)) { } else if(is_array($selected) && array_key_exists($name, $selected)) {
$optionsHere['selected'] = 'selected'; $optionsHere['selected'] = 'selected';
} }
$select[] $select[] = sprintf($this->tags['selectoption'], $name, $this->parseHtmlOptions($optionsHere), $title);
=sprintf($this->tags['selectoption'], $name, $this->parseHtmlOptions($optionsHere), $title);
} }
$select[]=sprintf($this->tags['selectend']); $select[] = sprintf($this->tags['selectend']);
return $this->output(implode("\n", $select), $return); return $this->output(implode("\n", $select), $return);
} }
/** /**
@ -855,9 +865,8 @@ class HtmlHelper extends Helper {
* @see HtmlHelper::submit() * @see HtmlHelper::submit()
*/ */
function submitTag() { function submitTag() {
$args=func_get_args(); $args = func_get_args();
return call_user_func_array(array(&$this, return call_user_func_array(array(&$this, "submit"), $args);
"submit"), $args);
} }
/************************************************************************* /*************************************************************************
* Moved methods * Moved methods
@ -1101,6 +1110,9 @@ class HtmlHelper extends Helper {
$hourValue = !isset($selected) ? date('H') : $selected; $hourValue = !isset($selected) ? date('H') : $selected;
} else { } else {
$hourValue = !isset($selected) ? date('g') : $selected; $hourValue = !isset($selected) ? date('g') : $selected;
if (intval($hourValue) == 0) {
$hourValue = 12;
}
} }
if ($format24Hours) { if ($format24Hours) {
@ -1179,6 +1191,10 @@ class HtmlHelper extends Helper {
} }
$meridian = 'am'; $meridian = 'am';
$selected = trim($selected);
if (strpos($selected, ' ') === false) {
$selected = '0000-00-00 ' . $selected;
}
$date = explode('-', $selected); $date = explode('-', $selected);
$days = explode(' ', $date[2]); $days = explode(' ', $date[2]);

View file

@ -36,64 +36,62 @@
*/ */
class JavascriptHelper extends Helper{ class JavascriptHelper extends Helper{
var $_cachedEvents = array();
var $_cacheEvents = false; var $_cachedEvents = array();
var $_cacheEvents = false;
var $_cacheToFile = false;
var $_cacheAll = false;
var $_rules = array();
/** /**
* Returns a JavaScript script tag. * Returns a JavaScript script tag.
* *
* @param string $script The JavaScript to be wrapped in SCRIPT tags. * @param string $script The JavaScript to be wrapped in SCRIPT tags.
* @param boolean $allowCache Allows the script to be cached if non-event caching is active
* @return string The full SCRIPT element, with the JavaScript inside it. * @return string The full SCRIPT element, with the JavaScript inside it.
*/ */
function codeBlock($script) { function codeBlock($script, $allowCache = true) {
return sprintf($this->tags['javascriptblock'], $script); if ($this->_cacheEvents && $this->_cacheAll && $allowCache) {
} $this->_cachedEvents[] = $script;
} else {
return sprintf($this->tags['javascriptblock'], $script);
}
}
/** /**
* Returns a JavaScript include tag (SCRIPT element) * Returns a JavaScript include tag (SCRIPT element)
* *
* @param string $url URL to JavaScript file. * @param string $url URL to JavaScript file.
* @return string * @return string
*/ */
function link($url) { function link($url) {
if (strpos($url, ".") === false) if (strpos($url, ".") === false) {
$url .= ".js"; $url .= ".js";
}
return sprintf($this->tags['javascriptlink'], $this->webroot . JS_URL . $this->themeWeb . $url); return sprintf($this->tags['javascriptlink'], $this->webroot . JS_URL . $this->themeWeb . $url);
} }
/** /**
* Returns a JavaScript include tag for an externally-hosted script * Returns a JavaScript include tag for an externally-hosted script
* *
* @param string $url URL to JavaScript file. * @param string $url URL to JavaScript file.
* @return string * @return string
*/ */
function linkOut($url) { function linkOut($url) {
if (strpos($url, ".") === false) if (strpos($url, ".") === false) {
$url .= ".js"; $url .= ".js";
}
return sprintf($this->tags['javascriptlink'], $url); return sprintf($this->tags['javascriptlink'], $url);
} }
/** /**
* Escape carriage returns and single and double quotes for JavaScript segments. * Escape carriage returns and single and double quotes for JavaScript segments.
* *
* @param string $script string that might have javascript elements * @param string $script string that might have javascript elements
* @return string escaped string * @return string escaped string
*/ */
function escapeScript($script) { function escapeScript($script) {
$script=str_replace(array("\r\n", $script = r(array("\r\n", "\n", "\r"), '\n', $script);
"\n", $script = r(array('"', "'"), array('\"', "\\'"), $script);
"\r"), '\n', return $script;
$script); }
$script=str_replace(array('"',
"'"), array('\"',
"\\'"), $script);
return $script;
}
/** /**
* Escape a string to be JavaScript friendly. * Escape a string to be JavaScript friendly.
* *
@ -107,15 +105,10 @@ class JavascriptHelper extends Helper{
* @param string $script String that needs to get escaped. * @param string $script String that needs to get escaped.
* @return string Escaped string. * @return string Escaped string.
*/ */
function escapeString($string) { function escapeString($string) {
$escape=array("\r\n" => '\n', $escape = array("\r\n" => '\n', "\r" => '\n', "\n" => '\n', '"' => '\"', "'" => "\\'");
"\r" => '\n', return r(array_keys($escape), array_values($escape), $string);
"\n" => '\n', }
'"' => '\"',
"'" => "\\'");
return str_replace(array_keys($escape), array_values($escape), $string);
}
/** /**
* Attach an event to an element. Used with the Prototype library. * Attach an event to an element. Used with the Prototype library.
* *
@ -125,42 +118,93 @@ class JavascriptHelper extends Helper{
* @param boolean $useCapture default true * @param boolean $useCapture default true
* @return boolean true on success * @return boolean true on success
*/ */
function event($object, $event, $observer, $useCapture = false) { function event($object, $event, $observer = null, $useCapture = false) {
if ($useCapture == true) {
$useCapture = "true";
} else {
$useCapture = "false";
}
$b="Event.observe($object, '$event', function(event){ $observer }, $useCapture);"; if ($useCapture == true) {
$useCapture = "true";
} else {
$useCapture = "false";
}
if ($this->_cacheEvents === true) { if ($object == 'window' || strpos($object, '$(') !== false || strpos($object, '"') !== false || strpos($object, '\'') !== false) {
$this->_cachedEvents[]=$b; $b = "Event.observe($object, '$event', function(event){ $observer }, $useCapture);";
return true; } else {
} else { $chars = array('#', ' ', ', ', '.', ':');
$found = false;
foreach ($chars as $char) {
if (strpos($object, $char) !== false) {
$found = true;
break;
}
}
if ($found) {
$this->_rules[$object] = $event;
} else {
$b = "Event.observe(\$('$object'), '$event', function(event){ $observer }, $useCapture);";
}
}
if (isset($b) && !empty($b)) {
if ($this->_cacheEvents === true) {
$this->_cachedEvents[] = $b;
return;
} else {
return $this->codeBlock($b); return $this->codeBlock($b);
} }
} }
}
/** /**
* Cache JavaScript events created with event() * Cache JavaScript events created with event()
* *
* @param boolean $file If true, code will be written to a file
* @param boolean $all If true, all code written with JavascriptHelper will be sent to a file
* @return null * @return null
*/ */
function cacheEvents() { function cacheEvents($file = false, $all = false) {
$this->_cacheEvents=true; $this->_cacheEvents = true;
} $this->_cacheToFile = $file;
$this->_cacheAll = $all;
}
/** /**
* Write cached JavaScript events * Write cached JavaScript events
* *
* @return string A single code block of all cached JavaScript events created with event() * @return string
*/ */
function writeEvents() { function writeEvents() {
$this->_cacheEvents=false;
return $this->codeBlock("\n" . implode("\n", $this->_cachedEvents) . "\n");
}
$rules = array();
if (!empty($this->_rules)) {
foreach ($this->_rules as $sel => $event) {
$rules[] = "\t'{$sel}': function(element, event) {\n\t\t{$event}\n\t}";
}
$this->_cacheEvents = true;
}
if ($this->_cacheEvents) {
$this->_cacheEvents = false;
$events = $this->_cachedEvents;
$data = implode("\n", $events);
$this->_cachedEvents = array();
if (!empty($rules)) {
$data .= "\n\nvar SelectorRules = {\n" . implode(",\n\n", $rules) . "\n}\n";
$data .= "\nEventSelectors.start(SelectorRules);\n";
}
if (!empty($events) || !empty($rules)) {
if ($this->_cacheToFile) {
$filename = md5($data);
if (!file_exists(JS . $filename . '.js')) {
cache(r(WWW_ROOT, '', JS) . $filename . '.js', $data, '+999 days', 'public');
}
return $this->link($filename);
} else {
return $this->codeBlock("\n" . $data . "\n");
}
}
}
}
/** /**
* Includes the Prototype Javascript library (and anything else) inside a single script tag. * Includes the Prototype Javascript library (and anything else) inside a single script tag.
* *
@ -170,23 +214,21 @@ class JavascriptHelper extends Helper{
* create remote script links. * create remote script links.
* @return string script with all javascript in/javascripts folder * @return string script with all javascript in/javascripts folder
*/ */
function includeScript($script = "") { function includeScript($script = "") {
if ($script == "") { if ($script == "") {
$files =scandir(JS); $files = scandir(JS);
$javascript=''; $javascript = '';
foreach($files as $file) { foreach($files as $file) {
if (substr($file, -3) == '.js') { if (substr($file, -3) == '.js') {
$javascript .= file_get_contents(JS . "{$file}") . "\n\n"; $javascript .= file_get_contents(JS . "{$file}") . "\n\n";
}
} }
} else { }
$javascript = file_get_contents(JS . "$script.js") . "\n\n"; } else {
} $javascript = file_get_contents(JS . "$script.js") . "\n\n";
}
return $this->codeBlock("\n\n" . $javascript); return $this->codeBlock("\n\n" . $javascript);
} }
/** /**
* Generates a JavaScript object in JavaScript Object Notation (JSON) * Generates a JavaScript object in JavaScript Object Notation (JSON)
* from an array * from an array
@ -200,65 +242,69 @@ class JavascriptHelper extends Helper{
* @param string $q The type of quote to use * @param string $q The type of quote to use
* @return string A JSON code block * @return string A JSON code block
*/ */
function object($data = array(), $block = false, $prefix = '', $postfix = '', $stringKeys = array(), function object($data = array(), $block = false, $prefix = '', $postfix = '', $stringKeys = array(), $quoteKeys = true, $q = "\"") {
$quoteKeys = true, $q = "\"") { if (is_object($data)) {
if (is_object($data)) { $data = get_object_vars($data);
$data = get_object_vars($data); }
}
$out=array(); $out = array();
$key=array(); $key = array();
if (is_array($data)) { if (is_array($data)) {
$keys = array_keys($data); $keys = array_keys($data);
} }
$numeric=true; $numeric = true;
if (!empty($keys)) { if (!empty($keys)) {
foreach($keys as $key) { foreach($keys as $key) {
if (!is_numeric($key)) { if (!is_numeric($key)) {
$numeric=false; $numeric = false;
break; break;
}
} }
} }
}
foreach($data as $key => $val) { foreach($data as $key => $val) {
if (is_array($val) || is_object($val)) { if (is_array($val) || is_object($val)) {
$val = $this->object($val, false, '', '', $stringKeys, $quoteKeys, $q); $val = $this->object($val, false, '', '', $stringKeys, $quoteKeys, $q);
} else { } else {
if ((!count($stringKeys) && !is_numeric($val) && !is_bool($val)) if ((!count($stringKeys) && !is_numeric($val) && !is_bool($val)) || ($quoteKeys && in_array($key, $stringKeys)) || (!$quoteKeys && !in_array($key, $stringKeys))) {
|| ($quoteKeys && in_array($key, $stringKeys)) $val = $q . $val . $q;
|| (!$quoteKeys && !in_array($key, $stringKeys))) {
$val = $q . $val . $q;
}
if (trim($val) == '') {
$val = 'null';
}
} }
if (trim($val) == '') {
if (!$numeric) { $val = 'null';
$val = $key . ':' . $val;
} }
}
$out[]=$val; if (!$numeric) {
} $val = $key . ':' . $val;
}
if (!$numeric) { $out[] = $val;
$rt = '{' . join(', ', $out) . '}'; }
} else {
$rt = '[' . join(', ', $out) . ']';
}
$rt=$prefix . $rt . $postfix; if (!$numeric) {
$rt = '{' . join(', ', $out) . '}';
} else {
$rt = '[' . join(', ', $out) . ']';
}
$rt = $prefix . $rt . $postfix;
if ($block) { if ($block) {
$rt = $this->codeBlock($rt); $rt = $this->codeBlock($rt);
} }
return $rt; return $rt;
} }
/**
* AfterRender callback. Writes any cached events to the view, or to a temp file.
*
* @return null
*/
function afterRender() {
echo $this->writeEvents();
}
} }
?> ?>

View file

@ -29,7 +29,7 @@
<html xmlns="http://www.w3.org/1999/xhtml"> <html xmlns="http://www.w3.org/1999/xhtml">
<head> <head>
<title>CakePHP : The PHP Rapid Development Framework :: <?php echo $title_for_layout?></title> <title>CakePHP : The PHP Rapid Development Framework :: <?php echo $title_for_layout?></title>
<link rel="shortcut icon" href="favicon.ico" type="image/x-icon" /> <link rel="shortcut icon" href="<?php echo $html->url('/favicon.ico');?>" type="image/x-icon" />
<?php echo $html->charset('UTF-8')?> <?php echo $html->charset('UTF-8')?>
<?php echo $html->css('cake.basic', 'stylesheet', array("media"=>"all" ));?> <?php echo $html->css('cake.basic', 'stylesheet', array("media"=>"all" ));?>
<?php echo $html->css('cake.forms', 'stylesheet', array("media"=>"all" ));?> <?php echo $html->css('cake.forms', 'stylesheet', array("media"=>"all" ));?>

View file

@ -35,9 +35,8 @@
<p style="background:#DBA941;padding:4px;font-size: 16px;">Cake<?php echo $connected->isConnected() ? ' 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->isConnected() ? ' is able to' : ' is not able to';?> connect to the database.</p>
<br /> <br />
<?php endif; ?> <?php endif; ?>
<h1>CakePHP</h1> <h2>CakePHP release information is on CakeForge</h2>
<a href="http://cakeforge.org/projects/cakephp">Read the release notes and get the latest version</a>
<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 this Page</h2> <h2>Editing this Page</h2>
<p> <p>
@ -62,15 +61,15 @@ to rapidly develop robust web applications, without any loss to flexibility.
<ul><li>Get your own CakePHP gear - Doughnate to Cake</li></ul></li> <ul><li>Get your own CakePHP gear - Doughnate to Cake</li></ul></li>
<li><a href="http://www.cakephp.org">CakePHP</a> <li><a href="http://www.cakephp.org">CakePHP</a>
<ul><li>The Rapid Development Framework</li></ul></li> <ul><li>The Rapid Development Framework</li></ul></li>
<li><a href="http://manual.cakephp.org">CakePHPManual</a> <li><a href="http://manual.cakephp.org">CakePHP Manual</a>
<ul><li>Your Rapid Development Cookbook</li></ul></li> <ul><li>Your Rapid Development Cookbook</li></ul></li>
<li><a href="http://wiki.cakephp.org">CakePHPWiki</a> <li><a href="http://wiki.cakephp.org">CakePHP Wiki</a>
<ul><li>The Community for CakePHP</li></ul></li> <ul><li>The Community for CakePHP</li></ul></li>
<li><a href="http://api.cakephp.org">CakePHPAPI</a> <li><a href="http://api.cakephp.org">CakePHP API</a>
<ul><li>Docblock Your Best Friend</li></ul></li> <ul><li>Docblock Your Best Friend</li></ul></li>
<li><a href="http://www.cakeforge.org">CakeForge</a> <li><a href="http://www.cakeforge.org">CakeForge</a>
<ul><li>Open Development for CakePHP</li></ul></li> <ul><li>Open Development for CakePHP</li></ul></li>
<li><a href="https://trac.cakephp.org/">CakePHPTrac</a> <li><a href="https://trac.cakephp.org/">CakePHP Trac</a>
<ul><li>For the Development of CakePHP (Tickets, SVN browser, Roadmap, Changelogs)</li></ul></li> <ul><li>For the Development of CakePHP (Tickets, SVN browser, Roadmap, Changelogs)</li></ul></li>
<li><a href="http://groups-beta.google.com/group/cake-php">CakePHP Google Group</a> <li><a href="http://groups-beta.google.com/group/cake-php">CakePHP Google Group</a>
<ul><li>Community mailing list</li></ul></li> <ul><li>Community mailing list</li></ul></li>

View file

@ -386,47 +386,58 @@ class View extends Object{
* @return mixed Rendered output, or false on error * @return mixed Rendered output, or false on error
*/ */
function renderLayout($content_for_layout) { function renderLayout($content_for_layout) {
$layout_fn=$this->_getLayoutFileName(); $layout_fn = $this->_getLayoutFileName();
if (DEBUG > 2 && $this->controller != null) { if (DEBUG > 2 && $this->controller != null) {
$debug = View::_render(LIBS . 'view' . DS . 'templates' . DS . 'elements' . DS $debug = View::_render(LIBS . 'view' . DS . 'templates' . DS . 'elements' . DS . 'dump.thtml', array('controller' => $this->controller), false);
. 'dump.thtml', array('controller' => $this->controller), false);
} else { } else {
$debug = ''; $debug = '';
} }
if ($this->pageTitle !== false) { if ($this->pageTitle !== false) {
$pageTitle = $this->pageTitle; $pageTitle = $this->pageTitle;
} else { } else {
$pageTitle = Inflector::humanize($this->viewPath); $pageTitle = Inflector::humanize($this->viewPath);
} }
$data_for_layout=array_merge($this->_viewVars, array('title_for_layout' => $pageTitle, $data_for_layout = array_merge(
'content_for_layout' => $content_for_layout, $this->_viewVars,
'cakeDebug' => $debug)); array(
'title_for_layout' => $pageTitle,
'content_for_layout' => $content_for_layout,
'cakeDebug' => $debug
)
);
if (is_file($layout_fn)) { if (is_file($layout_fn)) {
$data_for_layout=array_merge($data_for_layout, $this->loaded); if (empty($this->loaded) && !empty($this->helpers)) {
$loadHelpers = true;
} else {
$loadHelpers = false;
$data_for_layout = array_merge($data_for_layout, $this->loaded);
}
if (substr($layout_fn, -5) === 'thtml') { if (substr($layout_fn, -5) === 'thtml') {
$out = View::_render($layout_fn, $data_for_layout, false, true); $out = View::_render($layout_fn, $data_for_layout, $loadHelpers, true);
} else { } else {
$out = $this->_render($layout_fn, $data_for_layout, false); $out = $this->_render($layout_fn, $data_for_layout, $loadHelpers);
} }
if ($out === false) { if ($out === false) {
$out=$this->_render($layout_fn, $data_for_layout); $out = $this->_render($layout_fn, $data_for_layout);
trigger_error( trigger_error(sprintf(__("Error in layout %s, got: <blockquote>%s</blockquote>"), $layout_fn, $out), E_USER_ERROR);
sprintf(__("Error in layout %s, got: <blockquote>%s</blockquote>"), $layout_fn, $out), return false;
E_USER_ERROR); } else {
return false; return $out;
} else { }
return $out;
}
} else { } else {
return $this->cakeError('missingLayout', array(array('layout' => $this->layout, return $this->cakeError('missingLayout', array(
'file' => $layout_fn, array(
'base' => $this->base))); 'layout' => $this->layout,
'file' => $layout_fn,
'base' => $this->base
)
));
} }
} }
@ -436,7 +447,7 @@ class View extends Object{
* @param string $layout Name of layout. * @param string $layout Name of layout.
*/ */
function setLayout($layout) { function setLayout($layout) {
$this->layout=$layout; $this->layout = $layout;
} }
/** /**
@ -465,39 +476,37 @@ class View extends Object{
* @access private * @access private
*/ */
function _getViewFileName($action) { function _getViewFileName($action) {
$action=Inflector::underscore($action); $action = Inflector::underscore($action);
$paths =Configure::getInstance(); $paths = Configure::getInstance();
if (!is_null($this->webservices)) { if (!is_null($this->webservices)) {
$type = strtolower($this->webservices) . DS; $type = strtolower($this->webservices) . DS;
} else { } else {
$type = null; $type = null;
} }
$position=strpos($action, '..'); $position = strpos($action, '..');
if ($position === false) { if ($position === false) {
} else { } else {
$action=explode('/', $action); $action = explode('/', $action);
$i =array_search('..', $action); $i = array_search('..', $action);
unset ($action[$i - 1]); unset($action[$i - 1]);
unset ($action[$i]); unset($action[$i]);
$action='..' . DS . implode(DS, $action); $action='..' . DS . implode(DS, $action);
} }
foreach($paths->viewPaths as $path) { foreach($paths->viewPaths as $path) {
if (file_exists($path . $this->viewPath . DS . $this->subDir . $type . $action . $this->ext)) { if (file_exists($path . $this->viewPath . DS . $this->subDir . $type . $action . $this->ext)) {
$viewFileName=$path . $this->viewPath . DS . $this->subDir . $type . $action . $this->ext; $viewFileName = $path . $this->viewPath . DS . $this->subDir . $type . $action . $this->ext;
return $viewFileName; return $viewFileName;
} }
} }
if ($viewFileName = fileExistsInPath(LIBS . 'view' . DS . 'templates' . DS . 'errors' . DS . $type if ($viewFileName = fileExistsInPath(LIBS . 'view' . DS . 'templates' . DS . 'errors' . DS . $type . $action . '.thtml')) {
. $action . '.thtml')) { } elseif($viewFileName = fileExistsInPath(LIBS . 'view' . DS . 'templates' . DS . $this->viewPath . DS . $type . $action . '.thtml')) {
} elseif($viewFileName = fileExistsInPath(LIBS . 'view' . DS . 'templates' . DS . $this->viewPath . DS
. $type . $action . '.thtml')) {
} else { } else {
$viewFileName = VIEWS . $this->viewPath . DS . $this->subDir . $type . $action . $this->ext; $viewFileName = VIEWS . $this->viewPath . DS . $this->subDir . $type . $action . $this->ext;
} }
return $viewFileName; return $viewFileName;
@ -511,27 +520,23 @@ class View extends Object{
*/ */
function _getLayoutFileName() { function _getLayoutFileName() {
if (isset($this->webservices) && !is_null($this->webservices)) { if (isset($this->webservices) && !is_null($this->webservices)) {
$type = strtolower($this->webservices) . DS; $type = strtolower($this->webservices) . DS;
} else { } else {
$type = null; $type = null;
} }
if (isset($this->plugin) && !is_null($this->plugin)) { if (isset($this->plugin) && !is_null($this->plugin)) {
if (file_exists( if (file_exists(APP . 'plugins' . DS . $this->plugin . DS . 'views' . DS . 'layouts' . DS . $this->layout . $this->ext)) {
APP . 'plugins' . DS . $this->plugin . DS . 'views' . DS . 'layouts' . DS . $this->layout . $this->ext)) { $layoutFileName = APP . 'plugins' . DS . $this->plugin . DS . 'views' . DS . 'layouts' . DS . $this->layout . $this->ext;
$layoutFileName= return $layoutFileName;
APP . 'plugins' . DS . $this->plugin . DS . 'views' . DS . 'layouts' . DS . $this->layout . $this->ext; }
return $layoutFileName;
}
} }
if (file_exists(LAYOUTS . $this->subDir . $type . "{$this->layout}$this->ext")) { if (file_exists(LAYOUTS . $this->subDir . $type . "{$this->layout}$this->ext")) {
$layoutFileName = LAYOUTS . $this->subDir . $type . "{$this->layout}$this->ext"; $layoutFileName = LAYOUTS . $this->subDir . $type . "{$this->layout}$this->ext";
} elseif($layoutFileName } elseif($layoutFileName = fileExistsInPath(LIBS . 'view' . DS . 'templates' . DS . "layouts" . DS . $type . "{$this->layout}.thtml")) {
= fileExistsInPath(LIBS . 'view' . DS . 'templates' . DS . "layouts" . DS . $type . "{$this->layout}.thtml"))
{
} else { } else {
$layoutFileName = LAYOUTS . $type . "{$this->layout}$this->ext"; $layoutFileName = LAYOUTS . $type . "{$this->layout}$this->ext";
} }
return $layoutFileName; return $layoutFileName;
@ -548,14 +553,12 @@ class View extends Object{
*/ */
function _render($___viewFn, $___dataForView, $loadHelpers = true, $cached = false) { function _render($___viewFn, $___dataForView, $loadHelpers = true, $cached = false) {
if ($this->helpers != false && $loadHelpers === true) { if ($this->helpers != false && $loadHelpers === true) {
$helperVars = array();
$loadedHelpers = array(); $loadedHelpers = array();
$loadedHelpers = $this->_loadHelpers($loadedHelpers, $this->helpers); $loadedHelpers = $this->_loadHelpers($loadedHelpers, $this->helpers);
foreach(array_keys($loadedHelpers) as $helper) { foreach(array_keys($loadedHelpers) as $helper) {
$replace = strtolower(substr($helper, 0, 1)); $replace = strtolower(substr($helper, 0, 1));
$camelBackedHelper = preg_replace('/\\w/', $replace, $helper, 1); $camelBackedHelper = preg_replace('/\\w/', $replace, $helper, 1);
$helperVars[] = $camelBackedHelper;
${$camelBackedHelper} =& $loadedHelpers[$helper]; ${$camelBackedHelper} =& $loadedHelpers[$helper];
@ -564,7 +567,7 @@ class View extends Object{
${$camelBackedHelper}->{$subHelper} =& $loadedHelpers[$subHelper]; ${$camelBackedHelper}->{$subHelper} =& $loadedHelpers[$subHelper];
} }
} }
$this->loaded[$camelBackedHelper]=(${$camelBackedHelper}); $this->loaded[$camelBackedHelper] = (${$camelBackedHelper});
} }
} }
@ -582,8 +585,12 @@ class View extends Object{
} }
if ($this->helpers != false && $loadHelpers === true) { if ($this->helpers != false && $loadHelpers === true) {
foreach ($helperVars as $helper) { foreach ($loadedHelpers as $helper) {
${$helper}->afterRender(); if (is_object($helper)) {
if (is_subclass_of($helper, 'Helper') || is_subclass_of($helper, 'helper')) {
$helper->afterRender();
}
}
} }
} }
@ -597,11 +604,11 @@ class View extends Object{
$cache->view = &$this; $cache->view = &$this;
} }
$cache->base =$this->base; $cache->base = $this->base;
$cache->here =$this->here; $cache->here = $this->here;
$cache->action =$this->action; $cache->action = $this->action;
$cache->controllerName=$this->params['controller']; $cache->controllerName = $this->params['controller'];
$cache->cacheAction =$this->controller->cacheAction; $cache->cacheAction = $this->controller->cacheAction;
$cache->cache($___viewFn, $out, $cached); $cache->cache($___viewFn, $out, $cached);
} }
} }
@ -628,19 +635,17 @@ class View extends Object{
if (in_array($helper, array_keys($loaded)) !== true) { if (in_array($helper, array_keys($loaded)) !== true) {
if (!class_exists($helperCn)) { if (!class_exists($helperCn)) {
$helperFn = Inflector::underscore($helper) . '.php'; if (is_null($this->plugin) || !loadPluginHelper($this->plugin, $helper)) {
if (!loadHelper($helper)) {
if (file_exists(APP . 'plugins' . DS . $this->plugin . DS . 'views' . DS . 'helpers' . DS . $helperFn)) { return $this->cakeError('missingHelperFile', array(array(
$helperFn = APP . 'plugins' . DS . $this->plugin . DS . 'views' . DS . 'helpers' . DS . $helperFn; 'helper' => $helper,
} else if(file_exists(HELPERS . $helperFn)) { 'file' => Inflector::underscore($helper) . '.php',
$helperFn = HELPERS . $helperFn; 'base' => $this->base
} else if($helperFn = fileExistsInPath(LIBS . 'view' . DS . 'helpers' . DS . $helperFn)) { )));
} }
}
if (is_file($helperFn)) { if (!class_exists($helperCn)) {
require $helperFn; return $this->cakeError('missingHelperClass', array(array(
} else {
return $this->cakeError('missingHelperFile', array(array(
'helper' => $helper, 'helper' => $helper,
'file' => Inflector::underscore($helper) . '.php', 'file' => Inflector::underscore($helper) . '.php',
'base' => $this->base 'base' => $this->base
@ -651,34 +656,26 @@ class View extends Object{
$replace = strtolower(substr($helper, 0, 1)); $replace = strtolower(substr($helper, 0, 1));
$camelBackedHelper = preg_replace('/\\w/', $replace, $helper, 1); $camelBackedHelper = preg_replace('/\\w/', $replace, $helper, 1);
if (class_exists($helperCn)) { ${$camelBackedHelper} =& new $helperCn;
${$camelBackedHelper} =& new $helperCn; ${$camelBackedHelper}->view =& $this;
${$camelBackedHelper}->view =& $this; ${$camelBackedHelper}->base = $this->base;
${$camelBackedHelper}->base = $this->base; ${$camelBackedHelper}->webroot = $this->webroot;
${$camelBackedHelper}->webroot = $this->webroot; ${$camelBackedHelper}->here = $this->here;
${$camelBackedHelper}->here = $this->here; ${$camelBackedHelper}->params = $this->params;
${$camelBackedHelper}->params = $this->params; ${$camelBackedHelper}->action = $this->action;
${$camelBackedHelper}->action = $this->action; ${$camelBackedHelper}->data = $this->data;
${$camelBackedHelper}->data = $this->data; ${$camelBackedHelper}->themeWeb = $this->themeWeb;
${$camelBackedHelper}->themeWeb = $this->themeWeb; ${$camelBackedHelper}->tags = $tags;
${$camelBackedHelper}->tags = $tags; ${$camelBackedHelper}->plugin = $this->plugin;
${$camelBackedHelper}->plugin = $this->plugin;
if (!empty($this->validationErrors)) { if (!empty($this->validationErrors)) {
${$camelBackedHelper}->validationErrors = $this->validationErrors; ${$camelBackedHelper}->validationErrors = $this->validationErrors;
} }
$loaded[$helper] =& ${$camelBackedHelper}; $loaded[$helper] =& ${$camelBackedHelper};
if (isset(${$camelBackedHelper}->helpers) && is_array(${$camelBackedHelper}->helpers)) { if (isset(${$camelBackedHelper}->helpers) && is_array(${$camelBackedHelper}->helpers)) {
$loaded = &$this->_loadHelpers($loaded, ${$camelBackedHelper}->helpers); $loaded = &$this->_loadHelpers($loaded, ${$camelBackedHelper}->helpers);
}
} else {
return $this->cakeError('missingHelperClass', array(array(
'helper' => $helper,
'file' => Inflector::underscore($helper) . '.php',
'base' => $this->base
)));
} }
} }
} }

View file

@ -27,8 +27,12 @@
* @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
*/ */
ini_set('display_errors', '1'); define ('DS', DIRECTORY_SEPARATOR);
ini_set('error_reporting', '7'); if (function_exists('ini_set')) {
ini_set('display_errors', '1');
ini_set('error_reporting', '7');
}
$app = 'app'; $app = 'app';
$root = dirname(dirname(dirname(__FILE__))); $root = dirname(dirname(dirname(__FILE__)));
$core = null; $core = null;
@ -61,7 +65,12 @@
break; break;
} }
} }
define ('DS', DIRECTORY_SEPARATOR);
if (strlen($app) && $app[0] == DS) {
$cnt = substr_count($root, DS);
$app = str_repeat('..' . DS, $cnt) . $app;
}
define ('ROOT', $root.DS); define ('ROOT', $root.DS);
define ('APP_DIR', $app); define ('APP_DIR', $app);
define ('APP_PATH', $app.DS); define ('APP_PATH', $app.DS);
@ -71,6 +80,9 @@
if(function_exists('ini_set')) { if(function_exists('ini_set')) {
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);
} else {
define('APP_PATH', ROOT . DS . APP_DIR . DS);
define('CORE_PATH', CAKE_CORE_INCLUDE_PATH . DS);
} }
require_once (ROOT.'cake'.DS.'basics.php'); require_once (ROOT.'cake'.DS.'basics.php');
@ -219,12 +231,16 @@ class Bake {
} }
} }
$password = ''; $password = '';
$blankPassword = false;
while ($password == '') { while ($password == '' && $blankPassword == false) {
$password = $this->getInput('What is the database password?'); $password = $this->getInput('What is the database password?');
if ($password == '') { if ($password == '') {
$this->stdout('The password you supplied was empty. Please try again.'); $blank = $this->getInput('The password you supplied was empty. Use an empty password?', array('y', 'n'), 'n');
if($blank == 'y')
{
$blankPassword = true;
}
} }
} }
$database = ''; $database = '';
@ -272,7 +288,18 @@ class Bake {
}*/ }*/
$modelName = ''; $modelName = '';
$db =& ConnectionManager::getDataSource($dbConnection); $db =& ConnectionManager::getDataSource($dbConnection);
$tables = $db->listSources(); $usePrefix = empty($db->config['prefix']) ? '' : $db->config['prefix'];
if ($usePrefix) {
$tables = array();
foreach ($db->listSources() as $table) {
if (! strncmp($table, $usePrefix, strlen($usePrefix))) {
$tables[] = substr($table, strlen($usePrefix));
}
}
} else {
$tables = $db->listSources();
}
$inflect = new Inflector(); $inflect = new Inflector();
$this->stdout('Possible models based on your current database:'); $this->stdout('Possible models based on your current database:');
@ -391,7 +418,7 @@ class Bake {
$this->stdout('Done.'); $this->stdout('Done.');
$this->hr(); $this->hr();
//if none found... //if none found...
if(count($hasOneClasses) < 1 && count($hasManyClasses) < 1 && count($hasAndBelongsToManyClasses) < 1 && count($belongsToClasses)) { if(count($hasOneClasses) < 1 && count($hasManyClasses) < 1 && count($hasAndBelongsToManyClasses) < 1 && count($belongsToClasses) < 1) {
$this->stdout('None found.'); $this->stdout('None found.');
} else { } else {
$this->stdout('Please confirm the following associations:'); $this->stdout('Please confirm the following associations:');
@ -502,7 +529,7 @@ class Bake {
$looksGood = $this->getInput('Look okay?', array('y','n'), 'y'); $looksGood = $this->getInput('Look okay?', array('y','n'), 'y');
if (strtolower($looksGood) == 'y' || strtolower($looksGood) == 'yes') { if (strtolower($looksGood) == 'y' || strtolower($looksGood) == 'yes') {
if ($inflect->camelize($inflect->singularize($modelTableName)) == $modelClassName) { if ($modelTableName == $inflect->underscore($inflect->pluralize($modelClassName))) {
// set it to null... // set it to null...
// putting $useTable in the model // putting $useTable in the model
// is unnecessary. // is unnecessary.
@ -842,16 +869,13 @@ class Bake {
} }
$tempModel = new $controllerModel(); $tempModel = new $controllerModel();
$actions .= "\n"; $actions .= "\n";
$actions .= "\tfunction index()\n"; $actions .= "\tfunction index() {\n";
$actions .= "\t{\n";
$actions .= "\t\t\$this->{$controllerModel}->recursive = 0;\n"; $actions .= "\t\t\$this->{$controllerModel}->recursive = 0;\n";
$actions .= "\t\t\$this->set('{$this->lowCtrl}', \$this->{$controllerModel}->findAll());\n"; $actions .= "\t\t\$this->set('{$this->lowCtrl}', \$this->{$controllerModel}->findAll());\n";
$actions .= "\t}\n"; $actions .= "\t}\n";
$actions .= "\n"; $actions .= "\n";
$actions .= "\tfunction add()\n"; $actions .= "\tfunction add() {\n";
$actions .= "\t{\n"; $actions .= "\t\tif(empty(\$this->data)) {\n";
$actions .= "\t\tif(empty(\$this->data))\n";
$actions .= "\t\t{\n";
foreach($tempModel->hasAndBelongsToMany as $association => $relation) { foreach($tempModel->hasAndBelongsToMany as $association => $relation) {
if(!empty($relation['className'])) { if(!empty($relation['className'])) {
@ -869,26 +893,17 @@ class Bake {
} }
} }
$actions .= "\t\t\t\$this->set('{$this->lowCtrl}', null);\n"; $actions .= "\t\t\t\$this->set('{$this->lowCtrl}', null);\n";
$actions .= "\t\t}\n"; $actions .= "\t\t} else {\n";
$actions .= "\t\telse\n";
$actions .= "\t\t{\n";
$actions .= "\t\t\t\$this->cleanUpFields();\n"; $actions .= "\t\t\t\$this->cleanUpFields();\n";
$actions .= "\t\t\tif(\$this->{$controllerModel}->save(\$this->data))\n"; $actions .= "\t\t\tif(\$this->{$controllerModel}->save(\$this->data)) {\n";
$actions .= "\t\t\t{\n"; $actions .= "\t\t\t\tif(is_object(\$this->Session)) {\n";
$actions .= "\t\t\t\tif(is_object(\$this->Session))\n";
$actions .= "\t\t\t\t{\n";
$actions .= "\t\t\t\t\t\$this->Session->setFlash('The ".Inflector::humanize($controllerModel)." has been saved');\n"; $actions .= "\t\t\t\t\t\$this->Session->setFlash('The ".Inflector::humanize($controllerModel)." has been saved');\n";
$actions .= "\t\t\t\t\t\$this->redirect(\$this->viewPath.'/index');\n"; $actions .= "\t\t\t\t\t\$this->redirect(\$this->viewPath.'/index');\n";
$actions .= "\t\t\t\t}\n"; $actions .= "\t\t\t\t} else {\n";
$actions .= "\t\t\t\telse\n";
$actions .= "\t\t\t\t{\n";
$actions .= "\t\t\t\t\t\$this->flash('{$controllerModel} saved.', \$this->viewPath.'/index');\n"; $actions .= "\t\t\t\t\t\$this->flash('{$controllerModel} saved.', \$this->viewPath.'/index');\n";
$actions .= "\t\t\t\t}\n"; $actions .= "\t\t\t\t}\n";
$actions .= "\t\t\t}\n"; $actions .= "\t\t\t} else {\n";
$actions .= "\t\t\telse\n"; $actions .= "\t\t\t\tif(is_object(\$this->Session)) {\n";
$actions .= "\t\t\t{\n";
$actions .= "\t\t\t\tif(is_object(\$this->Session))\n";
$actions .= "\t\t\t\t{\n";
$actions .= "\t\t\t\t\t\$this->Session->setFlash('Please correct errors below.');\n"; $actions .= "\t\t\t\t\t\$this->Session->setFlash('Please correct errors below.');\n";
$actions .= "\t\t\t\t}\n"; $actions .= "\t\t\t\t}\n";
$actions .= "\t\t\t\t\$data = \$this->data;\n"; $actions .= "\t\t\t\t\$data = \$this->data;\n";
@ -901,10 +916,8 @@ class Bake {
$lowerName = strtolower($association); $lowerName = strtolower($association);
$actions .= "\t\t\t\t\${$lowerName} = null;\n"; $actions .= "\t\t\t\t\${$lowerName} = null;\n";
$actions .= "\t\t\t\t\$this->set('{$lowerName}Array', \$this->{$controllerModel}->{$model}->generateList());\n"; $actions .= "\t\t\t\t\$this->set('{$lowerName}Array', \$this->{$controllerModel}->{$model}->generateList());\n";
$actions .= "\t\t\t\tif(isset(\$data['{$model}']['{$model}']))\n"; $actions .= "\t\t\t\tif(isset(\$data['{$model}']['{$model}'])) {\n";
$actions .= "\t\t\t\t{\n"; $actions .= "\t\t\t\t\tforeach(\$data['{$model}']['{$model}'] as \$var) {\n";
$actions .= "\t\t\t\t\tforeach(\$data['{$model}']['{$model}'] as \$var)\n";
$actions .= "\t\t\t\t\t{\n";
$actions .= "\t\t\t\t\t\t\${$lowerName}[\$var] = \$var;\n"; $actions .= "\t\t\t\t\t\t\${$lowerName}[\$var] = \$var;\n";
$actions .= "\t\t\t\t\t}\n"; $actions .= "\t\t\t\t\t}\n";
$actions .= "\t\t\t\t}\n"; $actions .= "\t\t\t\t}\n";
@ -922,10 +935,8 @@ class Bake {
$actions .= "\t\t}\n"; $actions .= "\t\t}\n";
$actions .= "\t}\n"; $actions .= "\t}\n";
$actions .= "\n"; $actions .= "\n";
$actions .= "\tfunction edit(\$id)\n"; $actions .= "\tfunction edit(\$id) {\n";
$actions .= "\t{\n"; $actions .= "\t\tif(empty(\$this->data)) {\n";
$actions .= "\t\tif(empty(\$this->data))\n";
$actions .= "\t\t{\n";
$actions .= "\t\t\t\$data = \$this->{$controllerModel}->read(null, \$id);\n"; $actions .= "\t\t\t\$data = \$this->{$controllerModel}->read(null, \$id);\n";
$actions .= "\t\t\t\$this->set('{$this->lowCtrl}', \$data );\n"; $actions .= "\t\t\t\$this->set('{$this->lowCtrl}', \$data );\n";
@ -936,8 +947,7 @@ class Bake {
$lowerName = strtolower($association); $lowerName = strtolower($association);
$actions .= "\t\t\t\${$lowerName} = null;\n"; $actions .= "\t\t\t\${$lowerName} = null;\n";
$actions .= "\t\t\t\$this->set('{$lowerName}Array', \$this->{$controllerModel}->{$model}->generateList());\n"; $actions .= "\t\t\t\$this->set('{$lowerName}Array', \$this->{$controllerModel}->{$model}->generateList());\n";
$actions .= "\t\t\tforeach(\$data['{$model}'] as \$var)\n"; $actions .= "\t\t\tforeach(\$data['{$model}'] as \$var) {\n";
$actions .= "\t\t\t{\n";
$actions .= "\t\t\t\t\${$lowerName}[\$var['{$associationModel->primaryKey}']] = \$var['{$associationModel->primaryKey}'];\n"; $actions .= "\t\t\t\t\${$lowerName}[\$var['{$associationModel->primaryKey}']] = \$var['{$associationModel->primaryKey}'];\n";
$actions .= "\t\t\t}\n"; $actions .= "\t\t\t}\n";
$actions .= "\t\t\t\$this->set('selected{$model}', \${$lowerName});\n"; $actions .= "\t\t\t\$this->set('selected{$model}', \${$lowerName});\n";
@ -950,26 +960,17 @@ class Bake {
$actions .= "\t\t\t\$this->set('{$lowerName}Array', \$this->{$controllerModel}->{$model}->generateList());\n"; $actions .= "\t\t\t\$this->set('{$lowerName}Array', \$this->{$controllerModel}->{$model}->generateList());\n";
} }
} }
$actions .= "\t\t}\n"; $actions .= "\t\t} else {\n";
$actions .= "\t\telse\n";
$actions .= "\t\t{\n";
$actions .= "\t\t\t\$this->cleanUpFields();\n"; $actions .= "\t\t\t\$this->cleanUpFields();\n";
$actions .= "\t\t\tif(\$this->{$controllerModel}->save(\$this->data))\n"; $actions .= "\t\t\tif(\$this->{$controllerModel}->save(\$this->data)) {\n";
$actions .= "\t\t\t{\n"; $actions .= "\t\t\t\tif(is_object(\$this->Session)) {\n";
$actions .= "\t\t\t\tif(is_object(\$this->Session))\n";
$actions .= "\t\t\t\t{\n";
$actions .= "\t\t\t\t\t\$this->Session->setFlash('The ".Inflector::humanize($controllerModel)." has been saved');\n"; $actions .= "\t\t\t\t\t\$this->Session->setFlash('The ".Inflector::humanize($controllerModel)." has been saved');\n";
$actions .= "\t\t\t\t\t\$this->redirect(\$this->viewPath.'/index');\n"; $actions .= "\t\t\t\t\t\$this->redirect(\$this->viewPath.'/index');\n";
$actions .= "\t\t\t\t}\n"; $actions .= "\t\t\t\t} else {\n";
$actions .= "\t\t\t\telse\n";
$actions .= "\t\t\t\t{\n";
$actions .= "\t\t\t\t\t\$this->flash('{$controllerModel} saved.', \$this->viewPath.'/index');\n"; $actions .= "\t\t\t\t\t\$this->flash('{$controllerModel} saved.', \$this->viewPath.'/index');\n";
$actions .= "\t\t\t\t}\n"; $actions .= "\t\t\t\t}\n";
$actions .= "\t\t\t}\n"; $actions .= "\t\t\t} else {\n";
$actions .= "\t\t\telse\n"; $actions .= "\t\t\t\tif(is_object(\$this->Session)) {\n";
$actions .= "\t\t\t{\n";
$actions .= "\t\t\t\tif(is_object(\$this->Session))\n";
$actions .= "\t\t\t\t{\n";
$actions .= "\t\t\t\t\t\$this->Session->setFlash('Please correct errors below.');\n"; $actions .= "\t\t\t\t\t\$this->Session->setFlash('Please correct errors below.');\n";
$actions .= "\t\t\t\t}\n"; $actions .= "\t\t\t\t}\n";
$actions .= "\t\t\t\t\$data = \$this->data;\n"; $actions .= "\t\t\t\t\$data = \$this->data;\n";
@ -982,10 +983,8 @@ class Bake {
$lowerName = strtolower($association); $lowerName = strtolower($association);
$actions .= "\t\t\t\t\${$lowerName} = null;\n"; $actions .= "\t\t\t\t\${$lowerName} = null;\n";
$actions .= "\t\t\t\t\$this->set('{$lowerName}Array', \$this->{$controllerModel}->{$model}->generateList());\n"; $actions .= "\t\t\t\t\$this->set('{$lowerName}Array', \$this->{$controllerModel}->{$model}->generateList());\n";
$actions .= "\t\t\t\tif(isset(\$data['{$model}']['{$model}']))\n"; $actions .= "\t\t\t\tif(isset(\$data['{$model}']['{$model}'])) {\n";
$actions .= "\t\t\t\t{\n"; $actions .= "\t\t\t\t\tforeach(\$data['{$model}']['{$model}'] as \$var) {\n";
$actions .= "\t\t\t\t\tforeach(\$data['{$model}']['{$model}'] as \$var)\n";
$actions .= "\t\t\t\t\t{\n";
$actions .= "\t\t\t\t\t\t\${$lowerName}[\$var] = \$var;\n"; $actions .= "\t\t\t\t\t\t\${$lowerName}[\$var] = \$var;\n";
$actions .= "\t\t\t\t\t}\n"; $actions .= "\t\t\t\t\t}\n";
$actions .= "\t\t\t\t}\n"; $actions .= "\t\t\t\t}\n";
@ -1003,13 +1002,11 @@ class Bake {
$actions .= "\t\t}\n"; $actions .= "\t\t}\n";
$actions .= "\t}\n"; $actions .= "\t}\n";
$actions .= "\n"; $actions .= "\n";
$actions .= "\tfunction view(\$id)\n"; $actions .= "\tfunction view(\$id) {\n";
$actions .= "\t{\n";
$actions .= "\t\t\$this->set('{$this->lowCtrl}', \$this->{$controllerModel}->read(null, \$id));\n"; $actions .= "\t\t\$this->set('{$this->lowCtrl}', \$this->{$controllerModel}->read(null, \$id));\n";
$actions .= "\t}\n"; $actions .= "\t}\n";
$actions .= "\n"; $actions .= "\n";
$actions .= "\tfunction delete(\$id)\n"; $actions .= "\tfunction delete(\$id) {\n";
$actions .= "\t{\n";
$actions .= "\t\t\$this->{$controllerModel}->del(\$id);\n"; $actions .= "\t\t\$this->{$controllerModel}->del(\$id);\n";
$actions .= "\t\t\$this->redirect('/{$this->lowCtrl}/index');\n"; $actions .= "\t\t\$this->redirect('/{$this->lowCtrl}/index');\n";
$actions .= "\t}\n"; $actions .= "\t}\n";
@ -1890,7 +1887,6 @@ class Bake {
$this->stdout(' -core [path...] Absolute path to Cake\'s cake Folder.'); $this->stdout(' -core [path...] Absolute path to Cake\'s cake Folder.');
$this->stdout(' -help Shows this help message.'); $this->stdout(' -help Shows this help message.');
$this->stdout(' -project [path...] Generates a new app folder in the path supplied.'); $this->stdout(' -project [path...] Generates a new app folder in the path supplied.');
$this->stdout(' Must be used with the -app command.');
$this->stdout(' -root [path...] Absolute path to Cake\'s \app\webroot Folder.'); $this->stdout(' -root [path...] Absolute path to Cake\'s \app\webroot Folder.');
$this->stdout(''); $this->stdout('');
} }
@ -1924,13 +1920,6 @@ class Bake {
$parentPath = explode(DS, $projectPath); $parentPath = explode(DS, $projectPath);
$count = count($parentPath); $count = count($parentPath);
$appName = $parentPath[$count - 1]; $appName = $parentPath[$count - 1];
unset($parentPath[$count - 1]);
$parentPath = implode(DS, $parentPath);
if(!is_writable($parentPath)) {
$projectPath = $this->getInput('The directory path is not writable. Please try again');
$this->project($projectPath);
}
$this->__buildDirLayout($projectPath, $appName); $this->__buildDirLayout($projectPath, $appName);
exit(); exit();
} }
@ -2019,7 +2008,9 @@ class Bake {
$messages=array(); $messages=array();
if (!is_dir($toDir)) { if (!is_dir($toDir)) {
mkdir($toDir, 0755); uses('folder');
$folder = new Folder();
$folder->mkdirr($toDir, 0755);
} }
if (!is_writable($toDir)) { if (!is_writable($toDir)) {
@ -2082,11 +2073,12 @@ class Bake {
* Enter description here... * Enter description here...
* *
*/ */
function welcome() { function welcome()
{
$this->stdout(''); $this->stdout('');
$this->stdout(' ___ __ _ _ ___ __ _ _ __ __ __ _ _ ___ '); $this->stdout(' ___ __ _ _ ___ __ _ _ __ __ __ _ _ ___ ');
$this->stdout('| |__| |_/ |__ |__] |__| |__] |__] |__| |_/ |__ '); $this->stdout('| |__| |_/ |__ |__] |__| |__] |__] |__| |_/ |__ ');
$this->stdout('|___ | | | \_ |___ | | | | |__] | | | \_ |___ '); $this->stdout('|___ | | | \_ |___ | | | | |__] | | | \_ |___ ');
$this->hr(); $this->hr();
$this->stdout(''); $this->stdout('');
} }

View file

@ -37,7 +37,7 @@
* release/app/.htaccess * release/app/.htaccess
* release/app/webroot/.htaccess * release/app/webroot/.htaccess
*/ */
//define ('BASE_URL', env('SCRIPT_NAME')); // define ('BASE_URL', env('SCRIPT_NAME'));
/** /**
* Set debug level here: * Set debug level here:
* - 0: production * - 0: production
@ -76,6 +76,13 @@
* *
*/ */
define('CAKE_SESSION_SAVE', 'php'); define('CAKE_SESSION_SAVE', 'php');
/**
* If using you own table name for storing sessions
* set the table name here.
* DO NOT INCLUDE PREFIX IF YOU HAVE SET ONE IN database.php
*
*/
define('CAKE_SESSION_TABLE', 'cake_sessions');
/** /**
* Set a random string of used in session. * Set a random string of used in session.
* *
@ -108,7 +115,7 @@
* name you set CAKE_ADMIN to. * name you set CAKE_ADMIN to.
* For example: admin_index, admin_edit * For example: admin_index, admin_edit
*/ */
//define('CAKE_ADMIN', 'admin'); // define('CAKE_ADMIN', 'admin');
/** /**
* The define below is used to turn cake built webservices * The define below is used to turn cake built webservices
* on or off. Default setting is off. * on or off. Default setting is off.

View file

@ -33,34 +33,34 @@
* *
* $pluralRules = array('/(s)tatus$/i' => '\1\2tatuses', '/^(ox)$/i' => '\1\2en', '/([m|l])ouse$/i' => '\1ice'); * $pluralRules = array('/(s)tatus$/i' => '\1\2tatuses', '/^(ox)$/i' => '\1\2en', '/([m|l])ouse$/i' => '\1ice');
*/ */
$pluralRules = array(); $pluralRules = array();
/** /**
* This is a key only array of plural words that should not be inflected. * This is a key only array of plural words that should not be inflected.
* Notice the last comma * Notice the last comma
* *
* $uninflectedPlural = array('.*[nrlm]ese', '.*deer', '.*fish', '.*measles', '.*ois', '.*pox'); * $uninflectedPlural = array('.*[nrlm]ese', '.*deer', '.*fish', '.*measles', '.*ois', '.*pox');
*/ */
$uninflectedPlural = array(); $uninflectedPlural = array();
/** /**
* This is a key => value array of plural irregular words. * This is a key => value array of plural irregular words.
* If key matches then the value is returned. * If key matches then the value is returned.
* *
* $irregularPlural = array('atlas' => 'atlases', 'beef' => 'beefs', 'brother' => 'brothers') * $irregularPlural = array('atlas' => 'atlases', 'beef' => 'beefs', 'brother' => 'brothers')
*/ */
$irregularPlural = array(); $irregularPlural = array();
/** /**
* This is a key => value array of regex used to match words. * This is a key => value array of regex used to match words.
* If key matches then the value is returned. * If key matches then the value is returned.
* *
* $singularRules = array('/(s)tatuses$/i' => '\1\2tatus', '/(matr)ices$/i' =>'\1ix','/(vert|ind)ices$/i') * $singularRules = array('/(s)tatuses$/i' => '\1\2tatus', '/(matr)ices$/i' =>'\1ix','/(vert|ind)ices$/i')
*/ */
$singularRules = array(); $singularRules = array();
/** /**
* This is a key only array of singular words that should not be inflected. * This is a key only array of singular words that should not be inflected.
* You should not have to change this value below if you do change it use same format * You should not have to change this value below if you do change it use same format
* as the $uninflectedPlural above. * as the $uninflectedPlural above.
*/ */
$uninflectedSingular = $uninflectedPlural; $uninflectedSingular = $uninflectedPlural;
/** /**
* This is a key => value array of singular irregular words. * This is a key => value array of singular irregular words.
* Most of the time this will be a reverse of the above $irregularPlural array * Most of the time this will be a reverse of the above $irregularPlural array
@ -68,5 +68,5 @@ $uninflectedSingular = $uninflectedPlural;
* *
* $irregularSingular = array('atlases' => 'atlas', 'beefs' => 'beef', 'brothers' => 'brother') * $irregularSingular = array('atlases' => 'atlas', 'beefs' => 'beef', 'brothers' => 'brother')
*/ */
$irregularSingular = array_flip($irregularPlural); $irregularSingular = array_flip($irregularPlural);
?> ?>

View file

@ -33,14 +33,14 @@
* its action called 'display', and we pass a param to select the view file * its action called 'display', and we pass a param to select the view file
* to use (in this case, /app/views/pages/home.thtml)... * to use (in this case, /app/views/pages/home.thtml)...
*/ */
$Route->connect ('/', array('controller'=>'pages', 'action'=>'display', 'home')); $Route->connect('/', array('controller' => 'pages', 'action' => 'display', 'home'));
/** /**
* ...and connect the rest of 'Pages' controller's urls. * ...and connect the rest of 'Pages' controller's urls.
*/ */
$Route->connect ('/pages/*', array('controller'=>'pages', 'action'=>'display')); $Route->connect('/pages/*', array('controller' => 'pages', 'action' => 'display'));
/** /**
* Then we connect url '/test' to our test controller. This is helpfull in * Then we connect url '/test' to our test controller. This is helpfull in
* developement. * developement.
*/ */
$Route->connect ('/tests', array('controller'=>'tests', 'action'=>'index')); $Route->connect('/tests', array('controller' => 'tests', 'action' => 'index'));
?> ?>

View file

@ -2,7 +2,7 @@
<html xmlns="http://www.w3.org/1999/xhtml"> <html xmlns="http://www.w3.org/1999/xhtml">
<head> <head>
<title>CakePHP : <?php echo $title_for_layout;?></title> <title>CakePHP : <?php echo $title_for_layout;?></title>
<link rel="shortcut icon" href="favicon.ico" type="image/x-icon" /> <link rel="shortcut icon" href="<?php echo $html->url('/favicon.ico')?>" type="image/x-icon" />
<?php echo $html->css('generic.basic');?> <?php echo $html->css('generic.basic');?>
<?php echo $html->css('generic.forms');?> <?php echo $html->css('generic.forms');?>
</head> </head>

View file

@ -68,9 +68,10 @@
if (preg_match('|\.\.|', $url) || !preg_match('|^ccss/(.+)$|i', $url, $regs)) { if (preg_match('|\.\.|', $url) || !preg_match('|^ccss/(.+)$|i', $url, $regs)) {
die('Wrong file name.'); die('Wrong file name.');
} }
$filename = 'css/' . $regs[1];
$filepath = CSS . $regs[1]; $filename = 'css/' . $regs[1];
$cachepath = CACHE . 'css' . DS . str_replace(array('/','\\'), '-', $regs[1]); $filepath = CSS . $regs[1];
$cachepath = CACHE . 'css' . DS . str_replace(array('/','\\'), '-', $regs[1]);
if (!file_exists($filepath)) { if (!file_exists($filepath)) {
die('Wrong file name.'); die('Wrong file name.');

View file

@ -8,7 +8,7 @@ font-family:verdana,helvetica,arial,sans-serif;
font-size:12px; font-size:12px;
text-align:center; text-align:center;
color:#333; color:#333;
background:#fff; background:#003d4c;
line-height: 18px; line-height: 18px;
} }
@ -18,11 +18,11 @@ line-height: 18px;
a{ a{
color:#003d4c; color:#003d4c;
text-decoration:none; text-decoration:underline;
} }
a:hover{ a:hover{
color:#003d4c; color:#003d4c;
text-decoration:underline; text-decoration:none;
} }
a img{ a img{
@ -90,6 +90,8 @@ font-weight:normal;
#content{ #content{
padding: 10px 40px; padding: 10px 40px;
background-color: #fff;
color: #333;
} }
#footer{ #footer{
padding: 6px 10px; padding: 6px 10px;
@ -151,20 +153,29 @@ dd {
vertical-align:top; vertical-align:top;
} }
/* scaffold buttons */ /* notices and errors */
p.error, error_message {
color: #e32000;
font-size: 18px;
background-color: #fff;
margin: 8px 4px;
}
p.error em {
font-size: 18px;
color: #003d4c;
}
.notice { .notice {
color: #DB8101; color: #656565;
background-color: #ddd; font-size: 14px;
display: block; background-color: #f4f4f4;
padding: 1em; padding: 4px;
display:block;
} }
.tip { .tip {
color: #DB8101; color: #e32000;
background-color: #ddd; background-color: #ddd;
display: block;
padding: 1em;
} }

View file

@ -129,12 +129,7 @@ form div label.labelCheckbox, form div label.labelRadio {
form div fieldset label.labelCheckbox, form div fieldset label.labelRadio { form div fieldset label.labelCheckbox, form div fieldset label.labelRadio {
margin: 0px 0px 5px 0px; margin: 0px 0px 5px 0px;
} }
p.error {
color: #DB8101;
background-color: #DBA941;
font-size: 14px;
padding: 1em;
}
form div input, form div select, form div textarea { form div input, form div select, form div textarea {
padding: 1px 3px; padding: 1px 3px;

View file

@ -30,7 +30,7 @@
* Do not change * Do not change
*/ */
if (!defined('DS')) { if (!defined('DS')) {
define('DS', DIRECTORY_SEPARATOR); define('DS', DIRECTORY_SEPARATOR);
} }
/** /**
* These defines should only be edited if you have cake installed in * These defines should only be edited if you have cake installed in
@ -39,50 +39,49 @@
* *
*/ */
if (!defined('ROOT')) { if (!defined('ROOT')) {
//define('ROOT', 'FULL PATH TO DIRECTORY WHERE APP DIRECTORY IS LOCATED DO NOT ADD A TRAILING DIRECTORY SEPARATOR'; //define('ROOT', 'FULL PATH TO DIRECTORY WHERE APP DIRECTORY IS LOCATED DO NOT ADD A TRAILING DIRECTORY SEPARATOR';
//You should also use the DS define to seperate your directories //You should also use the DS define to seperate your directories
define('ROOT', dirname(dirname(dirname(__FILE__)))); define('ROOT', dirname(dirname(dirname(__FILE__))));
} }
if (!defined('APP_DIR')) { if (!defined('APP_DIR')) {
//define('APP_DIR', 'DIRECTORY NAME OF APPLICATION'; //define('APP_DIR', 'DIRECTORY NAME OF APPLICATION';
define('APP_DIR', basename(dirname(dirname(__FILE__)))); define('APP_DIR', basename(dirname(dirname(__FILE__))));
} }
/** /**
* This only needs to be changed if the cake installed libs are located * This only needs to be changed if the cake installed libs are located
* outside of the distributed directory structure. * outside of the distributed directory structure.
*/ */
if (!defined('CAKE_CORE_INCLUDE_PATH')) { if (!defined('CAKE_CORE_INCLUDE_PATH')) {
//define ('CAKE_CORE_INCLUDE_PATH', FULL PATH TO DIRECTORY WHERE CAKE CORE IS INSTALLED DO NOT ADD A TRAILING DIRECTORY SEPARATOR'; //define ('CAKE_CORE_INCLUDE_PATH', FULL PATH TO DIRECTORY WHERE CAKE CORE IS INSTALLED DO NOT ADD A TRAILING DIRECTORY SEPARATOR';
//You should also use the DS define to seperate your directories //You should also use the DS define to seperate your directories
define('CAKE_CORE_INCLUDE_PATH', ROOT); define('CAKE_CORE_INCLUDE_PATH', ROOT);
} }
/////////////////////////////// ///////////////////////////////
//DO NOT EDIT BELOW THIS LINE// //DO NOT EDIT BELOW THIS LINE//
/////////////////////////////// ///////////////////////////////
if (!defined('WEBROOT_DIR')) { if (!defined('WEBROOT_DIR')) {
define('WEBROOT_DIR', basename(dirname(__FILE__))); define('WEBROOT_DIR', basename(dirname(__FILE__)));
} }
if (!defined('WWW_ROOT')) { if (!defined('WWW_ROOT')) {
define('WWW_ROOT', dirname(__FILE__) . DS); define('WWW_ROOT', dirname(__FILE__) . DS);
} }
if (!defined('CORE_PATH')) { if (!defined('CORE_PATH')) {
if (function_exists('ini_set')) { if (function_exists('ini_set')) {
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);
define('APP_PATH', null); define('APP_PATH', null);
define('CORE_PATH', null); define('CORE_PATH', null);
} else { } else {
define('APP_PATH', ROOT . DS . APP_DIR . DS); define('APP_PATH', ROOT . DS . APP_DIR . DS);
define('CORE_PATH', CAKE_CORE_INCLUDE_PATH . DS); define('CORE_PATH', CAKE_CORE_INCLUDE_PATH . DS);
} }
} }
require CORE_PATH . 'cake' . DS . 'bootstrap.php'; require CORE_PATH . 'cake' . DS . 'bootstrap.php';
if (isset($_GET['url']) && $_GET['url'] === 'favicon.ico') { if (isset($_GET['url']) && $_GET['url'] === 'favicon.ico') {
} else { } else {
$Dispatcher = new Dispatcher(); $Dispatcher=new Dispatcher();
$Dispatcher->dispatch($url); $Dispatcher->dispatch($url);
} }
if (DEBUG) { if (DEBUG) {
echo "<!-- " . round(getMicrotime() - $TIME_START, 4) . "s -->"; echo "<!-- " . round(getMicrotime() - $TIME_START, 4) . "s -->";
} }
?> ?>