I've merged in Olle's changes.

Larry, I've merged in _some_ of your changes, I'll merge in the scaffolding and joins code when you tell me it's ready. But I don't want to break how the Controller class works, can't we really do without the constructClasses() method call? Which reminds me, with your joins code, will we be able to use constructs like $user->post->findAll() and $user->post->save()?

Also, what are your changes to the DBO_MySQL class? I mean the mysqlResultSet(), and fetchResult() methods. I didn't see any MySQL-specific code inside them, perhaps they belong to the DBO class itself? 

- I've changed the headers on user-editable files in /app and /config. I hope they will constitute a compromise between readability and legality. I've left file Id, copyright, and licence notices.

- /libs/basic.php::uses() function logs included files in global $loaded. Please, consider it a note to myself. Also, I've moved the NeatArray class out of the /libs/basics.php (into /libs/neat_array.php).
- Some cleanups in the Controller and Dispatcher classes.
- DBO::Prepare() accepts strings _and_ arrays now. It's a step towards a unified params theory.
- I think I've added some comments to DBO sub-classes, but it might have been Olle.
- A fix in Model class (findAll didn't work properly)
- Object's constructor sets $this->db to &DBO, which means all Object-descendand classes have default access to the database if it's connected. We need to clean up the code accordingly (some classes set their own $this->db references).

git-svn-id: https://svn.cakephp.org/repo/trunk/cake@236 3807eeeb-6ff5-0310-8944-8be069107fe0
This commit is contained in:
pies 2005-06-05 11:05:24 +00:00
parent dada2432f0
commit 443a702376
26 changed files with 464 additions and 661 deletions

View file

@ -4,41 +4,18 @@
// +------------------------------------------------------------------+ //
// + Cake <https://developers.nextco.com/cake/> + //
// + Copyright: (c) 2005, Cake Authors/Developers + //
// + Author(s): Michal Tatarynowicz aka Pies <tatarynowicz@gmail.com> + //
// + Larry E. Masters aka PhpNut <nut@phpnut.com> + //
// + Kamil Dzielinski aka Brego <brego.dk@gmail.com> + //
// +------------------------------------------------------------------+ //
// + Licensed under The MIT License + //
// + Redistributions of files must retain the above copyright notice. + //
// + See: http://www.opensource.org/licenses/mit-license.php + //
//////////////////////////////////////////////////////////////////////////
/**
* This file is application-wide controller file. You can put all
* application-wide controller-related methods here.
*
* @filesource
* @author Cake Authors/Developers
* @copyright Copyright (c) 2005, Cake Authors/Developers
* @link https://developers.nextco.com/cake/wiki/Authors Authors/Developers
* @package cake
* @subpackage cake.app
* @since Cake v 0.2.9
* @version $Revision$
* @modifiedby $LastChangedBy$
* @lastmodified $Date$
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
*/
/**
* Add your application-wide methods in the class below, your controllers
* will be inheriting them.
*
* @package cake
* @subpackage cake.app
* @since Cake v 0.2.9
*
*/
class AppController extends Controller {
}

View file

@ -4,41 +4,18 @@
// +------------------------------------------------------------------+ //
// + Cake <https://developers.nextco.com/cake/> + //
// + Copyright: (c) 2005, Cake Authors/Developers + //
// + Author(s): Michal Tatarynowicz aka Pies <tatarynowicz@gmail.com> + //
// + Larry E. Masters aka PhpNut <nut@phpnut.com> + //
// + Kamil Dzielinski aka Brego <brego.dk@gmail.com> + //
// +------------------------------------------------------------------+ //
// + Licensed under The MIT License + //
// + Redistributions of files must retain the above copyright notice. + //
// + See: http://www.opensource.org/licenses/mit-license.php + //
//////////////////////////////////////////////////////////////////////////
/**
* This file is application-wide model file. You can put all
* application-wide model-related methods here.
*
* @filesource
* @author Cake Authors/Developers
* @copyright Copyright (c) 2005, Cake Authors/Developers
* @link https://developers.nextco.com/cake/wiki/Authors Authors/Developers
* @package cake
* @subpackage cake.app
* @since Cake v 0.2.9
* @version $Revision$
* @modifiedby $LastChangedBy$
* @lastmodified $Date$
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
*/
/**
* Add your application-wide methods in the class below, your models
* will be inheriting them.
*
* @package cake
* @subpackage cake.app
* @since Cake v 0.2.9
*
*/
class AppModel extends Model {
}

View file

@ -4,41 +4,10 @@
// +------------------------------------------------------------------+ //
// + Cake <https://developers.nextco.com/cake/> + //
// + Copyright: (c) 2005, Cake Authors/Developers + //
// + Author(s): Michal Tatarynowicz aka Pies <tatarynowicz@gmail.com> + //
// + Larry E. Masters aka PhpNut <nut@phpnut.com> + //
// + Kamil Dzielinski aka Brego <brego.dk@gmail.com> + //
// +------------------------------------------------------------------+ //
// + Licensed under The MIT License + //
// + Redistributions of files must retain the above copyright notice. + //
// + See: http://www.opensource.org/licenses/mit-license.php + //
//////////////////////////////////////////////////////////////////////////
/**
*
*
*
* @filesource
* @author Cake Authors/Developers
* @copyright Copyright (c) 2005, Cake Authors/Developers
* @link https://developers.nextco.com/cake/wiki/Authors Authors/Developers
* @package cake
* @subpackage cake.app.controllers
* @since Cake v 1.0.0.158
* @version $Revision$
* @modifiedby $LastChangedBy$
* @lastmodified $Date$
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
*/
/**
*
*
*
* @package cake
* @subpackage cake.app.controllers
* @since Cake v 1.0.0.158
*
*/
class PagesController extends PagesHelper {
/**

View file

@ -4,31 +4,10 @@
// +------------------------------------------------------------------+ //
// + Cake <https://developers.nextco.com/cake/> + //
// + Copyright: (c) 2005, Cake Authors/Developers + //
// + Author(s): Michal Tatarynowicz aka Pies <tatarynowicz@gmail.com> + //
// + Larry E. Masters aka PhpNut <nut@phpnut.com> + //
// + Kamil Dzielinski aka Brego <brego.dk@gmail.com> + //
// +------------------------------------------------------------------+ //
// + Licensed under The MIT License + //
// + Redistributions of files must retain the above copyright notice. + //
// + See: http://www.opensource.org/licenses/mit-license.php + //
//////////////////////////////////////////////////////////////////////////
/**
*
*
*
* @filesource
* @author Cake Authors/Developers
* @copyright Copyright (c) 2005, Cake Authors/Developers
* @link https://developers.nextco.com/cake/wiki/Authors Authors/Developers
* @package cake
* @subpackage cake.app.controllers
* @since Cake v 1.0.0.158
* @version $Revision$
* @modifiedby $LastChangedBy$
* @lastmodified $Date$
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
*/
/**
* Description:
@ -36,15 +15,6 @@
*/
uses('test', 'folder', 'inflector');
/**
*
*
*
* @package cake
* @subpackage cake.app.controllers
* @since Cake v 1.0.0.158
*
*/
class TestsController extends TestsHelper {
/**

View file

@ -4,41 +4,10 @@
// +------------------------------------------------------------------+ //
// + Cake <https://developers.nextco.com/cake/> + //
// + Copyright: (c) 2005, Cake Authors/Developers + //
// + Author(s): Michal Tatarynowicz aka Pies <tatarynowicz@gmail.com> + //
// + Larry E. Masters aka PhpNut <nut@phpnut.com> + //
// + Kamil Dzielinski aka Brego <brego.dk@gmail.com> + //
// +------------------------------------------------------------------+ //
// + Licensed under The MIT License + //
// + Redistributions of files must retain the above copyright notice. + //
// + See: http://www.opensource.org/licenses/mit-license.php + //
//////////////////////////////////////////////////////////////////////////
/**
*
*
*
* @filesource
* @author Cake Authors/Developers
* @copyright Copyright (c) 2005, Cake Authors/Developers
* @link https://developers.nextco.com/cake/wiki/Authors Authors/Developers
* @package cake
* @subpackage cake.app.helpers
* @since Cake v 1.0.0.158
* @version $Revision$
* @modifiedby $LastChangedBy$
* @lastmodified $Date$
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
*/
/**
*
*
*
* @package cake
* @subpackage cake.app.helpers
* @since Cake v 1.0.0.158
*
*/
class PagesHelper extends AppController {
}

View file

@ -4,41 +4,10 @@
// +------------------------------------------------------------------+ //
// + Cake <https://developers.nextco.com/cake/> + //
// + Copyright: (c) 2005, Cake Authors/Developers + //
// + Author(s): Michal Tatarynowicz aka Pies <tatarynowicz@gmail.com> + //
// + Larry E. Masters aka PhpNut <nut@phpnut.com> + //
// + Kamil Dzielinski aka Brego <brego.dk@gmail.com> + //
// +------------------------------------------------------------------+ //
// + Licensed under The MIT License + //
// + Redistributions of files must retain the above copyright notice. + //
// + See: http://www.opensource.org/licenses/mit-license.php + //
//////////////////////////////////////////////////////////////////////////
/**
*
*
*
* @filesource
* @author Cake Authors/Developers
* @copyright Copyright (c) 2005, Cake Authors/Developers
* @link https://developers.nextco.com/cake/wiki/Authors Authors/Developers
* @package cake
* @subpackage cake.app.helpers
* @since Cake v 1.0.0.159
* @version $Revision$
* @modifiedby $LastChangedBy$
* @lastmodified $Date$
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
*/
/**
*
*
*
* @package cake
* @subpackage cake.app.helpers
* @since Cake v 1.0.0.159
*
*/
class TestsHelper extends AppController {
}

View file

@ -4,30 +4,13 @@
// +------------------------------------------------------------------+ //
// + Cake <https://developers.nextco.com/cake/> + //
// + Copyright: (c) 2005, Cake Authors/Developers + //
// + Author(s): Michal Tatarynowicz aka Pies <tatarynowicz@gmail.com> + //
// + Larry E. Masters aka PhpNut <nut@phpnut.com> + //
// + Kamil Dzielinski aka Brego <brego.dk@gmail.com> + //
// +------------------------------------------------------------------+ //
// + Licensed under The MIT License + //
// + Redistributions of files must retain the above copyright notice. + //
// + See: http://www.opensource.org/licenses/mit-license.php + //
//////////////////////////////////////////////////////////////////////////
/**
* This is core configuration file. Use it to configure core behaviour of
* Cake.
*
* @filesource
* @author Cake Authors/Developers
* @copyright Copyright (c) 2005, Cake Authors/Developers
* @link https://developers.nextco.com/cake/wiki/Authors Authors/Developers
* @package cake
* @subpackage cake.config
* @since Cake v 0.2.9
* @version $Revision$
* @modifiedby $LastChangedBy$
* @lastmodified $Date$
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
*/
/**

View file

@ -4,29 +4,12 @@
// +------------------------------------------------------------------+ //
// + Cake <https://developers.nextco.com/cake/> + //
// + Copyright: (c) 2005, Cake Authors/Developers + //
// + Author(s): Michal Tatarynowicz aka Pies <tatarynowicz@gmail.com> + //
// + Larry E. Masters aka PhpNut <nut@phpnut.com> + //
// + Kamil Dzielinski aka Brego <brego.dk@gmail.com> + //
// +------------------------------------------------------------------+ //
// + Licensed under The MIT License + //
// + Redistributions of files must retain the above copyright notice. + //
// + See: http://www.opensource.org/licenses/mit-license.php + //
//////////////////////////////////////////////////////////////////////////
/**
* In this file you set up your database connection details.
*
* @filesource
* @author Cake Authors/Developers
* @copyright Copyright (c) 2005, Cake Authors/Developers
* @link https://developers.nextco.com/cake/wiki/Authors Authors/Developers
* @package cake
* @subpackage cake.config
* @since Cake v 0.2.9
* @version $Revision$
* @modifiedby $LastChangedBy$
* @lastmodified $Date$
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
*/
/**

View file

@ -4,29 +4,12 @@
// +------------------------------------------------------------------+ //
// + Cake <https://developers.nextco.com/cake/> + //
// + Copyright: (c) 2005, Cake Authors/Developers + //
// + Author(s): Michal Tatarynowicz aka Pies <tatarynowicz@gmail.com> + //
// + Larry E. Masters aka PhpNut <nut@phpnut.com> + //
// + Kamil Dzielinski aka Brego <brego.dk@gmail.com> + //
// +------------------------------------------------------------------+ //
// + Licensed under The MIT License + //
// + Redistributions of files must retain the above copyright notice. + //
// + See: http://www.opensource.org/licenses/mit-license.php + //
//////////////////////////////////////////////////////////////////////////
/**
* In this file you set paths to different directories used by Cake.
*
* @filesource
* @author Cake Authors/Developers
* @copyright Copyright (c) 2005, Cake Authors/Developers
* @link https://developers.nextco.com/cake/wiki/Authors Authors/Developers
* @package cake
* @subpackage cake.config
* @since Cake v 0.2.9
* @version $Revision$
* @modifiedby $LastChangedBy$
* @lastmodified $Date$
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
*/
/**

View file

@ -4,32 +4,14 @@
// +------------------------------------------------------------------+ //
// + Cake <https://developers.nextco.com/cake/> + //
// + Copyright: (c) 2005, Cake Authors/Developers + //
// + Author(s): Michal Tatarynowicz aka Pies <tatarynowicz@gmail.com> + //
// + Larry E. Masters aka PhpNut <nut@phpnut.com> + //
// + Kamil Dzielinski aka Brego <brego.dk@gmail.com> + //
// +------------------------------------------------------------------+ //
// + Licensed under The MIT License + //
// + Redistributions of files must retain the above copyright notice. + //
// + See: http://www.opensource.org/licenses/mit-license.php + //
//////////////////////////////////////////////////////////////////////////
/**
* In this file, you set up routes to your controllers and their actions.
* Routes are very important mechanism that allows you to freely connect
* different urls to chosen controllers and their actions (functions).
*
* @filesource
* @author Cake Authors/Developers
* @copyright Copyright (c) 2005, Cake Authors/Developers
* @link https://developers.nextco.com/cake/wiki/Authors Authors/Developers
* @package cake
* @subpackage cake.config
* @since Cake v 0.2.9
* @version $Revision$
* @modifiedby $LastChangedBy$
* @lastmodified $Date$
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
*
*/
/**

View file

@ -4,32 +4,14 @@
// +------------------------------------------------------------------+ //
// + Cake <https://developers.nextco.com/cake/> + //
// + Copyright: (c) 2005, Cake Authors/Developers + //
// + Author(s): Michal Tatarynowicz aka Pies <tatarynowicz@gmail.com> + //
// + Larry E. Masters aka PhpNut <nut@phpnut.com> + //
// + Kamil Dzielinski aka Brego <brego.dk@gmail.com> + //
// +------------------------------------------------------------------+ //
// + Licensed under The MIT License + //
// + Redistributions of files must retain the above copyright notice. + //
// + See: http://www.opensource.org/licenses/mit-license.php + //
//////////////////////////////////////////////////////////////////////////
/**
* In this file, you set up routes to your controllers and their actions.
* Routes are very important mechanism that allows you to freely connect
* different urls to chosen controllers and their actions (functions).
*
* @filesource
* @author Cake Authors/Developers
* @copyright Copyright (c) 2005, Cake Authors/Developers
* @link https://developers.nextco.com/cake/wiki/Authors Authors/Developers
* @package cake
* @subpackage cake.config
* @since Cake v 0.2.9
* @version $Revision$
* @modifiedby $LastChangedBy$
* @lastmodified $Date$
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
*
*/
/**

View file

@ -4,30 +4,13 @@
// +------------------------------------------------------------------+ //
// + Cake <https://developers.nextco.com/cake/> + //
// + Copyright: (c) 2005, Cake Authors/Developers + //
// + Author(s): Michal Tatarynowicz aka Pies <tatarynowicz@gmail.com> + //
// + Larry E. Masters aka PhpNut <nut@phpnut.com> + //
// + Kamil Dzielinski aka Brego <brego.dk@gmail.com> + //
// +------------------------------------------------------------------+ //
// + Licensed under The MIT License + //
// + Redistributions of files must retain the above copyright notice. + //
// + See: http://www.opensource.org/licenses/mit-license.php + //
//////////////////////////////////////////////////////////////////////////
/**
* In this file, you can set up 'templates' for every tag generated by the tag
* generator.
*
* @filesource
* @author Cake Authors/Developers
* @copyright Copyright (c) 2005, Cake Authors/Developers
* @link https://developers.nextco.com/cake/wiki/Authors Authors/Developers
* @package cake
* @subpackage cake.config
* @since Cake v 0.2.9
* @version $Revision$
* @modifiedby $LastChangedBy$
* @lastmodified $Date$
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
*/
/**

View file

@ -15,7 +15,7 @@
/**
* Creates controller, model, view files, and the required directories on demand.
* Used by /scripts/add.php.
* Used by /scripts/bake.php.
*
* @filesource
* @author Cake Authors/Developers

View file

@ -30,6 +30,8 @@
*
*/
uses('neat_array');
/**
* Loads all models.
*
@ -107,6 +109,8 @@ function config () {
if (count($args) == 1) return false;
}
}
return true;
}
/**
@ -119,10 +123,21 @@ function config () {
*
* @uses LIBS
*/
function uses () {
function uses ()
{
global $loaded;
if (!is_array($loaded))
$loaded = array();
$args = func_get_args();
foreach ($args as $arg) {
require_once (LIBS.strtolower($arg).'.php');
foreach ($args as $arg)
{
if (0 == in_array($arg, $loaded))
{
require_once(LIBS.strtolower($arg).'.php');
$loaded[] = $arg;
}
}
}
@ -143,7 +158,6 @@ function debug($var = false, $show_html = false) {
if (!function_exists('getMicrotime')) {
/**
* Returns microtime for execution time checking.
*
@ -154,6 +168,7 @@ if (!function_exists('getMicrotime')) {
return ((float)$usec + (float)$sec);
}
}
if (!function_exists('sortByKey')) {
/**
* Sorts given $array by key $sortby.
@ -215,227 +230,4 @@ if (!function_exists('array_combine')) {
}
}
/**
* Class used for internal manipulation of multiarrays (arrays of arrays).
*
* @package cake
* @subpackage cake.libs
* @since Cake v 0.2.9
*/
class NeatArray {
/**
* Value of NeatArray.
*
* @var array
* @access public
*/
var $value;
/**
* Constructor. Defaults to an empty array.
*
* @param array $value
* @access public
* @uses NeatArray::value
*/
function NeatArray ($value=array()) {
$this->value = $value;
}
/**
* Checks whether $fieldName with $value exists in this NeatArray object.
*
* @param string $fieldName
* @param string $value
* @return mixed
* @access public
* @uses NeatArray::value
*/
function findIn ($fieldName, $value) {
$out = false;
foreach ($this->value as $k=>$v) {
if (isset($v[$fieldName]) && ($v[$fieldName] == $value)) {
$out[$k] = $v;
}
}
return $out;
}
/**
* Checks if $this->value is array, and removes all empty elements.
*
* @access public
* @uses NeatArray::value
*/
function cleanup () {
$out = is_array($this->value)? array(): null;
foreach ($this->value as $k=>$v) {
if ($v) {
$out[$k] = $v;
}
}
$this->value = $out;
}
/**
* Adds elements from the supplied array to itself.
*
* @param string $value
* @return bool
* @access public
* @uses NeatArray::value
*/
function add ($value) {
return ($this->value = $this->plus($value))? true: false;
}
/**
* Returns itself merged with given array.
*
* @param array $value Array to add to NeatArray.
* @return array
* @access public
* @uses NeatArray::value
*/
function plus ($value) {
return array_merge($this->value, (is_array($value)? $value: array($value)));
}
/**
* Counts repeating strings and returns an array of totals.
*
* @param int $sortedBy A value of 1 sorts by values, a value of 2 sorts by keys. Defaults to null (no sorting).
* @return array
* @access public
* @uses NeatArray::value
*/
function totals ($sortedBy=1,$reverse=true) {
$out = array();
foreach ($this->value as $val)
isset($out[$val])? $out[$val]++: $out[$val] = 1;
if ($sortedBy == 1) {
$reverse? arsort($out, SORT_NUMERIC): asort($out, SORT_NUMERIC);
}
if ($sortedBy == 2) {
$reverse? krsort($out, SORT_STRING): ksort($out, SORT_STRING);
}
return $out;
}
/**
* Enter description here...
*
* @param unknown_type $with
* @return unknown
*/
function filter ($with) {
return $this->value = array_filter($this->value, $with);
}
/**
* Passes each of its values through a specified function or method. Think of PHP's array_walk.
*
* @return array
* @access public
* @uses NeatArray::value
*/
function walk ($with) {
array_walk($this->value, $with);
return $this->value;
}
/**
* Extracts a value from all array items.
*
* @return array
* @access public
* @uses NeatArray::value
*/
function extract ($name) {
$out = array();
foreach ($this->value as $val) {
if (isset($val[$name]))
$out[] = $val[$name];
}
return $out;
}
/**
* Enter description here...
*
* @return unknown
*/
function unique () {
return array_unique($this->value);
}
/**
* Enter description here...
*
* @return unknown
*/
function makeUnique () {
return $this->value = array_unique($this->value);
}
/**
* Enter description here...
*
* @param unknown_type $his
* @param unknown_type $onMine
* @param unknown_type $onHis
* @return unknown
*/
function joinWith ($his, $onMine, $onHis=null) {
if (empty($onHis)) $onHis = $onMine;
$his = new NeatArray($his);
$out = array();
foreach ($this->value as $key=>$val) {
if ($fromHis = $his->findIn($onHis, $val[$onMine])) {
list($fromHis) = array_values($fromHis);
$out[$key] = array_merge($val, $fromHis);
}
else {
$out[$key] = $val;
}
}
return $this->value = $out;
}
/**
* Enter description here...
*
* @param unknown_type $root
* @param unknown_type $idKey
* @param unknown_type $parentIdKey
* @param unknown_type $childrenKey
* @return unknown
*/
function threaded ($root=null, $idKey='id', $parentIdKey='parent_id', $childrenKey='children') {
$out = array();
for ($ii=0; $ii<sizeof($this->value); $ii++) {
if ($this->value[$ii][$parentIdKey] == $root) {
$tmp = $this->value[$ii];
$tmp[$childrenKey] = isset($this->value[$ii][$idKey])?
$this->threaded($this->value[$ii][$idKey], $idKey, $parentIdKey, $childrenKey):
null;
$out[] = $tmp;
}
}
return $out;
}
}
?>

View file

@ -111,7 +111,7 @@ class Controller extends Template {
$this->name = strtolower($r[1]);
$this->viewpath = Inflector::underscore($r[1]);
$model_class = Inflector::singularize($this->name);
if (($this->uses === false) && class_exists($model_class)) {
if (!$DB)
@ -403,20 +403,26 @@ class Controller extends Template {
* Returns a SELECT element,
*
* @param string $tag_name Name attribute of the SELECT
* @param array $options Array of the OPTION elements to be used in the SELECT element
* @param array $outer_options Array of HTML options for the opening SELECT element
* @param array $inner_options
* @param array $option_elements Array of the OPTION elements (as 'value'=>'Text' pairs) to be used in the SELECT element
* @param array $select_attr Array of HTML options for the opening SELECT element
* @param array $option_attr Array of HTML options for the enclosed OPTION elements
* @return string Formatted SELECT element
*/
function selectTag ($tag_name, $options, $outer_options=null, $inner_options=null) {
if (!is_array($options) || !count($options))
function selectTag ($tag_name, $option_elements, $selected=null, $select_attr=null, $option_attr=null)
{
if (!is_array($option_elements) || !count($option_elements))
return null;
$selected = isset($html_options['value'])? $html_options['value']: $this->tagValue($tag_name);
$select[] = sprintf(TAG_SELECT_START, $tag_name, $this->parseHtmlOptions($outer_options));
$select[] = sprintf(TAG_SELECT_EMPTY, $this->parseHtmlOptions($inner_options));
foreach ($options as $name=>$title) {
$options_here = $selected==$name? array_merge($inner_options, array('selected'=>'selected')): $inner_options;
$select[] = sprintf(TAG_SELECT_START, $tag_name, $this->parseHtmlOptions($select_attr));
$select[] = sprintf(TAG_SELECT_EMPTY, $this->parseHtmlOptions($option_attr));
foreach ($option_elements as $name=>$title)
{
$options_here = $option_attr;
if ($selected == $name)
$options_here['selected'] = 'selected';
$select[] = sprintf(TAG_SELECT_OPTION, $name, $this->parseHtmlOptions($options_here), $title);
}
@ -491,9 +497,8 @@ class Controller extends Template {
* @param array $th_options
* @return string
*/
function tableHeaders ($names, $tr_options=null, $th_options=null) {
$args = func_get_args();
function tableHeaders ($names, $tr_options=null, $th_options=null)
{
$out = array();
foreach ($names as $arg)
$out[] = sprintf(TAG_TABLE_HEADER, $this->parseHtmlOptions($th_options), $arg);
@ -597,11 +602,16 @@ class Controller extends Template {
* @param string $text
* @return string If there are errors this method returns an error message, else NULL.
*/
function tagErrorMsg ($field, $text) {
if ($error = $this->tagIsInvalid($field)) {
function tagErrorMsg ($field, $text)
{
$error = $this->tagIsInvalid($field);
if (0 == $error)
{
return sprintf(SHORT_ERROR_MESSAGE, is_array($text)? (empty($text[$error-1])? 'Error in field': $text[$error-1]): $text);
}
else {
else
{
return null;
}
}
@ -759,23 +769,24 @@ class Controller extends Template {
* @param array $options options for javascript
* @return string html code for link to remote action
*/
function remoteFunction ($options=null) {
function remoteFunction ($options=null)
{
$javascript_options = $this->__optionsForAjax($options);
$func = isset($options['update'])?
"new Ajax.Updater('{$options['update']}', " :
"new Ajax.Request(";
$func = isset($options['update'])
? "new Ajax.Updater('{$options['update']}', "
: "new Ajax.Request(";
$func .= "'" . $this->urlFor($options['url']) . "'";
$func .= ", $javascript_options)";
if (isset($options['before']))
$func .= "{$options['before']}; $function";
$func = "{$options['before']}; $func";
if (isset($options['after']))
$func .= "$func; {$options['before']};";
$func = "$func; {$options['before']};";
if (isset($options['condition']))
$func .= "if ({$options['condition']}) { $func; }";
$func = "if ({$options['condition']}) { $func; }";
if (isset($options['confirm']))
$func .= "if (confirm('" . $this->escapeJavascript($options['confirm']) . "')) { $func; }";
$func = "if (confirm('" . $this->escapeJavascript($options['confirm']) . "')) { $func; }";
return $func;
}

View file

@ -178,8 +178,8 @@ class DBO extends Object {
/**
* Maximum number of items in query log, to prevent query log taking over
* too much memory on large amounts of queries -- we've had problems at
* ~6000 queries.
* too much memory on large amounts of queries -- I we've had problems at
* >6000 queries on one system.
*
* @var int Maximum number of queries in the queries log.
* @access private
@ -212,10 +212,6 @@ class DBO extends Object {
die('Please implement DBO::fields() first.');
}
function prepare ($data) {
die('Please implement DBO::prepare() first.');
}
function lastError ($result) {
die('Please implement DBO::lastError() first.');
}
@ -274,6 +270,23 @@ class DBO extends Object {
$this->connected = false;
}
/**
* Prepares a value, or an array of values for database queries by quoting and escaping them.
*
* @param mixed $data A value or an array of values to prepare.
* @return mixed Prepared value or array of values.
*/
function prepare ($data) {
if (!is_array($data))
$data = array($data);
$out = null;
foreach ($data as $key=>$item) {
$out[$key] = $this->prepareValue($item);
}
return $out;
}
/**
* Executes given SQL statement.
*
@ -378,19 +391,6 @@ class DBO extends Object {
return $this->connected;
}
/**
* Prepares an array of data values by quoting and escaping them.
*
* @return array Array of prepared data
*/
function prepareArray($data) {
$out = null;
foreach ($data as $key=>$item) {
$out[$key] = $this->prepare($item);
}
return $out;
}
/**
* Outputs the contents of the log.
*

View file

@ -15,7 +15,7 @@
/**
* Purpose: DBO_AdoDB
* AdoDB layer for DBO
* AdoDB layer for DBO.
*
* @filesource
* @author Cake Authors/Developers
@ -37,8 +37,7 @@
require_once(VENDORS.'adodb/adodb.inc.php');
/**
* Enter description here...
*
* AdoDB layer for DBO.
*
* @package cake
* @subpackage cake.libs
@ -69,7 +68,7 @@ class DBO_AdoDB extends DBO {
/**
* Disconnects from database.
*
* @return unknown
* @return boolean True if the database could be disconnected, else false
*/
function disconnect () {
return $this->_adodb->close();
@ -78,18 +77,18 @@ class DBO_AdoDB extends DBO {
/**
* Executes given SQL statement.
*
* @param string $sql
* @return unknown
* @param string $sql SQL statement
* @return resource Result resource identifier
*/
function execute ($sql) {
return $this->_adodb->execute($sql);
}
/**
* Return a row from given resultset.
* Returns a row from given resultset as an array .
*
* @param unknown_type $res Resultset
* @return unknown
* @return array The fetched row as an array
*/
function fetchRow ($res) {
return $res->FetchRow();
@ -98,7 +97,7 @@ class DBO_AdoDB extends DBO {
/**
* Returns an array of tables in the database. If there are no tables, an error is raised and the application exits.
*
* @return unknown
* @return array Array of tablenames in the database
*/
function tables() {
$tables = $this->_adodb->MetaTables('TABLES');
@ -127,42 +126,49 @@ class DBO_AdoDB extends DBO {
}
/**
* To be implemented
* Returns a quoted and escaped string of $data for use in an SQL statement.
*
* @param unknown_type $data
* @param string $data String to be prepared for use in an SQL statement
* @return string Quoted and escaped
*
* :TODO: To be implemented.
*/
function prepare ($data) { die('Please implement DBO::prepare() first.'); }
function prepareValue ($data) { die('Please implement DBO::prepare() first.'); }
/**
* Returns last SQL error message.
* Returns a formatted error message from previous database operation.
*
* @return unknown
* @return string Error message
*/
function lastError () {
return $this->_adodb->ErrorMsg();
}
/**
* Returns number of affected rows
* Returns number of affected rows in previous database operation. If no previous operation exists, this returns false.
*
* @return int
* @return int Number of affected rows
*/
function lastAffected () {
return $this->_adodb->Affected_Rows();
}
/**
* Returns number of rows in resultset of the last database operation.
* Returns number of rows in previous resultset. If no previous resultset exists,
* this returns false.
*
* @return int Number of rows in resultset
* @return int Number of rows
*/
function lastNumRows () {
return $this->_result? $this->_result->RecordCount(): false;
}
/**
* To be implemented
* Returns the ID generated from the previous INSERT operation.
*
* @return int
*
* :TODO: To be implemented.
*/
function lastInsertId () { die('Please implement DBO::lastInsertId() first.'); }
}

View file

@ -20,7 +20,6 @@
//////////////////////////////////////////////////////////////////////////
/**
* Purpose: DBO_MySQL
* MySQL layer for DBO
*
* @filesource
@ -37,7 +36,7 @@
*/
/**
* Enter description here...
* Include DBO.
*
*/
@ -45,7 +44,6 @@ uses('dbo');
/**
* MySQL layer for DBO.
*
*
* @package cake
* @subpackage cake.libs
* @since Cake v 0.2.9
@ -144,7 +142,7 @@ class DBO_MySQL extends DBO {
* @param string $data String to be prepared for use in an SQL statement
* @return string Quoted and escaped
*/
function prepare ($data) {
function prepareValue ($data) {
return "'".mysql_real_escape_string($data)."'";
}
@ -179,6 +177,7 @@ class DBO_MySQL extends DBO {
/**
* Returns the ID generated from the previous INSERT operation.
*
* @param string $table Name of the database table
* @return int
*/
function lastInsertId() {

View file

@ -19,9 +19,8 @@
// +------------------------------------------------------------------+ //
//////////////////////////////////////////////////////////////////////////
/*
* Name: DBO/Pear
* Pear::DB layer for DBO
/**
* Pear::DB layer for DBO.
*
* @filesource
* @author Cake Authors/Developers
@ -37,14 +36,12 @@
*/
/**
* Enter description here...
* Include DBO.
*
*/
uses('dbo');
/**
* Enter description here...
*
* Pear::DB layer for DBO.
*
* @package cake
* @subpackage cake.libs
@ -54,48 +51,47 @@ uses('dbo');
class DBO_Pear extends DBO {
/**
* Enter description here...
* Connects to the database using options in the given configuration array.
*
* @param unknown_type $config
* @return unknown
* @param array $config Configuration array for connecting
*/
function connect ($config) {
die('Please implement DBO::connect() first.');
}
/**
* Enter description here...
* Disconnects from database.
*
* @return unknown
* @return boolean True if the database could be disconnected, else false
*/
function disconnect () {
die('Please implement DBO::disconnect() first.');
}
/**
* Enter description here...
* Executes given SQL statement.
*
* @param unknown_type $sql
* @return unknown
* @param string $sql SQL statement
* @return resource Result resource identifier
*/
function execute ($sql) {
return $this->_pear->query($sql);
}
/**
* Enter description here...
* Returns a row from given resultset as an array .
*
* @param unknown_type $res
* @return unknown
* @param unknown_type $res Resultset
* @return array The fetched row as an array
*/
function fetchRow ($result) {
return $result->fetchRow(DB_FETCHMODE_ASSOC);
}
/**
* Enter description here...
* Returns an array of tables in the database. If there are no tables, an error is raised and the application exits.
*
* @return unknown
* @return array Array of tablenames in the database
*/
function tables () { // POSTGRESQL ONLY! PEAR:DB DOESN'T SUPPORT LISTING TABLES
$sql = "SELECT a.relname AS name
@ -118,10 +114,10 @@ class DBO_Pear extends DBO {
}
/**
* Enter description here...
* Returns an array of the fields in given table name.
*
* @param unknown_type $table_name
* @return unknown
* @param string $table_name Name of database table to inspect
* @return array Fields in table. Keys are name and type
*/
function fields ($table_name) {
$data = $this->_pear->tableInfo($table_name);
@ -134,37 +130,38 @@ class DBO_Pear extends DBO {
}
/**
* Enter description here...
* Returns a quoted and escaped string of $data for use in an SQL statement.
*
* @param unknown_type $data
* @return unknown
* @param string $data String to be prepared for use in an SQL statement
* @return string Quoted and escaped
*/
function prepare ($data) {
function prepareValue ($data) {
return $this->_pear->quoteSmart($data);
}
/**
* Enter description here...
* Returns a formatted error message from previous database operation.
*
* @return unknown
* @return string Error message
*/
function lastError () {
return PEAR::isError($this->_result)? $this->_result->getMessage(): null;
}
/**
* Enter description here...
* Returns number of affected rows in previous database operation. If no previous operation exists, this returns false.
*
* @return unknown
* @return int Number of affected rows
*/
function lastAffected () {
return $this->_pear->affectedRows();
}
/**
* Enter description here...
* Returns number of rows in previous resultset. If no previous resultset exists,
* this returns false.
*
* @return unknown
* @return int Number of rows
*/
function lastNumRows ($result) {
if (method_exists($result, 'numRows'))
@ -174,9 +171,10 @@ class DBO_Pear extends DBO {
}
/**
* Enter description here...
* Returns the ID generated from the previous INSERT operation.
*
* @return unknown
* @param string $table Name of the database table
* @return int
*/
function lastInsertId ($table) {
return $this->field('id', "SELECT MAX(id) FROM {$table}");

View file

@ -14,8 +14,7 @@
//////////////////////////////////////////////////////////////////////////
/**
* Purpose: DBO_Postgres
* Enter description here...
* PostgreSQL layer for DBO.
*
* @filesource
* @author Cake Authors/Developers
@ -31,10 +30,11 @@
*/
/**
* Enter description here...
* Include DBO.
*
*/
uses('dbo');
uses('object', 'dbo');
/**
* PostgreSQL layer for DBO.
*
@ -49,7 +49,6 @@ class DBO_Postgres extends DBO {
* Connects to the database using options in the given configuration array.
*
* @param array $config Configuration array for connecting
* @return unknown
*/
function connect ($config) {
if($config) {
@ -68,7 +67,7 @@ class DBO_Postgres extends DBO {
/**
* Disconnects from database.
*
* @return unknown
* @return boolean True if the database could be disconnected, else false
*/
function disconnect () {
return pg_close($this->_conn);
@ -77,8 +76,8 @@ class DBO_Postgres extends DBO {
/**
* Executes given SQL statement.
*
* @param string $sql
* @return unknown
* @param string $sql SQL statement
* @return resource Result resource identifier
*/
function execute ($sql) {
return pg_query($this->_conn, $sql);
@ -144,7 +143,7 @@ class DBO_Postgres extends DBO {
* @param string $data String to be prepared for use in an SQL statement
* @return string Quoted and escaped
*/
function prepare ($data) {
function prepareValue ($data) {
return "'".pg_escape_string($data)."'";
}
@ -167,9 +166,10 @@ class DBO_Postgres extends DBO {
}
/**
* Returns number of rows in previous resultset. If no previous resultset exists, this returns false.
* Returns number of rows in previous resultset. If no previous resultset exists,
* this returns false.
*
* @return int
* @return int Number of rows
*/
function lastNumRows () {
return $this->_result? pg_num_rows($this->_result): false;

View file

@ -72,38 +72,38 @@ class DBO_SQLite extends DBO {
}
/**
* Enter description here...
* Disconnects from database.
*
* @return unknown
* @return boolean True if the database could be disconnected, else false
*/
function disconnect () {
return sqlite_close($this->_conn);
}
/**
* Enter description here...
* Executes given SQL statement.
*
* @param unknown_type $sql
* @return unknown
* @param string $sql SQL statement
* @return resource Result resource identifier
*/
function execute ($sql) {
return sqlite_query($this->_conn, $sql);
}
/**
* Enter description here...
* Returns a row from given resultset as an array .
*
* @param unknown_type $res
* @return unknown
* @param unknown_type $res Resultset
* @return array The fetched row as an array
*/
function fetchRow ($res) {
return sqlite_fetch_array($res);
}
/**
* Enter description here...
* Returns an array of tables in the database. If there are no tables, an error is raised and the application exits.
*
* @return unknown
* @return array Array of tablenames in the database
*/
function tables () {
$result = sqlite_query($this->_conn, "SELECT name FROM sqlite_master WHERE type='table' ORDER BY name;");
@ -122,10 +122,10 @@ $this->_conn
}
/**
* Enter description here...
* Returns an array of the fields in given table name.
*
* @param unknown_type $table_name
* @return unknown
* @param string $table_name Name of database table to inspect
* @return array Fields in table. Keys are name and type
*/
function fields ($table_name)
{
@ -139,46 +139,47 @@ $this->_conn
}
/**
* Enter description here...
* Returns a quoted and escaped string of $data for use in an SQL statement.
*
* @param unknown_type $data
* @return unknown
* @param string $data String to be prepared for use in an SQL statement
* @return string Quoted and escaped
*/
function prepare ($data) {
function prepareValue ($data) {
return "'".sqlite_escape_string($data)."'";
}
/**
* Enter description here...
* Returns a formatted error message from previous database operation.
*
* @return unknown
* @return string Error message
*/
function lastError () {
return sqlite_last_error($this->_conn)? sqlite_last_error($this->_conn).': '.sqlite_error_string(sqlite_last_error($this->_conn)): null;
}
/**
* Enter description here...
* Returns number of affected rows in previous database operation. If no previous operation exists, this returns false.
*
* @return unknown
* @return int Number of affected rows
*/
function lastAffected () {
return $this->_result? sqlite_changes($this->_conn): false;
}
/**
* Enter description here...
* Returns number of rows in previous resultset. If no previous resultset exists,
* this returns false.
*
* @return unknown
* @return int Number of rows in resultset
*/
function lastNumRows () {
return $this->_result? sqlite_num_rows($this->_result): false;
}
/**
* Enter description here...
* Returns the ID generated from the previous INSERT operation.
*
* @return unknown
* @return int
*/
function lastInsertId() {
Return sqlite_last_insert_rowid($this->_conn);

View file

@ -78,6 +78,7 @@ class Dispatcher extends Object {
function dispatch ($url) {
global $_POST, $_GET, $_FILES, $_SESSION;
/* @var $params array */
$params = $this->parseParams($url);
// die if no controller set
@ -87,31 +88,39 @@ class Dispatcher extends Object {
$ctrl_name = Inflector::camelize($params['controller']);
$ctrl_class = $ctrl_name.'Controller';
// if specified controller class doesn't exist
/**
* Find out if the specified controller exists, and die if not.
*/
if (!loadController($ctrl_name) || !class_exists($ctrl_class))
$this->errorUnknownController($url, $ctrl_name);
$controller = new $ctrl_class ($this);
$controller->cache = &$Cache;
$controller->base = $this->base;
$ctrl_methods = get_class_methods($ctrl_class);
$ctrl_vars = get_class_vars($ctrl_class);
// if action is not set, and the default Controller::index() method doesn't exist
if (empty($params['action'])) {
if (method_exists($controller, 'index'))
$params['action'] = 'index';
else
$this->errorNoAction($url);
/**
* If _no_action_is set, check if the default action, index() exists. If it doesn't, die.
*/
if (empty($params['action']) && in_array('index', $ctrl_methods))
{
$params['action'] = 'index';
}
else {
$this->errorNoAction($url);
}
// if the requested action doesn't exist
if (!method_exists($controller, $params['action']))
/**
* Check if the specified action really exists.
*/
if (!in_array($params['action'], $ctrl_methods))
{
$this->errorUnknownAction($url, $ctrl_class, $params['action']);
}
$controller->params = $params;
$controller->action = $params['action'];
$controller->data = empty($params['data'])? null: $params['data'];
$controller->passed_args = empty($params['pass'])? null: $params['pass'];
$controller->passed_args = empty($params['pass'])? null: $params['pass'];
// EXECUTE THE REQUESTED ACTION
call_user_func_array(array(&$controller, $params['action']), empty($params['pass'])? null: $params['pass']);

View file

@ -53,7 +53,7 @@ if (version_compare(phpversion(), '5.0') < 0) {
* @require PHP 4.0.0 (user_error)
*/
if (!function_exists('file_get_contents')) {
function file_get_contents($filename, $incpath = false, $resource_context = null)
function file_get_contents($filename, $incpath = false)
{
if (false === $fh = fopen($filename, 'rb', $incpath)) {
user_error('file_get_contents() failed to open stream: No such file or directory',

View file

@ -518,7 +518,7 @@ class Model extends Object {
else
$f = array('*');
$condtions = $this->db->prepare($conditions);
$conditions = $this->db->prepare($conditions);
$joins = $whers = array();

258
libs/neat_array.php Normal file
View file

@ -0,0 +1,258 @@
<?PHP
/**
* Class used for internal manipulation of multiarrays (arrays of arrays).
*
* @package cake
* @subpackage cake.libs
* @since Cake v 0.2.9
*/
class NeatArray {
/**
* Value of NeatArray.
*
* @var array
* @access public
*/
var $value;
/**
* Constructor. Defaults to an empty array.
*
* @param array $value
* @access public
* @uses NeatArray::value
*/
function NeatArray ($value=array()) {
$this->value = $value;
}
/**
* Checks whether $fieldName with $value exists in this NeatArray object.
*
* @param string $fieldName
* @param string $value
* @return mixed
* @access public
* @uses NeatArray::value
*/
function findIn ($fieldName, $value) {
$out = false;
foreach ($this->value as $k=>$v) {
if (isset($v[$fieldName]) && ($v[$fieldName] == $value)) {
$out[$k] = $v;
}
}
return $out;
}
/**
* Checks if $this->value is array, and removes all empty elements.
*
* @access public
* @uses NeatArray::value
*/
function cleanup () {
$out = is_array($this->value)? array(): null;
foreach ($this->value as $k=>$v) {
if ($v) {
$out[$k] = $v;
}
}
$this->value = $out;
}
/**
* Adds elements from the supplied array to itself.
*
* @param string $value
* @return bool
* @access public
* @uses NeatArray::value
*/
function add ($value) {
return ($this->value = $this->plus($value))? true: false;
}
/**
* Returns itself merged with given array.
*
* @param array $value Array to add to NeatArray.
* @return array
* @access public
* @uses NeatArray::value
*/
function plus ($value) {
return array_merge($this->value, (is_array($value)? $value: array($value)));
}
/**
* Counts repeating strings and returns an array of totals.
*
* @param int $sortedBy A value of 1 sorts by values, a value of 2 sorts by keys. Defaults to null (no sorting).
* @return array
* @access public
* @uses NeatArray::value
*/
function totals ($sortedBy=1,$reverse=true) {
$out = array();
foreach ($this->value as $val)
isset($out[$val])? $out[$val]++: $out[$val] = 1;
if ($sortedBy == 1) {
$reverse? arsort($out, SORT_NUMERIC): asort($out, SORT_NUMERIC);
}
if ($sortedBy == 2) {
$reverse? krsort($out, SORT_STRING): ksort($out, SORT_STRING);
}
return $out;
}
/**
* Performs an array_filter() on the contents.
*
* @param unknown_type $with
* @return unknown
*/
function filter ($with) {
return $this->value = array_filter($this->value, $with);
}
/**
* Passes each of its values through a specified function or method. Think of PHP's array_walk.
*
* @return array
* @access public
* @uses NeatArray::value
*/
function walk ($with) {
array_walk($this->value, $with);
return $this->value;
}
function sprintf($template)
{
for ($ii=0; $ii<count($this->value); $ii++)
{
$this->value[$ii] = sprintf($template, $this->value[$ii]);
}
return $this->value;
}
/**
* Extracts a value from all array items.
*
* @return array
* @access public
* @uses NeatArray::value
*/
function extract ($name) {
$out = array();
foreach ($this->value as $val) {
if (isset($val[$name]))
$out[] = $val[$name];
}
return $out;
}
/**
* Returns a list of unique elements.
*
* @return array
*/
function unique () {
return array_unique($this->value);
}
/**
* Removes duplicate elements from the value and returns it.
*
* @return array
*/
function makeUnique () {
return $this->value = array_unique($this->value);
}
/**
* Joins an array with myself using a key (like a join between database tables).
*
* Example:
*
* $alice = array('id'=>'1', 'name'=>'Alice');
* $bob = array('id'=>'2', 'name'=>'Bob');
*
* $users = new NeatArray(array($alice, $bob));
*
* $born = array
* (
* array('user_id'=>'1', 'born'=>'1980'),
* array('user_id'=>'2', 'born'=>'1976')
* );
*
* $users->joinWith($born, 'id', 'user_id');
*
* Result:
*
* $users->value == array
* (
* array('id'=>'1', 'name'=>'Alice', 'born'=>'1980'),
* array('id'=>'2', 'name'=>'Bob', 'born'=>'1976')
* );
*
*
* @param array $his The array to join with myself.
* @param string $onMine Key to use on myself.
* @param string $onHis Key to use on him.
* @return array
*/
function joinWith ($his, $onMine, $onHis=null) {
if (empty($onHis)) $onHis = $onMine;
$his = new NeatArray($his);
$out = array();
foreach ($this->value as $key=>$val) {
if ($fromHis = $his->findIn($onHis, $val[$onMine])) {
list($fromHis) = array_values($fromHis);
$out[$key] = array_merge($val, $fromHis);
}
else {
$out[$key] = $val;
}
}
return $this->value = $out;
}
/**
* Enter description here...
*
* @param unknown_type $root
* @param unknown_type $idKey
* @param unknown_type $parentIdKey
* @param unknown_type $childrenKey
* @return unknown
*/
function threaded ($root=null, $idKey='id', $parentIdKey='parent_id', $childrenKey='children') {
$out = array();
for ($ii=0; $ii<sizeof($this->value); $ii++) {
if ($this->value[$ii][$parentIdKey] == $root) {
$tmp = $this->value[$ii];
$tmp[$childrenKey] = isset($this->value[$ii][$idKey])?
$this->threaded($this->value[$ii][$idKey], $idKey, $parentIdKey, $childrenKey):
null;
$out[] = $tmp;
}
}
return $out;
}
}
?>

View file

@ -13,8 +13,6 @@
// + See: http://www.opensource.org/licenses/mit-license.php + //
//////////////////////////////////////////////////////////////////////////
uses('log');
/**
* Purpose: Object
* Allows for __construct to be used in PHP4.
@ -51,7 +49,11 @@ class Object {
*
* @return Object
*/
function Object() {
function Object()
{
global $DB;
$this->db =& $DB;
$args = func_get_args();
register_shutdown_function(array(&$this, '__destruct'));
call_user_func_array(array(&$this, '__construct'), $args);