Part of the EllisLab Network
   
2 of 6
2
Extending Core Libraries in System Folder
Posted: 20 April 2007 02:14 PM   [ Ignore ]   [ # 16 ]  
Research Assistant
Avatar
RankRankRank
Total Posts:  472
Joined  09-26-2006

I’ve been trying out Ian’s patch, (very nice work BTW). I’m just using a vanilla CI 1.5.3.
I set

$config['custom_lib_path' = 'libraries/custom/';

and added a custom dir below system/libraries.

Everything seems to be working well and I am trying out various configurations.

I’m just a little perturbed, this is definitely a “must-have” for CI, and several intriguing solutions
have been proposed. Perhaps we should be a little conservative in approaching this. It’s quite easy to go overboard.  Shadowhand has posted a very interesting solution here http://codeigniter.com/forums/viewthread/50092/, albeit not for exactly the same problem.

Obviously, The usages of CI extend far beyond what Rick initially might have imagined, so it shows its limitations in this regard. It absolutely must be upgraded to cater for running multiple apps off one (or more, for versioning easier) system installations, AND for cleanly importing resources from user configured locations.

But this needs to be thought through, we need an elegant, configurable, complete solution, not various ad hoc fixes (excellent though each may be individually).
Just my 300 000 Lira wink

 Signature 

Old programmers never die, they just parse away.

Profile
 
 
Posted: 20 April 2007 02:24 PM   [ Ignore ]   [ # 17 ]  
Lab Assistant
RankRank
Total Posts:  128
Joined  04-06-2007
Oscar Bajner - 20 April 2007 02:14 PM

But this needs to be thought through, we need an elegant, configurable, complete solution, not various
ad hoc fixes (excellent though each may be individually).
Just my 300 000 Lira wink

Oscar, I whole-heartedly agree.  I fully plan on continuing my solution to completion and making it available for other eyes to look at.  If, afterward, the consensus is that mine is not suitable for CI for any reason, I am ok with that. It is CI I want to see benefit, not me personally.

If it seems mine would be a good fit and needs some polishing, I am up for any suggestions one may have for it.

I will say that mine is a modification to several methods in several different core files (though generally it is the same modification to each).  So several good sets of eyes will need to be on the code as well as some good testing performed.

Jim

Profile
 
 
Posted: 20 April 2007 04:19 PM   [ Ignore ]   [ # 18 ]  
Research Assistant
RankRankRank
Total Posts:  970
Joined  04-13-2006
Oscar Bajner - 20 April 2007 02:14 PM

I’m just a little perturbed, this is definitely a “must-have” for CI, and several intriguing solutions
have been proposed. Perhaps we should be a little conservative in approaching this. It’s quite easy to go overboard.  Shadowhand has posted a very interesting solution here http://codeigniter.com/forums/viewthread/50092/, albeit not for exactly the same problem.

Obviously, The usages of CI extend far beyond what Rick initially might have imagined, so it shows its limitations in this regard. It absolutely must be upgraded to cater for running multiple apps off one (or more, for versioning easier) system installations, AND for cleanly importing resources from user configured locations.

But this needs to be thought through, we need an elegant, configurable, complete solution, not various ad hoc fixes (excellent though each may be individually).
Just my 300 000 Lira wink

Good points, Oscar. My original thought was only for libraries that were not application-specific, but plainly this ties in with other kinds of resource. We’re now looking at a very significant re-design of the include path process, and we don’t want to screw it up. I’m still trying to find the time to give Ian’s code a thorough testing, but the comments so far are very encouraging. Pats on the back for the community.

Profile
 
 
Posted: 20 April 2007 08:12 PM   [ Ignore ]   [ # 19 ]  
Lab Technician
Avatar
RankRankRankRank
Total Posts:  1740
Joined  06-23-2006

Good work JAAulde. What a great way to learn how the framework is constructed, eh? Get right in there… grin

 Signature 

Mac OS X 10.4.10, Apache 1.3.3, PHP 5.2.3, CodeIgniter 1.5.x., baby!

Profile
 
 
Posted: 20 April 2007 08:19 PM   [ Ignore ]   [ # 20 ]  
Lab Technician
Avatar
RankRankRankRank
Total Posts:  1740
Joined  06-23-2006

1) application/libraries/
2) or the libraries/ directory of any number of configurable global extension paths
3) or finally the system/libraries/ directory if nothing else is found.

I suppose my only reservation is that this only includes Libraries, but the finished solutions should work for many types of resources:
- libraries
- models
- views
- ...

 Signature 

Mac OS X 10.4.10, Apache 1.3.3, PHP 5.2.3, CodeIgniter 1.5.x., baby!

Profile
 
 
Posted: 20 April 2007 10:16 PM   [ Ignore ]   [ # 21 ]  
Lab Assistant
RankRank
Total Posts:  128
Joined  04-06-2007
coolfactor - 20 April 2007 08:12 PM

Good work JAAulde. What a great way to learn how the framework is constructed, eh? Get right in there… grin

Indeed!  I have learned a TON about CI by doing this.  I amazed at how brilliantly put together it all is.  Rick has a very clear understanding of OOP and how to manipulate PHP4.  It is all so elegant, yet so simple.

coolfactor - 20 April 2007 08:19 PM

1) application/libraries/
2) or the libraries/ directory of any number of configurable global extension paths
3) or finally the system/libraries/ directory if nothing else is found.

I suppose my only reservation is that this only includes Libraries, but the finished solutions should work for many types of resources:
- libraries
- models
- views
- ...

Just so you know, the section you quoted was only referencing the portion I had done at that time, namely the core file loads that take place in CodeIgniter.php via &load_class().  At this time, I have also completed several other sections as noted in the edits at the bottom of the post you quoted.

I agree that there should be several resource types capable of being loaded from the extension directories and am working on that.

Profile
 
 
Posted: 21 April 2007 03:38 AM   [ Ignore ]   [ # 22 ]  
Research Assistant
RankRankRank
Total Posts:  915
Joined  07-10-2006
coolfactor - 20 April 2007 08:19 PM

1) application/libraries/
2) or the libraries/ directory of any number of configurable global extension paths
3) or finally the system/libraries/ directory if nothing else is found.

