📄 acp_styles.php
字号:
$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)) { $filemtime[$row['template_filename']] = $row['template_mtime']; } $db->sql_freeresult($result); } // Get a list of cached template files and then retrieve additional information about them $file_ary = $this->template_cache_filelist($template_row['template_path']); foreach ($file_ary as $file) { $filename = "{$cache_prefix}_$file.html.$phpEx"; $template->assign_block_vars('file', array( 'U_VIEWSOURCE' => $this->u_action . "&action=cache&id=$template_id&source=$file", 'UA_VIEWSOURCE' => str_replace('&', '&', $this->u_action) . "&action=cache&id=$template_id&source=$file", 'CACHED' => $user->format_date(filemtime("{$phpbb_root_path}cache/$filename")), 'FILENAME' => $file, 'FILESIZE' => sprintf('%.1f KB', 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/$file.html") : $filemtime[$file . '.html'])) ); } unset($filemtime); $template->assign_vars(array( 'S_CACHE' => true, 'S_TEMPLATE' => true, 'U_ACTION' => $this->u_action . "&action=cache&id=$template_id", 'U_BACK' => $this->u_action) ); } /** * Provides a css editor and a basic easier to use stylesheet editing tool for less experienced (or lazy) users * * @param int $theme_id specifies which theme is being edited */ function edit_theme($theme_id) { global $phpbb_root_path, $phpbb_admin_path, $phpEx, $config, $db, $cache, $user, $template, $safe_mode; $this->page_title = 'EDIT_THEME'; // we want newlines no carriage returns! $_POST['css_data'] = (isset($_POST['css_data']) && !empty($_POST['css_data'])) ? str_replace(array("\r\n", "\r"), array("\n", "\n"), $_POST['css_data']) : ''; // get user input $text_rows = max(5, min(999, request_var('text_rows', 20))); $hide_css = request_var('hidecss', false); $show_css = !$hide_css && request_var('showcss', false); $edit_class = request_var('css_class', ''); $custom_class = request_var('custom_class', ''); $css_data = (STRIP) ? stripslashes($_POST['css_data']) : $_POST['css_data']; $submit = isset($_POST['submit']) ? true : false; $add_custom = isset($_POST['add_custom']) ? true : false; $matches = array(); // Retrieve some information about the theme $sql = 'SELECT theme_storedb, theme_path, theme_name, theme_data FROM ' . STYLES_THEME_TABLE . " WHERE theme_id = $theme_id"; $result = $db->sql_query($sql); if (!($theme_info = $db->sql_fetchrow($result))) { trigger_error($user->lang['NO_THEME'] . adm_bacl_link($this->u_action), E_USER_WARNING); } $db->sql_freeresult($result); $stylesheet_path = $phpbb_root_path . 'styles/' . $theme_info['theme_path'] . '/theme/stylesheet.css'; // Get the CSS data from either database or filesystem if (!$theme_info['theme_storedb']) { if (!file_exists($stylesheet_path) || !($stylesheet = file_get_contents($stylesheet_path))) { trigger_error($user->lang['NO_THEME'] . adm_back_link($this->u_action), E_USER_WARNING); } } else { $stylesheet = &$theme_info['theme_data']; } // Pull out a list of classes $classes = array(); if (preg_match_all('/^([a-z0-9\.,:#> \t]+?)[ \t\n]*?\{.*?\}/msi', $stylesheet, $matches)) { $classes = $matches[1]; } // Generate html for the list of classes $s_hidden_fields = array(); $s_classes = ''; sort($classes); foreach ($classes as $class) { $selected = ($class == $edit_class) ? ' selected="selected"' : ''; $s_classes .= '<option value="' . $class . '" title="' . $class . '"' . $selected . '>' . truncate_string($class, 40, false, '...') . '</option>'; } $template->assign_vars(array( 'S_EDIT_THEME' => true, 'S_SHOWCSS' => $show_css, 'S_CLASSES' => $s_classes, 'S_CLASS' => $edit_class, 'U_ACTION' => $this->u_action . "&action=edit&id=$theme_id&showcss=$show_css&text_rows=$text_rows", 'U_BACK' => $this->u_action, 'SELECTED_THEME' => $theme_info['theme_name'], 'TEXT_ROWS' => $text_rows) ); // only continue if we are really editing anything if (!$edit_class && !$add_custom) { return; } // These are the elements for the simple view $match_elements = array( 'colors' => array('background-color', 'color',), 'sizes' => array('font-size', 'line-height',), 'images' => array('background-image',), 'repeat' => array('background-repeat',), 'other' => array('font-weight', 'font-family', 'font-style', 'text-decoration',), ); // Used in an sprintf statement to generate appropriate output for rawcss mode $map_elements = array( 'colors' => '%s', 'sizes' => '%1.10f', 'images' => 'url(\'./%s\')', 'repeat' => '%s', 'other' => '%s', ); $units = array('px', '%', 'em', 'pt'); $repeat_types = array( '' => $user->lang['UNSET'], 'none' => $user->lang['REPEAT_NO'], 'repeat-x' => $user->lang['REPEAT_X'], 'repeat-y' => $user->lang['REPEAT_Y'], 'both' => $user->lang['REPEAT_ALL'], ); // Fill css_data with the class contents from the stylesheet // in case we just selected a class and it's not filled yet if (!$css_data && !$submit && !isset($_POST['hidecss']) && !isset($_POST['showcss']) && !$add_custom) { preg_match('#^[ \t]*?' . preg_quote($edit_class, '#') . '[ \t\n]*?\{(.*?)\}#ms', $stylesheet, $matches); if (!isset($matches[1])) { trigger_error($user->lang['NO_CLASS'] . adm_back_link($this->u_action), E_USER_WARNING); } $css_data = implode(";\n", array_diff(array_map('trim', explode("\n", preg_replace("#;[\n]*#s", "\n", $matches[1]))), array(''))); if ($css_data) { $css_data .= ';'; } } // If we don't show raw css and the user did not submit any modification // then generate a list of css elements and output them via the template if (!$show_css && !$submit && !$add_custom) { $css_elements = array_diff(array_map('trim', explode("\n", preg_replace("#;[\n]*#s", "\n", $css_data))), array('')); // Grab list of potential images for the "images" type $img_filelist = filelist($phpbb_root_path . 'styles/' . $theme_info['theme_name'] . '/theme'); foreach ($match_elements as $type => $match_ary) { foreach ($match_ary as $match) { $var = str_replace('-', '_', $match); $value = ''; $unit = ''; if (sizeof($css_elements)) { // first read in the setting foreach ($css_elements as $key => $element) { if (preg_match('#^' . preg_quote($match, '#') . ':[ \t\n]*?(.*?)$#', $element, $matches)) { switch ($type) { case 'sizes': $value = trim($matches[1]); if (preg_match('#(.*?)(px|%|em|pt)#', $matches[1], $matches)) { $unit = trim($matches[2]); $value = trim($matches[1]); } break; case 'images': if (preg_match('#url\(\'(.*?)\'\)#', $matches[1], $matches)) { $value = trim($matches[1]); } break; case 'colors': $value = trim($matches[1]); if ($value[0] == '#') { $value = substr($value, 1); } break; default: $value = trim($matches[1]); } // Remove this element from array unset($css_elements[$key]); break; } } } // then display it in the template switch ($type) { case 'sizes': // generate a list of units $s_units = ''; foreach ($units as $unit_option) { $selected = ($unit_option == $unit) ? ' selected="selected"' : ''; $s_units .= "<option value=\"$unit_option\"$selected>$unit_option</option>"; } $s_units = '<option value=""' . (($unit == '') ? ' selected="selected"' : '') . '>' . $user->lang['NO_UNIT'] . '</option>' . $s_units; $template->assign_vars(array( strtoupper($var) => $value, 'S_' . strtoupper($var) . '_UNITS' => $s_units) ); break; case 'images': // generate a list of images for this setting $s_imglist = ''; foreach ($img_filelist as $path => $img_ary) { foreach ($img_ary as $img) { $img = htmlspecialchars(((substr($path, 0, 1) == '/') ? substr($path, 1) : $path) . $img); $selected = (preg_match('#' . preg_quote($img) . '$#', $value)) ? ' selected="selected"' : ''; $s_imglist .= "<option value=\"$img\"$selected>$img</option>"; } } $s_imglist = '<option value=""' . (($value == '') ? ' selected="selected"' : '') . '>' . $user->lang['NO_IMAGE'] . '</option>' . $s_imglist; $template->assign_vars(array( 'S_' . strtoupper($var) => $s_imglist) ); unset($s_imglist); break; case 'repeat': // generate a list of repeat options $s_repeat_types = ''; foreach ($repeat_types as $repeat_type => $repeat_lang) { $selected = ($value == $repeat_type) ? ' selected="selected"' : ''; $s_repeat_types .= "<option value=\"$repeat_type\"$selected>$repeat_lang</option>"; } $template->assign_vars(array( 'S_' . strtoupper($var) => $s_repeat_types) ); default: $template->assign_vars(array( strtoupper($var) => $value) ); } } } // Any remaining elements must be custom data so we save that in a hidden field if (sizeof($css_elements)) { $s_hidden_fields['cssother'] = implode(' ;; ', $css_elements); } unset($img_filelist, $css_elements); } // else if we are showing raw css or the user submitted data from the simple view // then we need to turn the given information into raw css elseif (!$css_data && !$add_custom) { foreach ($match_elements as $type => $match_ary) { foreach ($match_ary as $match) { $var = str_replace('-', '_', $match); $value = ''; $unit = ''; // retrieve and validate data for this setting switch ($type) { case 'sizes': $value = request_var($var, 0.0); $unit = request_var($var . '_unit', ''); if ((request_var($var, '') === '') || !in_array($unit, $units)) { $value = ''; } break; case 'images': $value = str_replace('..', '.', request_var($var, '')); if (!file_exists("{$phpbb_root_path}styles/{$theme_info['theme_path']}/theme/" . $value)) { $value = ''; } break; case 'colors': $value = request_var($var, ''); if (preg_match('#^(?:[A-F0-9]{6}|[A-F0-9]{3})$#', $value)) { $value = '#' . $value; } break; case 'repeat': $value = request_var($var, ''); if (!isset($repeat_types[$value])) { $value = ''; } break; default: $value = request_var($var, ''); } // use the element mapping to create raw css code if ($value !== '') { $css_data .= $match . ': ' . ($type == 'sizes' ? rtrim(sprintf($map_elements[$type], $value), '0') : sprintf($map_elements[$type], $value)) . $unit . ";\n"; } } } // append additional data sent to us if ($other = request_var('cssother', '')) { $css_data .= str_replace(' ;; ', ";\n", $other) . ';'; $css_data = preg_replace("#\*/;\n#", "*/\n", $css_data); } } // make sure we have $show_css set, so we can link to the show_css page if we need to elseif (!$hide_css) { $show_css = true; } if ($submit || $add_custom) { if ($submit) { // if the user submitted a modification replace the old class definition in the stylesheet // with the new one if (preg_match('#^' . preg_quote($edit_class, '#') . '[ \t\n]*?\{(.*?)\}#ms', $stylesheet)) { $stylesheet = preg_replace('#^(' . preg_quote($edit_class, '#') . '[ \t\n]*?\{).*?(\})#ms', "$1\n\t" . str_replace("\n", "\n\t", $css_data) . "\n$2", $stylesheet); } $message = $user->lang['THEME_UPDATED']; } else { // check whether the custom class name is valid if (!preg_match('/^[a-z0-9#:.\- ]+$/i', $add_custom)) { trigger_error($user->lang['THEME_ERR_CLASS_CHARS'] . adm_back_link($this->u_action . "&action=edit&id=$theme_id&text_rows=$text_rows"), E_USER_WARNING); } else { // append an empty class definition to the stylesheet $stylesheet .= "\n$custom_class\n{\n}"; $message = $user->lang['THEME_CLASS_ADDED']; } } // where should we store the CSS? if (!$safe_mode && !$theme_info['theme_storedb'] && file_exists($stylesheet_path) && is_writeable($stylesheet_path)) { // write stylesheet to file if (!($fp = fopen($stylesheet_path, 'wb'))) { trigger_error($user->lang['NO_THEME'] . adm_back_link($this->u_action), E_USER_WARNING); } fwrite($fp, $stylesheet); fclose($fp); } else { // Write stylesheet to db $sql_ary = array( 'theme_mtime' => time(), 'theme_storedb' => 1, 'theme_data' => $this->db_theme_data($theme_info, $stylesheet), ); $sql = 'UPDATE ' . STYLES_THEME_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $sql_ary) . ' WHERE theme_id = ' . $theme_id; $db->sql_query($sql); $cache->destroy('sql', STYLES_THEME_TABLE);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -