Welcome Guest, Not a member yet? Register   Sign In
Creating a new "shared" folder for models and libraries
#1

[eluser]Phil Sturgeon[/eluser]
A common question on these forums (and to me directly) is how to share models and libraries between different applications. As far as I know there is no smooth way of doing this that doesn't involve symlinks as although you can place your shared libraries in the system folder, models are only ever looked for in the application.

For this I knocked together a MY_Loader.php which will look in a "shared" folder which can look something like this:

Quote:/usr/local/codeigniter/system

/usr/local/codeigniter/shared/libraries
/usr/local/codeigniter/shared/models

/home/site-one.com/public_html/config
/home/site-one.com/public_html/controller
/home/site-one.com/public_html/models
/home/site-one.com/public_html/views
/home/site-one.com/public_html/index.php

/home/site-two.com/public_html/config
/home/site-two.com/public_html/controller
/home/site-two.com/public_html/models
/home/site-two.com/public_html/views
/home/site-two.com/public_html/index.php

The code is rough and obviously "SHAREPATH" can be moved somewhere more useful, but my main question is am I approaching this the right way?

If so should I keep going and get things like helpers and plugins working?

It's a shame to sacrifice a MY_Loader to something like this, as MY_Loader is used for so much i.e Modular Separation or Matchbox.
#2

[eluser]Tom Schlick[/eluser]
hmm interesting concept here. we use 3 seperate codebases at work for admin, application, and maintenance/cron etc. i find myself copying and pasting when i update one library to all of the other libraries. this would solve that problem. im all for it as long as it can be turned off so we are not searching for things that we dont need to.
#3

[eluser]Natebot[/eluser]
Sorry to arrive late to the party Phil.

I use symlinks in my applications' helper and library directories to common files. So far it has served me well. Although it's not a solution in the code but in the OS, my chosen repository, svn, does support symlinking so that's something I suppose.

I like what you've done here. My one suggestion is that SHAREPATH be set in the index.php file in the exact same way the other path constants, like APPPATH, are defined and testing for existance. Downside of course is that MY_Loader now depends on it, but I like keeping my path constants in one place and getting warned early if they can't be found.

@trs21219 - you can 'turn off' this extension to Loader by simply renaming MY_Loader.php and it will no longer be instantiated. However, that might not be needed as I believe Phil's code will load any application specific models and libraries (those in APPPATH) first before looking to load them from the SHAREDPATH (or the BASEPATH in the case of Libraries). So you'd only need to place a copy of the desired model into your application's model directory for your app to load it instead of the common version.

Unfortunately MY_Loader.php would have to be replicated on each application's library directory.
#4

[eluser]Phil Sturgeon[/eluser]
Yeah that is one problem. However replicating MY_Loader.php for me would be much easier than replicating symlinks so that could be one plus.

SHAREPATH would of course go somewhere better, this code was more "proof of concept" than anything else.

As far as the dependency goes when its moved, a simple if(defined('SHAREPATH') && !empty(SHAREPATH)) could help MY_Loader check if the SHAREPATH was set, therefore working out if it should try looking for shared files (or soft error?).
#5

[eluser]Natebot[/eluser]
I would prefer a soft error with some attempt at error correcting. It could look in a conventional location first before complaining. The index.php file already does this for the other path constants, that's why I suggest SHAREPATH can be treated there too.

You could replicate that treatment inside MY_Loader too, for those who install it without altering their index.php, followed by a warning in the log.

Could we use the constants.php config file to store this path? I'm not sure what what point it is loaded. Would that be considered a bit more friendly than a new index.php?
#6

[eluser]Phil Sturgeon[/eluser]
I think it probably doesn't really matter. Seeing as this wont ever be included in the core, the only time people will use this is if I clean it up and blog/wiki it. That means they will implement it themselves so "guessing" and whatnot is entirely unnecessary.

I'll knock this up in 2010 by which time hopefully I will have recovered enough to think of some smaller implementation of this. Sick
#7

[eluser]Unknown[/eluser]
Dear folks, i am new in this forum. First of all, sorry for my poor english :-)

The sharing of models it's really a common task. In my case, i must use a authentication component like redux_auth for more than one application/module. But this - or other compontents - consist of at least one library, model(s) and configuration files.

The sharing of the libraries is simple: storing into the CI-libraries folder. The sharing of configs are also a simple task (eg. load by 'require_once' into the controller), because commonly they are no dependencies to other classes/modules.

Maybe, there is a short solution with some minor changes at the core code of CI:
* Edit the 'Loader.php' of your CI-Installation (CI 1.7.1, 1.7.2);
* Pickup the 'model'-Method (near to line 115);
* Go to the line (near Line 160):
Code:
.
        $model = strtolower($model);

and add this lines:
Code:
.
        $model       = strtolower($model);
        $LoadState   = FALSE;
        $LoadPath    = FALSE;

* Than replace the following statements:
Code:
.
        if ( ! file_exists(APPPATH.'models/'.$path.$model.EXT))
        {
            show_error('Unable to locate the model you have specified: '.$model);
        }

by
Code:
.
        if( $LoadState === FALSE AND file_exists(APPPATH.'models/'.$path.$model.EXT))
        {
            $LoadState    = TRUE;
            $LoadPath    = APPPATH;
        }
        
        if( $LoadState === FALSE AND file_exists(BASEPATH.'models/'.$path.$model.EXT))
        {
            $LoadState    = TRUE;
            $LoadPath    = BASEPATH;
        }

        if ( $LoadState === false )
        {
            show_error('Unable to locate the model you have specified: '.$model);
        }

* Each 'if'-Statement represents one directory lookup. The first match wins and set the LoadPath-Variable.
* Finally, you must modify the 'require_once'-Statement near line 180 from:
Code:
.
        require_once(APPPATH.'models/'.$path.$model.EXT);

to

Code:
.
        require_once($LoadPath.'models/'.$path.$model.EXT);

This approach works very well for me.

With best regards

[edit] Uuuups, sorry - i take a look at your MY_Loader-Class.
It's basically the same solution :-)
#8

[eluser]Phil Sturgeon[/eluser]
Haha yes it is basically the same soultion, but thanks for your suggestions.
#9

[eluser]steward[/eluser]
Thanks for posting that Phil.

An extended loader for CI multi-apps is essential.

If you are able to modify php.ini, consider the "include_path" setting as an alternative to symlinks.

I wrote a generic script that looks at the HTTP_HOST to see what the current site is, and then sets up a few global variables and functions, so any script knows where it is, eg:

site_path() '/home/mysite/path', '/home/myothersite/path', etc
site_home() 'mysite.com', 'myothersite.com', etc
site_domain() 'com', 'dev', etc
site_subdomain() 'travel', 'forums', etc

Since this script is on the include path, I can use it anywhere.
It starts by overriding a few config variables, so eg CI site_url() works as expected.

Then I took the opposite approach, putting the sites further down the folder tree:

/home/CodeIgnitor_1_7_1
/home/domains
/home/domains/mysite
/home/domains/myothersite
/home/app
/home/app/controllers/
/home/app/controllers/mysite
/home/app/controllers/myothersite
/home/app/views/
/home/app/views/mysite
/home/app/views/myothersite

In my case the sites are closely related, and share many views, models etc. They all share the same system and application folders.

I still long for a more "zend-like" approach to loading models, so I always have base functionality but can extend any give site/class as required.
#10

[eluser]Phil Sturgeon[/eluser]
For anyone finding this on Google now, this is a core 2.0 feature called Application Packages.




Theme © iAndrew 2016 - Forum software by © MyBB