Welcome Guest, Not a member yet? Register   Sign In
Modular Extensions - HMVC version 5.2

[eluser]dcunited08[/eluser]
[quote author="wiredesignz" date="1240339565"]Modular Extensions version 5.2.07 is available on the wiki.

Autoloader bug fixed.[/quote]

wiredesignz,

It seems that version 5.2 changed the fundamental way libraries are used. In CI the library is added to the Controller in such a way that you can define a variable such as 'var $class_name;' and it will fill that variable with the library's object. This is also the way ME worked until the release 5.2. Now the objects are stored in a static variable within the CI class named APP and any undefined call is caught by the function __get to pass it on to the Controller object at CI::$APP. This means that if I define a variable such as 'var $class_name;' the code fails with a 'Call to a member function method_name() on a non-object' error. I upgraded from 5.1, which worked. Is there any way to revert back to the original way? It seems like some of the posters on ME's WIKI thread are running into a similar issue.

[eluser]bEz[/eluser]
Quote:Local Server (xampp 1.7.0 -- may upgrade to 1.7.1)
PHP 5.2.8, Apache 2.2.11

Remote Server
PHP 5.2.9, Apache 2.2.11

Both servers use:
CI 1.7.1
ME 5.2.01

The problem is that the local server runs the CI app without error.
However, the remote server was just upgraded to Apache 2.2 and now Modular Extensions fails as such
Code:
Fatal error: Class 'CI' not found in .../applications/libraries/Controller.php on line 6:
and Controller.php has not been touched.
Code:
3 | /* load the modules library */
4 | require_once 'Modules.php';
5 | /* create the CI application object */
6 | CI::$app = new CI();

I also utilize the datamapper library (DMZ edition).
I tried commenting out any use of
Code:
$this->CI =& get_instance();
in the models create, but that did not resolve the fatal error.

Anyone experience this error?

[eluser]wiredesignz[/eluser]
Quote:... In CI the library is added to the Controller in such a way that you can define a variable such as 'var $class_name;' and it will fill that variable with the library's object.

@dcunited08

The var $class_name is not filled by CI, it is replaced by the object you load with the same name.

Personally I can't see why you would need to declare vars for your loaded objects when CI replaces them anyway, but, if you need this functionality you could use the PHP4 version of Modular Extensions.

[eluser]dcunited08[/eluser]
[quote author="wiredesignz" date="1240397234"]Personally I can't see why you would need to declare vars for your loaded objects when CI replaces them anyway, but, if you need this functionality you could use the PHP4 version of Modular Extensions.[/quote]

@wiredesignz

I understand why you set it up to use a static variable but it, to me, seems to remove one of the basic fundamentals of OOP, encapsulation. The property name is no longer unique to the controller object, if loaded via the load object, so it is probable to have another module replace that object. Please review my test code below to see what I mean.
Code:
class Welcome extends Controller {
    
    function Welcome()
    {
        parent::Controller();
    }

    function index()
    {
        $this->load->library('table', array(), 'test1');
        $this->test1->add_row('asdf','qwer');
        $this->load->view('welcome_message');
        $asdf = $this->load->module('Test2');
        $asdf->index();
        
        $this->test1->add_row('asdf2','qwer2'); //Call to undefined method TestMe::add_row()
        
     }
}

class Test2 extends Controller{

    function index()
    {
        $this->load->view('welcome_message');
        $this->load->library('TestMe', array(), 'test1');
        $this->test1->run();
    }
}

In my application, I use $loaded_model quite a lot because I dynamically load models based on what type of data the user is requesting. This allows me to define a parent class and define the actual library that is loaded in a subclass as several of my tables have the same structure but different data. My guess is you made so that you no longer have to copy libraries and models to different objects, they are already there. Unfortunately it also tightly couples all of the loaded modules together more rather than allowing them to work independently of each other. You can manually override this behavior by either explicitly declaring the variable and creating another instance of it ($this->loaded_model = new Asdf_mode()) or explicitly copying it ($this->loaded_model = CI::$APP->loaded_modelWink but this is counter to CI's methodology.

I have used your library for about 6-8 months now and greatly admire your work. Coming out with a PHP5 version that fully supports OOP is a great thing, I wish CI would follow your lead. I find ME to be very useful and I would like to continue to use it but I see replacing this fundamental piece of how classes work, particularly the Controller class in CI, to be a major issue.

Thank you very much for your library,
dcunited

[eluser]wiredesignz[/eluser]
Modular extensions 5.2.08 is available on the wiki.

Corrected a problem loading a view in view described on the wiki thread. Thanks yuga Wink

[eluser]Michel-Ange[/eluser]
Another subfolder question :

Each module could have an admin section, made from several controllers.
A module directory integrating an admin section will look like this :

application
|_ modules
|_ myModule
|_ controllers
|_ admin
|_ myAdminController1.php
|_ myAdminController2.php
|_ myModule.php

To put subfolders in module controllers folder seems not to be possible with ME.
Has someone a solution ?

[eluser]wiredesignz[/eluser]
Hi Michel-Ange,

Module controller subdirectories functionality will add another level of complication to the MY_Router extension.

I am not in a situation where I can do this myself, but you are welcome to offer a solution which I would incorporate into ME if successful.

[eluser]Michel-Ange[/eluser]
@wiredesign : OK, will simply create admin controllers in the controllers folder for the moment. Hope I wil have time to do this more strict.

Other thing :
When using a library to show views :
In ME 5.2.01, i can call views located in "myModule/views/admin" folder from views.
ME 5.2.08 don't find the view anymore.

Example of use :

Code:
// Controller

class Test extends Controller {

    var $template = array();

    function Test()
    {
        parent::Controller();    
    }
    
    function index()
    {
        $this->template['view'] = 'admin/index';

        $this->layout->load($this->template, 'body');
    }
}

// Library :

class Layout {

    var $obj;

    function Layout()
    {
        if ( !isset($this->obj) ) $this->obj = &get;_instance();
    }

    /** Feeds one view with the transmitted data and display it.
     *    @param     $view_data        Array of the view elements
     *    @param    $view            String, View name to display
     */      
    function load($view_data, $view)
    {
        $this->obj->load->view('body', $view_data);
    }
}

// View : myModule/views/body.php
<html>
<body>
    <?php $this->load->view($view);?>
</body>
</html>


// View : myModule/views/admin/index.php
<h1 style="color:#c00;">This is a included view</h1>

Precisions :
The Layout library is autoloaded.

[eluser]wiredesignz[/eluser]
Hi Michel-Ange,

In Modular Extensions version 5.2, get_instance() returns the CI application object (a singleton). Controllers access the CI application object by utilizing the PHP5 overload methods. This allows all Controllers to have access to any loaded libraries and models

The CI application object is not a controller itself.

If a library needs access to the current controller then you must specifically pass a reference to it.

The use of get_instance() is fine if there is only one controller (native CI) but is really just a lazy (over-abused) way of getting a reference to CI in most cases.

Also by passing an object reference to a library it does not specifically make it dependedent on CodeIgniter.

[eluser]Michel-Ange[/eluser]
Hmmm...
But it was possible with ME 5.2.01...

So the 2 solutions are :

1. Each controller has to load the library and to pass $this in the contructor ?
2. Each library function has to get the controller reference ?

But in the first case, it will not be possible to autoload the library ?




Theme © iAndrew 2016 - Forum software by © MyBB