I suppose my only reservation is that this only includes Libraries, but the finished solutions should work for many types of resources:
- libraries
- models
- views
- ...

It sounds like the system might need its own paths config file (directory search paths), possibly patterned after the arrays in autoload.php. If the paths in those arrays were absolute relative to FCPATH, BASEPATH, and APPPATH, then any path could be specified. Then the individual arrays for libraries, models, views, etc. could be referenced by the core and core extensions.

Profile
 
 
Posted: 21 April 2007 08:19 AM   [ Ignore ]   [ # 23 ]  
Administrator
Avatar
RankRankRankRankRankRank
Total Posts:  6762
Joined  03-23-2006

Just wanted to chime in here.  I’m following this thread with great interest.  This is a fundamental change to CI, and not a decision I’m willing to make on my own, but it does have lots of merit, and if we get it to a stable point, I’ll bring it up with Rick/dev team for inclusion. 

In a worst case scenario, we could provide alternate resource files with CI, and could commit to keeping any changes between the 2 consistent, and therefore “official”.  Thus, as a developer if you wanted to take advantage of sub-apps, you could just delete the default files and replace with the new ones. 

Input.php
Sub_App_Input.php
etc

 Signature 

DerekAllard.com - CodeIgniter, ExpressionEngine, and the World of Web Design
BambooInvoice - Open Source, CodeIgniter powered invoicing.

Profile
MSG
 
 
Posted: 23 April 2007 11:11 AM   [ Ignore ]   [ # 24 ]  
Lab Assistant
RankRank
Total Posts:  128
Joined  04-06-2007

OK…I should have this ready for lots of eyes-on-code and testing-by-other-people by tomorrow…


Jim

Profile
 
 
Posted: 24 April 2007 03:12 PM   [ Ignore ]   [ # 25 ]  
Lab Assistant
RankRank
Total Posts:  128
Joined  04-06-2007

I have a fully modified version of CI packaged in the default 1.5.3 structure which allows for a configured set of global resources. (SEE FOLLOWING POST)

The only resource loading I DID NOT TOUCH are those found in system/libraries/Router.php as I believe it is best for that library to look in the local application directory for its routes.config, and controllers should always be loaded from the local application dir.

CHANGES:

application/config/config.php
*added after section where subclass_prefix is set

/*
|---------------------------------------------------------------
| CI Search Paths
|---------------------------------------------------------------
|
| If you want this application to share globally accessible directories
| of configurations, helpers, libraries, etc. with other applications
| you can tell CI where to look for these items.  This setting is an array and
| can have as many entries as you want.  Know, though, that the more you have
| the longer it will take to load a file that is actually in the system directory.
|
| By default, the CI loader looks in the local application directory for
| these sorts of files, and if nothing exists it looks in the core
| system directory.  Adding enteries here adds intermediate places to look
| for code files.  CI will now look in the local application directory, then
| in any directory you configure here (in order from first listed to last
| if more than one), then finally the core system directory.
|
| For example, if you were loading a library via $this->load->library('validation')
| the loader would first look for the validation library file in
| application/libraries/, then in the libraries/ directory under any configured
| 'ci_search_paths' directory, then in system/libraries/.
|
| FORMATTING
|  *This path can be
|     Relative (to the front controller which THIS config file configures)
|     or Absolute
|  *NO TRAILING SLASHES
|
*/
$config['ci_search_paths'] = Array(

);

system/codeigniter/Common.php
*added 2 functions to the bottom of the file

/**
* Set Search Paths
*
* Build an array of absolute paths where the first entry is the local
* application directory (APPPATH), the next entries are validated entries
* from the 'ci_search_paths' entry in main config, and the last entry is
* the system directory (BASEPATH)
*
* @access    public
* @return    array
*/
function set_search_paths()
{
    $search_paths
= array(APPPATH);
    
$configed_paths = config_item('ci_search_paths');
    if (
is_array($configed_paths) && count($configed_paths)>0 )
    
{
        
foreach($configed_paths as $path)
        
{
            $path
=
                
substr($path,0,1)=='/'?
                    
$path:
                    
SELF.$path;
            if ( (
$path=realpath($path))!==FALSE && is_dir($path) )
            
{
                $search_paths[]
= $path.'/';
            
}
        }
    }
    $search_paths[]
= BASEPATH;

    return
$search_paths;
}

/**
* Find Resource
*
* Takes a filename, resource subdirectory (libraries, helpers, plugins, etc),
* and optional list of paths to exclude in the search and returns absolute
* path to first matching filename in search path hierarchy or BOOL FALSE if
* not found
*
* @access   public
* @param    string
* @param    string
* @param    array
* @return   mixed
*/
function ci_find_resource($resource_file,$resource_subdir,$exclude_in_search=array())
{
    
global $SPATHS;
    
$returnVal = false;
    foreach (
$SPATHS as $spath )
    
{
        
if ( (is_array($exclude_in_search) && !in_array($spath,$exclude_in_search)) && is_file($spath.$resource_subdir.'/'.$resource_file) )
        {
            $returnVal
= $spath.$resource_subdir.'/'.$resource_file;
            break;
        
}
    }
    
return $returnVal;
}


*modified function &load_class() to use new global function ci_find_resource()

system/codeigniter/CodeIgniter.php
*added after the section that require() Common.php:

/*
* ------------------------------------------------------
*  Get the list of search paths for resource loading
* ------------------------------------------------------
*/
$SPATHS = set_search_paths();

system/codeigniter/libraries/Loader.php
*modified methods to use new global function ci_find_resource()
>> _ci_load_class()
>> model()
>> helper()
>> plugin()
>> script()
>> _ci_load()—this effected methods file() and view()
>> _ci_init_class()
>> _ci_autoloader()

*Removed initial setting of property $_ci_view_path from the constructer as it is not needed unless explicitly set by scaffolding or the like

system/libraries/Language.php
*modified method load() to use new global function ci_find_resource()

system/libraries/Config.php
*modified method load() to use new global function ci_find_resource()

system/libraries/User_agent.php
*modified method _load_agent_file() to use new global function ci_find_resource()

system/database/DB.php
*modified method &DB() to use new global function ci_find_resource()

system/libraries/Exceptions.php
*modified methods to use new global function ci_find_resource()
>> show_error()
>> show_php_error()

system/libraries/Upload.php
*modified method mimes_types() to use new global function ci_find_resource()

system/libraries/Hooks.php
*modified methods to use new global function ci_find_resource()
>> _initialize()
>> _run_hook()

system/helpers/smiley_helper.php
*modified method _get_smiley_array() to use new global function ci_find_resource()

system/helpers/download_helper.php
*modified method force_download() to use new global function ci_find_resource()

Profile
 
 
Posted: 24 April 2007 03:13 PM   [ Ignore ]   [ # 26 ]  
Lab Assistant
RankRank
Total Posts:  128
Joined  04-06-2007

I had to add this link to a second post because I reached the board limit of 6000 chars and the attachment of the file was too large.  smile

Here is the package:

CodeIgniter_1.5.3_modLoader

I have done a lot of my own testing and I think I hit most everything.  However, I am new to CI so I could have missed something…

Be sure to ask if you have any questions on functionality, etc.

Jim

Edit: I forgot to mention earlier what the directory structure would look like on the configured directory.  You would basically set up subdirectories in the configured directory like those that are in the CI application directory.  So lets say I had configured the search paths like so:

$config['ci_search_paths'] = Array(
  
'/var/www/global_ci_extend'
);


and say I wanted a configuration named myconf.php to be globally accessible.  I would simply create a directory named config (just like in the app dir) in /var/www/global_ci_extend and place the myconf.php into that new directory.

Profile
 
 
Posted: 24 April 2007 03:28 PM   [ Ignore ]   [ # 27 ]  
Lab Technician
Avatar
RankRankRankRank
Total Posts:  1740
Joined  06-23-2006

Your efforts are greatly appreciately, JAAulde. Lookin’ good.

 Signature 

Mac OS X 10.4.10, Apache 1.3.3, PHP 5.2.3, CodeIgniter 1.5.x., baby!

Profile
 
 
Posted: 24 April 2007 03:35 PM   [ Ignore ]   [ # 28 ]  
Lab Technician
Avatar
RankRankRankRank
Total Posts:  1740
Joined  06-23-2006

Just checking out the code, in Common::load_class(), you have this:

//does an extended version of a base class exist, if so load base class and extended class and flag that we have loaded a subclass
if ( FALSE !== ($abs_resource_path = ci_find_resource(config_item('subclass_prefix').$class.EXT,'libraries',array(BASEPATH))) )
{
    
require(BASEPATH.'libraries/'.$class.EXT);
    require(
$abs_resource_path);
    
$is_subclass = TRUE;
}
//no extended class existed in search paths, look for requested class in search paths and require it and flag as non-subclass if found
else if ( FALSE !== ($abs_resource_path = ci_find_resource($class.EXT,'libraries')) )
{
    
require($abs_resource_path);
    
$is_subclass = FALSE;
}

Rather than call ci_find_resource() twice depending on whether or not a library class is prefixed or not, could you build that check into the function? If the resource is a library class, then check for both the prefixed and non-prefixed versions of the library internally, and return the correct path.

Just a thought.

 Signature 

Mac OS X 10.4.10, Apache 1.3.3, PHP 5.2.3, CodeIgniter 1.5.x., baby!

Profile
 
 
Posted: 24 April 2007 03:38 PM   [ Ignore ]   [ # 29 ]  
Lab Technician
Avatar
RankRankRankRank
Total Posts:  1740
Joined  06-23-2006

Okay, responding to myself. I jumped the gun with that thought. There’s more dependencies involved, which is why you did the way you did. Good work.

 Signature 

Mac OS X 10.4.10, Apache 1.3.3, PHP 5.2.3, CodeIgniter 1.5.x., baby!

Profile
 
 
Posted: 24 April 2007 04:04 PM   [ Ignore ]   [ # 30 ]  
Lab Assistant
RankRank
Total Posts:  128
Joined  04-06-2007

Yeah, I didn’t like having that call in their twice in a row, but didn’t want to add the complication to the ci_find_resource() in order to avoid it.

I was also not crazy about going global with the two new functions and the variable to hold the paths.  But as many times as I had to call that stuff from all over, it was better.  I guess technically I could have written a separate class, but then it could be confusing because there is already a loader class.

Profile
 
 
   
2 of 6
2
 
Post Marker Legend
New Topic New posts Hot Topic Hot Topic with new posts New Poll New Poll Moved Topic Moved Topic Sticky Topic Sticky topic
Old Topic No new posts Hot Old Topic Hot Topic with no new posts Old Poll Old Poll Closed Topic Closed Topic Announcement Announcements
Theme
Change Theme
Visitor Statistics
The most visitors ever was 719, on June 06, 2008 10:16 AM
Total Registered Members: 66430 Total Logged-in Users: 37
Total Topics: 84793 Total Anonymous Users: 3
Total Replies: 455058 Total Guests: 222
Total Posts: 539851    
Members ( View Memberlist )
Newest Members:  Dylan1978X_franbaguasllogocsaturkeyPeter BryanttherendStudioGeorgiaJZeerfedeghe