Currently, before returning the list of themes, the list_themes() function does a file_exists() check on each theme's .info file. If the file doesn't exist, it removes the theme from the returned list.

Issues:

  1. This code is called on every non-cached page request, and can't be great for performance (especially since it calls it for every theme on your site, even disabled ones).
  2. Imagine some sporadic error that causes file_exists() to return FALSE (filesystem glitch, whatever - i.e. if the files are temporarily unreadable). Then any code that runs on that page request which calls list_themes() will assume your theme simply does not exist. That can have unintended consequences. For example, if you are visiting the block configuration page on that request (or clearing caches, etc), _block_rehash() will run and will disable all blocks for the theme, which isn't good.

    Note that we've seen this "all blocks get disabled" bug on rare occasions in Drupal Gardens and don't know exactly what causes it, but suspect this might be the root cause. (I also have a patch at #925360: Block module sometimes disables all blocks (root cause not yet found) to treat the symptom.)

  3. Finally, there is really no fundamental reason why list_themes() should check that the theme data in the database is consistent with the filesystem. Code that needs to make sure that it is getting the latest data from the filesystem should already be calling (and does call) system_rebuild_theme_data() instead.

It looks like this file_exists() check has been around since at least Drupal 4.6, so it may be that it served a purpose a long time ago but no longer does.

The attached patch simply removes it.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

pwolanin’s picture

Status: Needs review » Reviewed & tested by the community

This make a lot of sense. We should hunt down and kill more such unneeded checks.

effulgentsia’s picture

Status: Reviewed & tested by the community » Needs review
Issue tags: +API change

RTBC +1. Given that the file_exists() has existed for so long, I believe it's legacy cruft rather than anything currently needed, and I fully agree with all points in the OD, and I think the first one is reason enough to do it: file_exists() is not always cheap, especially on network file systems under heavy load. It's possible this will cause a regression, so this change should be announced to the dev list, which is why I'm giving it the "API change" tag, even though this isn't technically an API change. But any such regression is indicative of faulty calling code, and can be fixed with something more appropriate, as per point 3 in the OD.

effulgentsia’s picture

Status: Needs review » Reviewed & tested by the community

x-post.

Damien Tournoud’s picture

Oh my. +1 here as well

ksenzee’s picture

Yes please. We should probably grep for file_exists and see just how much legacy cruft there is.

sun’s picture

That entire function needs an overhaul, and I'll do that ASAP, but this patch is ready to go.

sun’s picture

Version: 7.x-dev » 8.x-dev

Although badly needed, this is D8 material according to the rules (I had to learn today).

David_Rothstein’s picture

Version: 8.x-dev » 7.x-dev

As @effulgentsia said above, the extent to which this is actually an "API change" is extremely tiny and probably nonexistent. Anyone who somehow relied on this behavior had a bug in their calling code to begin with...

Moving back to D7 for consideration.

Dries’s picture

Status: Reviewed & tested by the community » Fixed

Calling this an API change is a bit of a stretch, IMO. Committed to CVS HEAD. Thanks.

rfay’s picture

Sounds like no API change announcement is required from what I read. Let me know if otherwise.

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

c960657’s picture