if (!class_exists($class)) { // Skip to next one continue;
}
$adapter = new $class($this, $this->_db, $options); $this->_adapters[$name] = clone $adapter;
} } } }
Adapters must be in the specific folder in order to be used. To get around that, you have to use a system plugin to call setAdapter before the adapter is to be used.
Instead, I would like to use: JPluginHelper::importPlugin('adapters'); $dispatcher = JEventDispatcher::getInstance(); $dispatcher->trigger('onAdapterLoadAdapters', $this, $options);
This would allow a plugin written to run onAdapterLoad to check the adapter class being loaded, and if it matches call setAdapter to load additional adapters.
For example, if you need an "application" package class for the installer, you could program: function onAdapterLoadAdapters($adapter, $options) { if (is_a($adapter,'JInstaller', false) { if !(class_exists('JInstallerApplication') { // Try to load the adapter object include_once $this->_basepath . '/path/to/my/adapter/application.php'; if (class_exists('JInstallerApplication') { $adapter = new JInstallerApplication($adapter, $adapter->_db, $options); $adapter->setAdapter($adapter); } } } }
By the same token, I'm adding the same functionality to: JSession for session stores. JDatabaseFactory for database drivers JCache for cache stores JCacheController for cache controllers
I wanted to see if anyone has a better suggestion for setting these up so that additional adapters/storage mechanisms can be added without having to place them in the core directories.
Note JDatabaseFactory is a bit of an oddball since the plugin system depends on the database to function..so while it would be possible to use it to load /additional/ database drivers, it can't be used to load the default database driver.. the easy way around that would be to use the old directory based plugin system for JDatabaseFactory...the cleaner way to handle it would be to specifically add the path of the default database driver to JConfig and load it so it is always available.
I'm not sure tying adapters to the plugin system (and database) is
necessarily a good idea. As you point out for JDatabase at least it's
not going to fly and the idea of hard coding the path to something
scares me. I really don't see the aversion to putting the file where
it needs to be because when you're hard coding random file paths I'm
not sure we've necessarily gained much beyond being able to put a file
anywhere and more confused support requests on the forum.
On Fri, Jul 6, 2012 at 9:25 AM, garyamort <garyam...@gmail.com> wrote:
> I'll be submitting some pull requests I've been working on this weekend and
> wanted to also get some feedback here.
> Currently, I find it a real pain to try to add "adapters" [and some related
> types] because their directory related.
> Adapters must be in the specific folder in order to be used. To get around
> that, you have to use a system plugin to call setAdapter before the adapter
> is to be used.
> Instead, I would like to use:
> JPluginHelper::importPlugin('adapters');
> $dispatcher = JEventDispatcher::getInstance();
> $dispatcher->trigger('onAdapterLoadAdapters', $this, $options);
> This would allow a plugin written to run onAdapterLoad to check the adapter
> class being loaded, and if it matches call setAdapter to load additional
> adapters.
> For example, if you need an "application" package class for the installer,
> you could program:
> function onAdapterLoadAdapters($adapter, $options)
> {
> if (is_a($adapter,'JInstaller', false) {
> if !(class_exists('JInstallerApplication') {
> // Try to load the adapter object
> include_once $this->_basepath . '/path/to/my/adapter/application.php';
> if (class_exists('JInstallerApplication') {
> $adapter = new JInstallerApplication($adapter,
> $adapter->_db, $options);
> $adapter->setAdapter($adapter);
> }
> }
> }
> }
> By the same token, I'm adding the same functionality to:
> JSession for session stores.
> JDatabaseFactory for database drivers
> JCache for cache stores
> JCacheController for cache controllers
> I wanted to see if anyone has a better suggestion for setting these up so
> that additional adapters/storage mechanisms can be added without having to
> place them in the core directories.
> Note JDatabaseFactory is a bit of an oddball since the plugin system depends
> on the database to function..so while it would be possible to use it to load
> /additional/ database drivers, it can't be used to load the default database
> driver.. the easy way around that would be to use the old directory based
> plugin system for JDatabaseFactory...the cleaner way to handle it would be
> to specifically add the path of the default database driver to JConfig and
> load it so it is always available.
In general, when subfolders are used to load adapters, adding dependency injection so that alternate locations can be defined, will increase the flexibility of the framework and prevent the need for plugins to override large, important core classes -- simply to name the location of a file.
> Adapters must be in the specific folder in order to be used. To get > around that, you have to use a system plugin to call setAdapter before the > adapter is to be used.
> Instead, I would like to use: > JPluginHelper::importPlugin('adapters'); > $dispatcher = JEventDispatcher::getInstance(); > $dispatcher->trigger('onAdapterLoadAdapters', $this, $options);
> This would allow a plugin written to run onAdapterLoad to check the > adapter class being loaded, and if it matches call setAdapter to load > additional adapters.
> For example, if you need an "application" package class for the installer, > you could program: > function onAdapterLoadAdapters($adapter, $options) > { > if (is_a($adapter,'JInstaller', false) { > if !(class_exists('JInstallerApplication') { > // Try to load the adapter object > include_once $this->_basepath . '/path/to/my/adapter/application.php'; > if (class_exists('JInstallerApplication') { > $adapter = new JInstallerApplication($adapter, > $adapter->_db, $options); > $adapter->setAdapter($adapter); > } > } > } > }
> By the same token, I'm adding the same functionality to: > JSession for session stores. > JDatabaseFactory for database drivers > JCache for cache stores > JCacheController for cache controllers
> I wanted to see if anyone has a better suggestion for setting these up so > that additional adapters/storage mechanisms can be added without having to > place them in the core directories.
> Note JDatabaseFactory is a bit of an oddball since the plugin system > depends on the database to function..so while it would be possible to use > it to load /additional/ database drivers, it can't be used to load the > default database driver.. the easy way around that would be to use the old > directory based plugin system for JDatabaseFactory...the cleaner way to > handle it would be to specifically add the path of the default database > driver to JConfig and load it so it is always available.
The problem mostly solves itself with the increasing use of autoloading. We already lost a lot of hard coded paths however JDocument is a notable exception.
Also this doesn't solve the problem of generating the list of db/session/cache handlers, we still rely on specific folders there.
> The problem mostly solves itself with the increasing use of autoloading.
> We already lost a lot of hard coded paths however JDocument is a notable
> exception.
Good point. That's been an important achievement across the board and a
good move towards flexibility.
> Also this doesn't solve the problem of generating the list of
> db/session/cache handlers, we still rely on specific folders there.
Maybe adapters should be installable/uninstallable?
On Friday, July 6, 2012 11:25:53 AM UTC-5, garyamort wrote:
> I wanted to see if anyone has a better suggestion for setting these up so > that additional adapters/storage mechanisms can be added without having to > place them in the core directories.
> Gary - as Sam pointed out, the installer can place adapters/etc into the
folders needed so that the code functions properly. Is there a technical reason or problem with installing directly into the core directories? Seems to me that should be okay.
On Sunday, July 8, 2012 2:34:04 PM UTC-4, Samuel Moffatt wrote:
> I'm not sure tying adapters to the plugin system (and database) is > necessarily a good idea. As you point out for JDatabase at least it's > not going to fly and the idea of hard coding the path to something > scares me.
Isn't that what we're already doing? :-) That's why I want to move away from it with plugins where possible.
> I really don't see the aversion to putting the file where > it needs to be because when you're hard coding random file paths I'm > not sure we've necessarily gained much beyond being able to put a file > anywhere and more confused support requests on the forum.
Well, one item I'm fiddling with is replacing various libraries and components with PHAR files. Ie instead of <rootdir>/libraries/joomla/* I use <rootdir>/libraries/joomla.phar
By requiring signatures and setting them to read only, http://www.php.net/manual/en/phar.configuration.php It blocks out completely any hacks which depend on modifying one of the php files in the archive dynamically. The PHAR file can only be replaced entirely.
It also provides an easy way to pull all the file hashes and compare them against the latest release.
Having occasionally to go through other people's installs of Joomla after they have been hacked, and check file by file to see what was changed...and was it changed by the virus, or because someone was hacking core code in the past....it makes it really attractive to me to lock all that up in a PHAR file so it is slightly harder to modify the core code and the person doing it will hopefully think half a dozen more times before doing it.
But if I do that, then anything that is locked into the core files I can't simply add a new library/adapter.
> On Friday, July 6, 2012 11:25:53 AM UTC-5, garyamort wrote:
> I wanted to see if anyone has a better suggestion for setting these up so that additional adapters/storage mechanisms can be added without having to place them in the core directories.
> Gary - as Sam pointed out, the installer can place adapters/etc into the folders needed so that the code functions properly. Is there a technical reason or problem with installing directly into the core directories? Seems to me that should be okay.
Well it does get tricky when something breaks with updates (e.g. a new method added to an interface).