Posted by setvik on April 17, 2011 at 6:47am
3 followers
| Project: | Skinr |
| Version: | 6.x-1.x-dev |
| Component: | Code |
| Category: | bug report |
| Priority: | normal |
| Assigned: | Unassigned |
| Status: | needs review |
Issue Summary
_system_theme_data() reads theme files from the disk and executes drupal_alter.
On a system with many modules and/or themes this adds a performance hit.
Replacing _system_theme_data() with a DB read of the system table (as done in common.inc's list_themes()) can greatly improve performance.
$result = db_query("SELECT * FROM {system} WHERE type = '%s'", 'theme');
while ($theme = db_fetch_object($result)) {
if (file_exists($theme->filename)) {
$theme->info = unserialize($theme->info);
$themes[] = $theme;
}
}is around 40-50x faster than
_system_theme_data()Patch follows.
Comments
#1
#2
Refer #1
I like it: +1 rating
Good lateral thinking setvik
I had several issues with the
private _system_theme_data()methodused in skinr 6.x-1.x-dev
#3
Also see #943782: _system_theme_data() causes PHP notices, but system_theme_data() causes themes to be disabled on update
#4
I have updated your patch in #1:
I was getting PHP E-Notices: ==>
Notice: Trying to get property of non-object in system_find_base_themes()New code (below):
<?php
/**
* Helper function to load theme data
* Code borrowed from list_themes().
*
* If the database is active then it will be retrieved from the database.
* Otherwise it will retrieve a new list.
*
* @return
* An array of the currently available themes.
*/
function _skinr_get_theme_data() {
static $themes = array();
if (empty($themes)) {
$themes = array();
// Extract from the database only when it is available.
// Also check that the site is not in the middle of an install or update.
if (db_is_active() && !defined('MAINTENANCE_MODE')) {
$result = db_query("SELECT * FROM {system} WHERE type = '%s'", 'theme');
while ($theme = db_fetch_object($result)) {
if (file_exists($theme->filename)) {
$theme->info = unserialize($theme->info);
$themes[] = $theme;
}
}
}
else {
// Scan the installation when the database should not be read.
$themes = _system_theme_data();
}
foreach ($themes as $theme) {
foreach ($theme->info['stylesheets'] as $media => $stylesheets) {
foreach ($stylesheets as $stylesheet => $path) {
$theme->stylesheets[$media][$stylesheet] = $path;
}
}
foreach ($theme->info['scripts'] as $script => $path) {
if (file_exists($path)) {
$theme->scripts[$script] = $path;
}
}
if (isset($theme->info['engine'])) {
$theme->engine = $theme->info['engine'];
}
if (isset($theme->info['base theme'])) {
$theme->base_theme = $theme->info['base theme'];
}
// Status is normally retrieved from the database. Add zero values when
// read from the installation directory to prevent notices.
if (!isset($theme->status)) {
$theme->status = 0;
}
$themes[$theme->name] = $theme;
}
}
return $themes;
}
?>
I no longer see PHP 5.3.x 'E-Notice' reports via Pressflow 6.22.