It should not be necessary to copy image toolkit include files into the /includes directory. Some image toolkits are shipped with a module (for example, the Image module includes the ImageMagick image toolkit), and enabling this toolkit should be as easy as enabling the module and then going to the image toolkit administration page to select the new toolkit.
I have provided an implementation that allows image toolkit include files to be identified in a module's .info file. This scheme leverages the new registry functionality and reduces the administration effort required to get a new image toolkit deployed.
During testing I used the Image module as my example and made the following additions to its .info file:
files[] = image.module
files[] = image.admin.inc
files[] = image.imagemagick.inc
files[] = views.inc
image_toolkit[] = image.imagemagick.inc
The last line identifies the image.imagemagick.inc file as an image toolkit. Simply by enabling this module, the image.imagemagick.inc toolkit becomes an option on the image toolkits menu.
Comment | File | Size | Author |
---|---|---|---|
#38 | changelog-270508-38.patch | 702 bytes | cburschka |
#36 | changelog-270508-36.patch | 697 bytes | dropcube |
#34 | changelog-270508-34.patch | 684 bytes | dropcube |
#32 | changelog-270508.patch | 688 bytes | dropcube |
#22 | image_toolkit_270508_22.patch | 19.36 KB | pwolanin |
Comments
Comment #1
paul.lovvik CreditAttribution: paul.lovvik commentedAnd here is the patch.
Comment #2
pwolanin CreditAttribution: pwolanin commentedWe should coordinate a little this patch with the broader issue: http://drupal.org/node/259103
Comment #3
pwolanin CreditAttribution: pwolanin commentedminor code suggestion:
instead of doing this:
maybe you should just select the filename in the query too? since if you trace through what drupal_get_path() is doing, it's just calling dirname() on the filename field from {system}.
Of course, maybe it's beeter to continue to use the API in case that changes.
Comment #4
Dries CreditAttribution: Dries commentedI don't know (yet) how often
_get_toolkits_from_module_info()
would get called but it seems like a hook-based approach could yield better performance. Right now, it takes an SQL query and a lot of unserialization -- both are expensive. If_get_toolkits_from_module_info()
gets called on every page view, that would be a problem IMO. I guess there could exist situations where_get_toolkits_from_module_info()
gets called a lot ... ?Comment #5
pwolanin CreditAttribution: pwolanin commented@Dries - currently it is not called often. I discussed with Paul the alternatives between a module hook and the .info file. My suggestion to go this way was based on the idea that we may be moving towards modules that don't require a .module file. http://drupal.org/node/259412 So, I'm not sure what the tradeoff is between load/parse a file vs. this? I guess if you are running with an opcode cache the module hook would be faster?
Comment #6
paul.lovvik CreditAttribution: paul.lovvik commented@pwolanin - I think this functionality is orthogonal to the choice of whether pluggable toolkits should be implemented using federated function names or OOP. In fact, no matter how pluggable toolkits are implemented the same problem will arise. Specifically, that all such pluggable toolkits should be able to be deployed without moving files into Drupal's /includes directory.
Comment #7
pwolanin CreditAttribution: pwolanin commented@paul.lovick - yes, I agree that this problem will need to be solved for all toolkit/framework types. Probably it would make sense to get this patch in and then consider subsequently the question of standardizing the approach used by toolkits/frameworks
Comment #8
paul.lovvik CreditAttribution: paul.lovvik commented@Dries - pwolanin is correct in that _get_toolkits_from_module_info() is not called often. It is currently only called from image_get_available_toolkits, which is only called from system_image_toolkit_settings(). Therefore it would only be used if a user went to the toolkit selection page, which I expect would only be available to administrators and used very infrequently.
Also, if my patch to improve the user experience of setting up the Image module is approved (http://drupal.org/node/267489) image_get_available_toolkits would be called when the status report is displayed as well.
On my system (stock Drupal 7 + Image module) it takes 68 ms to execute the _get_toolkits_from_module_info() function. This is pretty fast, but I expect that time would increase with a very large database.
I will implement it with a module hook and compare the timing.
Comment #9
paul.lovvik CreditAttribution: paul.lovvik commentedI reworked the patch to use a module hook instead. This improved the performance significantly:
* 4.2ms for the first execution
* 0.24ms for subsequent executions
It is definitely worth using the hook approach instead. Here is the new patch.
Comment #10
Dries CreditAttribution: Dries commentedI agree that the hook-based approach is better.
I'd be happy to remove the "copy your toolkit into ./includes" mechanism. Is there a good reason to maintain backward compatibility? We can probably count the number of image toolkits on two fingers so I recommend that we try to clean this up as much as we can (if possible). Cleaning things up makes it easier to explain/document in books, workshops, etc -- and will make things a tad faster.
Comment #11
paul.lovvik CreditAttribution: paul.lovvik commentedAs far as backward compatibility, we have to be careful not to break the gd image toolkit. This one ships in Drupal core and is in the /includes directory, not associated with any module (at least not that I am aware of).
We could either keep it the way it is so gd continues to work unmodified, or we could associate the gd image toolkit with one of the core required modules. I was thinking we would leave it the way it is for the gd toolkit, but I'm definitely open to any guidance there.
Comment #12
Crell CreditAttribution: Crell commentedI am about 70% of the way through writing an RFC on a pluggable framework for D7. It will be posted to the planet hopefully later tonight. The image system is one of the subsystems I consider a target. :-)
Comment #13
pwolanin CreditAttribution: pwolanin commented@Cell - look forward to reading it, though I think a simple re-write with procedural code is going to be a lot less pain than other options...
Comment #14
Dries CreditAttribution: Dries commented@Crell, I agree with pwolanin that it is going to be pretty hard to beat this patch in terms of simplicity.
@paul, associating the GD image toolkit with the system module _might_ be a good idea. There are other special cases in system.module. It's worth thinking about some more.
Comment #15
Dries CreditAttribution: Dries commented@Crell, Paul, pwolanin: I think we should go ahead with Paul's patch, or a simplification of that. Let's not block this by creating dependencies.
@Crell: propose the pluggable framework as a separate patch on top of this one. It will put us in a better position to compare both.
Comment #16
Crell CreditAttribution: Crell commented@Dries: RFC has been posted to the planet and dev list.
We certainly could go forward with this patch for now and convert later when/if it makes sense to. I just wonder if that will be more work in the long run, and if that's worth it. I will not block such an effort, however.
Comment #17
drewish CreditAttribution: drewish commentedThis seems pretty similar to #140932: Improve image-api: Image toolkits should be implemented as modules.. The change would allow you to create an imagemagick module that just implements the hook and points to its .inc file. Then the toolkit could implement hook_requirements and make use of the update status notifications.
That said I think I'd rather have all the toolkits as modules so GD isn't a special case.
Comment #18
pwolanin CreditAttribution: pwolanin commentedOne minor comment - looks like you could be using module_invoke_all to simplify this code:
http://api.drupal.org/api/function/module_invoke_all/7
like:
Comment #19
paul.lovvik CreditAttribution: paul.lovvik commentedI thought about using module_invoke_all, but I need the names of the modules as well as the toolkit include file, or the full path to the include file. I could make the return type more complex to also include the module name, but in either case it doesn't seem worthwhile to make the endpoints more complicated to simplify the core code.
I think we should be simplifying APIs as much as possible because that keeps the barrier for contributing more great capabilities low.
Comment #20
Crell CreditAttribution: Crell commentedThat's something I ran into when adding the page split functionality to the D6 menu system. module_invoke_all() is only useful if you don't care what modules returned what. If you do, you have to do it manually. Sounds like that's a worthwhile feature addition of some kind. It's also a separate issue from this patch, so it's probably best to go with the manual method for now and refactor later when/if we have a module_invoke_all_with_name() of some kind. (That would be a bad implementation, but you get the idea.)
Comment #21
paul.lovvik CreditAttribution: paul.lovvik commentedHere is a new patch that moves the image.gd.inc file into the modules/system directory and locates this toolkit the same as any other contributed image toolkit.
Any feedback is greatly appreciated.
Comment #22
pwolanin CreditAttribution: pwolanin commentedI think this can actually be simplified - we can indeed use module_invoke_all(), unless I'm missing something, since drupal_function_exists() will find the include file based on the registry.
One minor question - should we hack the repository to retain the revision history for image.gd.inc?
Comment #23
Crell CreditAttribution: Crell commentedI'm against hacking the repository. Every time we do that, it makes it harder to ever do anything but CVS, and our specific customized CVS repository in particular. If someone is really tracing back the history of that file (how often does that happen over a long term?), they'll note that it disappeared and reappeared somewhere else between two given revisions and know to start looking there. No big deal, as long as there are no changes to the file at the same time (thus eliminating the need to diff between the two files).
Comment #24
pwolanin CreditAttribution: pwolanin commentedthere are no changes - it's a simple move.
Comment #25
Dries CreditAttribution: Dries commentedCommitted to CVS HEAD. I didn't move the file because that would make it impossible to check out a DRUPAL-5 or DRUPAL-6 branch, AFAIK.
Comment #26
xmacinfoTried this with CVS update and got this message:
I got this error while trying to load:
http://devel.drupal.cvs/admin/settings/image-toolkit
Comment #27
pwolanin CreditAttribution: pwolanin commented@xmacinfo - you need to force a registry rebuild - go to admin/settings/performance and hit the "Clear cached data" button at the bottom
Comment #28
xmacinfoDone. Thanks.
Comment #29
cburschkahook_image_toolkits should perhaps be mentioned in contributions/docs/developer/hooks/core.php. That way, it will be documented on api.drupal.org. A hook is only useful if module developers can find it...
Something like this should do it:
Comment #30
pwolanin CreditAttribution: pwolanin commented@Arancaytar - looks like you have CVS access. It would be great if you could commit any updates you see as needed - anyone with CVS can alter the developer docs. http://drupal.org/cvs?commit=126084
Comment #31
cburschkapwolanin: Oh. I'm afraid I didn't quite realize how the contrib repository works - I thought I only had commit access to the module I'm maintaining. Thanks for the info!
Comment #32
dropcube CreditAttribution: dropcube commentedThe patch adds a line to the change log file.
Comment #33
cburschkaThat line should probably be descriptive, like the other lines in the changelog.
The change is already in, so you need to say "can now be added by modules without being copied to includes/".
Comment #34
dropcube CreditAttribution: dropcube commentedWhat about this one?
Comment #35
Susurrus CreditAttribution: Susurrus commentedThe English is a little off. Maybe something like:
Comment #36
dropcube CreditAttribution: dropcube commentedOk, this patch includes Susurrus' suggestion (sorry, English is not my native language)
Comment #37
paul.lovvik CreditAttribution: paul.lovvik commentedThis text doesn't exactly describe the behavior. You can no longer include an image toolkit by copying it into the includes directory. The text should describe this a bit more explicitly. I suggest this text:
Image toolkits are added by modules and are no longer copied into the includes directory to be used.
Comment #38
cburschkaYeah, that would be it.
Comment #39
StevenPatzComment #40
Dries CreditAttribution: Dries commentedCommitted to CVS HEAD. Thanks.
Comment #41
Anonymous (not verified) CreditAttribution: Anonymous commentedAutomatically closed -- issue fixed for two weeks with no activity.