My Application works with Third Party Applications. The Thirdparty Application is a Library Class, which is locaded in application/libraries/NAMEOFTHECLASS/main.php
.
I have a Library the modulehandler which has the job to handle the ThirdParty-Classes.
The Third Party Class looks like this:
class main {
var $name;
var $description;
var $saphir;
var $location;
public function init($config = array()) {
$this->name = $config['name'];
$this->description = $config['description'];
$this->saphir =& get_instance();
$this->location = $config['location'];
}
public function getFormElements() {
$html = $this->saphir->load->file($this->location.'/tpl/main.html',true);
$this->saphir->load->library('parser');
$data = array(
'name' => $this->name,
'description' => $this->description
);
$html = $this->saphir->parser->parse_string($html, $data, TRUE);
return $html;
}
public function validation($post_data)
{
$array = explode(',', $post_data);
if($post_data != is_array($array) )
return array("error" => array("name" => $this->name, "message" => "Bitte geben Sie nur eine Kommagetrennte Liste an"));
}
public function handleData($post_data) {
$array = explode(',', $post_data);
$return = array();
foreach($array as $key => $val) {
array_push($return, array("data" => $val));
}
return $return;
}
}
In the Module Handler i load in a foreach every thirdparty class which i need and call a function.
Zb in my ModuleHandler Class here is the method to get Form Elements from the Thirdparty Scripts:
private function getForm()
{
$form_data = array();
foreach($this->schema as $schema) {
$config = array("type" => $schema['type'], "name" => $schema['name'], "description" => $schema['description'], 'location' => 'application/libraries/thirdparty/cm_system/'.$schema['type']);
$type = $schema['type'];
if($this->edit) {
$value = $this->info;
$val = array();
foreach($value->ELEMENT as $element)
{
$holder = (string)$element;
array_push($val, $holder);
}
$value = $val;
}
else {
$value = "";
}
$ins = $this->CI->load->library('thirdparty/cm_system/'.$type.'/main');
$this->CI->main->init($config);
$form_elements = $this->CI->main->getFormElements($value);
array_push($form_data, $form_elements);
}
return $form_data;
}
The problem is, that every thirdparty Class has the name main. And i get the error that i cant redeclare class main. Is there a way to unset the loaded class?
I tried it already with unset. But it dont works.
You can do this:
$ins = $this->CI->load->library('thirdparty/cm_system/'.$type.'/main', null, $type);
If you navigate to /ci/system/core/loader.php
you will find public function library()
on line #194:
public function library($library = '', $params = NULL, $object_name = NULL)
The third parameter allows you to specify a unique object name to avoid collisions.
So now you can simply call:
$this->CI->load->library('thirdparty/cm_system/'.$type.'/main', null, $type);
// and use it like:
$this->$type->someFunction();
You can unload the library using a small hack, to do this you have to extend the Loader
Create a file in appilication/core/MY_Loader MY
is the prefix coming from $config['subclass_prefix']
class MY_Loader extends CI_Loader {
public function unload_library($name) {
$name = strtolower($name);
foreach ($this->_ci_loaded_files as $key => $path) {
$file_name = basename($path);
$value = substr($file_name, 0, strlen($file_name) - 4);
if (strtolower($name) == strtolower($value)) {
unset($this->_ci_loaded_files[$key]);
$CI = & get_instance();
unset($CI->$name);
}
}
}
}
Now you can unload a library using
$this->load->unload_library('YOUR_LIB_NAME');
Since CI does not use namespaces, there is no way to make this work as it is.
It's not a CI limitation, it's a PHP one. CI include
the file, so if you include 2 files with a class Main
, it will of course crash.
The easiest and cleanest solution is to name your class and the associated file with the same name as the folder.
ie:
$ins = $this->CI->load->library('thirdparty/cm_system/'.$type.'/'.$type);
Having the "main" class named the same as the folder is pretty common.