Permalink
Browse files

Improving core components and datasources

- Moves loader.php and environment.php into core subfolder.
- Renames config.php to config-sample.php and updates default settings.
- Modifies config defaults to play nice with database config settings.
- Changes datasource config structure to be more consistent between
  datasource types.
- Changes Load::Cache() and Load::DB() to more intelligently choose
  default based on configuration settings.
- Removes default definition "db" from Load::Datasource().
- Changes Load::Session() to ensure a config change to session type
  isn't applied mid-request.
- Adds exception_error_handler() function which can be used in places
  where exception handling is favorable over errors.
- Adds the local (object) storage of the last saved/loaded version of
  data in models.
- Removes manipulation of model objects by datasources.  Assignment of
  data is instead handled within the model logic.
- Fixes a bug where unset model fields would not get saved (as empty)
  to the database/datasources.
- Renames $model->assignVars() to setValues() and creates original as
  alias.  Code depending on assignVars() should be changed as the alias
  will eventually be removed.
- Adds $model->getValues() function which gets the current model data
  (based on schema fields).
- Changes ACL helper to accept a zero (root) context.
- Removes $usesuffix convention from all cache types.  This method of
  pseudo-clearing the cache was bad practice that could result in
  excessive memory usage, cache slams, etc.
- Improves connection checking in memcache helper.
- Adds two-level debugging to memcache helper.  Level 1 debug messages
  output the operation, key, and value performed.  Level 2 messages
  (turned on by setting $cache->debug = 2) output backtraces.
- Adds request cache helper, replacing arrcache datasource helper.
- Improves PDO database helper, including many various improvements to
  schema handling, caching, and optimized SQL generation and execution.
- Renames $pdo->address to $pdo->host.
- Improves connection checking in PDO helper.
- Fixes $pdo->getAssoc() for two-column result sets.
- Changes memcache datasource helper to generalized cache datasource
  helper.
- Adds "mode" option to database datasource for differentiating between
  inserts and updates.
- Improves handling of json-encoded "array" fields in database
  datasource.
  • Loading branch information...
