Load config and language files on demand

Discussions and requests related to new CMSimple features, plugins, templates etc. and how to develop.
Please don't ask for support at this forums!
Post Reply
cmb
Posts: 14225
Joined: Tue Jun 21, 2011 11:04 am
Location: Bingen, RLP, DE
Contact:

Load config and language files on demand

Post by cmb » Sun Jan 11, 2015 3:26 pm

Hello Community,

I suggest to avoid loading of unnecessary config and language files of plugins. Currently for each plugin 4 such files are loaded (defaultconfig.php, config.php, default.php and $sl.php) on each request, even if the plugin might not be involved at all. Consider, for instance, Pagemanager which is never used by front-end requests, but nonetheless its 4 config/language files are always loaded; several other plugins are only used on some pages (e.g. galleries, sliders, guestbooks).

Unfortunately, there is no way for the core (pluginloader) to know in advance which plugins will be used. However, a simple solution would be to use functions or methods (instead of variables) to access the config options and language strings, so the method could load the respective files on demand. Until all (relevant) plugins would be converted to use this new API throughout, all config and language files would still need to be loaded, so I suggest to introduce the API as soon as possible, i.e. for XH 1.7. The new API could already be delivered by a utility plugin/addon, what would provide backward compatibility with older CMSimple(_XH) versions, but even then it would make sense to agree on a reasonable API first.

Any suggestions?

Christoph
Christoph M. Becker – Plugins for CMSimple_XH

svasti
Posts: 1651
Joined: Wed Dec 17, 2008 5:08 pm

Re: Load config and language files on demand

Post by svasti » Thu Jan 15, 2015 11:05 am

1.7 is going to be great!

What about a config option $cf['plugins']['backendonly'] which would only be loaded in edit mode, i.e.:
$cf['plugins']['backendonly']="meta_tags,page_params,pagemanager,tinymce,ckeditor, translator,stylemanager,morepagedata,hi_uploadcheck";

Looking forward to your proposed API.

cmb
Posts: 14225
Joined: Tue Jun 21, 2011 11:04 am
Location: Bingen, RLP, DE
Contact:

Re: Load config and language files on demand

Post by cmb » Thu Jan 15, 2015 1:01 pm

svasti wrote:What about a config option $cf['plugins']['backendonly'] which would only be loaded in edit mode, i.e.:
$cf['plugins']['backendonly']="meta_tags,page_params,pagemanager,tinymce,ckeditor, translator,stylemanager,morepagedata,hi_uploadcheck";
That makes some sense until we can switch to loading on demand only. However, one would have to be very careful about which plugins to exclude for the front-end, because that could lead to nasty bugs when a plugin is used in the front-end nevertheless.
svasti wrote:Looking forward to your proposed API.
Basically the API might look like the following:

Code: Select all

function getConfigOption($plugin, $key)
{
    global $plugin_cf;

    if (!isset($plugin_cf[$plugin])) {
        loadConfiguration($plugin);
    }
    return $plugin_cf[$plugin][$key];
}
Plugins would have to call it like so:

Code: Select all

getConfigOption('pagemanager', 'treeview_theme') 
instead of:

Code: Select all

$plugin_cf['pagemanager']['treeview_theme'] 
Quite obviously, there are many possible variations having their advantages and drawbacks. One possibility would be:

Code: Select all

function getConfig($plugin)
{
    global $plugin_cf;

    if (!isset($plugin_cf[$plugin])) {
        loadConfiguration($plugin);
    }
    return $plugin_cf[$plugin];
}
which would be used like so:

Code: Select all

$pcf = getConfig('pagemanager');
$pcf['treeview_theme']; 
Another more object-oriented possibility would be to define a respective method in an abstract base class from which a plugin class could inherit[1]:

Code: Select all

abstract class Plugin 
{
     protected function getConfigOption($key)
     {
          // ...
     }
}
class Pagemanager extends Plugin
{
     public function doSomething()
     {
         doSomethingWith($this->getConfigOption('treeview_theme'));
     }
}

However, I assume that many plugin developers don't want to be forced to using classes, so a procedural API or one based on helper classes is likely the way to go for XH 1.7.

With regard to the language strings it's probably a good idea to extend the API. For instance, something like Filebrowser_View::translate($key, $args) seems to be interesting, and maybe something that takes into account the number (numerus).

Anyhow, I don't have any strong preferences, so I'm looking forward for other opinions and suggestions.

[1] Using a Trait would be cleaner, though.
Christoph M. Becker – Plugins for CMSimple_XH

Holger
Site Admin
Posts: 3470
Joined: Mon May 19, 2008 7:10 pm
Location: Hessen, Germany

Re: Load config and language files on demand

Post by Holger » Thu Jan 15, 2015 10:13 pm

Hmm, good idea, even if I'm happy with the performance of 1.6.x, it's better (or best?) practise to load the configs only on demand.

But I would suggest another option:

Code: Select all

