Skip to content

Commit

Permalink
Added support for extending individual driver classes and driver unit…
Browse files Browse the repository at this point in the history
… tests

Signed-off-by: dchill42 <dchill42@gmail.com>
  • Loading branch information
dchill42 committed Nov 25, 2012
1 parent ad5f1d0 commit 6262d05
Show file tree
Hide file tree
Showing 11 changed files with 352 additions and 126 deletions.
13 changes: 6 additions & 7 deletions system/core/Loader.php
Original file line number Diff line number Diff line change
Expand Up @@ -669,6 +669,12 @@ public function driver($library = '', $params = NULL, $object_name = NULL)
return FALSE;
}

if ( ! class_exists('CI_Driver_Library'))
{
// We aren't instantiating an object here, just making the base class available
require BASEPATH.'libraries/Driver.php';
}

// We can save the loader some time since Drivers will *always* be in a subfolder,
// and typically identically named to the library
if ( ! strpos($library, '/'))
Expand Down Expand Up @@ -949,13 +955,6 @@ protected function _ci_load_class($class, $params = NULL, $object_name = NULL)

// Get the filename from the path
$class = substr($class, $last_slash);

// Check for match and driver base class
if (strtolower(trim($subdir, '/')) == strtolower($class) && ! class_exists('CI_Driver_Library'))
{
// We aren't instantiating an object here, just making the base class available
require BASEPATH.'libraries/Driver.php';
}
}