1 parent 2485fc4 commit a5cbb82184880104343ae17b56b97b0b97ecd355 @thomshouse thomshouse committed May 28, 2012
@@ -12,13 +12,13 @@
// Database
$database['default'] = array(
- 'type' => 'adodb',
- 'adotype' => 'mysqli',
- 'address' => '127.0.0.1',
+ 'type' => 'pdo',
+ 'driver' => 'mysql',
+ 'host' => '127.0.0.1',
'username' => '',
'password' => '',
'database' => '',
- 'prefix' => 'esc_'
+ 'prefix' => 'esc_'
);
// Site config variables
@@ -28,7 +28,7 @@
// Routes
$static_routes = array(
'about' => array('controller' => 'page','id' => 2,'title' => 'About'),
- 'blog' => array('controller' => 'blog','id' => 1,'title' => 'Blog')
+ 'blog' => array('controller' => 'blog','id' => 1,'title' => 'Blog')
);
// Determines "active" plugins for running hooks
@@ -1,13 +1,5 @@
<?php
-// Convenience declarations
-$title = 'My Website';
-$subtitle = 'Powered by Escher';
-$wwwroot = '';
-
-// Data sources (read/write priority)
-$datasource_order['all'] = array('db');
-
// Router allows arguments sent to the root controller
$allow_root_args = TRUE;
@@ -37,7 +29,6 @@
);
// Maintenance mode defaults
-$maintenance_mode = FALSE;
$maintenance_message = 'This website is currently undergoing maintenance.';
$maintenance_root = array(
'controller'=>'errors',
@@ -71,14 +62,35 @@
array('admin','administrator','system')
);
-// Translate Cache datasource to default Cache
-if (!isset($cache)
- && !empty($datasource_cache_order['all'])
- && is_array($datasource_cache_order['all'])
-) {
- $cache = $datasource_cache_order['all'][0];
+// Set datasource order
+if (empty($datasource_order['all'])) {
+ $datasource_order['all'] = array();
+ foreach($datasource as $name => $ds) {
+ if (!empty($ds['helper']) && $ds['helper']=='database') {
+ $datasource_order['all'][] = $name;
+ }
+ }
+ unset($ds,$name);
+}
+
+// Set cache order
+if (empty($datasource_cache_order['all'])) {
+ $datasource_cache_order['all'] = array();
+ foreach($datasource as $name => $ds) {
+ if (!empty($ds['helper']) && $ds['helper']=='cache') {
+ $datasource_cache_order['all'][] = $name;
+ }
+ }
+ unset($ds,$name);
}
+// Add the request cache (static array)
+$datasource['request'] = array(
+ 'helper' => 'cache',
+ 'type' => 'request',
+);
+//array_unshift($datasource_cache_order['all'],'request');
+
// Document root and Escher path
$document_root = ESCHER_DOCUMENT_ROOT;
$escher_path = ESCHER_REAL_PATH;
@@ -22,3 +22,10 @@ function die_r($arr) {
unset($_GET['_PATH_INFO'],$GLOBALS['_REQUEST']['_PATH_INFO']);
$_SERVER['QUERY_STRING'] = http_build_query($_GET);
}
+
+// Error-to-exception handler
+if (!function_exists('exception_error_handler')) {
+ function exception_error_handler($errno, $errstr, $errfile, $errline ) {
+ throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
+ }
+}
@@ -154,11 +154,11 @@ public function Helper($helper,$type='default',$args=NULL) {
$newhelper = new $classname($args);
if (is_array($helper)) {
$newhelper->plugin = strtolower($helper[0]);
- $newhelper->type = strtolower($helper[1]);
+ $newhelper->helper = strtolower($helper[1]);
} else {
- $newhelper->type = strtolower($helper);
+ $newhelper->helper = strtolower($helper);
}
- $newhelper->flavor = strtolower($type);
+ $newhelper->type = strtolower($type);
return $newhelper;
} else {
return false;
@@ -194,8 +194,8 @@ public function PersistentHelper($name,$helper,$type='default',$args=NULL) {
if ($plugin!='core') {
$PHelpers[$helpername][$plugin][$type][$name]->plugin = $plugin;
}
- $PHelpers[$helpername][$plugin][$type][$name]->type = $helpername;
- $PHelpers[$helpername][$plugin][$type][$name]->flavor = $type;
+ $PHelpers[$helpername][$plugin][$type][$name]->helper = $helpername;
+ $PHelpers[$helpername][$plugin][$type][$name]->type = $type;
return $PHelpers[$helpername][$plugin][$type][$name];
} else {
return false;
@@ -263,14 +263,32 @@ public function ACL() {
* Shorthand for loading the default cache handler for the current Escher configuration.
* @return object|bool Returns the cache helper object, or false on failure.
*/
- public function Cache($name='default') {
+ public function Cache($name=NULL) {
$CFG = Load::Config();
- if (empty($CFG['cache'])) { return false; }
- $cache = $CFG['datasource'][$CFG['cache']];
- if (is_array($cache['type'])) {
- return Load::PersistentHelper($name,array($cache['type'][0],'cache'),$cache['type'][1],$cache['settings']);
+ if (is_null($name)) {
+ foreach($CFG['datasource_cache_order']['all'] as $n) {
+ if ($CFG['datasource'][$n]['helper']=='cache') {
+ $name = $n;
+ $args = $CFG['datasource'][$n];
+ break;
+ }
+ }
+ if (is_null($name)) { return FALSE; }
+ } elseif (array_key_exists($name,$CFG['datasource'])
+ && !empty($args['helper'])
+ && $args['helper']=='cache'
+ ) {
+ $args = $CFG['datasource'][$name];
+ } else {
+ return FALSE;
+ }
+ $type = $args['type'];
+ unset($args['helper'],$args['type']);
+ if (is_array($type)) {
+ return Load::PersistentHelper($name,array($type[0],'cache'),
+ $type[1],$args);
} else {
- return Load::PersistentHelper($name,'cache',$cache['type'],$cache['settings']);
+ return Load::PersistentHelper($name,'cache',$type,$args);
}
}
@@ -288,37 +306,51 @@ public function CFG() { return self::Config(); } // Shorthand
* Shorthand for loading the default database for the current Escher configuration.
* @return object|bool Returns the database helper object, or false on failure.
*/
- public function DB($name='default') {
+ public function DB($name=NULL) {
$CFG = Load::Config();
- $args = $CFG['database'][$name];
+ if (is_null($name)) {
+ foreach($CFG['datasource_order']['all'] as $n) {
+ if ($CFG['datasource'][$n]['helper']=='database') {
+ $name = $n;
+ $args = $CFG['datasource'][$n];
+ break;
+ }
+ }
+ if (is_null($name)) { return FALSE; }
+ } elseif (array_key_exists($name,$CFG['datasource'])
+ && !empty($args['helper'])
+ && $args['helper']=='database'
+ ) {
+ $args = $CFG['datasource'][$name];
+ } else {
+ return FALSE;
+ }
$type = $args['type'];
- unset($args['type']);
+ unset($args['helper'],$args['type']);
if (is_array($type)) {
- return Load::PersistentHelper($name,array($type[0],'database'),$type[1],$args);
+ return Load::PersistentHelper($name,array($type[0],'database'),
+ $type[1],$args);
} else {
return Load::PersistentHelper($name,'database',$type,$args);
}
}
/**
- * Shorthand for loading a Datasource object.
+ * Shorthand for loading a config-defined Datasource.
* @return object Returns the Datasource object.
*/
- public function Datasource($definition='db') {
+ public function Datasource($definition) {
$CFG = Load::Config();
- if ($definition=='db' && !isset($CFG['datasource']['db'])) {
- return Load::PersistentHelper('db','datasource','db');
- } elseif ($definition=='arrcache' && !isset($CFG['datasource']['arrcache'])) {
- return Load::PersistentHelper('arrcache','datasource','arrcache');
- } elseif (isset($CFG['datasource'][$definition]['type'])) {
- $type = $CFG['datasource'][$definition]['type'];
- $settings = !empty($CFG['datasource'][$definition]['settings'])
- ? $CFG['datasource'][$definition]['settings']
- : array();
- if (is_array($type)) {
- return Load::PersistentHelper($definition,array($type[0],'datasource'),$type[1],$settings);
+ if (isset($CFG['datasource'][$definition]['helper'])) {
+ $settings = $CFG['datasource'][$definition];
+ $helper = $settings['helper'];
+ unset($settings['helper']);
+ if (is_array($helper)) {
+ return Load::PersistentHelper($definition,
+ array($helper[0],'datasource'),$helper[1],$settings);
} else {
- return Load::PersistentHelper($definition,'datasource',$type,$settings);
+ return Load::PersistentHelper($definition,'datasource',
+ $helper,$settings);
}
}
return false;
@@ -451,8 +483,12 @@ public function Router($path=NULL) {
* @return object|bool Returns the session helper object, or false on failure.
*/
public function Session() {
- $CFG = Load::Config();
- $args = $CFG['session'];
+ static $session;
+ if (is_null($session)) {
+ $CFG = Load::Config();
+ $session = $CFG['session'];
+ }
+ $args = $session;
$type = $args['type'];
unset($args['type']);
self::$internalCall = true;
@@ -5,7 +5,10 @@
protected $_schemaKeys = array();
protected $_schemaTriggers = array();
protected $_outputType = 'php';
+ protected $_new = TRUE;
+ protected $_savedValues = array();
+ // Used to keep track of parsed form inputs for new models
protected static $_parsedNew = array();
public function __construct($key=NULL) {
@@ -47,7 +50,9 @@ function loadCached($key) {
foreach($sources as $s) {
$ds = Load::Datasource($s);
if ($result = $ds->get($this,$key)) {
- // Assign class vars (metadata, content, etc.) and return
+ $this->assignVars($result);
+ $this->_savedValues = (array)$result;
+ $this->_new = FALSE;
return true;
}
}
@@ -74,6 +79,8 @@ function loadUncached($key) {
$this->_datasource = $s;
// Assign class vars (metadata, content, etc.)
$this->assignVars($result);
+ $this->_savedValues = (array)$result;
+ $this->_new = FALSE;
return true;
}
}
@@ -88,16 +95,39 @@ public function save() {
$this->_runTriggers('modify');
}
+ $values = array();
+ foreach($this->_schemaFields as $k => $p) {
+ if (isset($this->$k)) {
+ $values[$k] = $this->$k;
+ } elseif (array_key_exists($k,$this->_savedValues)) {
+ $values[$k] = '';
+ }
+ }
+
+ // Set datasource options
+ $options = array(
+ 'mode' => $this->_new
+ ? 'insert'
+ : 'update'
+ );
+
$sources = $this->_getDatasources();
// Iterate through the datasources and save
// Note: Only new objects should have to iterate
foreach($sources as $s) {
$ds = Load::Datasource($s);
- if ($ds->set($this)) {
+ if ($id = $ds->set($this->_m(),$values,$options)) {
+ $this->_new = FALSE;
+ if ($this->_primaryKey() && !$this->id()) {
+ $this->setValues(array(
+ $this->_primaryKey() => $id,
+ ));
+ }
if (!isset($this->_datasource)) {
$this->_datasource = $s;
}
- $this->cache();
+ $this->expire();
+ $this->_savedValues = $values;
return true;
}
}
@@ -214,13 +244,8 @@ protected function _getCacheDatasources() {
$CFG = Load::Config();
if (isset($CFG['datasource_cache_order'][$this->_m()])) {
$sources = $CFG['datasource_cache_order'][$this->_m()];
- } elseif (isset($CFG['datasource_cache_order']['all'])) {
- $sources = $CFG['datasource_cache_order']['all'];
} else {
- $sources = array('arrcache');
- }
- if (!in_array('arrcache',$sources)) {
- array_unshift($sources,'arrcache');
+ $sources = $CFG['datasource_cache_order']['all'];
}
return $sources;
}
@@ -255,7 +280,9 @@ function find($conditions=array(),$options=array()) {
}
// Override assignVars to protect class variables
- public function assignVars($vars) {
+ public function assignVars($vars) { return $this->setValues($vars); }
+
+ public function setValues($vars) {
if (!is_array($vars) || array_values($vars)==$vars) {
return false;
}
@@ -269,6 +296,16 @@ public function assignVars($vars) {
return true;
}
+ public function getValues() {
+ $values = array();
+ foreach($this->_schemaFields as $k => $props) {
+ if (isset($this->$k)) {
+ $values[$k] = $this->$k;
+ }
+ }
+ return $values;
+ }
+
function id() {
return $this->{$this->_primaryKey()};
}
@@ -298,6 +335,7 @@ function _primaryKey() {
case '_schemaFields':
case '_schemaKeys':
case '_schemaTriggers':
+ case '_savedValues':
return isset($this->$name)
? $this->$name
: NULL;
Oops, something went wrong.

0 comments on commit a5cbb82

Please sign in to comment.