Welcome Guest, Not a member yet? Register   Sign In
Dynamic Models and Views; Parser
#1

[eluser]popovich[/eluser]
Hello everyone,

before I get there myself (and it's been a while now), I would appreciate any help from this forum.

My objective is to load multiple models dynamically, based on the database reference. These models are the modules, which can be switched back and forth on the fly, through admin interface of the CMS I am building. Basically, db holds a model name (like, 'press'), its position on the page, and the order it appears in regard to other modules. However, the sorting of this kind causes no problems. It is a 'different object name', as it is read in the user guide.

In the main controller I try to initialize models
Code:
function init_modules( $modules ) {
    
        $retour = array();
        
        if( count($modules) < 1 ){
        
            return false;
            
        }else{
        
            foreach ( $modules as $mod ) {
                
                $data = array();
                $dynamic_model = 'modules/mm_'.$mod;
                $dynamic_view = 'modules/mv_'.$mod;

                $this->load->model($dynamic_model, 'temp');

                # every model has this function, so it can start running
                $data = $this->temp->initialize();
                
                $retour[]['mod_content'] = $this->parser->parse($dynamic_view, $data);
                
            }    
                                        
        }

        return $retour;
        
    }

Container for modules in the main layout
Code:
{mods}
            
<div class="module_right">
            
{mod_content}
            
</div>

{/mods}

1 of 2 models being loaded, the 'press'
Code:
&lt;?php

class Mm_press extends Model {

     function Mm_press (){
        parent::Model();
    }
    
    
    function initialize() {
        return array('press'=>"do press");
    }

}

?&gt;

The parser template for the model 'press'
Code:
<em>Press Releases</em>
        
        <p>
        {press}
        </p>

2 of 2 models being loaded, the 'store'
Code:
&lt;?php

class Mm_store extends Model {

     function Mm_store (){
        parent::Model();
    }
    
    
    function initialize() {
        return array('store'=>"do store");
    }

}

?&gt;

The parser template for this very model
Code:
<em>Find a Store</em>
        
        <p>
        {store}
        </p>

It all seems to work properly except for two lines in the controller, I guess:
Code:
$this->load->model($dynamic_model, 'temp');
                $data = $this->temp->initialize();

The "temp" variable is not being evaluated, when called in a loop. It is being evaluated just once and when loading another model, it still references the first model. So if I load first "store", then "press", the "store" view is being parsed correctly, the "press" — not. If first goes "press", then "store", the "press" view is being parsed correctly, the store stays unparsed.

My question is: where is the catch? Or, how do I reference a dynamically loaded model?

Any help is greatly appreciated.
#2

[eluser]popovich[/eluser]
Update

I am now trying to use custom classes instead of models.
Here is how the code looks now.

Main controller
Code:
function init_modules( $modules ) {
    
        $retour = array();
        
        if( count($modules) < 1 ){
        
            return false;
            
        }else{
        
            foreach ( $modules as $mod ) {
                
                $data = array();
                $dynamic_class = 'mc_'.$mod;
                $dynamic_view = 'modules/mv_'.$mod;

                $data = $this->load->library($dynamic_class);
                $retour[]['mod_content'] = $this->load->view($dynamic_view, $data);
                
            }    
                                        
        }

        return $retour;
        
    }

One of the classes, system\application\libraries\mc_press.php

Code:
&lt;?php if (!defined('BASEPATH')) exit('No direct script access allowed');

class Mm_press {
    
     function Mm_press() {
        return array('press'=>"do press");
    }

}

?&gt;

And here is the fatal error (!)
Fatal error: Class 'mc_press' not found in D:\***\system\libraries\Loader.php on line 871

?!
#3

[eluser]popovich[/eluser]
Fixed the problem with fatal error (false class name was causing it).
Now the variables are not being returned from within the class constructor...
#4

[eluser]Seppo[/eluser]
The constructor can not return an array. The constructor always return the new instance.
#5

[eluser]popovich[/eluser]
So what do I do to return values? I do not actually need an instance of the class, I need it to run through some functions and return values, which the parser can chew on later.

This behavior will not work for me:
Code:
$temp_class = new MyOwnClass();
$data = $temp_class->some_method_to_return_values();

as the class name is being generated on the fly. This is why I use

Code:
$this->load->library($dynamic_class)

and this is why I try to get return values from within the constructor (certainly, the examples above are just there for testing the concept; there surely will be more functions for every class to run through).

Any ideas? I guess, the firstly mentioned model approach is not the best solution in this case?
#6

[eluser]popovich[/eluser]
SOLVED

The solution was to set a global variable and instead of returning values directly to it, the class assigns it from within the constructor. Think $CI instance.


Main controller, edited: note the global MOD array and passing $mod argument when initialising the class.
Code:
function init_modules( $modules ) {
    
        $retour = array();
        $this->MOD = array();
        
        if( count($modules) < 1 ){
        
            return false;
            
        }else{
        
            foreach ( $modules as $mod ) {
                
                $dynamic_class = 'mc_'.$mod;
                $dynamic_view = 'modules/mv_'.$mod;

                $this->load->library($dynamic_class,$mod);
                
                $retour[]['mod_content'] = $this->parser->parse($dynamic_view, $this->MOD[$mod]);
                
            }    
                                        
        }
        
        return $retour;
        
    }

Mc_press class, assigning values to the already defined MOD[$module_name] array
Code:
&lt;?php if (!defined('BASEPATH')) exit('No direct script access allowed');

class Mc_press {

    
     function Mc_press( $module_name ) {
            $CI =& get_instance();
            $CI->MOD[$module_name] = array('press'=>"do press");
    }

}

?&gt;

Seems to work now.
Again, thinking aloud and a tip from an experienced igniter help more than just browsing and searching around. Thanks, Seppo.




Theme © iAndrew 2016 - Forum software by © MyBB