diff options
author | Henry Sudhof <kellanved@phpbb.com> | 2008-07-28 14:24:37 +0000 |
---|---|---|
committer | Henry Sudhof <kellanved@phpbb.com> | 2008-07-28 14:24:37 +0000 |
commit | eda1d40861fb5a2b74e7e5ade618cc9fa83cafd1 (patch) | |
tree | 14514edf6dc3f86506779b4e8a9d183d88b4ce9c /phpBB/includes | |
parent | 6b07f206d581c1404c15875eabd73b9a3d46a826 (diff) | |
download | forums-eda1d40861fb5a2b74e7e5ade618cc9fa83cafd1.tar forums-eda1d40861fb5a2b74e7e5ade618cc9fa83cafd1.tar.gz forums-eda1d40861fb5a2b74e7e5ade618cc9fa83cafd1.tar.bz2 forums-eda1d40861fb5a2b74e7e5ade618cc9fa83cafd1.tar.xz forums-eda1d40861fb5a2b74e7e5ade618cc9fa83cafd1.zip |
Okay. Frozen, we never said anything about it being permafrost. Also, this is not 100% tested, expect troubel with store_db (I'm waiting for the bug reports)
git-svn-id: file:///svn/phpbb/branches/phpBB-3_0_0@8697 89ea8834-ac86-4346-8a33-228a782c2dd0
Diffstat (limited to 'phpBB/includes')
-rw-r--r-- | phpBB/includes/acp/acp_styles.php | 506 | ||||
-rw-r--r-- | phpBB/includes/bbcode.php | 15 | ||||
-rw-r--r-- | phpBB/includes/functions_template.php | 6 | ||||
-rw-r--r-- | phpBB/includes/session.php | 2 | ||||
-rw-r--r-- | phpBB/includes/template.php | 129 |
5 files changed, 575 insertions, 83 deletions
diff --git a/phpBB/includes/acp/acp_styles.php b/phpBB/includes/acp/acp_styles.php index dd5255f755..fb146ad858 100644 --- a/phpBB/includes/acp/acp_styles.php +++ b/phpBB/includes/acp/acp_styles.php @@ -93,6 +93,17 @@ version = {VERSION} parse_css_file = {PARSE_CSS_FILE} '; + $this->template_cfg .= ' +# Some configuration options + +# +# You can use this function to inherit templates from another template. +# The template of the given name has to be installed. +# Templates cannot inherit from inheriting templates. +# +inherit_from = {INHERIT_FROM} +'; + $this->imageset_keys = array( 'logos' => array( 'site_logo', @@ -670,6 +681,11 @@ parse_css_file = {PARSE_CSS_FILE} { global $phpbb_root_path, $phpEx, $config, $db, $cache, $user, $template, $safe_mode; + if (defined('DISABLE_ACP_EDITOR')) + { + trigger_error($user->lang['EDITOR_DISABLED'] . adm_back_link($this->u_action)); + } + $this->page_title = 'EDIT_TEMPLATE'; $filelist = $filelist_cats = array(); @@ -729,13 +745,14 @@ parse_css_file = {PARSE_CSS_FILE} // If it's not stored in the db yet, then update the template setting and store all template files in the db if (!$template_info['template_storedb']) { - $sql = 'UPDATE ' . STYLES_TEMPLATE_TABLE . ' - SET template_storedb = 1 - WHERE template_id = ' . $template_id; - $db->sql_query($sql); - - $filelist = filelist("{$phpbb_root_path}styles/{$template_info['template_path']}/template", '', 'html'); - $this->store_templates('insert', $template_id, $template_info['template_path'], $filelist); + if ($this->get_super('template', $template_id)) + { + $this->store_in_db('template', $super['template_id']); + } + else + { + $this->store_in_db('template', $template_id); + } add_log('admin', 'LOG_TEMPLATE_EDIT_DETAILS', $template_info['template_name']); $additional .= '<br />' . $user->lang['EDIT_TEMPLATE_STORED_DB']; @@ -975,17 +992,30 @@ parse_css_file = {PARSE_CSS_FILE} $filemtime = array(); if ($template_row['template_storedb']) { - $sql = 'SELECT template_filename, template_mtime - FROM ' . STYLES_TEMPLATE_DATA_TABLE . " - WHERE template_id = $template_id"; - $result = $db->sql_query($sql); - - $filemtime = array(); - while ($row = $db->sql_fetchrow($result)) + $ids = array(); + if (isset($template_row['template_inherits_id']) && $template_row['template_inherits_id']) { - $filemtime[$row['template_filename']] = $row['template_mtime']; + $ids[] = $template_row['template_inherits_id']; + } + $ids[] = $template_row['template_id']; + + $filemtime = array(); + $file_template_db = array(); + + foreach ($ids as $id) + { + $sql = 'SELECT template_filename, template_mtime + FROM ' . STYLES_TEMPLATE_DATA_TABLE . " + WHERE template_id = $id"; + $result = $db->sql_query($sql); + + while ($row = $db->sql_fetchrow($result)) + { + $filemtime[$row['template_filename']] = $row['template_mtime']; + $file_template_db[$row['template_filename']] = $id; + } + $db->sql_freeresult($result); } - $db->sql_freeresult($result); } // Get a list of cached template files and then retrieve additional information about them @@ -1006,14 +1036,39 @@ parse_css_file = {PARSE_CSS_FILE} { continue; } + + $file_tpl = "{$phpbb_root_path}styles/{$template_row['template_path']}/template/$tpl_file.html"; + $inherited = false; + + if (isset($template_row['template_inherits_id']) && $template_row['template_inherits_id']) + { + if (!$template_row['template_storedb']) + { + if (!file_exists($file)) + { + $file_tpl = "{$phpbb_root_path}styles/{$template_row['template_inherit_path']}/template/$tpl_file.html"; + $inherited = true; + } + } + else + { + if ($file_template_db[$file . '.html'] == $template_row['template_inherits_id']) + { + $file_tpl = "{$phpbb_root_path}styles/{$template_row['template_inherit_path']}/template/$tpl_file.html"; + $inherited = true; + } + } + } + $template->assign_block_vars('file', array( 'U_VIEWSOURCE' => $this->u_action . "&action=cache&id=$template_id&source=$file", 'CACHED' => $user->format_date(filemtime("{$phpbb_root_path}cache/$filename")), 'FILENAME' => $file, + 'FILENAME_PATH' => $file_tpl, 'FILESIZE' => sprintf('%.1f ' . $user->lang['KIB'], filesize("{$phpbb_root_path}cache/$filename") / 1024), - 'MODIFIED' => $user->format_date((!$template_row['template_storedb']) ? filemtime("{$phpbb_root_path}styles/{$template_row['template_path']}/template/$tpl_file.html") : $filemtime[$file . '.html'])) + 'MODIFIED' => $user->format_date((!$template_row['template_storedb']) ? filemtime($file_tpl) : $filemtime[$file . '.html'])) ); } unset($filemtime); @@ -1517,6 +1572,18 @@ parse_css_file = {PARSE_CSS_FILE} break; } + if ($mode === 'template' && ($conflicts = $this->check_inheritance($mode, $style_id))) + { + $l_type = strtoupper($mode); + $msg = $user->lang[$l_type . '_DELETE_DEPENDENT']; + foreach ($conflicts as $id => $values) + { + $msg .= '<br />' . $values['template_name']; + } + + trigger_error($msg . adm_back_link($this->u_action), E_USER_WARNING); + } + $l_prefix = strtoupper($mode); $sql = "SELECT $sql_select @@ -2218,51 +2285,38 @@ parse_css_file = {PARSE_CSS_FILE} if ($style_row['template_storedb'] != $store_db) { - if (!$store_db && !$safe_mode && @is_writable("{$phpbb_root_path}styles/{$style_row['template_path']}/template")) + if ($super = $this->get_super($mode, $style_row['template_id'])) { - $sql = 'SELECT * - FROM ' . STYLES_TEMPLATE_DATA_TABLE . " - WHERE template_id = $style_id"; - $result = $db->sql_query($sql); - - while ($row = $db->sql_fetchrow($result)) + $error[] = (sprintf($user->lang["{$l_type}_INHERITS"], $super['template_name'])); + $sql_ary = array(); + } + else + { + if (!$store_db && !$safe_mode && @is_writable("{$phpbb_root_path}styles/{$style_row['template_path']}/template")) { - if (!($fp = @fopen("{$phpbb_root_path}styles/{$style_row['template_path']}/template/" . $row['template_filename'], 'wb'))) + $err = $this->store_in_fs('template', $style_row['template_id']); + if ($err) { - $store_db = 1; - $error[] = $user->lang['EDIT_TEMPLATE_STORED_DB']; - break; + $error += $err; } - - fwrite($fp, $row['template_data']); - fclose($fp); } - $db->sql_freeresult($result); - - if (!$store_db) + else if ($store_db) { + $this->store_in_db('template', $style_row['template_id']); + } + else + { + // We no longer store within the db, but are also not able to update the file structure + // Since the admin want to switch this, we adhere to his decision. But we also need to remove the cache $sql = 'DELETE FROM ' . STYLES_TEMPLATE_DATA_TABLE . " WHERE template_id = $style_id"; $db->sql_query($sql); } - } - else if ($store_db) - { - $filelist = filelist("{$phpbb_root_path}styles/{$style_row['template_path']}/template", '', 'html'); - $this->store_templates('insert', $style_id, $style_row['template_path'], $filelist); - } - else - { - // We no longer store within the db, but are also not able to update the file structure - // Since the admin want to switch this, we adhere to his decision. But we also need to remove the cache - $sql = 'DELETE FROM ' . STYLES_TEMPLATE_DATA_TABLE . " - WHERE template_id = $style_id"; - $db->sql_query($sql); - } - $sql_ary += array( - 'template_storedb' => $store_db, - ); + $sql_ary += array( + 'template_storedb' => $store_db, + ); + } } break; } @@ -2312,6 +2366,16 @@ parse_css_file = {PARSE_CSS_FILE} $db->sql_freeresult($result); } } + + + if ($mode == 'template') + { + $super = array(); + if (isset($style_row[$mode . '_inherits_id']) && $style_row['template_inherits_id']) + { + $super = $this->get_super($mode, $style_row['template_id']); + } + } $this->page_title = 'EDIT_DETAILS_' . $l_type; @@ -2323,8 +2387,10 @@ parse_css_file = {PARSE_CSS_FILE} 'S_THEME' => ($mode == 'theme') ? true : false, 'S_IMAGESET' => ($mode == 'imageset') ? true : false, 'S_STORE_DB' => (isset($style_row[$mode . '_storedb'])) ? $style_row[$mode . '_storedb'] : 0, + 'S_STORE_DB_DISABLED' => (isset($style_row[$mode . '_inherits_id'])) ? $style_row[$mode . '_inherits_id'] : 0, 'S_STYLE_ACTIVE' => (isset($style_row['style_active'])) ? $style_row['style_active'] : 0, 'S_STYLE_DEFAULT' => (isset($style_row['style_default'])) ? $style_row['style_default'] : 0, + 'S_SUPERTEMPLATE' => (isset($style_row[$mode . '_inherits_id']) && $style_row[$mode . '_inherits_id']) ? $super['template_name'] : 0, 'S_TEMPLATE_OPTIONS' => ($mode == 'style') ? $template_options : '', 'S_THEME_OPTIONS' => ($mode == 'style') ? $theme_options : '', @@ -2682,6 +2748,7 @@ parse_css_file = {PARSE_CSS_FILE} 'S_DETAILS' => true, 'S_INSTALL' => true, 'S_ERROR_MSG' => (sizeof($error)) ? true : false, + 'S_LOCATION' => (isset($installcfg['inherit_from']) && $installcfg['inherit_from']) ? false : true, 'S_STYLE' => ($mode == 'style') ? true : false, 'S_TEMPLATE' => ($mode == 'template') ? true : false, 'S_THEME' => ($mode == 'theme') ? true : false, @@ -3034,6 +3101,9 @@ parse_css_file = {PARSE_CSS_FILE} { global $phpbb_root_path, $db, $user; + // we parse the cfg here (again) + $cfg_data = parse_cfg_file("$root_path$mode/$mode.cfg"); + switch ($mode) { case 'template': @@ -3074,6 +3144,7 @@ parse_css_file = {PARSE_CSS_FILE} $result = $db->sql_query($sql); $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); + if ($row) { @@ -3087,6 +3158,34 @@ parse_css_file = {PARSE_CSS_FILE} $error[] = $user->lang[$l_type . '_ERR_NAME_EXIST']; } + if (isset($cfg_data['inherit_from']) && $cfg_data['inherit_from']) + { + $sql = "SELECT {$mode}_id, {$mode}_name, {$mode}_path, {$mode}_storedb + FROM $sql_from + WHERE {$mode}_name = '" . $db->sql_escape(strtolower($cfg_data['inherit_from'])) . "' + AND {$mode}_inherits_id = 0"; + $result = $db->sql_query($sql); + $row = $db->sql_fetchrow($result); + $db->sql_freeresult($result); + if (!$row) + { + $error[] = sprintf($user->lang[$l_type . '_ERR_REQUIRED_OR_INCOMPLETE'], $inherit_from); + } + else + { + $inherit_id = $row["{$mode}_id"]; + $inherit_path = $row["{$mode}_path"]; + $cfg_data['store_db'] = $row["{$mode}_storedb"]; + $store_db = $row["{$mode}_storedb"]; + } + } + else + { + $inherit_id = 0; + $inherit_path = ''; + } + + if (sizeof($error)) { return false; @@ -3102,8 +3201,6 @@ parse_css_file = {PARSE_CSS_FILE} { case 'template': // We check if the template author defined a different bitfield - $cfg_data = parse_cfg_file("$root_path$mode/template.cfg"); - if (!empty($cfg_data['template_bitfield'])) { $sql_ary['bbcode_bitfield'] = $cfg_data['template_bitfield']; @@ -3115,15 +3212,21 @@ parse_css_file = {PARSE_CSS_FILE} // We set a pre-defined bitfield here which we may use further in 3.2 $sql_ary += array( - 'template_storedb' => $store_db + 'template_storedb' => $store_db, ); + if (isset($cfg_data['inherit_from']) && $cfg_data['inherit_from']) + { + $sql_ary += array( + 'template_inherits_id' => $inherit_id, + 'template_inherit_path' => $inherit_path, + ); + } break; case 'theme': // We are only interested in the theme configuration for now - $theme_cfg = parse_cfg_file("{$phpbb_root_path}styles/$path/theme/theme.cfg"); - if (isset($theme_cfg['parse_css_file']) && $theme_cfg['parse_css_file']) + if (isset($cfg_data['parse_css_file']) && $cfg_data['parse_css_file']) { $store_db = 1; } @@ -3262,6 +3365,297 @@ parse_css_file = {PARSE_CSS_FILE} // Return store_db in case it had to be altered return $store_db; } + + /** + * Checks downwards dependencies + * + * @visibility public + * @param string $mode The element type to check - only template is supported + * @param int $id The template id + * @returns false if no component inherits, array with name, path and id for each subtemplate otherwise + */ + function check_inheritance($mode, $id) + { + global $db; + + $l_type = strtoupper($mode); + + switch ($mode) + { + case 'template': + $sql_from = STYLES_TEMPLATE_TABLE; + break; + + case 'theme': + $sql_from = STYLES_THEME_TABLE; + break; + + case 'imageset': + $sql_from = STYLES_IMAGESET_TABLE; + break; + } + + $sql = "SELECT {$mode}_id, {$mode}_name, {$mode}_path + FROM $sql_from + WHERE {$mode}_inherits_id = " . (int) $id; + $result = $db->sql_query($sql); + + $names = array(); + while ($row = $db->sql_fetchrow($result)) + { + + $names[$row["{$mode}_id"]] = array( + "{$mode}_id" => $row["{$mode}_id"], + "{$mode}_name" => $row["{$mode}_name"], + "{$mode}_path" => $row["{$mode}_path"], + ); + } + $db->sql_freeresult($result); + + if (sizeof($names)) + { + return $names; + } + else + { + return false; + } + } + + /** + * Checks upwards dependencies + * + * @visibility public + * @param string $mode The element type to check - only template is supported + * @param int $id The template id + * @returns false if the component does not inherit, array with name, path and id otherwise + */ + function get_super($mode, $id) + { + global $db; + + $l_type = strtoupper($mode); + + switch ($mode) + { + case 'template': + $sql_from = STYLES_TEMPLATE_TABLE; + break; + + case 'theme': + $sql_from = STYLES_THEME_TABLE; + break; + + case 'imageset': + $sql_from = STYLES_IMAGESET_TABLE; + break; + } + + + $sql = "SELECT {$mode}_inherits_id + FROM $sql_from + WHERE {$mode}_id = " . (int) $id; + $result = $db->sql_query_limit($sql, 1); + + if ($row = $db->sql_fetchrow($result)) + { + $db->sql_freeresult($result); + } + else + { + return false; + } + + $super_id = $row["{$mode}_inherits_id"]; + + $sql = "SELECT {$mode}_id, {$mode}_name, {$mode}_path + FROM $sql_from + WHERE {$mode}_id = " . (int) $super_id; + + $result = $db->sql_query_limit($sql, 1); + if ($row = $db->sql_fetchrow($result)) + { + $db->sql_freeresult($result); + return $row; + } + + return false; + } + + /** + * Moves a template set and its subtemplates to the database + * + * @visibility public + * @param string $mode The component to move - only template is supported + * @param int $id The template id + */ + function store_in_db($mode, $id) + { + global $db, $user; + + $error = array(); + $l_type = strtoupper($mode); + if ($super = $this->get_super($mode, $id)) + { + $error[] = (sprintf($user->lang["{$l_type}_INHERITS"], $super['template_name'])); + return $error; + } + + $sql = "SELECT {$mode}_id, {$mode}_name, {$mode}_path + FROM " . STYLES_TEMPLATE_TABLE . ' + WHERE template_id = ' . (int) $id; + + $result = $db->sql_query_limit($sql, 1); + if ($row = $db->sql_fetchrow($result)) + { + $db->sql_freeresult($result); + $subs = $this->check_inheritance($mode, $id); + + $this->_store_in_db($mode, $id, $row["{$mode}_path"]); + if ($subs && sizeof($subs)) + { + foreach ($subs as $sub_id => $sub) + { + if ($err = $this->_store_in_db($mode, $sub["{$mode}_id"], $sub["{$mode}_path"])) + { + $error[] = $err; + } + } + } + } + if (sizeof($error)) + { + return $error; + } + + return false; + } + + /** + * Moves a template set to the database + * + * @visibility private + * @param string $mode The component to move - only template is supported + * @param int $id The template id + * @param string $path TThe path to the template files + */ + function _store_in_db($mode, $id, $path) + { + global $phpbb_root_path, $db; + + $filelist = filelist("{$phpbb_root_path}styles/{$path}/template", '', 'html'); + $this->store_templates('insert', $id, $path, $filelist); + + // Okay, we do the query here -shouldn't be triggered often. + $sql = 'UPDATE ' . STYLES_TEMPLATE_TABLE . ' + SET template_storedb = 1 + WHERE template_id = ' . $id; + $db->sql_query($sql); + } + + /** + * Moves a template set and its subtemplates to the filesystem + * + * @visibility public + * @param string $mode The component to move - only template is supported + * @param int $id The template id + */ + function store_in_fs($mode, $id) + { + global $db, $user; + + $error = array(); + $l_type = strtoupper($mode); + if ($super = $this->get_super($mode, $id)) + { + $error[] = (sprintf($user->lang["{$l_type}_INHERITS"], $super['template_name'])); + return($error); + } + + $sql = "SELECT {$mode}_id, {$mode}_name, {$mode}_path + FROM " . STYLES_TEMPLATE_TABLE . ' + WHERE template_id = ' . (int) $id; + + $result = $db->sql_query_limit($sql, 1); + if ($row = $db->sql_fetchrow($result)) + { + $db->sql_freeresult($result); + if (!sizeof($error)) + { + $subs = $this->check_inheritance($mode, $id); + + $this->_store_in_fs($mode, $id, $row["{$mode}_path"]); + + if ($subs && sizeof($subs)) + { + foreach ($subs as $sub_id => $sub) + { + $this->_store_in_fs($mode, $sub["{$mode}_id"], $sub["{$mode}_path"]); + } + } + } + if (sizeof($error)) + { + $this->store_in_db($id, $mode); + return $error; + } + } + return false; + } + + /** + * Moves a template set to the filesystem + * + * @visibility private + * @param string $mode The component to move - only template is supported + * @param int $id The template id + * @param string $path The path to the template + */ + function _store_in_fs($mode, $id, $path) + { + global $phpbb_root_path, $db, $user, $safe_mode; + + $store_db = 0; + $error = array(); + if (!$safe_mode && @is_writable("{$phpbb_root_path}styles/{$path}/template")) + { + $sql = 'SELECT * + FROM ' . STYLES_TEMPLATE_DATA_TABLE . " + WHERE template_id = $id"; + $result = $db->sql_query($sql); + + while ($row = $db->sql_fetchrow($result)) + { + if (!($fp = @fopen("{$phpbb_root_path}styles/{$path}/template/" . $row['template_filename'], 'wb'))) + { + $store_db = 1; + $error[] = $user->lang['EDIT_TEMPLATE_STORED_DB']; + break; + } + + fwrite($fp, $row['template_data']); + fclose($fp); + } + $db->sql_freeresult($result); + + if (!$store_db) + { + $sql = 'DELETE FROM ' . STYLES_TEMPLATE_DATA_TABLE . " + WHERE template_id = $id"; + $db->sql_query($sql); + } + } + if (sizeof($error)) + { + return $error; + } + $sql = 'UPDATE ' . STYLES_TEMPLATE_TABLE . ' + SET template_storedb = 0 + WHERE template_id = ' . $id; + $db->sql_query($sql); + + return false; + } } diff --git a/phpBB/includes/bbcode.php b/phpBB/includes/bbcode.php index ef73762582..fd8fadf3a7 100644 --- a/phpBB/includes/bbcode.php +++ b/phpBB/includes/bbcode.php @@ -134,10 +134,21 @@ class bbcode { $this->template_bitfield = new bitfield($user->theme['bbcode_bitfield']); $this->template_filename = $phpbb_root_path . 'styles/' . $user->theme['template_path'] . '/template/bbcode.html'; - + if (!@file_exists($this->template_filename)) { - trigger_error('The file ' . $this->template_filename . ' is missing.', E_USER_ERROR); + if (isset($user->theme['template_inherits_id']) && $user->theme['template_inherits_id']) + { + $this->template_filename = $phpbb_root_path . 'styles/' . $user->theme['template_inherit_path'] . '/template/bbcode.html'; + if (!@file_exists($this->template_filename)) + { + trigger_error('The file ' . $this->template_filename . ' is missing.', E_USER_ERROR); + } + } + else + { + trigger_error('The file ' . $this->template_filename . ' is missing.', E_USER_ERROR); + } } } diff --git a/phpBB/includes/functions_template.php b/phpBB/includes/functions_template.php index 17d3328427..1e7fbaa8e6 100644 --- a/phpBB/includes/functions_template.php +++ b/phpBB/includes/functions_template.php @@ -72,15 +72,15 @@ class template_compile if ($store_in_db) { global $db, $user; - + $sql_ary = array( - 'template_id' => $user->theme['template_id'], + 'template_id' => $this->template->files_template[$handle], 'template_filename' => $this->template->filename[$handle], 'template_included' => '', 'template_mtime' => time(), 'template_data' => trim(@file_get_contents($this->template->files[$handle])), ); - + $sql = 'INSERT INTO ' . STYLES_TEMPLATE_DATA_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary); $db->sql_query($sql); } diff --git a/phpBB/includes/session.php b/phpBB/includes/session.php index b2a9bd2559..30101c7411 100644 --- a/phpBB/includes/session.php +++ b/phpBB/includes/session.php @@ -1480,7 +1480,7 @@ class user extends session $style = ($style) ? $style : ((!$config['override_user_style']) ? $this->data['user_style'] : $config['default_style']); } - $sql = 'SELECT s.style_id, t.template_storedb, t.template_path, t.template_id, t.bbcode_bitfield, c.theme_path, c.theme_name, c.theme_storedb, c.theme_id, i.imageset_path, i.imageset_id, i.imageset_name + $sql = 'SELECT s.style_id, t.template_storedb, t.template_path, t.template_id, t.bbcode_bitfield, t.template_inherits_id, t.template_inherit_path, c.theme_path, c.theme_name, c.theme_storedb, c.theme_id, i.imageset_path, i.imageset_id, i.imageset_name FROM ' . STYLES_TABLE . ' s, ' . STYLES_TEMPLATE_TABLE . ' t, ' . STYLES_THEME_TABLE . ' c, ' . STYLES_IMAGESET_TABLE . " i WHERE s.style_id = $style AND t.template_id = s.template_id diff --git a/phpBB/includes/template.php b/phpBB/includes/template.php index 2e60beb658..d17ad55691 100644 --- a/phpBB/includes/template.php +++ b/phpBB/includes/template.php @@ -36,6 +36,9 @@ class template var $cachepath = ''; var $files = array(); var $filename = array(); + var $files_inherit = array(); + var $files_template = array(); + var $inherit_root = ''; // this will hash handle names to the compiled/uncompiled code for that handle. var $compiled_code = array(); @@ -52,6 +55,11 @@ class template { $this->root = $phpbb_root_path . 'styles/' . $user->theme['template_path'] . '/template'; $this->cachepath = $phpbb_root_path . 'cache/tpl_' . $user->theme['template_path'] . '_'; + + if ($user->theme['template_inherits_id']) + { + $this->inherit_root = $phpbb_root_path . 'styles/' . $user->theme['template_inherit_path'] . '/template'; + } } else { @@ -88,7 +96,6 @@ class template { return false; } - foreach ($filename_array as $handle => $filename) { if (empty($filename)) @@ -98,8 +105,13 @@ class template $this->filename[$handle] = $filename; $this->files[$handle] = $this->root . '/' . $filename; + + if ($this->inherit_root) + { + $this->files_inherit[$handle] = $this->inherit_root . '/' . $filename; + } } - + return true; } @@ -197,7 +209,7 @@ class template return true; } - + /** * Load a compiled template if possible, if not, recompile it * @access private @@ -207,9 +219,24 @@ class template global $user, $phpEx, $config; $filename = $this->cachepath . str_replace('/', '.', $this->filename[$handle]) . '.' . $phpEx; - - $recompile = (($config['load_tplcompile'] && @filemtime($filename) < filemtime($this->files[$handle])) || !file_exists($filename) || @filesize($filename) === 0) ? true : false; - + $this->files_template[$handle] = $user->theme['template_id']; + + $recompile = false; + if (!file_exists($filename) || @filesize($filename) === 0) + { + $recompile = true; + } + else if ($config['load_tplcompile']) + { + // No way around it: we need to check inheritance here + if ($user->theme['template_inherits_id'] && !file_exists($this->files[$handle])) + { + $this->files[$handle] = $this->files_inherit[$handle]; + $this->files_template[$handle] = $user->theme['template_inherits_id']; + } + $recompile = (@filemtime($filename) < filemtime($this->files[$handle])) ? true : false; + } + // Recompile page if the original template is newer, otherwise load the compiled version if (!$recompile) { @@ -222,7 +249,14 @@ class template { include($phpbb_root_path . 'includes/functions_template.' . $phpEx); } - + + // Inheritance - we point to another template file for this one. Equality is also used for store_db + if (isset($user->theme['template_inherits_id']) && $user->theme['template_inherits_id'] && !file_exists($this->files[$handle])) + { + $this->files[$handle] = $this->files_inherit[$handle]; + $this->files_template[$handle] = $user->theme['template_inherits_id']; + } + $compile = new template_compile($this); // If we don't have a file assigned to this handle, die. @@ -240,28 +274,70 @@ class template if (isset($user->theme['template_storedb']) && $user->theme['template_storedb']) { - $sql = 'SELECT * + $rows = array(); + $ids = array(); + // Inheritance + if (isset($user->theme['template_inherits_id']) && $user->theme['template_inherits_id']) + { + $ids[] = $user->theme['template_inherits_id']; + } + $ids[] = $user->theme['template_id']; + + foreach ($ids as $id) + { + $sql = 'SELECT * FROM ' . STYLES_TEMPLATE_DATA_TABLE . ' - WHERE template_id = ' . $user->theme['template_id'] . " + WHERE template_id = ' . $id . " AND (template_filename = '" . $db->sql_escape($this->filename[$handle]) . "' OR template_included " . $db->sql_like_expression($db->any_char . $this->filename[$handle] . ':' . $db->any_char) . ')'; - $result = $db->sql_query($sql); - $row = $db->sql_fetchrow($result); - - if ($row) + + $result = $db->sql_query($sql); + while ($row = $db->sql_fetchrow($result)) + { + $rows[$row['template_filename']] = $row; + } + $db->sql_freeresult($result); + } + + if (sizeof($rows)) { - do + foreach ($rows as $row) { - if ($row['template_mtime'] < filemtime($phpbb_root_path . 'styles/' . $user->theme['template_path'] . '/template/' . $row['template_filename'])) + $file = $this->root . '/' . $row['template_filename']; + $force_reload = false; + if ($row['template_id'] != $user->theme['template_id']) + { + // make sure that we are not overlooking a file not in the db yet + if (isset($user->theme['template_inherits_id']) && $user->theme['template_inherits_id'] && !file_exists($file)) + { + $file = $this->inherit_root . '/' . $row['template_filename']; + $this->files[$row['template_filename']] = $file; + $this->files_inherit[$row['template_filename']] = $file; + $this->files_template[$row['template_filename']] = $user->theme['template_inherits_id']; + } + else if (isset($user->theme['template_inherits_id']) && $user->theme['template_inherits_id']) + { + // Ok, we have a situation. There is a file in the subtemplate, but nothing in the DB. We have to fix that. + $force_reload = true; + $this->files_template[$row['template_filename']] = $user->theme['template_inherits_id']; + } + } + else + { + $this->files_template[$row['template_filename']] = $user->theme['template_id']; + } + + if ($force_reload || $row['template_mtime'] < filemtime($file)) { if ($row['template_filename'] == $this->filename[$handle]) { - $compile->_tpl_load_file($handle); + $compile->_tpl_load_file($handle, true); } else { - $this->files[$row['template_filename']] = $this->root . '/' . $row['template_filename']; - $compile->_tpl_load_file($row['template_filename']); + $this->files[$row['template_filename']] = $file; + $this->filename[$row['template_filename']] = $row['template_filename']; + $compile->_tpl_load_file($row['template_filename'], true); unset($this->compiled_code[$row['template_filename']]); unset($this->files[$row['template_filename']]); unset($this->filename[$row['template_filename']]); @@ -284,15 +360,22 @@ class template } } } - while ($row = $db->sql_fetchrow($result)); } else { + $file = $this->root . '/' . $row['template_filename']; + + if (isset($user->theme['template_inherits_id']) && $user->theme['template_inherits_id'] && !file_exists($file)) + { + $file = $this->inherit_root . '/' . $row['template_filename']; + $this->files[$row['template_filename']] = $file; + $this->files_inherit[$row['template_filename']] = $file; + $this->files_template[$row['template_filename']] = $user->theme['template_inherits_id']; + } // Try to load from filesystem and instruct to insert into the styles table... $compile->_tpl_load_file($handle, true); return false; } - $db->sql_freeresult($result); return false; } @@ -512,8 +595,12 @@ class template $handle = $filename; $this->filename[$handle] = $filename; $this->files[$handle] = $this->root . '/' . $filename; + if ($this->inherit_root) + { + $this->files_inherit[$handle] = $this->inherit_root . '/' . $filename; + } - $filename = $this->_tpl_load($handle); + $filename = $this->_tpl_load($handle); if ($include) { |