I have the following code in file called AbstractClass.php in the libraries folder
abstract class AbstractClass {
abstract prote
Ok. I know this is WAY late, but I'm sure many people are having questions about this.
This is actually a limitation of the core Loader class, as it attempts to instantiate each of the items defined by the first parameter. As we all know, Abstract Classes by their very definition are Abstract and CANNOT be instantiated. So how do we get around this?
But most importantly: How do we get around this while conforming to the CodeIgniter Standards?
Since I've only just started using CodeIgniter, I can't really say for certain how Core Extensions were handled in the past. However, in the most recent version, the CodeIgniter framework will allow you to extend and override its core classes by Prefixing the filename with your defined Subclass Prefix (in most cases "MY_") followed by the name of the file you plan on extending.
*/application/core/MY_Loader.php*
Chances are good that if you know how to utilize Abstract Classes, you know what this does. Basically, this Class now inherits all properties and methods of the original CI_Loader class. The code snippet above is technically an exact duplicate of the original Loader Class, but the most important thing here is that now this class will take over all load methods rather than the original.
Now all we need to do is provide the loader class with the means to know if it's loading and instantiating a concrete class, or if it's simply including an abstract class.
There are two methods that handle the loading of any Libraries:
Method 1) public function library
Method 2) protected function _ci_load_class
Method 1 handles the processing of all parameters passed to it by iterating through itself if the first parameter is an array, makes sure the data provided is clean, and prevents any actions from being taken if certain criteria aren't met.
Method 2 handles the actual loading of the necessary assets, error handling, etc.
We can override the behavior of methods 1 and 2 by redefining them within our new MY_Loader Class. I've done this by creating almost exact replicas of the original methods, but with the addition of a 4th parameter that - when true - will prevent the Loader from instantiating the defined Library Class in the second method. I've also included an additional method public function abstract_library that will allow you to explicitly define the Library as Abstract in shorthand fashion.
The following is the MY_Loader.php class in its entirety. This will not affect any existing calls to the library method.
Hope this helps!
*/application/core/MY_Loader.php*
library($class, $params);
}
return;
}
if($library == '' OR isset($this->_base_classes[$library])){
return FALSE;
}
if(!is_null($params) && ! is_array($params)){
$params = NULL;
}
$this->_ci_load_class($library, $params, $object_name, $is_abstract);
}
public function abstract_library($library=''){
$this->library($library, NULL , NULL, true);
}
protected function _ci_load_class($class, $params = NULL, $object_name = NULL, $is_abstract=false)
{
$class = str_replace('.php', '', trim($class, '/'));
$subdir = '';
if(($last_slash = strrpos($class, '/')) !== FALSE){
$subdir = substr($class, 0, $last_slash + 1);
$class = substr($class, $last_slash + 1);
}
foreach(array(ucfirst($class), strtolower($class)) as $class){
$subclass = APPPATH.'libraries/'.$subdir.config_item('subclass_prefix').$class.'.php';
if(file_exists($subclass)){
$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);
}
if(in_array($subclass, $this->_ci_loaded_files)){
if(!is_null($object_name)){
$CI =& get_instance();
if(!isset($CI->$object_name)){
return $is_abstract ? true : $this->_ci_init_class($class, config_item('subclass_prefix'), $params, $object_name);
}
}
$is_duplicate = TRUE;
log_message('debug', $class." class already loaded. Second attempt ignored.");
return;
}
include_once($baseclass);
include_once($subclass);
$this->_ci_loaded_files[] = $subclass;
return $is_abstract ? true : $this->_ci_init_class($class, config_item('subclass_prefix'), $params, $object_name);
}
$is_duplicate = FALSE;
foreach ($this->_ci_library_paths as $path){
$filepath = $path.'libraries/'.$subdir.$class.'.php';
if(!file_exists($filepath)){
continue;
}
if(in_array($filepath, $this->_ci_loaded_files)){
if(!is_null($object_name)){
$CI =& get_instance();
if(!isset($CI->$object_name)){
return $is_abstract ? true : $this->_ci_init_class($class, '', $params, $object_name);
}
}
$is_duplicate = TRUE;
log_message('debug', $class." class already loaded. Second attempt ignored.");
return;
}
include_once($filepath);
$this->_ci_loaded_files[] = $filepath;
return $is_abstract ? true : $this->_ci_init_class($class, '', $params, $object_name);
}
} // END FOREACH
if($subdir == ''){
$path = strtolower($class).'/'.$class;
return $this->_ci_load_class($path, $params, $is_abstract);
}
if($is_duplicate == FALSE){
log_message('error', "Unable to load the requested class: ".$class);
show_error("Unable to load the requested class: ".$class);
}
}
}
?>
Loading an abstract library:
load->library("My_Abstract_Library", NULL, NULL, true);
/* -- OR -- */
$this->load->abstract_library("My_Abstract_Library");
?>