function getConfig($plugin, $configFiles)
{
    global $plugin_cf, $pth;

    if(count($configFiles == 0)) {
        $configFiles = array('/config/config.php', '/config/defaultconfig.php', .....)
    }

    if (!isset($plugin_cf[$plugin])) {
       foreach($configFiles as $configFile) {
          include($pth['folder']['plugins'] . $plugin . $pluginFile;
       }
    }
}
That would allow plugins to split their configuration over more than one file, given in the array $configFiles. For example consider a plugin like a gallery: config.php holds only global options like the folder configuration and so on. Every single gallery gets his own config-file with local settings like the size of the thumbnails for example. Those gallery-based config files could be easy managed with the new FileEdit class and stored in a folder together with the images.
And, BTW, some plugins have really a lot of config options that it seems to be a good idea to me to split them over more than one form...

I'm not sure if getConfig() should load the language file too, or if it's better to provide another function for that :?. Because sometimes translations are only necessary for the admin part.
cmb wrote:The new API could already be delivered by a utility plugin/addon, what would provide backward compatibility with older CMSimple(_XH) versions
Someday we must break with compatibility or it'll never end -- like the still present PHP4 compatibility.
So I'll suggest to do it the other way around: add the new API to the core and provide a "migrate" plugin for backward compatibility.
But in both cases we should not forget that we've changed the order the files get loaded with 1.6 AFAIK. So a plugin that, uses another plugin, could access the whole config of all installed plugins. I'm not sure how to provide that by a plugin.

cmb
Posts: 14225
Joined: Tue Jun 21, 2011 11:04 am
Location: Bingen, RLP, DE
Contact:

Re: Load config and language files on demand

Post by cmb » Fri Jan 16, 2015 12:52 am

Holger wrote:But I would suggest another option:
[ code ]
What bothers me with this suggestion is that we won't make a first step to get rid of the global variables $plugin_cf and $plugin_tx. I have not pointed that out in the OP, but it seems to me this is really important in the long run. Global state is generally an issue, but global variables have to be avoided, because they offer no abstraction (you can't rename them, change their representation, etc., because some other component might rely on them; heck, you can't even trigger a deprecated notice!) At least getConfig() should return the configuration array of the plugin, IMO, and plugins should be rewritten over time to avoid accessing $plugin_cf/$plugin_tx.
Holger wrote:For example consider a plugin like a gallery: config.php holds only global options like the folder configuration and so on. Every single gallery gets his own config-file with local settings like the size of the thumbnails for example. Those gallery-based config files could be easy managed with the new FileEdit class and stored in a folder together with the images.
Most likely you would use the same keys for every single gallery configuration, so loading the configurations of multiple galleries would not be possible. It seems to me that is rather restrictive, but okay, it's optional so I'm not opposed to it.
Holger wrote:And, BTW, some plugins have really a lot of config options that it seems to be a good idea to me to split them over more than one form...
That's surely something to consider. The drawback is likely to be performance, because supposedly it is faster to read a single large config file instead of multiple small ones. Of course, the same holds for PHP code files, but byte code caches would solve this issue, and due to the inclusion of OPcache in the PHP distribution I'm optimistic that it will be widely available on shared hosting in the not too distant future. As long as config/language files will be PHP files, those will be also cached, but I'm not convinced that this is the best format with regard to file locking (see XH_includeVar).
Holger wrote:Someday we must break with compatibility or it'll never end -- like the still present PHP4 compatibility.
So I'll suggest to do it the other way around: add the new API to the core and provide a "migrate" plugin for backward compatibility.
Seems reasonable.
Holger wrote:But in both cases we should not forget that we've changed the order the files get loaded with 1.6 AFAIK.
Yes. All config/language files are loaded before index/admin.php since XH 1.6.
Holger wrote:So a plugin that, uses another plugin, could access the whole config of all installed plugins.
Yes. However, I don't think it is a good idea to access the configuration of another plugin directly, because IMO the configuration should be regarded as private data, with the core and perhaps very special plugins acting as friends. If there is the need to access the configuration of another plugin, this plugin should offer some API to do so.
Holger wrote:I'm not sure how to provide that by a plugin.
All required_classes.php files are loaded before the config/language files, so these could be (mis)used, if necessary.
Christoph M. Becker – Plugins for CMSimple_XH

manu
Posts: 1086
Joined: Wed Jun 04, 2008 12:05 pm
Location: St. Gallen - Schweiz
Contact:

Re: Load config and language files on demand

Post by manu » Sat Jan 17, 2015 11:57 am

cmb wrote:Another more object-oriented possibility would be to define a respective method in an abstract base class from which a plugin class could inherit[1]:
...
However, I assume that many plugin developers don't want to be forced to using classes, so a procedural API or one based on helper classes is likely the way to go for XH 1.7.
and don't forget Autoloading.

cmb
Posts: 14225
Joined: Tue Jun 21, 2011 11:04 am
Location: Bingen, RLP, DE
Contact:

Re: Load config and language files on demand

Post by cmb » Sat Jan 17, 2015 12:39 pm

manu wrote:
cmb wrote:Another more object-oriented possibility would be to define a respective method in an abstract base class from which a plugin class could inherit[1]:
...
However, I assume that many plugin developers don't want to be forced to using classes, so a procedural API or one based on helper classes is likely the way to go for XH 1.7.
and don't forget Autoloading.
Yes, indeed, a good reason to use objects instead of purely procedural code, but not necessarily something that will be enforced. Or do you suggest to require it in the long run (maybe for XH 2.0)? I'm afraid that wouldn't go down particularly well.
Christoph M. Becker – Plugins for CMSimple_XH

cmb
Posts: 14225
Joined: Tue Jun 21, 2011 11:04 am
Location: Bingen, RLP, DE
Contact:

Re: Load config and language files on demand

Post by cmb » Fri Dec 09, 2016 12:11 pm

Note the closely related (well, somehow it's a duplicate) suggestion to make use of ArrayAccess.
Christoph M. Becker – Plugins for CMSimple_XH

Post Reply