// We'll test for both lowercase and capitalized versions of the file name
Expand Down
12 changes: 6 additions & 6 deletions system/libraries/Cache/Cache.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,12 @@ class CI_Cache extends CI_Driver_Library {
* @var array
*/
protected $valid_drivers = array(
'cache_apc',
'cache_dummy',
'cache_file',
'cache_memcached',
'cache_redis',
'cache_wincache'
'apc',
'dummy',
'file',
'memcached',
'redis',
'wincache'
);

/**
Expand Down
125 changes: 92 additions & 33 deletions system/libraries/Driver.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ class CI_Driver_Library {
* The first time a child is used it won't exist, so we instantiate it
* subsequents calls will go straight to the proper child.
*
* @param string Child class name
* @return object Child class
* @param string Child class name
* @return object Child class
*/
public function __get($child)
{
Expand All @@ -74,61 +74,120 @@ public function __get($child)
*
* Separate load_driver call to support explicit driver load by library or user
*
* @param string Child class name
* @return object Child class
* @param string Driver name (w/o parent prefix)
* @return object Child class
*/
public function load_driver($child)
{
// Get CodeIgniter instance and subclass prefix
$CI = get_instance();
$prefix = (string) $CI->config->item('subclass_prefix');

if ( ! isset($this->lib_name))
{
$this->lib_name = get_class($this);
// Get library name without any prefix
$this->lib_name = str_replace(array('CI_', $prefix), '', get_class($this));
}

// The child will be prefixed with the parent lib
$child_name = $this->lib_name.'_'.$child;

// See if requested child is a valid driver
if ( ! in_array($child, array_map('strtolower', $this->valid_drivers)))
{
// The requested driver isn't valid!
$msg = 'Invalid driver requested: '.$child_name;
log_message('error', $msg);
show_error($msg);
}

// The class will be prefixed with the parent lib
$child_class = $this->lib_name.'_'.$child;
// All driver files should be in a library subdirectory - capitalized
$subdir = ucfirst(strtolower($this->lib_name));

// Remove the CI_ prefix and lowercase
$lib_name = ucfirst(strtolower(str_replace('CI_', '', $this->lib_name)));
$driver_name = strtolower(str_replace('CI_', '', $child_class));
// Get package paths and filename case variations to search
$paths = $CI->load->get_package_paths(TRUE);
$cases = array(ucfirst($child_name), strtolower($child_name));

if (in_array($driver_name, array_map('strtolower', $this->valid_drivers)))
// Is there an extension?
$class_name = $prefix.$child_name;
$found = class_exists($class_name);
if ( ! $found)
{
// check and see if the driver is in a separate file
if ( ! class_exists($child_class))
// Check for subclass file
foreach ($paths as $path)
{
// check application path first
foreach (get_instance()->load->get_package_paths(TRUE) as $path)
// Extension will be in drivers subdirectory
$path .= 'libraries/'.$subdir.'/drivers/';

// Try filename with caps and all lowercase
foreach ($cases as $name)
{
// loves me some nesting!
foreach (array(ucfirst($driver_name), $driver_name) as $class)
// Does the file exist?
$file = $path.$prefix.$name.'.php';
if (file_exists($file))
{
$filepath = $path.'libraries/'.$lib_name.'/drivers/'.$class.'.php';

if (file_exists($filepath))
// Yes - require base class from BASEPATH
$basepath = BASEPATH.'libraries/'.$subdir.'/drivers/'.ucfirst($child_name).'.php';
if ( ! file_exists($basepath))
{
include_once $filepath;
break 2;
$msg = 'Unable to load the requested class: CI_'.$child_name;
log_message('error', $msg);
show_error($msg);
}

// Include both sources and mark found
include($basepath);
include($file);
$found = TRUE;
break 2;
}
}
}
}

// it's a valid driver, but the file simply can't be found
if ( ! class_exists($child_class))
// Do we need to search for the class?
if ( ! $found)
{
// Use standard class name
$class_name = 'CI_'.$child_name;
$found = class_exists($class_name);
if ( ! $found)
{
// Check package paths
foreach ($paths as $path)
{
log_message('error', 'Unable to load the requested driver: '.$child_class);
show_error('Unable to load the requested driver: '.$child_class);
// Class will be in drivers subdirectory
$path .= 'libraries/'.$subdir.'/drivers/';

// Try filename with caps and all lowercase
foreach ($cases as $name)
{
// Does the file exist?
$file = $path.$name.'.php';
if (file_exists($file))
{
// Include source
include($file);
break 2;
}
}
}
}
}

$obj = new $child_class;
$obj->decorate($this);
$this->$child = $obj;
return $this->$child;
// Did we finally find the class?
if ( ! class_exists($class_name))
{
$msg = 'Unable to load the requested driver: '.$class_name;
log_message('error', $msg);
show_error($msg);
}

// The requested driver isn't valid!
log_message('error', 'Invalid driver requested: '.$child_class);
show_error('Invalid driver requested: '.$child_class);
// Instantiate, decorate, and add child
$obj = new $class_name;
$obj->decorate($this);
$this->$child = $obj;
return $this->$child;
}

}
Expand Down
20 changes: 9 additions & 11 deletions system/libraries/Session/Session.php
Original file line number Diff line number Diff line change
Expand Up @@ -107,17 +107,15 @@ public function __construct(array $params = array())

// Get valid drivers list
$this->valid_drivers = array(
'Session_native',
'Session_cookie'
'native',
'cookie'
);
$key = 'sess_valid_drivers';
$drivers = isset($params[$key]) ? $params[$key] : $CI->config->item($key);
if ($drivers)
{
is_array($drivers) OR $drivers = array($drivers);

// Add driver names to valid list
foreach ($drivers as $driver)
foreach ((array) $drivers as $driver)
{
if ( ! in_array(strtolower($driver), array_map('strtolower', $this->valid_drivers)))
{
Expand All @@ -134,9 +132,9 @@ public function __construct(array $params = array())
$driver = 'cookie';
}

if ( ! in_array('session_'.strtolower($driver), array_map('strtolower', $this->valid_drivers)))
if ( ! in_array(strtolower($driver), array_map('strtolower', $this->valid_drivers)))
{
$this->valid_drivers[] = 'Session_'.$driver;
$this->valid_drivers[] = $driver;
}

// Save a copy of parameters in case drivers need access
Expand Down Expand Up @@ -178,17 +176,17 @@ public function load_driver($driver)
/**
* Select default session storage driver
*
* @param string Driver classname
* @param string Driver name
* @return void
*/
public function select_driver($driver)
{
// Validate driver name
$lowername = strtolower(str_replace('CI_', '', $driver));
if (in_array($lowername, array_map('strtolower', $this->valid_drivers)))
$prefix = (string) get_instance()->config->item('subclass_prefix');
$child = strtolower(str_replace(array('CI_', $prefix, $this->lib_name.'_'), '', $driver));
if (in_array($child, array_map('strtolower', $this->valid_drivers)))
{
// See if driver is loaded
$child = str_replace($this->lib_name.'_', '', $driver);
if (isset($this->$child))
{
// See if driver is already current
Expand Down
Loading

0 comments on commit 6262d05

Please sign in to comment.