drupal_get_filename returns a different set of results (or rather returns results or doesn't return results) depending on the case that it falls into.
Before the db is active, if a call to drupal_get_path exists, elements falling into the else clause return results _iff_ it is a module and only in situations more apt for Drupal 4 than Drupal 6:
sites/{sitename}/modules/{modulename}.module
sites/{sitename}/modules/{modulename}/{modulename}.module
modules/{modulename}.module
modules/{modulename}/{modulename}.module
Since most modules now go into sites/all/modules rather than sites/{sitename} or /modules, (and since modules are placed in folders inside of the modules directory instead of placed in the modules directory parent) it seems to make sense to modify this logic.
The primary fault (and the way to reproduce this error) is when using a profile to install modules that have a call to drupal_get_path in the install files. CCK in particular has a call to drupal_get_path at the beginning of most of the .install files and therefore cannot install correctly via a profile.
Since both modules and themes support .info files at this point, I chose to search for {filename}.info so that it would correctly find both modules & themes (mirroring what you would find in the system table that would be hit if the db were active). This modifies the return of the else case in many situations, but I believe it is more accurate not less accurate.
Thoughts?
Comment | File | Size | Author |
---|---|---|---|
#14 | 241086_bootstrap_inc_get_filename.patch | 1.35 KB | Senpai |
#10 | bootstap.inc-get_filename-patch.txt | 1.32 KB | csevb10 |
#9 | drupal-HEAD-241086.patch | 1.68 KB | Steven Jones |
bootstap.inc-get_filename-patch.txt | 1.02 KB | csevb10 |
Comments
Comment #1
floretan CreditAttribution: floretan commentedThe patch looks good, and removes some code duplication in drupal_get_filename() by calling drupal_system_listing() instead of doing the check for the possible locations directly. I haven't tested this fix in a situation where drupal_get_filename() is called before the database is set up, but in all other cases the patched function behaves just like the original.
I didn't find any existing tests for this function, having some would be very helpful in this case.
Moving to 7.x, and we can backport this to 6.x later.
Comment #2
Steven Jones CreditAttribution: Steven Jones commentedBy using drupal_system_listing which is in common.inc, you've made this function dependant on that include, and therefore if we don't have a database active, unusable until
DRUPAL_BOOTSTRAP_FULL
.I'm going to set as code needs work because either you need to run a function_exists to make sure you can call drupal_system_listing or you need to provide a further fallback in drupal_get_filename as well, if we're before
DRUPAL_BOOTSTRAP_FULL
.Comment #3
csevb10 CreditAttribution: csevb10 commentedI thought the same thing, but I can't find a situation where this function is called without common.inc being included. During the install process, common.inc is included, and once things are up and running, you're doing a full bootstrap, so common.inc is included. If you can give me an example of a case that I should protect against, that'd be supremely helpful. I, of course, can check for the function, but if the case never fails then it's sort of unwarranted overhead.
Also, the current system fails completely when it has to drop to this case for drupal_get_path, and this at least provides some functionality for that case that wasn't covered before. I want to cover the full scope of cases, but if we look at this as an incremental step, it seems like movement in the correct direction. That being said, if there are use-cases where this function gets called without common.inc being included, I would love to cover those cases.
Comment #4
floretan CreditAttribution: floretan commentedChanging title to reflect the real problem. From the original issue:
If install profiles cannot use CCK, that's a big limitation on their use cases, so I'm also bumping this to critical.
Comment #5
Senpai CreditAttribution: Senpai commentedTested on a 7.x-dev, fully updated, and no existing database. I have fresh head checkouts of Views, CCK, and Admin_menu in my sites/all/contrib/ directory because they're required by the install profile I'm testing with.
Without the patch, I went to use an install profile, and got this error, proving that the installation bug in http://drupal.org/node/210752 hasn't been fixed yet.
I can't proceed with this test until I get that thing sorted out, and when I do, I'll be sure to post some more details on the afore mentioned thread 210752.
Comment #6
Senpai CreditAttribution: Senpai commentedI accidentally changed the status. Setting back to critical.
Comment #7
Senpai CreditAttribution: Senpai commentedComment #8
Steven Jones CreditAttribution: Steven Jones commented@csevb10 Okay, well we're fixing a serious bug here, and are worrying about some serious edge cases. Can you reroll a patch so that drupal_get_filename will first check for the database, then if that fails, do a function_exists for drupal_system_listing, and use that but, but if that fails, then it falls back to the old way, but add some more paths too.
That should cover most of the edge cases no? And still provide the updated functionality. The function is already built using failover, so it's more of an extension to the current functionality anyway.
Comment #9
Steven Jones CreditAttribution: Steven Jones commentedSomething like this.
Comment #10
csevb10 CreditAttribution: csevb10 commentedThat's a fair point. 'tis core code and all. :-P
Here's a slightly tighter version, I think, a little less code duplication.
Comment #11
lilou CreditAttribution: lilou commentedPatch still applies.
Comment #12
Anonymous (not verified) CreditAttribution: Anonymous commentedThe last submitted patch failed testing.
Comment #13
SebCorbin CreditAttribution: SebCorbin commentedUsing 6.12, this problem is not fixed yet, waiting for a patch please.
Comment #14
Senpai CreditAttribution: Senpai commentedChasing HEAD. Patch looks good.
This patch could use a test or two, but for what?
A) Check to see if the $files[$type][$name] array is populated with recognizable strings?
B) See if function_exists('drupal_system_listing') is coming back TRUE so we don't accidentally add things that break core later? (since there's no calls that fail right now)
C) ...
Comment #15
Senpai CreditAttribution: Senpai commentedLets see if the TestBot likes it...
Comment #17
Senpai CreditAttribution: Senpai commentedOdd, HEAD installs perfectly for me with this patch applied. Don't know what the problem is.
Comment #19
Senpai CreditAttribution: Senpai commentedAhh, the install.php is failing due to a
Warning: preg_match() [/www/manual_php/function.preg-match.html]: Delimiter must not be alphanumeric or backslash in /www/drupalhead/includes/file.inc on line 1652
error.Comment #20
sun.core CreditAttribution: sun.core commentedNot sure whether this is still an issue at all.
Comment #21
David Stosik CreditAttribution: David Stosik commentedHello,
I don't know if this has been solved in Drupal 7, but in Drupal 6, when using drupal_get_path during the execution of an installation profile, it looks in sites/default (where it won't find any of my modules).
Maybe it should also search inside sites/all ?
Regards,
David
Comment #22
duellj CreditAttribution: duellj commentedThis has been fixed in D7, but make sure if you are trying to get the path of a profile, use the type 'module'. The docblock for drupal_get_path should probably be updated, because currently it says:
which implies that you can use 'profile' for the $type param, which doesn't work.
Comment #23
Steven Jones CreditAttribution: Steven Jones commentedA related issue in D7 is being looked at here: #1006714: drupal_get_path doesn't work for profiles
Comment #24
quicksketchThis is a different issue than the one being described here. This issue is about drupal_get_path() not working in install profiles (because it requires a database connection I believe). The issue you're describing is the one Steven Jones pointed to in #1006714: drupal_get_path doesn't work for profiles, where profiles can't be *located* using drupal_get_path(), not that they can't actually use the function.