Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Finished Driver extension changes

Signed-off-by: dchill42 <dchill42@gmail.com>
  • Loading branch information...
commit b9981f6bce98d94357e7a2f8cbecd7f0350e3bd0 1 parent 28bee3d
@dchill42 authored
View
146 system/core/Loader.php
@@ -918,100 +918,118 @@ protected function _ci_load_class($class, $params = NULL, $object_name = NULL)
}
}
+ // Establish subdirectories to try - if one was specified, just use that
+ $trysubs = array($subdir);
+ if ($subdir == '')
+ {
+ // Also check subdirectories matching class name
+ $dir = strtolower($class).'/';
+ $trysubs[] = ucfirst($dir);
+ $trysubs[] = $dir;
+ }
+
// We'll test for both lowercase and capitalized versions of the file name
foreach (array(ucfirst($class), strtolower($class)) as $class)
{
- $subclass = APPPATH.'libraries/'.$subdir.config_item('subclass_prefix').$class.'.php';
-
// Is this a class extension request?
- if (file_exists($subclass))
+ foreach($trysubs as $dir)
{
- $baseclass = BASEPATH.'libraries/'.ucfirst($class).'.php';
-
- if ( ! file_exists($baseclass))
- {
- log_message('error', 'Unable to load the requested class: '.$class);
- show_error('Unable to load the requested class: '.$class);
- }
-
- // Safety: Was the class already loaded by a previous call?
- if (in_array($subclass, $this->_ci_loaded_files))
+ // Check each path for an extension file
+ $subclass = APPPATH.'libraries/'.$dir.config_item('subclass_prefix').$class.'.php';
+ if (file_exists($subclass))
{
- // Before we deem this to be a duplicate request, let's see
- // if a custom object name is being supplied. If so, we'll
- // return a new instance of the object
- if ( ! is_null($object_name))
+ // Found it - check paths for the base
+ // The second loop here allows us to match an extension in
+ // the libraries root with a base in a subdirectory (like a driver!)
+ $found = FALSE;
+ foreach ($trysubs as $dir)
{
- $CI =& get_instance();
- if ( ! isset($CI->$object_name))
+ $baseclass = BASEPATH.'libraries/'.$dir.ucfirst($class).'.php';
+ if (file_exists($baseclass))
{
- return $this->_ci_init_class($class, config_item('subclass_prefix'), $params, $object_name);
+ $found = TRUE;
+ break;
}
}
- $is_duplicate = TRUE;
- log_message('debug', $class.' class already loaded. Second attempt ignored.');
- return;
- }
+ if ( ! $found)
+ {
+ // No base matches extension - bail
+ $msg = 'Unable to load the requested class: '.$class;
+ log_message('error', $msg);
+ show_error($msg);
+ }
+
+ // Safety: Was the class already loaded by a previous call?
+ if (in_array($subclass, $this->_ci_loaded_files))
+ {
+ // Before we deem this to be a duplicate request, let's see
+ // if a custom object name is being supplied. If so, we'll
+ // return a new instance of the object
+ if ( ! is_null($object_name))
+ {
+ $CI =& get_instance();
+ if ( ! isset($CI->$object_name))
+ {
+ return $this->_ci_init_class($class, config_item('subclass_prefix'), $params,
+ $object_name);
+ }
+ }
- include_once($baseclass);
- include_once($subclass);
- $this->_ci_loaded_files[] = $subclass;
+ $is_duplicate = TRUE;
+ log_message('debug', $class.' class already loaded. Second attempt ignored.');
+ return;
+ }
- return $this->_ci_init_class($class, config_item('subclass_prefix'), $params, $object_name);
@nickl-
nickl- added a note

Round about here do something like this instead:

<?php

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

Which is where it's going to matter and helps to make it understandable because the dependents are being included in the following two lines.

@dchill42 Owner

True - with the changes to subdirectory handling, the Driver base loading up at L914 won't work anymore. I'll have to move that - just not to where you've indicated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ include_once($baseclass);
+ include_once($subclass);
@nickl-
nickl- added a note

Is there any reason why include is not sufficient?
If yes rather do if class_exists as it's got cache advantages (ie APC) which *_once misses out on.

@dchill42 Owner

Agreed - include is sufficient. include_once was the existing call, but it could be updated while we're here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ $this->_ci_loaded_files[] = $subclass;
+
+ return $this->_ci_init_class($class, config_item('subclass_prefix'), $params, $object_name);
+ }
}
// Lets search for the requested library file and load it.
$is_duplicate = FALSE;
foreach ($this->_ci_library_paths as $path)
{
- $filepath = $path.'libraries/'.$subdir.$class.'.php';
-
- // Does the file exist? No? Bummer...
- if ( ! file_exists($filepath))
+ foreach ($trysubs as $dir)
{
- continue;
- }
+ $filepath = $path.'libraries/'.$dir.$class.'.php';
- // Safety: Was the class already loaded by a previous call?
- if (in_array($filepath, $this->_ci_loaded_files))
- {
- // Before we deem this to be a duplicate request, let's see
- // if a custom object name is being supplied. If so, we'll
- // return a new instance of the object
- if ( ! is_null($object_name))
+ // Does the file exist? No? Bummer...
+ if ( ! file_exists($filepath))
+ {
+ continue;
+ }
+
+ // Safety: Was the class already loaded by a previous call?
+ if (in_array($filepath, $this->_ci_loaded_files))
{
- $CI =& get_instance();
- if ( ! isset($CI->$object_name))
+ // Before we deem this to be a duplicate request, let's see
+ // if a custom object name is being supplied. If so, we'll
+ // return a new instance of the object
+ if ( ! is_null($object_name))
{
- return $this->_ci_init_class($class, '', $params, $object_name);
+ $CI =& get_instance();
+ if ( ! isset($CI->$object_name))
+ {
+ return $this->_ci_init_class($class, '', $params, $object_name);
+ }
}
+
+ $is_duplicate = TRUE;
+ log_message('debug', $class.' class already loaded. Second attempt ignored.');
+ return;
}
- $is_duplicate = TRUE;
- log_message('debug', $class.' class already loaded. Second attempt ignored.');
- return;
+ include_once($filepath);
@nickl-
nickl- added a note

Something must be wrong, why are we going through the whole ric-ma-role again the class was included. Rather find out why it's doing double runs then to go the safe route here.

@dchill42 Owner

There are two different operations here. The first pass loads an extension and the base class, whereas the second pass is for identifying the regular library in the package paths if an extension wasn't found. This is how the loader works.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ $this->_ci_loaded_files[] = $filepath;
+ return $this->_ci_init_class($class, '', $params, $object_name);
}
-
- include_once($filepath);
- $this->_ci_loaded_files[] = $filepath;
- return $this->_ci_init_class($class, '', $params, $object_name);
}
} // END FOREACH
- // One last attempt. Maybe the library is in a subdirectory, but it wasn't specified?
- if ($subdir === '')
- {
- $path = strtolower($class).'/'.$class;
- return $this->_ci_load_class($path, $params, $object_name);
- }
- else if (ucfirst($subdir) != $subdir)
- {
- // Lowercase subdir failed - retry capitalized
- $path = ucfirst($subdir).$class;
- return $this->_ci_load_class($path, $params, $object_name);
- }
-
// If we got this far we were unable to find the requested class.
// We do not issue errors if the load call failed due to a duplicate request
if ($is_duplicate === FALSE)
View
14 system/libraries/Cache/Cache.php
@@ -42,12 +42,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'
);
/**
@@ -226,4 +226,4 @@ public function is_supported($driver)
}
/* End of file Cache.php */
-/* Location: ./system/libraries/Cache/Cache.php */
+/* Location: ./system/libraries/Cache/Cache.php */
View
149 system/libraries/Driver.php
@@ -37,7 +37,7 @@
* @author EllisLab Dev Team
* @link
*/
-abstract class CI_Driver_Library {
+class CI_Driver_Library {
/**
* Array of drivers that are available to use with the driver class
@@ -54,11 +54,11 @@
protected $lib_name;
/**
- * Name of the base class
+ * Subclass prefix from config
*
- * @var string
+ * @var string
*/
- protected $base_name;
+ protected $subclass_prefix = '';
/**
* Get magic method
@@ -70,7 +70,7 @@
* @return object Child class
*/
public function __get($child)
- {
+ {
// Try to load the driver
return $this->load_driver($child);
}
@@ -80,83 +80,122 @@ public function __get($child)
*
* Separate load_driver call to support explicit driver load by library or user
*
- * @param string Child class name
+ * @param string Driver name (w/o parent prefix)
* @return object Child class
*/
public function load_driver($child)
{
+ // Get CodeIgniter instance
+ $CI = get_instance();
+
if ( ! isset($this->lib_name))
{
- // Get both the current class (extension) and the base driver library class
- $this->lib_name = get_class($this);
- $this->base_name = $this->_get_base();
+ // Get library name without any prefix
+ $this->subclass_prefix = (string)$CI->config->item('subclass_prefix');
+ $this->lib_name = str_replace(array('CI_', $this->subclass_prefix), '', get_class($this));
}
- if (in_array($child, array_map('strtolower', $this->valid_drivers)))
+ // 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)))
{
- $found = FALSE;
- foreach (array($this->lib_name, $this->base_name) as $lib_name)
- {
- // The class will be prefixed with the parent lib
- $child_class = $lib_name.'_'.$child;
+ // The requested driver isn't valid!
+ $msg = 'Invalid driver requested: '.$child_name;
+ log_message('error', $msg);
+ show_error($msg);
+ }
- // Remove the CI_ prefix and lowercase
- $base_name = ucfirst(strtolower(str_replace('CI_', '', $this->base_name)));
- $driver_name = strtolower(str_replace('CI_', '', $child_class));
+ // All driver files should be in a library subdirectory - capitalized
+ $subdir = ucfirst(strtolower($this->lib_name));
- // Check and see if the driver is in a separate file
- error_log('Checking for '.$child_class.' in '.$base_name);
- if ( ! class_exists($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));
+
+ // Is there an extension?
+ $class_name = $this->subclass_prefix.$child_name;
+ $found = class_exists($class_name);
+ if ( ! $found)
+ {
+ // Check for subclass file
+ foreach ($paths as $path)
+ {
+ // Extension will be in drivers subdirectory
+ $path .= 'libraries/'.$subdir.'/drivers/';
+
+ // Try filename with caps and all lowercase
+ foreach ($cases as $name)
{
- // Check application path first
- foreach (get_instance()->load->get_package_paths(TRUE) as $path)
+ // Does the file exist?
+ $file = $path.$this->subclass_prefix.$name.'.php';
+ if (file_exists($file))
{
- // Check upper- and lower-case names
- foreach (array(ucfirst($driver_name), $driver_name) as $class)
+ // Yes - require base class from last path (BASEPATH)
+ $basepath = end($paths).'libraries/'.$subdir.'/drivers/'.ucfirst($child_name).'.php';
+ if ( ! file_exists($basepath))
{
- $filepath = $path.'libraries/'.$base_name.'/drivers/'.$class.'.php';
-
- if (file_exists($filepath))
- {
- include_once $filepath;
- if (class_exists($child_class))
- {
- $found = TRUE;
- break 3;
- }
- }
+ $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
+ // 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)
{
- log_message('error', 'Unable to load the requested driver: '.$child_class);
- show_error('Unable to load the requested driver: '.$child_class);
+ // Check package paths
+ foreach ($paths as $path)
+ {
+ // 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;
}
- /**
- * Get base driver library class
- *
- * Each driver library MUST implement this abstract method!
- * The implementation should look like:
- * protected function _get_base() { return __CLASS__; }
- */
- abstract protected function _get_base();
-
}
// --------------------------------------------------------------------------
View
11 system/libraries/Session/Session.php
@@ -127,13 +127,6 @@ public function __construct(array $params = array())
// ------------------------------------------------------------------------
- protected function _get_base()
- {
- return __CLASS__;
- }
-
- // ------------------------------------------------------------------------
-
/**
* Loads session storage driver
*
@@ -153,13 +146,13 @@ 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
- $child = strtolower(str_replace(array('CI_', $this->lib_name, $this->base_name), '', $driver));
+ $child = strtolower(str_replace(array('CI_', $this->subclass_prefix, $this->lib_name.'_'), '', $driver));
if (in_array($child, array_map('strtolower', $this->valid_drivers)))
{
// See if driver is loaded
View
9 tests/codeigniter/libraries/Session_test.php
@@ -41,6 +41,9 @@ public function set_up()
}
$this->ci_instance($obj);
+ // Set subclass prefix to match our mock
+ $obj->config->set_item('subclass_prefix', 'Mock_Libraries_');
+
// Attach session instance locally
$config = array(
'sess_encrypt_cookie' => FALSE,
@@ -58,11 +61,7 @@ public function set_up()
'sess_time_to_update' => 300,
'time_reference' => 'local',
'cookie_prefix' => '',
- 'encryption_key' => 'foobar',
- 'sess_valid_drivers' => array(
- 'native',
- 'cookie'
- )
+ 'encryption_key' => 'foobar'
);
$this->session = new Mock_Libraries_Session($config);
}
View
5 tests/mocks/libraries/session.php
@@ -36,8 +36,3 @@ protected function _setcookie($name, $value = '', $expire = 0, $path = '', $doma
}
}
-/**
- * Mock native driver (just for consistency in loading)
- */
-//class Mock_Libraries_Session_native extends CI_Session_native { }
-

1 comment on commit b9981f6

@nickl-

This is bad for cherry picking too much happening in one commit.

Can this not be don in 4 maybe even 8 separate commits?

I lost the plot when the cache changes started =(

Please sign in to comment.
Something went wrong with that request. Please try again.