5
* @version $Id: acp_styles.php,v 1.117 2007/10/21 11:26:24 acydburn Exp $
6
* @copyright (c) 2005 phpBB Group
7
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
14
if (!defined('IN_PHPBB'))
32
function main($id, $mode)
34
global $db, $user, $auth, $template, $cache;
35
global $config, $phpbb_root_path, $phpbb_admin_path, $phpEx;
37
// Hardcoded template bitfield to add for new templates
38
$bitfield = new bitfield();
45
define('TEMPLATE_BITFIELD', $bitfield->get_base64());
48
$user->add_lang('acp/styles');
50
$this->tpl_name = 'acp_styles';
51
$this->page_title = 'ACP_CAT_STYLES';
53
$action = request_var('action', '');
54
$action = (isset($_POST['add'])) ? 'add' : $action;
55
$style_id = request_var('id', 0);
57
// Fill the configuration variables
58
$this->style_cfg = $this->template_cfg = $this->theme_cfg = $this->imageset_cfg = '
60
# phpBB {MODE} configuration file
63
# @copyright (c) 2005 phpBB Group
64
# @license http://opensource.org/licenses/gpl-license.php GNU Public License
67
# At the left is the name, please do not change this
68
# At the right the value is entered
69
# For on/off options the valid values are on, off, 1, 0, true and false
71
# Values get trimmed, if you want to add a space in front or at the end of
72
# the value, then enclose the value with single or double quotes.
73
# Single and double quotes do not need to be escaped.
77
# General Information about this {MODE}
79
copyright = {COPYRIGHT}
84
# Some configuration options
87
# You have to turn this option on if you want to use the
88
# path template variables ({T_IMAGESET_PATH} for example) within
90
# This is mostly the case if you want to use language specific
91
# images within your css file.
93
parse_css_file = {PARSE_CSS_FILE}
96
$this->imageset_keys = array(
101
'icon_back_top', 'icon_contact_aim', 'icon_contact_email', 'icon_contact_icq', 'icon_contact_jabber', 'icon_contact_msnm', 'icon_contact_pm', 'icon_contact_yahoo', 'icon_contact_www', 'icon_post_delete', 'icon_post_edit', 'icon_post_info', 'icon_post_quote', 'icon_post_report', 'icon_user_online', 'icon_user_offline', 'icon_user_profile', 'icon_user_search', 'icon_user_warn', 'button_pm_forward', 'button_pm_new', 'button_pm_reply', 'button_topic_locked', 'button_topic_new', 'button_topic_reply',
104
'icon_post_target', 'icon_post_target_unread', 'icon_topic_attach', 'icon_topic_latest', 'icon_topic_newest', 'icon_topic_reported', 'icon_topic_unapproved', 'icon_friend', 'icon_foe',
107
'forum_link', 'forum_read', 'forum_read_locked', 'forum_read_subforum', 'forum_unread', 'forum_unread_locked', 'forum_unread_subforum', 'subforum_read', 'subforum_unread'
110
'topic_moved', 'topic_read', 'topic_read_mine', 'topic_read_hot', 'topic_read_hot_mine', 'topic_read_locked', 'topic_read_locked_mine', 'topic_unread', 'topic_unread_mine', 'topic_unread_hot', 'topic_unread_hot_mine', 'topic_unread_locked', 'topic_unread_locked_mine', 'sticky_read', 'sticky_read_mine', 'sticky_read_locked', 'sticky_read_locked_mine', 'sticky_unread', 'sticky_unread_mine', 'sticky_unread_locked', 'sticky_unread_locked_mine', 'announce_read', 'announce_read_mine', 'announce_read_locked', 'announce_read_locked_mine', 'announce_unread', 'announce_unread_mine', 'announce_unread_locked', 'announce_unread_locked_mine', 'global_read', 'global_read_mine', 'global_read_locked', 'global_read_locked_mine', 'global_unread', 'global_unread_mine', 'global_unread_locked', 'global_unread_locked_mine', 'pm_read', 'pm_unread',
113
'poll_left', 'poll_center', 'poll_right',
119
'user_icon1', 'user_icon2', 'user_icon3', 'user_icon4', 'user_icon5', 'user_icon6', 'user_icon7', 'user_icon8', 'user_icon9', 'user_icon10',
123
// Execute overall actions
129
$this->remove($mode, $style_id);
137
$this->export($mode, $style_id);
143
$this->install($mode);
155
$this->details($mode, $style_id);
166
return $this->edit_imageset($style_id);
168
return $this->edit_template($style_id);
170
return $this->edit_theme($style_id);
181
return $this->template_cache($style_id);
196
if ($style_id == $config['default_style'])
198
trigger_error($user->lang['DEACTIVATE_DEFAULT'] . adm_back_link($this->u_action), E_USER_WARNING);
201
$sql = 'UPDATE ' . STYLES_TABLE . '
202
SET style_active = ' . (($action == 'activate') ? 1 : 0) . '
203
WHERE style_id = ' . $style_id;
204
$db->sql_query($sql);
206
// Set style to default for any member using deactivated style
207
if ($action == 'deactivate')
209
$sql = 'UPDATE ' . USERS_TABLE . '
210
SET user_style = ' . $config['default_style'] . "
211
WHERE user_style = $style_id";
212
$db->sql_query($sql);
214
$sql = 'UPDATE ' . FORUMS_TABLE . '
216
WHERE forum_style = ' . $style_id;
217
$db->sql_query($sql);
222
$this->frontend('style', array('details'), array('export', 'delete'));
229
// Refresh template data stored in db and clear cache
233
FROM ' . STYLES_TEMPLATE_TABLE . "
234
WHERE template_id = $style_id";
235
$result = $db->sql_query($sql);
236
$template_row = $db->sql_fetchrow($result);
237
$db->sql_freeresult($result);
241
trigger_error($user->lang['NO_TEMPLATE'] . adm_back_link($this->u_action), E_USER_WARNING);
244
if (confirm_box(true))
246
$template_refreshed = '';
248
// Only refresh database if the template is stored in the database
249
if ($template_row['template_storedb'] && file_exists("{$phpbb_root_path}styles/{$template_row['template_path']}/template/"))
251
$filelist = array('' => array());
253
$sql = 'SELECT template_filename, template_mtime
254
FROM ' . STYLES_TEMPLATE_DATA_TABLE . "
255
WHERE template_id = $style_id";
256
$result = $db->sql_query($sql);
258
while ($row = $db->sql_fetchrow($result))
260
// if (@filemtime("{$phpbb_root_path}styles/{$template_row['template_path']}/template/" . $row['template_filename']) > $row['template_mtime'])
262
// get folder info from the filename
263
if (($slash_pos = strrpos($row['template_filename'], '/')) === false)
265
$filelist[''][] = $row['template_filename'];
269
$filelist[substr($row['template_filename'], 0, $slash_pos + 1)][] = substr($row['template_filename'], $slash_pos + 1, strlen($row['template_filename']) - $slash_pos - 1);
273
$db->sql_freeresult($result);
275
$this->store_templates('update', $style_id, $template_row['template_path'], $filelist);
278
$template_refreshed = $user->lang['TEMPLATE_REFRESHED'] . '<br />';
279
add_log('admin', 'LOG_TEMPLATE_REFRESHED', $template_row['template_name']);
282
$this->clear_template_cache($template_row);
284
trigger_error($template_refreshed . $user->lang['TEMPLATE_CACHE_CLEARED'] . adm_back_link($this->u_action));
288
confirm_box(false, ($template_row['template_storedb']) ? $user->lang['CONFIRM_TEMPLATE_REFRESH'] : $user->lang['CONFIRM_TEMPLATE_CLEAR_CACHE'], build_hidden_fields(array(
299
$this->frontend('template', array('edit', 'cache', 'details'), array('refresh', 'export', 'delete'));
306
// Refresh theme data stored in the database
310
FROM ' . STYLES_THEME_TABLE . "
311
WHERE theme_id = $style_id";
312
$result = $db->sql_query($sql);
313
$theme_row = $db->sql_fetchrow($result);
314
$db->sql_freeresult($result);
318
trigger_error($user->lang['NO_THEME'] . adm_back_link($this->u_action), E_USER_WARNING);
321
if (!$theme_row['theme_storedb'])
323
trigger_error($user->lang['THEME_ERR_REFRESH_FS'] . adm_back_link($this->u_action), E_USER_WARNING);
326
if (confirm_box(true))
328
if ($theme_row['theme_storedb'] && file_exists("{$phpbb_root_path}styles/{$theme_row['theme_path']}/theme/stylesheet.css"))
332
'theme_mtime' => (int) filemtime("{$phpbb_root_path}styles/{$theme_row['theme_path']}/theme/stylesheet.css"),
333
'theme_data' => $this->db_theme_data($theme_row)
336
$sql = 'UPDATE ' . STYLES_THEME_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $sql_ary) . "
337
WHERE theme_id = $style_id";
338
$db->sql_query($sql);
340
$cache->destroy('sql', STYLES_THEME_TABLE);
342
add_log('admin', 'LOG_THEME_REFRESHED', $theme_row['theme_name']);
343
trigger_error($user->lang['THEME_REFRESHED'] . adm_back_link($this->u_action));
348
confirm_box(false, $user->lang['CONFIRM_THEME_REFRESH'], build_hidden_fields(array(
358
$this->frontend('theme', array('edit', 'details'), array('refresh', 'export', 'delete'));
368
FROM ' . STYLES_IMAGESET_TABLE . "
369
WHERE imageset_id = $style_id";
370
$result = $db->sql_query($sql);
371
$imageset_row = $db->sql_fetchrow($result);
372
$db->sql_freeresult($result);
376
trigger_error($user->lang['NO_IMAGESET'] . adm_back_link($this->u_action), E_USER_WARNING);
379
if (confirm_box(true))
383
$imageset_definitions = array();
384
foreach ($this->imageset_keys as $topic => $key_array)
386
$imageset_definitions = array_merge($imageset_definitions, $key_array);
389
$cfg_data_imageset = parse_cfg_file("{$phpbb_root_path}styles/{$imageset_row['imageset_path']}/imageset/imageset.cfg");
391
$db->sql_transaction('begin');
393
$sql = 'DELETE FROM ' . STYLES_IMAGESET_DATA_TABLE . '
394
WHERE imageset_id = ' . $style_id;
395
$result = $db->sql_query($sql);
397
foreach ($cfg_data_imageset as $image_name => $value)
399
if (strpos($value, '*') !== false)
401
if (substr($value, -1, 1) === '*')
403
list($image_filename, $image_height) = explode('*', $value);
408
list($image_filename, $image_height, $image_width) = explode('*', $value);
413
$image_filename = $value;
414
$image_height = $image_width = 0;
417
if (strpos($image_name, 'img_') === 0 && $image_filename)
419
$image_name = substr($image_name, 4);
420
if (in_array($image_name, $imageset_definitions))
423
'image_name' => (string) $image_name,
424
'image_filename' => (string) $image_filename,
425
'image_height' => (int) $image_height,
426
'image_width' => (int) $image_width,
427
'imageset_id' => (int) $style_id,
434
$sql = 'SELECT lang_dir
436
$result = $db->sql_query($sql);
438
while ($row = $db->sql_fetchrow($result))
440
if (@file_exists("{$phpbb_root_path}styles/{$imageset_row['imageset_path']}/imageset/{$row['lang_dir']}/imageset.cfg"))
442
$cfg_data_imageset_data = parse_cfg_file("{$phpbb_root_path}styles/{$imageset_row['imageset_path']}/imageset/{$row['lang_dir']}/imageset.cfg");
443
foreach ($cfg_data_imageset_data as $image_name => $value)
445
if (strpos($value, '*') !== false)
447
if (substr($value, -1, 1) === '*')
449
list($image_filename, $image_height) = explode('*', $value);
454
list($image_filename, $image_height, $image_width) = explode('*', $value);
459
$image_filename = $value;
460
$image_height = $image_width = 0;
463
if (strpos($image_name, 'img_') === 0 && $image_filename)
465
$image_name = substr($image_name, 4);
466
if (in_array($image_name, $imageset_definitions))
469
'image_name' => (string) $image_name,
470
'image_filename' => (string) $image_filename,
471
'image_height' => (int) $image_height,
472
'image_width' => (int) $image_width,
473
'imageset_id' => (int) $style_id,
474
'image_lang' => (string) $row['lang_dir'],
481
$db->sql_freeresult($result);
483
$db->sql_multi_insert(STYLES_IMAGESET_DATA_TABLE, $sql_ary);
485
$db->sql_transaction('commit');
487
$cache->destroy('sql', STYLES_IMAGESET_DATA_TABLE);
489
add_log('admin', 'LOG_IMAGESET_REFRESHED', $imageset_row['imageset_name']);
490
trigger_error($user->lang['IMAGESET_REFRESHED'] . adm_back_link($this->u_action));
494
confirm_box(false, $user->lang['CONFIRM_IMAGESET_REFRESH'], build_hidden_fields(array(
504
$this->frontend('imageset', array('edit', 'details'), array('refresh', 'export', 'delete'));
510
* Build Frontend with supplied options
512
function frontend($mode, $options, $actions)
514
global $user, $template, $db, $config, $phpbb_root_path, $phpEx;
517
$style_count = array();
522
$sql_from = STYLES_TABLE;
524
$sql = 'SELECT user_style, COUNT(user_style) AS style_count
525
FROM ' . USERS_TABLE . '
526
GROUP BY user_style';
527
$result = $db->sql_query($sql);
529
while ($row = $db->sql_fetchrow($result))
531
$style_count[$row['user_style']] = $row['style_count'];
533
$db->sql_freeresult($result);
538
$sql_from = STYLES_TEMPLATE_TABLE;
542
$sql_from = STYLES_THEME_TABLE;
546
$sql_from = STYLES_IMAGESET_TABLE;
550
$l_prefix = strtoupper($mode);
552
$this->page_title = 'ACP_' . $l_prefix . 'S';
554
$template->assign_vars(array(
555
'S_FRONTEND' => true,
556
'S_STYLE' => ($mode == 'style') ? true : false,
558
'L_TITLE' => $user->lang[$this->page_title],
559
'L_EXPLAIN' => $user->lang[$this->page_title . '_EXPLAIN'],
560
'L_NAME' => $user->lang[$l_prefix . '_NAME'],
561
'L_INSTALLED' => $user->lang['INSTALLED_' . $l_prefix],
562
'L_UNINSTALLED' => $user->lang['UNINSTALLED_' . $l_prefix],
563
'L_NO_UNINSTALLED' => $user->lang['NO_UNINSTALLED_' . $l_prefix],
564
'L_CREATE' => $user->lang['CREATE_' . $l_prefix],
566
'U_ACTION' => $this->u_action,
572
$result = $db->sql_query($sql);
574
$installed = array();
576
$basis_options = '<option class="sep" value="">' . $user->lang['OPTIONAL_BASIS'] . '</option>';
577
while ($row = $db->sql_fetchrow($result))
579
$installed[] = $row[$mode . '_name'];
580
$basis_options .= '<option value="' . $row[$mode . '_id'] . '">' . $row[$mode . '_name'] . '</option>';
582
$stylevis = ($mode == 'style' && !$row['style_active']) ? 'activate' : 'deactivate';
584
$s_options = array();
585
foreach ($options as $option)
587
$s_options[] = '<a href="' . $this->u_action . "&action=$option&id=" . $row[$mode . '_id'] . '">' . $user->lang[strtoupper($option)] . '</a>';
590
$s_actions = array();
591
foreach ($actions as $option)
593
$s_actions[] = '<a href="' . $this->u_action . "&action=$option&id=" . $row[$mode . '_id'] . '">' . $user->lang[strtoupper($option)] . '</a>';
596
$template->assign_block_vars('installed', array(
597
'S_DEFAULT_STYLE' => ($mode == 'style' && $row['style_id'] == $config['default_style']) ? true : false,
598
'U_EDIT' => $this->u_action . '&action=' . (($mode == 'style') ? 'details' : 'edit') . '&id=' . $row[$mode . '_id'],
599
'U_STYLE_ACT_DEACT' => $this->u_action . '&action=' . $stylevis . '&id=' . $row[$mode . '_id'],
600
'L_STYLE_ACT_DEACT' => $user->lang['STYLE_' . strtoupper($stylevis)],
601
'S_OPTIONS' => implode(' | ', $s_options),
602
'S_ACTIONS' => implode(' | ', $s_actions),
603
'U_PREVIEW' => ($mode == 'style') ? append_sid("{$phpbb_root_path}index.$phpEx", "$mode=" . $row[$mode . '_id']) : '',
605
'NAME' => $row[$mode . '_name'],
606
'STYLE_COUNT' => ($mode == 'style' && isset($style_count[$row['style_id']])) ? $style_count[$row['style_id']] : 0,
610
$db->sql_freeresult($result);
612
// Grab uninstalled items
613
$new_ary = $cfg = array();
615
$dp = @opendir("{$phpbb_root_path}styles");
619
while (($file = readdir($dp)) !== false)
621
$subpath = ($mode != 'style') ? "$mode/" : '';
622
if ($file[0] != '.' && file_exists("{$phpbb_root_path}styles/$file/$subpath$mode.cfg"))
624
if ($cfg = file("{$phpbb_root_path}styles/$file/$subpath$mode.cfg"))
626
$items = parse_cfg_file('', $cfg);
627
$name = (isset($items['name'])) ? trim($items['name']) : false;
629
if ($name && !in_array($name, $installed))
634
'copyright' => $items['copyright'],
645
if (sizeof($new_ary))
647
foreach ($new_ary as $cfg)
649
$template->assign_block_vars('uninstalled', array(
650
'NAME' => $cfg['name'],
651
'COPYRIGHT' => $cfg['copyright'],
652
'U_INSTALL' => $this->u_action . '&action=install&path=' . urlencode($cfg['path']))
658
$template->assign_vars(array(
659
'S_BASIS_OPTIONS' => $basis_options)
665
* Provides a template editor which allows saving changes to template files on the filesystem or in the database.
667
* @param int $template_id specifies which template set is being edited
669
function edit_template($template_id)
671
global $phpbb_root_path, $phpEx, $config, $db, $cache, $user, $template, $safe_mode;
673
$this->page_title = 'EDIT_TEMPLATE';
675
$filelist = $filelist_cats = array();
677
$template_data = utf8_normalize_nfc(request_var('template_data', '', true));
678
$template_data = htmlspecialchars_decode($template_data);
679
$template_file = utf8_normalize_nfc(request_var('template_file', '', true));
680
$text_rows = max(5, min(999, request_var('text_rows', 20)));
681
$save_changes = (isset($_POST['save'])) ? true : false;
683
// make sure template_file path doesn't go upwards
684
$template_file = str_replace('..', '.', $template_file);
686
// Retrieve some information about the template
687
$sql = 'SELECT template_storedb, template_path, template_name
688
FROM ' . STYLES_TEMPLATE_TABLE . "
689
WHERE template_id = $template_id";
690
$result = $db->sql_query($sql);
691
$template_info = $db->sql_fetchrow($result);
692
$db->sql_freeresult($result);
696
trigger_error($user->lang['NO_TEMPLATE'] . adm_back_link($this->u_action), E_USER_WARNING);
699
// save changes to the template if the user submitted any
700
if ($save_changes && $template_file)
702
// Get the filesystem location of the current file
703
$file = "{$phpbb_root_path}styles/{$template_info['template_path']}/template/$template_file";
706
// If the template is stored on the filesystem try to write the file else store it in the database
707
if (!$safe_mode && !$template_info['template_storedb'] && file_exists($file) && @is_writable($file))
709
if (!($fp = @fopen($file, 'wb')))
711
trigger_error($user->lang['NO_TEMPLATE'] . adm_back_link($this->u_action), E_USER_WARNING);
713
fwrite($fp, $template_data);
718
$db->sql_transaction('begin');
720
// If it's not stored in the db yet, then update the template setting and store all template files in the db
721
if (!$template_info['template_storedb'])
723
$sql = 'UPDATE ' . STYLES_TEMPLATE_TABLE . '
724
SET template_storedb = 1
725
WHERE template_id = ' . $template_id;
726
$db->sql_query($sql);
728
$filelist = filelist("{$phpbb_root_path}styles/{$template_info['template_path']}/template", '', 'html');
729
$this->store_templates('insert', $template_id, $template_info['template_path'], $filelist);
731
add_log('admin', 'LOG_TEMPLATE_EDIT_DETAILS', $template_info['template_name']);
732
$additional .= '<br />' . $user->lang['EDIT_TEMPLATE_STORED_DB'];
735
// Update the template_data table entry for this template file
736
$sql = 'UPDATE ' . STYLES_TEMPLATE_DATA_TABLE . "
737
SET template_data = '" . $db->sql_escape($template_data) . "', template_mtime = " . time() . "
738
WHERE template_id = $template_id
739
AND template_filename = '" . $db->sql_escape($template_file) . "'";
740
$db->sql_query($sql);
742
$db->sql_transaction('commit');
745
// destroy the cached version of the template (filename without extension)
746
$this->clear_template_cache($template_info, array(substr($template_file, 0, -5)));
748
$cache->destroy('sql', STYLES_TABLE);
750
add_log('admin', 'LOG_TEMPLATE_EDIT', $template_info['template_name'], $template_file);
751
trigger_error($user->lang['TEMPLATE_FILE_UPDATED'] . $additional . adm_back_link($this->u_action . "&action=edit&id=$template_id&text_rows=$text_rows&template_file=$template_file"));
754
// Generate a category array containing template filenames
755
if (!$template_info['template_storedb'])
757
$template_path = "{$phpbb_root_path}styles/{$template_info['template_path']}/template";
759
$filelist = filelist($template_path, '', 'html');
760
$filelist[''] = array_diff($filelist[''], array('bbcode.html'));
764
if (!file_exists($template_path . "/$template_file") || !($template_data = file_get_contents($template_path . "/$template_file")))
766
trigger_error($user->lang['NO_TEMPLATE'] . adm_back_link($this->u_action), E_USER_WARNING);
773
FROM ' . STYLES_TEMPLATE_DATA_TABLE . "
774
WHERE template_id = $template_id";
775
$result = $db->sql_query($sql);
777
$filelist = array('' => array());
778
while ($row = $db->sql_fetchrow($result))
780
$file_info = pathinfo($row['template_filename']);
782
if (($file_info['basename'] != 'bbcode') && ($file_info['extension'] == 'html'))
784
if (($file_info['dirname'] == '.') || empty($file_info['dirname']))
786
$filelist[''][] = $row['template_filename'];
790
$filelist[$file_info['dirname'] . '/'][] = $file_info['basename'];
794
if ($row['template_filename'] == $template_file)
796
$template_data = $row['template_data'];
799
$db->sql_freeresult($result);
803
// Now create the categories
804
$filelist_cats[''] = array();
805
foreach ($filelist as $pathfile => $file_ary)
807
// Use the directory name as category name
808
if (!empty($pathfile))
810
$filelist_cats[$pathfile] = array();
811
foreach ($file_ary as $file)
813
$filelist_cats[$pathfile][$pathfile . $file] = $file;
816
// or if it's in the main category use the word before the first underscore to group files
820
foreach ($file_ary as $file)
822
$cats[] = substr($file, 0, strpos($file, '_'));
823
$filelist_cats[substr($file, 0, strpos($file, '_'))][$file] = $file;
826
$cats = array_values(array_unique($cats));
828
// we don't need any single element categories so put them into the misc '' category
829
for ($i = 0, $n = sizeof($cats); $i < $n; $i++)
831
if (sizeof($filelist_cats[$cats[$i]]) == 1 && $cats[$i] !== '')
833
$filelist_cats[''][key($filelist_cats[$cats[$i]])] = current($filelist_cats[$cats[$i]]);
834
unset($filelist_cats[$cats[$i]]);
842
// Generate list of categorised template files
844
ksort($filelist_cats);
845
foreach ($filelist_cats as $category => $tpl_ary)
849
if (!empty($category))
851
$tpl_options .= '<option class="sep" value="">' . $category . '</option>';
854
foreach ($tpl_ary as $filename => $file)
856
$selected = ($template_file == $filename) ? ' selected="selected"' : '';
857
$tpl_options .= '<option value="' . $filename . '"' . $selected . '>' . $file . '</option>';
861
$template->assign_vars(array(
862
'S_EDIT_TEMPLATE' => true,
863
'S_HIDDEN_FIELDS' => build_hidden_fields(array('template_file' => $template_file)),
864
'S_TEMPLATES' => $tpl_options,
866
'U_ACTION' => $this->u_action . "&action=edit&id=$template_id&text_rows=$text_rows",
867
'U_BACK' => $this->u_action,
869
'L_EDIT' => $user->lang['EDIT_TEMPLATE'],
870
'L_EDIT_EXPLAIN' => $user->lang['EDIT_TEMPLATE_EXPLAIN'],
871
'L_EDITOR' => $user->lang['TEMPLATE_EDITOR'],
872
'L_EDITOR_HEIGHT' => $user->lang['TEMPLATE_EDITOR_HEIGHT'],
873
'L_FILE' => $user->lang['TEMPLATE_FILE'],
874
'L_SELECT' => $user->lang['SELECT_TEMPLATE'],
875
'L_SELECTED' => $user->lang['SELECTED_TEMPLATE'],
876
'L_SELECTED_FILE' => $user->lang['SELECTED_TEMPLATE_FILE'],
878
'SELECTED_TEMPLATE' => $template_info['template_name'],
879
'TEMPLATE_FILE' => $template_file,
880
'TEMPLATE_DATA' => utf8_htmlspecialchars($template_data),
881
'TEXT_ROWS' => $text_rows)
886
* Allows the admin to view cached versions of template files and clear single template cache files
888
* @param int $template_id specifies which template's cache is shown
890
function template_cache($template_id)
892
global $phpbb_root_path, $phpEx, $config, $db, $cache, $user, $template;
894
$source = str_replace('/', '.', request_var('source', ''));
895
$file_ary = array_diff(request_var('delete', array('')), array(''));
896
$submit = isset($_POST['submit']) ? true : false;
899
FROM ' . STYLES_TEMPLATE_TABLE . "
900
WHERE template_id = $template_id";
901
$result = $db->sql_query($sql);
902
$template_row = $db->sql_fetchrow($result);
903
$db->sql_freeresult($result);
907
trigger_error($user->lang['NO_TEMPLATE'] . adm_back_link($this->u_action), E_USER_WARNING);
910
// User wants to delete one or more files ...
911
if ($submit && $file_ary)
913
$this->clear_template_cache($template_row, $file_ary);
914
trigger_error($user->lang['TEMPLATE_CACHE_CLEARED'] . adm_back_link($this->u_action . "&action=cache&id=$template_id"));
917
$cache_prefix = 'tpl_' . $template_row['template_path'];
919
// Someone wants to see the cached source ... so we'll highlight it,
920
// add line numbers and indent it appropriately. This could be nasty
921
// on larger source files ...
922
if ($source && file_exists("{$phpbb_root_path}cache/{$cache_prefix}_$source.html.$phpEx"))
924
adm_page_header($user->lang['TEMPLATE_CACHE']);
926
$template->set_filenames(array(
927
'body' => 'viewsource.html')
930
$template->assign_vars(array(
931
'FILENAME' => str_replace('.', '/', $source) . '.html')
934
$code = str_replace(array("\r\n", "\r"), array("\n", "\n"), file_get_contents("{$phpbb_root_path}cache/{$cache_prefix}_$source.html.$phpEx"));
936
$conf = array('highlight.bg', 'highlight.comment', 'highlight.default', 'highlight.html', 'highlight.keyword', 'highlight.string');
937
foreach ($conf as $ini_var)
939
@ini_set($ini_var, str_replace('highlight.', 'syntax', $ini_var));
942
$marker = 'MARKER' . time();
943
$code = highlight_string(str_replace("\n", $marker, $code), true);
944
$code = str_replace($marker, "\n", $code);
945
$str_from = array('<span style="color: ', '<font color="syntax', '</font>', '<code>', '</code>','[', ']', '.', ':');
946
$str_to = array('<span class="', '<span class="syntax', '</span>', '', '', '[', ']', '.', ':');
948
$code = str_replace($str_from, $str_to, $code);
949
$code = preg_replace('#^(<span class="[a-z_]+">)\n?(.*?)\n?(</span>)$#ism', '$1$2$3', $code);
950
$code = substr($code, strlen('<span class="syntaxhtml">'));
951
$code = substr($code, 0, -1 * strlen('</ span>'));
952
$code = explode("\n", $code);
954
foreach ($code as $key => $line)
956
$template->assign_block_vars('source', array(
957
'LINENUM' => $key + 1,
958
'LINE' => preg_replace('#([^ ;]) ([^ &])#', '$1 $2', $line))
966
$filemtime = array();
967
if ($template_row['template_storedb'])
969
$sql = 'SELECT template_filename, template_mtime
970
FROM ' . STYLES_TEMPLATE_DATA_TABLE . "
971
WHERE template_id = $template_id";
972
$result = $db->sql_query($sql);
974
$filemtime = array();
975
while ($row = $db->sql_fetchrow($result))
977
$filemtime[$row['template_filename']] = $row['template_mtime'];
979
$db->sql_freeresult($result);
982
// Get a list of cached template files and then retrieve additional information about them
983
$file_ary = $this->template_cache_filelist($template_row['template_path']);
985
foreach ($file_ary as $file)
987
$file = str_replace('/', '.', $file);
989
// perform some dirty guessing to get the path right.
990
// We assume that three dots in a row were '../'
991
$tpl_file = str_replace('.', '/', $file);
992
$tpl_file = str_replace('///', '../', $tpl_file);
994
$filename = "{$cache_prefix}_$file.html.$phpEx";
996
if (!file_exists("{$phpbb_root_path}cache/$filename"))
1001
$template->assign_block_vars('file', array(
1002
'U_VIEWSOURCE' => $this->u_action . "&action=cache&id=$template_id&source=$file",
1004
'CACHED' => $user->format_date(filemtime("{$phpbb_root_path}cache/$filename")),
1005
'FILENAME' => $file,
1006
'FILESIZE' => sprintf('%.1f KB', filesize("{$phpbb_root_path}cache/$filename") / 1024),
1007
'MODIFIED' => $user->format_date((!$template_row['template_storedb']) ? filemtime("{$phpbb_root_path}styles/{$template_row['template_path']}/template/$tpl_file.html") : $filemtime[$file . '.html']))
1012
$template->assign_vars(array(
1014
'S_TEMPLATE' => true,
1016
'U_ACTION' => $this->u_action . "&action=cache&id=$template_id",
1017
'U_BACK' => $this->u_action)
1022
* Provides a css editor and a basic easier to use stylesheet editing tool for less experienced (or lazy) users
1024
* @param int $theme_id specifies which theme is being edited
1026
function edit_theme($theme_id)
1028
global $phpbb_root_path, $phpEx, $config, $db, $cache, $user, $template, $safe_mode;
1030
$this->page_title = 'EDIT_THEME';
1032
$filelist = $filelist_cats = array();
1034
$theme_data = utf8_normalize_nfc(request_var('template_data', '', true));
1035
$theme_data = htmlspecialchars_decode($theme_data);
1036
$theme_file = utf8_normalize_nfc(request_var('template_file', '', true));
1037
$text_rows = max(5, min(999, request_var('text_rows', 20)));
1038
$save_changes = (isset($_POST['save'])) ? true : false;
1040
// make sure theme_file path doesn't go upwards
1041
$theme_file = str_replace('..', '.', $theme_file);
1043
// Retrieve some information about the theme
1044
$sql = 'SELECT theme_storedb, theme_path, theme_name, theme_data
1045
FROM ' . STYLES_THEME_TABLE . "
1046
WHERE theme_id = $theme_id";
1047
$result = $db->sql_query($sql);
1049
if (!($theme_info = $db->sql_fetchrow($result)))
1051
trigger_error($user->lang['NO_THEME'] . adm_back_link($this->u_action), E_USER_WARNING);
1053
$db->sql_freeresult($result);
1055
// save changes to the theme if the user submitted any
1058
// Get the filesystem location of the current file
1059
$file = "{$phpbb_root_path}styles/{$theme_info['theme_path']}/theme/$theme_file";
1061
$message = $user->lang['THEME_UPDATED'];
1063
// If the theme is stored on the filesystem try to write the file else store it in the database
1064
if (!$safe_mode && !$theme_info['theme_storedb'] && file_exists($file) && @is_writable($file))
1066
if (!($fp = @fopen($file, 'wb')))
1068
trigger_error($user->lang['NO_THEME'] . adm_back_link($this->u_action), E_USER_WARNING);
1070
fwrite($fp, $theme_data);
1075
// Write stylesheet to db
1077
'theme_mtime' => time(),
1078
'theme_storedb' => 1,
1079
'theme_data' => $this->db_theme_data($theme_info, $theme_data),
1081
$sql = 'UPDATE ' . STYLES_THEME_TABLE . '
1082
SET ' . $db->sql_build_array('UPDATE', $sql_ary) . '
1083
WHERE theme_id = ' . $theme_id;
1084
$db->sql_query($sql);
1086
$cache->destroy('sql', STYLES_THEME_TABLE);
1088
// notify the user if the theme was not stored in the db before his modification
1089
if (!$theme_info['theme_storedb'])
1091
add_log('admin', 'LOG_THEME_EDIT_DETAILS', $theme_info['theme_name']);
1092
$message .= '<br />' . $user->lang['EDIT_THEME_STORED_DB'];
1095
$cache->destroy('sql', STYLES_THEME_TABLE);
1096
add_log('admin', (!$theme_info['theme_storedb']) ? 'LOG_THEME_EDIT_FILE' : 'LOG_THEME_EDIT', $theme_info['theme_name'], (!$theme_info['theme_storedb']) ? $theme_file : '');
1098
trigger_error($message . adm_back_link($this->u_action . "&action=edit&id=$theme_id&template_file=$theme_file&text_rows=$text_rows"));
1101
// Generate a category array containing theme filenames
1102
if (!$theme_info['theme_storedb'])
1104
$theme_path = "{$phpbb_root_path}styles/{$theme_info['theme_path']}/theme";
1106
$filelist = filelist($theme_path, '', 'css');
1110
if (!file_exists($theme_path . "/$theme_file") || !($theme_data = file_get_contents($theme_path . "/$theme_file")))
1112
trigger_error($user->lang['NO_THEME'] . adm_back_link($this->u_action), E_USER_WARNING);
1118
$theme_data = &$theme_info['theme_data'];
1121
// Now create the categories
1122
$filelist_cats[''] = array();
1123
foreach ($filelist as $pathfile => $file_ary)
1125
// Use the directory name as category name
1126
if (!empty($pathfile))
1128
$filelist_cats[$pathfile] = array();
1129
foreach ($file_ary as $file)
1131
$filelist_cats[$pathfile][$pathfile . $file] = $file;
1134
// or if it's in the main category use the word before the first underscore to group files
1138
foreach ($file_ary as $file)
1140
$cats[] = substr($file, 0, strpos($file, '_'));
1141
$filelist_cats[substr($file, 0, strpos($file, '_'))][$file] = $file;
1144
$cats = array_values(array_unique($cats));
1146
// we don't need any single element categories so put them into the misc '' category
1147
for ($i = 0, $n = sizeof($cats); $i < $n; $i++)
1149
if (sizeof($filelist_cats[$cats[$i]]) == 1 && $cats[$i] !== '')
1151
$filelist_cats[''][key($filelist_cats[$cats[$i]])] = current($filelist_cats[$cats[$i]]);
1152
unset($filelist_cats[$cats[$i]]);
1160
// Generate list of categorised theme files
1162
ksort($filelist_cats);
1163
foreach ($filelist_cats as $category => $tpl_ary)
1167
if (!empty($category))
1169
$tpl_options .= '<option class="sep" value="">' . $category . '</option>';
1172
foreach ($tpl_ary as $filename => $file)
1174
$selected = ($theme_file == $filename) ? ' selected="selected"' : '';
1175
$tpl_options .= '<option value="' . $filename . '"' . $selected . '>' . $file . '</option>';
1179
$template->assign_vars(array(
1180
'S_EDIT_THEME' => true,
1181
'S_HIDDEN_FIELDS' => build_hidden_fields(array('template_file' => $theme_file)),
1182
'S_THEME_IN_DB' => $theme_info['theme_storedb'],
1183
'S_TEMPLATES' => $tpl_options,
1185
'U_ACTION' => $this->u_action . "&action=edit&id=$theme_id&text_rows=$text_rows",
1186
'U_BACK' => $this->u_action,
1188
'L_EDIT' => $user->lang['EDIT_THEME'],
1189
'L_EDIT_EXPLAIN' => $user->lang['EDIT_THEME_EXPLAIN'],
1190
'L_EDITOR' => $user->lang['THEME_EDITOR'],
1191
'L_EDITOR_HEIGHT' => $user->lang['THEME_EDITOR_HEIGHT'],
1192
'L_FILE' => $user->lang['THEME_FILE'],
1193
'L_SELECT' => $user->lang['SELECT_THEME'],
1194
'L_SELECTED' => $user->lang['SELECTED_THEME'],
1195
'L_SELECTED_FILE' => $user->lang['SELECTED_THEME_FILE'],
1197
'SELECTED_TEMPLATE' => $theme_info['theme_name'],
1198
'TEMPLATE_FILE' => $theme_file,
1199
'TEMPLATE_DATA' => utf8_htmlspecialchars($theme_data),
1200
'TEXT_ROWS' => $text_rows)
1208
* @param int $imageset_id specifies which imageset is being edited
1210
function edit_imageset($imageset_id)
1212
global $db, $user, $phpbb_root_path, $cache, $template;
1214
$this->page_title = 'EDIT_IMAGESET';
1216
$update = (isset($_POST['update'])) ? true : false;
1218
$imgname = request_var('imgname', '');
1219
$imgpath = request_var('imgpath', '');
1220
$imgsize = request_var('imgsize', false);
1221
$imgwidth = request_var('imgwidth', 0);
1222
$imgheight = request_var('imgheight', 0);
1224
$imgname = preg_replace('#[^a-z0-9\-+_]#i', '', $imgname);
1225
$imgpath = str_replace('..', '.', $imgpath);
1229
$sql = 'SELECT imageset_path, imageset_name
1230
FROM ' . STYLES_IMAGESET_TABLE . "
1231
WHERE imageset_id = $imageset_id";
1232
$result = $db->sql_query($sql);
1233
$imageset_row = $db->sql_fetchrow($result);
1234
$db->sql_freeresult($result);
1236
$imageset_path = $imageset_row['imageset_path'];
1237
$imageset_name = $imageset_row['imageset_name'];
1240
if (strpos($imgname, '-') !== false)
1242
list($imgname, $imgnamelang) = explode('-', $imgname);
1243
$sql_extra = " AND image_lang IN ('" . $db->sql_escape($imgnamelang) . "', '')";
1246
$sql = 'SELECT image_filename, image_width, image_height, image_lang, image_id
1247
FROM ' . STYLES_IMAGESET_DATA_TABLE . "
1248
WHERE imageset_id = $imageset_id
1249
AND image_name = '" . $db->sql_escape($imgname) . "'$sql_extra";
1250
$result = $db->sql_query($sql);
1251
$imageset_data_row = $db->sql_fetchrow($result);
1252
$db->sql_freeresult($result);
1254
$image_filename = $imageset_data_row['image_filename'];
1255
$image_width = $imageset_data_row['image_width'];
1256
$image_height = $imageset_data_row['image_height'];
1257
$image_lang = $imageset_data_row['image_lang'];
1258
$image_id = $imageset_data_row['image_id'];
1262
trigger_error($user->lang['NO_IMAGESET'] . adm_back_link($this->u_action), E_USER_WARNING);
1265
// Check to see whether the selected image exists in the table
1266
$valid_name = ($update) ? false : true;
1268
foreach ($this->imageset_keys as $category => $img_ary)
1270
if (in_array($imgname, $img_ary))
1277
if ($update && isset($_POST['imgpath']))
1281
// If imgwidth and imgheight are non-zero grab the actual size
1282
// from the image itself ... we ignore width settings for the poll center image
1283
$imgwidth = request_var('imgwidth', 0);
1284
$imgheight = request_var('imgheight', 0);
1287
if ($imgpath && !file_exists("{$phpbb_root_path}styles/$imageset_path/imageset/$imgpath"))
1289
trigger_error($user->lang['NO_IMAGE_ERROR'] . adm_back_link($this->u_action), E_USER_WARNING);
1292
if ($imgsize && $imgpath)
1294
if (!$imgwidth || !$imgheight)
1296
list($imgwidth_file, $imgheight_file) = getimagesize("{$phpbb_root_path}styles/$imageset_path/imageset/$imgpath");
1297
$imgwidth = ($imgwidth) ? $imgwidth : $imgwidth_file;
1298
$imgheight = ($imgheight) ? $imgheight : $imgheight_file;
1300
$imgwidth = ($imgname != 'poll_center') ? (int) $imgwidth : 0;
1301
$imgheight = (int) $imgheight;
1305
if (strpos($imgpath, '/') !== false)
1307
list($imglang, $imgfilename) = explode('/', $imgpath);
1311
$imgfilename = $imgpath;
1315
'image_filename' => (string) $imgfilename,
1316
'image_width' => (int) $imgwidth,
1317
'image_height' => (int) $imgheight,
1318
'image_lang' => (string) $imglang,
1322
if ($imageset_data_row)
1324
$sql = 'UPDATE ' . STYLES_IMAGESET_DATA_TABLE . '
1325
SET ' . $db->sql_build_array('UPDATE', $sql_ary) . "
1326
WHERE image_id = $image_id";
1327
$db->sql_query($sql);
1330
else if (!$imageset_data_row)
1332
$sql_ary['image_name'] = $imgname;
1333
$sql_ary['imageset_id'] = (int) $imageset_id;
1334
$db->sql_query('INSERT INTO ' . STYLES_IMAGESET_DATA_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary));
1337
$cache->destroy('sql', STYLES_IMAGESET_DATA_TABLE);
1339
add_log('admin', 'LOG_IMAGESET_EDIT', $imageset_name);
1341
$template->assign_var('SUCCESS', true);
1343
$image_filename = $imgfilename;
1344
$image_width = $imgwidth;
1345
$image_height = $imgheight;
1346
$image_lang = $imglang;
1352
$imagesetlist = array('nolang' => array(), 'lang' => array());
1355
$dir = "{$phpbb_root_path}styles/$imageset_path/imageset";
1356
$dp = @opendir($dir);
1360
while (($file = readdir($dp)) !== false)
1362
if ($file[0] != '.' && strtoupper($file) != 'CVS' && !is_file($dir . '/' . $file) && !is_link($dir . '/' . $file))
1366
else if (preg_match('#\.(?:gif|jpg|png)$#', $file))
1368
$imagesetlist['nolang'][] = $file;
1374
$dp2 = @opendir("$dir/$imgnamelang");
1378
while (($file2 = readdir($dp2)) !== false)
1380
if (preg_match('#\.(?:gif|jpg|png)$#', $file2))
1382
$imagesetlist['lang'][] = "$imgnamelang/$file2";
1391
// Generate list of image options
1393
foreach ($this->imageset_keys as $category => $img_ary)
1395
$template->assign_block_vars('category', array(
1396
'NAME' => $user->lang['IMG_CAT_' . strtoupper($category)]
1399
foreach ($img_ary as $img)
1401
if ($category == 'buttons')
1403
foreach ($langs as $language)
1405
$template->assign_block_vars('category.images', array(
1406
'SELECTED' => ($img == $imgname && $language == $imgnamelang),
1407
'VALUE' => $img . '-' . $language,
1408
'TEXT' => $user->lang['IMG_' . strtoupper($img)] . ' [ ' . $language . ' ]'
1414
$template->assign_block_vars('category.images', array(
1415
'SELECTED' => ($img == $imgname),
1417
'TEXT' => (($category == 'custom') ? $img : $user->lang['IMG_' . strtoupper($img)])
1423
// Make sure the list of possible images is sorted alphabetically
1424
sort($imagesetlist['lang']);
1425
sort($imagesetlist['nolang']);
1427
$image_found = false;
1429
foreach ($imagesetlist as $type => $img_ary)
1431
if ($type !== 'lang' || $sql_extra)
1433
$template->assign_block_vars('imagesetlist', array(
1434
'TYPE' => ($type == 'lang')
1438
foreach ($img_ary as $img)
1440
$imgtext = preg_replace('/^([^\/]+\/)/', '', $img);
1441
$selected = (!empty($imgname) && strpos($image_filename, $imgtext) !== false);
1444
$image_found = true;
1445
$img_val = htmlspecialchars($img);
1447
$template->assign_block_vars('imagesetlist.images', array(
1448
'SELECTED' => $selected,
1450
'VALUE' => htmlspecialchars($img)
1455
$imgsize_bool = (!empty($imgname) && $image_width && $image_height) ? true : false;
1456
$image_request = '../styles/' . $imageset_path . '/imageset/' . ($image_lang ? $imgnamelang . '/' : '') . $image_filename;
1458
$template->assign_vars(array(
1459
'S_EDIT_IMAGESET' => true,
1460
'L_TITLE' => $user->lang[$this->page_title],
1461
'L_EXPLAIN' => $user->lang[$this->page_title . '_EXPLAIN'],
1462
'IMAGE_OPTIONS' => $img_options,
1463
'IMAGE_SIZE' => $image_width,
1464
'IMAGE_HEIGHT' => $image_height,
1465
'IMAGE_REQUEST' => (empty($image_filename)) ? 'images/no_image.png' : $image_request,
1466
'U_ACTION' => $this->u_action . "&action=edit&id=$imageset_id",
1467
'U_BACK' => $this->u_action,
1468
'NAME' => $imageset_name,
1469
'A_NAME' => addslashes($imageset_name),
1470
'ERROR' => !$valid_name,
1471
'IMG_SRC' => ($image_found) ? '../styles/' . $imageset_path . '/imageset/' . $img_val : 'images/no_image.png',
1472
'IMAGE_SELECT' => $image_found
1477
* Remove style/template/theme/imageset
1479
function remove($mode, $style_id)
1481
global $db, $template, $user, $phpbb_root_path, $cache, $config;
1483
$new_id = request_var('new_id', 0);
1484
$update = (isset($_POST['update'])) ? true : false;
1490
$sql_from = STYLES_TABLE;
1491
$sql_select = 'style_name';
1492
$sql_where = 'AND style_active = 1';
1496
$sql_from = STYLES_TEMPLATE_TABLE;
1497
$sql_select = 'template_name, template_path, template_storedb';
1501
$sql_from = STYLES_THEME_TABLE;
1502
$sql_select = 'theme_name, theme_path, theme_storedb';
1506
$sql_from = STYLES_IMAGESET_TABLE;
1507
$sql_select = 'imageset_name, imageset_path';
1511
$l_prefix = strtoupper($mode);
1513
$sql = "SELECT $sql_select
1515
WHERE {$mode}_id = $style_id";
1516
$result = $db->sql_query($sql);
1517
$style_row = $db->sql_fetchrow($result);
1518
$db->sql_freeresult($result);
1522
trigger_error($user->lang['NO_' . $l_prefix] . adm_back_link($this->u_action), E_USER_WARNING);
1525
$sql = "SELECT {$mode}_id, {$mode}_name
1527
WHERE {$mode}_id <> $style_id
1529
ORDER BY {$mode}_name ASC";
1530
$result = $db->sql_query($sql);
1534
if ($row = $db->sql_fetchrow($result))
1538
$s_options .= '<option value="' . $row[$mode . '_id'] . '">' . $row[$mode . '_name'] . '</option>';
1540
while ($row = $db->sql_fetchrow($result));
1544
trigger_error($user->lang['ONLY_' . $l_prefix] . adm_back_link($this->u_action), E_USER_WARNING);
1546
$db->sql_freeresult($result);
1550
$sql = "DELETE FROM $sql_from
1551
WHERE {$mode}_id = $style_id";
1552
$db->sql_query($sql);
1554
if ($mode == 'style')
1556
$sql = 'UPDATE ' . USERS_TABLE . "
1557
SET user_style = $new_id
1558
WHERE user_style = $style_id";
1559
$db->sql_query($sql);
1561
$sql = 'UPDATE ' . FORUMS_TABLE . "
1562
SET forum_style = $new_id
1563
WHERE forum_style = $style_id";
1564
$db->sql_query($sql);
1566
if ($style_id == $config['default_style'])
1568
set_config('default_style', $new_id);
1573
if ($mode == 'imageset')
1575
$sql = 'DELETE FROM ' . STYLES_IMAGESET_DATA_TABLE . "
1576
WHERE imageset_id = $style_id";
1577
$db->sql_query($sql);
1579
$sql = 'UPDATE ' . STYLES_TABLE . "
1580
SET {$mode}_id = $new_id
1581
WHERE {$mode}_id = $style_id";
1582
$db->sql_query($sql);
1585
$cache->destroy('sql', STYLES_TABLE);
1587
add_log('admin', 'LOG_' . $l_prefix . '_DELETE', $style_row[$mode . '_name']);
1588
$message = ($mode != 'style') ? $l_prefix . '_DELETED_FS' : $l_prefix . '_DELETED';
1589
trigger_error($user->lang[$message] . adm_back_link($this->u_action));
1592
$this->page_title = 'DELETE_' . $l_prefix;
1594
$template->assign_vars(array(
1596
'S_REPLACE_OPTIONS' => $s_options,
1598
'L_TITLE' => $user->lang[$this->page_title],
1599
'L_EXPLAIN' => $user->lang[$this->page_title . '_EXPLAIN'],
1600
'L_NAME' => $user->lang[$l_prefix . '_NAME'],
1601
'L_REPLACE' => $user->lang['REPLACE_' . $l_prefix],
1602
'L_REPLACE_EXPLAIN' => $user->lang['REPLACE_' . $l_prefix . '_EXPLAIN'],
1604
'U_ACTION' => $this->u_action . "&action=delete&id=$style_id",
1605
'U_BACK' => $this->u_action,
1607
'NAME' => $style_row[$mode . '_name'],
1613
* Export style or style elements
1615
function export($mode, $style_id)
1617
global $db, $template, $user, $phpbb_root_path, $cache, $phpEx, $config;
1619
$update = (isset($_POST['update'])) ? true : false;
1621
$inc_template = request_var('inc_template', 0);
1622
$inc_theme = request_var('inc_theme', 0);
1623
$inc_imageset = request_var('inc_imageset', 0);
1624
$store = request_var('store', 0);
1625
$format = request_var('format', '');
1628
$methods = array('tar');
1630
$available_methods = array('tar.gz' => 'zlib', 'tar.bz2' => 'bz2', 'zip' => 'zlib');
1631
foreach ($available_methods as $type => $module)
1633
if (!@extension_loaded($module))
1641
if (!in_array($format, $methods))
1649
if ($update && ($inc_template + $inc_theme + $inc_imageset) < 1)
1651
$error[] = $user->lang['STYLE_ERR_MORE_ELEMENTS'];
1654
$name = 'style_name';
1656
$sql_select = 's.style_id, s.style_name, s.style_copyright';
1657
$sql_select .= ($inc_template) ? ', t.*' : ', t.template_name';
1658
$sql_select .= ($inc_theme) ? ', c.*' : ', c.theme_name';
1659
$sql_select .= ($inc_imageset) ? ', i.*' : ', i.imageset_name';
1660
$sql_from = STYLES_TABLE . ' s, ' . STYLES_TEMPLATE_TABLE . ' t, ' . STYLES_THEME_TABLE . ' c, ' . STYLES_IMAGESET_TABLE . ' i';
1661
$sql_where = "s.style_id = $style_id AND t.template_id = s.template_id AND c.theme_id = s.theme_id AND i.imageset_id = s.imageset_id";
1663
$l_prefix = 'STYLE';
1667
$name = 'template_name';
1670
$sql_from = STYLES_TEMPLATE_TABLE;
1671
$sql_where = "template_id = $style_id";
1673
$l_prefix = 'TEMPLATE';
1677
$name = 'theme_name';
1680
$sql_from = STYLES_THEME_TABLE;
1681
$sql_where = "theme_id = $style_id";
1683
$l_prefix = 'THEME';
1687
$name = 'imageset_name';
1690
$sql_from = STYLES_IMAGESET_TABLE;
1691
$sql_where = "imageset_id = $style_id";
1693
$l_prefix = 'IMAGESET';
1697
if ($update && !sizeof($error))
1699
$sql = "SELECT $sql_select
1702
$result = $db->sql_query($sql);
1703
$style_row = $db->sql_fetchrow($result);
1704
$db->sql_freeresult($result);
1708
trigger_error($user->lang['NO_' . $l_prefix] . adm_back_link($this->u_action), E_USER_WARNING);
1711
$var_ary = array('style_id', 'style_name', 'style_copyright', 'template_id', 'template_name', 'template_path', 'template_copyright', 'template_storedb', 'bbcode_bitfield', 'theme_id', 'theme_name', 'theme_path', 'theme_copyright', 'theme_storedb', 'theme_mtime', 'theme_data', 'imageset_id', 'imageset_name', 'imageset_path', 'imageset_copyright');
1713
foreach ($var_ary as $var)
1715
if (!isset($style_row[$var]))
1717
$style_row[$var] = '';
1721
$files = $data = array();
1723
if ($mode == 'style')
1725
$style_cfg = str_replace(array('{MODE}', '{NAME}', '{COPYRIGHT}', '{VERSION}'), array($mode, $style_row['style_name'], $style_row['style_copyright'], $config['version']), $this->style_cfg);
1727
$style_cfg .= (!$inc_template) ? "\nrequired_template = {$style_row['template_name']}" : '';
1728
$style_cfg .= (!$inc_theme) ? "\nrequired_theme = {$style_row['theme_name']}" : '';
1729
$style_cfg .= (!$inc_imageset) ? "\nrequired_imageset = {$style_row['imageset_name']}" : '';
1732
'src' => $style_cfg,
1733
'prefix' => 'style.cfg'
1739
// Export template core code
1740
if ($mode == 'template' || $inc_template)
1742
$template_cfg = str_replace(array('{MODE}', '{NAME}', '{COPYRIGHT}', '{VERSION}'), array($mode, $style_row['template_name'], $style_row['template_copyright'], $config['version']), $this->template_cfg);
1743
$template_cfg .= "\nbbcode_bitfield = {$style_row['bbcode_bitfield']}";
1746
'src' => $template_cfg,
1747
'prefix' => 'template/template.cfg'
1750
// This is potentially nasty memory-wise ...
1751
if (!$style_row['template_storedb'])
1754
'src' => "styles/{$style_row['template_path']}/template/",
1755
'prefix-' => "styles/{$style_row['template_path']}/",
1757
'exclude' => 'template.cfg'
1762
$sql = 'SELECT template_filename, template_data
1763
FROM ' . STYLES_TEMPLATE_DATA_TABLE . "
1764
WHERE template_id = {$style_row['template_id']}";
1765
$result = $db->sql_query($sql);
1767
while ($row = $db->sql_fetchrow($result))
1770
'src' => $row['template_data'],
1771
'prefix' => 'template/' . $row['template_filename']
1774
$db->sql_freeresult($result);
1776
unset($template_cfg);
1779
// Export theme core code
1780
if ($mode == 'theme' || $inc_theme)
1782
$theme_cfg = str_replace(array('{MODE}', '{NAME}', '{COPYRIGHT}', '{VERSION}'), array($mode, $style_row['theme_name'], $style_row['theme_copyright'], $config['version']), $this->theme_cfg);
1784
// Read old cfg file
1785
$items = $cache->obtain_cfg_items($style_row);
1786
$items = $items['theme'];
1788
if (!isset($items['parse_css_file']))
1790
$items['parse_css_file'] = 'off';
1793
$theme_cfg = str_replace(array('{PARSE_CSS_FILE}'), array($items['parse_css_file']), $theme_cfg);
1796
'src' => "styles/{$style_row['theme_path']}/theme/",
1797
'prefix-' => "styles/{$style_row['theme_path']}/",
1799
'exclude' => ($style_row['theme_storedb']) ? 'stylesheet.css,theme.cfg' : 'theme.cfg'
1803
'src' => $theme_cfg,
1804
'prefix' => 'theme/theme.cfg'
1807
if ($style_row['theme_storedb'])
1810
'src' => $style_row['theme_data'],
1811
'prefix' => 'theme/stylesheet.css'
1815
unset($items, $theme_cfg);
1818
// Export imageset core code
1819
if ($mode == 'imageset' || $inc_imageset)
1821
$imageset_cfg = str_replace(array('{MODE}', '{NAME}', '{COPYRIGHT}', '{VERSION}'), array($mode, $style_row['imageset_name'], $style_row['imageset_copyright'], $config['version']), $this->imageset_cfg);
1823
$imageset_main = array();
1825
$sql = 'SELECT image_filename, image_name, image_height, image_width
1826
FROM ' . STYLES_IMAGESET_DATA_TABLE . "
1827
WHERE imageset_id = $style_id
1828
AND image_lang = ''";
1829
$result = $db->sql_query($sql);
1830
while ($row = $db->sql_fetchrow($result))
1832
$imageset_main[$row['image_name']] = $row['image_filename'] . ($row['image_height'] ? '*' . $row['image_height']: '') . ($row['image_width'] ? '*' . $row['image_width']: '');
1834
$db->sql_freeresult($result);
1836
foreach ($this->imageset_keys as $topic => $key_array)
1838
foreach ($key_array as $key)
1840
if (isset($imageset_main[$key]))
1842
$imageset_cfg .= "\nimg_" . $key . ' = ' . str_replace("styles/{$style_row['imageset_path']}/imageset/", '{PATH}', $imageset_main[$key]);
1848
'src' => "styles/{$style_row['imageset_path']}/imageset/",
1849
'prefix-' => "styles/{$style_row['imageset_path']}/",
1851
'exclude' => 'imageset.cfg'
1855
'src' => trim($imageset_cfg),
1856
'prefix' => 'imageset/imageset.cfg'
1861
$imageset_root = "{$phpbb_root_path}styles/{$style_row['imageset_path']}/imageset/";
1863
if ($dh = @opendir($imageset_root))
1865
while (($fname = readdir($dh)) !== false)
1867
if ($fname[0] != '.' && $fname != 'CVS' && is_dir("$imageset_root$fname"))
1869
$files[key($files)]['exclude'] .= ',' . $fname . '/imageset.cfg';
1875
$imageset_lang = array();
1877
$sql = 'SELECT image_filename, image_name, image_height, image_width, image_lang
1878
FROM ' . STYLES_IMAGESET_DATA_TABLE . "
1879
WHERE imageset_id = $style_id
1880
AND image_lang <> ''";
1881
$result = $db->sql_query($sql);
1882
while ($row = $db->sql_fetchrow($result))
1884
$imageset_lang[$row['image_lang']][$row['image_name']] = $row['image_filename'] . ($row['image_height'] ? '*' . $row['image_height']: '') . ($row['image_width'] ? '*' . $row['image_width']: '');
1886
$db->sql_freeresult($result);
1888
foreach ($imageset_lang as $lang => $imageset_localized)
1890
$imageset_cfg = str_replace(array('{MODE}', '{NAME}', '{COPYRIGHT}', '{VERSION}'), array($mode, $style_row['imageset_name'], $style_row['imageset_copyright'], $config['version']), $this->imageset_cfg);
1892
foreach ($this->imageset_keys as $topic => $key_array)
1894
foreach ($key_array as $key)
1896
if (isset($imageset_localized[$key]))
1898
$imageset_cfg .= "\nimg_" . $key . ' = ' . str_replace("styles/{$style_row['imageset_path']}/imageset/", '{PATH}', $imageset_localized[$key]);
1904
'src' => trim($imageset_cfg),
1905
'prefix' => 'imageset/' . $lang . '/imageset.cfg'
1909
unset($imageset_cfg);
1916
$mimetype = 'x-tar';
1917
$compress = 'compress_tar';
1927
$mimetype = 'x-gzip';
1932
$mimetype = 'x-bzip2';
1936
$error[] = $user->lang[$l_prefix . '_ERR_ARCHIVE'];
1939
if (!sizeof($error))
1941
include($phpbb_root_path . 'includes/functions_compress.' . $phpEx);
1943
if ($mode == 'style')
1945
$path = preg_replace('#[^\w-]+#', '_', $style_row['style_name']);
1949
$path = $style_row[$mode . '_path'];
1952
if ($format == 'zip')
1954
$compress = new compress_zip('w', $phpbb_root_path . "store/$path$ext");
1958
$compress = new compress_tar('w', $phpbb_root_path . "store/$path$ext", $ext);
1963
foreach ($files as $file_ary)
1965
$compress->add_file($file_ary['src'], $file_ary['prefix-'], $file_ary['prefix+'], $file_ary['exclude']);
1971
foreach ($data as $data_ary)
1973
$compress->add_data($data_ary['src'], $data_ary['prefix']);
1979
add_log('admin', 'LOG_' . $l_prefix . '_EXPORT', $style_row[$mode . '_name']);
1983
$compress->download($path);
1984
@unlink("{$phpbb_root_path}store/$path$ext");
1988
trigger_error(sprintf($user->lang[$l_prefix . '_EXPORTED'], "store/$path$ext") . adm_back_link($this->u_action));
1992
$sql = "SELECT {$mode}_id, {$mode}_name
1993
FROM " . (($mode == 'style') ? STYLES_TABLE : $sql_from) . "
1994
WHERE {$mode}_id = $style_id";
1995
$result = $db->sql_query($sql);
1996
$style_row = $db->sql_fetchrow($result);
1997
$db->sql_freeresult($result);
2001
trigger_error($user->lang['NO_' . $l_prefix] . adm_back_link($this->u_action), E_USER_WARNING);
2004
$this->page_title = $l_prefix . '_EXPORT';
2006
$format_buttons = '';
2007
foreach ($methods as $method)
2009
$format_buttons .= '<label><input type="radio"' . ((!$format_buttons) ? ' id="format"' : '') . ' class="radio" value="' . $method . '" name="format"' . (($method == $format) ? ' checked="checked"' : '') . ' /> ' . $method . '</label>';
2012
$template->assign_vars(array(
2014
'S_ERROR_MSG' => (sizeof($error)) ? true : false,
2015
'S_STYLE' => ($mode == 'style') ? true : false,
2017
'L_TITLE' => $user->lang[$this->page_title],
2018
'L_EXPLAIN' => $user->lang[$this->page_title . '_EXPLAIN'],
2019
'L_NAME' => $user->lang[$l_prefix . '_NAME'],
2021
'U_ACTION' => $this->u_action . '&action=export&id=' . $style_id,
2022
'U_BACK' => $this->u_action,
2024
'ERROR_MSG' => (sizeof($error)) ? implode('<br />', $error) : '',
2025
'NAME' => $style_row[$mode . '_name'],
2026
'FORMAT_BUTTONS' => $format_buttons)
2033
function details($mode, $style_id)
2035
global $template, $db, $config, $user, $safe_mode, $cache, $phpbb_root_path;
2037
$update = (isset($_POST['update'])) ? true : false;
2038
$l_type = strtoupper($mode);
2041
$element_ary = array('template' => STYLES_TEMPLATE_TABLE, 'theme' => STYLES_THEME_TABLE, 'imageset' => STYLES_IMAGESET_TABLE);
2046
$sql_from = STYLES_TABLE;
2050
$sql_from = STYLES_TEMPLATE_TABLE;
2054
$sql_from = STYLES_THEME_TABLE;
2058
$sql_from = STYLES_IMAGESET_TABLE;
2064
WHERE {$mode}_id = $style_id";
2065
$result = $db->sql_query($sql);
2066
$style_row = $db->sql_fetchrow($result);
2067
$db->sql_freeresult($result);
2071
trigger_error($user->lang['NO_' . $l_type] . adm_back_link($this->u_action), E_USER_WARNING);
2074
$style_row['style_default'] = ($mode == 'style' && $config['default_style'] == $style_id) ? 1 : 0;
2078
$name = utf8_normalize_nfc(request_var('name', '', true));
2079
$copyright = utf8_normalize_nfc(request_var('copyright', '', true));
2081
$template_id = request_var('template_id', 0);
2082
$theme_id = request_var('theme_id', 0);
2083
$imageset_id = request_var('imageset_id', 0);
2085
$style_active = request_var('style_active', 0);
2086
$style_default = request_var('style_default', 0);
2087
$store_db = request_var('store_db', 0);
2089
if ($mode == 'style' && (!$template_id || !$theme_id || !$imageset_id))
2091
$error[] = $user->lang['STYLE_ERR_NO_IDS'];
2094
if ($mode == 'style' && $style_row['style_active'] && !$style_active && $config['default_style'] == $style_id)
2096
$error[] = $user->lang['DEACTIVATE_DEFAULT'];
2101
$error[] = $user->lang[$l_type . '_ERR_STYLE_NAME'];
2104
if ($mode === 'theme' || $mode === 'template')
2106
// a rather elaborate check we have to do here once to avoid trouble later
2107
$check = "{$phpbb_root_path}styles/" . $style_row["{$mode}_path"] . (($mode === 'theme') ? '/theme/stylesheet.css' : '/template');
2108
if (($style_row["{$mode}_storedb"] != $store_db) && !$store_db && ($safe_mode || !@is_writable($check)))
2110
$error[] = $user->lang['EDIT_' . strtoupper($mode) . '_STORED_DB'];
2114
// themes which have to be parsed have to go into db
2115
if ($mode == 'theme')
2117
$cfg = parse_cfg_file("{$phpbb_root_path}styles/" . $style_row["{$mode}_path"] . "/theme/theme.cfg");
2119
if (isset($cfg['parse_css_file']) && $cfg['parse_css_file'] && !$store_db)
2121
$error[] = $user->lang['EDIT_THEME_STORE_PARSED'];
2127
if (!sizeof($error))
2129
// Check length settings
2130
if (utf8_strlen($name) > 30)
2132
$error[] = $user->lang[$l_type . '_ERR_NAME_LONG'];
2135
if (utf8_strlen($copyright) > 60)
2137
$error[] = $user->lang[$l_type . '_ERR_COPY_LONG'];
2142
if ($update && sizeof($error))
2144
$style_row = array_merge($style_row, array(
2145
'template_id' => $template_id,
2146
'theme_id' => $theme_id,
2147
'imageset_id' => $imageset_id,
2148
'style_active' => $style_active,
2149
$mode . '_storedb' => $store_db,
2150
$mode . '_name' => $name,
2151
$mode . '_copyright' => $copyright)
2155
// User has submitted form and no errors have occurred
2156
if ($update && !sizeof($error))
2159
$mode . '_name' => $name,
2160
$mode . '_copyright' => $copyright
2168
'template_id' => (int) $template_id,
2169
'theme_id' => (int) $theme_id,
2170
'imageset_id' => (int) $imageset_id,
2171
'style_active' => (int) $style_active,
2180
if ($style_row['theme_storedb'] != $store_db)
2184
if (!$style_row['theme_storedb'])
2186
$theme_data = $this->db_theme_data($style_row);
2188
else if (!$store_db && !$safe_mode && @is_writable("{$phpbb_root_path}styles/{$style_row['theme_path']}/theme/stylesheet.css"))
2191
$theme_data = $style_row['theme_data'];
2193
if ($fp = @fopen("{$phpbb_root_path}styles/{$style_row['theme_path']}/theme/stylesheet.css", 'wb'))
2195
$store_db = (@fwrite($fp, str_replace("styles/{$style_row['theme_path']}/theme/", './', $theme_data))) ? 0 : 1;
2201
'theme_mtime' => ($store_db) ? filemtime("{$phpbb_root_path}styles/{$style_row['theme_path']}/theme/stylesheet.css") : 0,
2202
'theme_storedb' => $store_db,
2203
'theme_data' => ($store_db) ? $theme_data : '',
2210
if ($style_row['template_storedb'] != $store_db)
2212
if (!$store_db && !$safe_mode && @is_writable("{$phpbb_root_path}styles/{$style_row['template_path']}/template"))
2215
FROM ' . STYLES_TEMPLATE_DATA_TABLE . "
2216
WHERE template_id = $style_id";
2217
$result = $db->sql_query($sql);
2219
while ($row = $db->sql_fetchrow($result))
2221
if (!($fp = @fopen("{$phpbb_root_path}styles/{$style_row['template_path']}/template/" . $row['template_filename'], 'wb')))
2224
$error[] = $user->lang['EDIT_TEMPLATE_STORED_DB'];
2228
fwrite($fp, $row['template_data']);
2231
$db->sql_freeresult($result);
2235
$sql = 'DELETE FROM ' . STYLES_TEMPLATE_DATA_TABLE . "
2236
WHERE template_id = $style_id";
2237
$db->sql_query($sql);
2242
$filelist = filelist("{$phpbb_root_path}styles/{$style_row['template_path']}/template", '', 'html');
2243
$this->store_templates('insert', $style_id, $style_row['template_path'], $filelist);
2247
// We no longer store within the db, but are also not able to update the file structure
2248
// Since the admin want to switch this, we adhere to his decision. But we also need to remove the cache
2249
$sql = 'DELETE FROM ' . STYLES_TEMPLATE_DATA_TABLE . "
2250
WHERE template_id = $style_id";
2251
$db->sql_query($sql);
2255
'template_storedb' => $store_db,
2261
if (sizeof($sql_ary))
2263
$sql = "UPDATE $sql_from
2264
SET " . $db->sql_build_array('UPDATE', $sql_ary) . "
2265
WHERE {$mode}_id = $style_id";
2266
$db->sql_query($sql);
2268
// Making this the default style?
2269
if ($mode == 'style' && $style_default)
2271
set_config('default_style', $style_id);
2275
$cache->destroy('sql', STYLES_TABLE);
2277
add_log('admin', 'LOG_' . $l_type . '_EDIT_DETAILS', $name);
2280
trigger_error(implode('<br />', $error) . adm_back_link($this->u_action), E_USER_WARNING);
2284
trigger_error($user->lang[$l_type . '_DETAILS_UPDATED'] . adm_back_link($this->u_action));
2288
if ($mode == 'style')
2290
foreach ($element_ary as $element => $table)
2292
$sql = "SELECT {$element}_id, {$element}_name
2294
ORDER BY {$element}_id ASC";
2295
$result = $db->sql_query($sql);
2297
${$element . '_options'} = '';
2298
while ($row = $db->sql_fetchrow($result))
2300
$selected = ($row[$element . '_id'] == $style_row[$element . '_id']) ? ' selected="selected"' : '';
2301
${$element . '_options'} .= '<option value="' . $row[$element . '_id'] . '"' . $selected . '>' . $row[$element . '_name'] . '</option>';
2303
$db->sql_freeresult($result);
2307
$this->page_title = 'EDIT_DETAILS_' . $l_type;
2309
$template->assign_vars(array(
2310
'S_DETAILS' => true,
2311
'S_ERROR_MSG' => (sizeof($error)) ? true : false,
2312
'S_STYLE' => ($mode == 'style') ? true : false,
2313
'S_TEMPLATE' => ($mode == 'template') ? true : false,
2314
'S_THEME' => ($mode == 'theme') ? true : false,
2315
'S_IMAGESET' => ($mode == 'imageset') ? true : false,
2316
'S_STORE_DB' => (isset($style_row[$mode . '_storedb'])) ? $style_row[$mode . '_storedb'] : 0,
2317
'S_STYLE_ACTIVE' => (isset($style_row['style_active'])) ? $style_row['style_active'] : 0,
2318
'S_STYLE_DEFAULT' => (isset($style_row['style_default'])) ? $style_row['style_default'] : 0,
2320
'S_TEMPLATE_OPTIONS' => ($mode == 'style') ? $template_options : '',
2321
'S_THEME_OPTIONS' => ($mode == 'style') ? $theme_options : '',
2322
'S_IMAGESET_OPTIONS' => ($mode == 'style') ? $imageset_options : '',
2324
'U_ACTION' => $this->u_action . '&action=details&id=' . $style_id,
2325
'U_BACK' => $this->u_action,
2327
'L_TITLE' => $user->lang[$this->page_title],
2328
'L_EXPLAIN' => $user->lang[$this->page_title . '_EXPLAIN'],
2329
'L_NAME' => $user->lang[$l_type . '_NAME'],
2330
'L_LOCATION' => ($mode == 'template' || $mode == 'theme') ? $user->lang[$l_type . '_LOCATION'] : '',
2331
'L_LOCATION_EXPLAIN' => ($mode == 'template' || $mode == 'theme') ? $user->lang[$l_type . '_LOCATION_EXPLAIN'] : '',
2333
'ERROR_MSG' => (sizeof($error)) ? implode('<br />', $error) : '',
2334
'NAME' => $style_row[$mode . '_name'],
2335
'COPYRIGHT' => $style_row[$mode . '_copyright'],
2341
* Load css file contents
2343
function load_css_file($path, $filename)
2345
global $phpbb_root_path;
2347
$file = "{$phpbb_root_path}styles/$path/theme/$filename";
2349
if (file_exists($file) && ($content = file_get_contents($file)))
2351
$content = trim($content);
2362
* Returns a string containing the value that should be used for the theme_data column in the theme database table.
2363
* Includes contents of files loaded via @import
2365
* @param array $theme_row is an associative array containing the theme's current database entry
2366
* @param mixed $stylesheet can either be the new content for the stylesheet or false to load from the standard file
2367
* @param string $root_path should only be used in case you want to use a different root path than "{$phpbb_root_path}styles/{$theme_row['theme_path']}"
2369
* @return string Stylesheet data for theme_data column in the theme table
2371
function db_theme_data($theme_row, $stylesheet = false, $root_path = '')
2373
global $phpbb_root_path;
2377
$root_path = $phpbb_root_path . 'styles/' . $theme_row['theme_path'];
2383
if (file_exists($root_path . '/theme/stylesheet.css'))
2385
$stylesheet = file_get_contents($root_path . '/theme/stylesheet.css');
2389
// Match CSS imports
2391
preg_match_all('/@import url\(["\'](.*)["\']\);/i', $stylesheet, $matches);
2393
if (sizeof($matches))
2395
foreach ($matches[0] as $idx => $match)
2397
$stylesheet = str_replace($match, acp_styles::load_css_file($theme_row['theme_path'], $matches[1][$idx]), $stylesheet);
2402
return str_replace('./', 'styles/' . $theme_row['theme_path'] . '/theme/', $stylesheet);
2406
* Store template files into db
2408
function store_templates($mode, $style_id, $template_path, $filelist)
2410
global $phpbb_root_path, $phpEx, $db;
2412
$template_path = $template_path . '/template/';
2413
$includes = array();
2414
foreach ($filelist as $pathfile => $file_ary)
2416
foreach ($file_ary as $file)
2418
if (!($fp = @fopen("{$phpbb_root_path}styles/$template_path$pathfile$file", 'r')))
2420
trigger_error("Could not open {$phpbb_root_path}styles/$template_path$pathfile$file", E_USER_ERROR);
2422
$template_data = fread($fp, filesize("{$phpbb_root_path}styles/$template_path$pathfile$file"));
2425
if (preg_match_all('#<!-- INCLUDE (.*?\.html) -->#is', $template_data, $matches))
2427
foreach ($matches[1] as $match)
2429
$includes[trim($match)][] = $file;
2435
foreach ($filelist as $pathfile => $file_ary)
2437
foreach ($file_ary as $file)
2440
if (strpos($file, 'index.') === 0)
2445
// We could do this using extended inserts ... but that could be one
2446
// heck of a lot of data ...
2448
'template_id' => (int) $style_id,
2449
'template_filename' => "$pathfile$file",
2450
'template_included' => (isset($includes[$file])) ? implode(':', $includes[$file]) . ':' : '',
2451
'template_mtime' => (int) filemtime("{$phpbb_root_path}styles/$template_path$pathfile$file"),
2452
'template_data' => (string) file_get_contents("{$phpbb_root_path}styles/$template_path$pathfile$file"),
2455
if ($mode == 'insert')
2457
$sql = 'INSERT INTO ' . STYLES_TEMPLATE_DATA_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary);
2461
$sql = 'UPDATE ' . STYLES_TEMPLATE_DATA_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $sql_ary) . "
2462
WHERE template_id = $style_id
2463
AND template_filename = '" . $db->sql_escape("$pathfile$file") . "'";
2465
$db->sql_query($sql);
2471
* Returns an array containing all template filenames for one template that are currently cached.
2473
* @param string $template_path contains the name of the template's folder in /styles/
2475
* @return array of filenames that exist in /styles/$template_path/template/ (without extension!)
2477
function template_cache_filelist($template_path)
2479
global $phpbb_root_path, $phpEx, $user;
2481
$cache_prefix = 'tpl_' . $template_path;
2483
if (!($dp = @opendir("{$phpbb_root_path}cache")))
2485
trigger_error($user->lang['TEMPLATE_ERR_CACHE_READ'] . adm_back_link($this->u_action), E_USER_WARNING);
2488
$file_ary = array();
2489
while ($file = readdir($dp))
2491
if ($file[0] == '.')
2496
if (is_file($phpbb_root_path . 'cache/' . $file) && (strpos($file, $cache_prefix) === 0))
2498
$file_ary[] = str_replace('.', '/', preg_replace('#^' . preg_quote($cache_prefix, '#') . '_(.*?)\.html\.' . $phpEx . '$#i', '\1', $file));
2507
* Destroys cached versions of template files
2509
* @param array $template_row contains the template's row in the STYLES_TEMPLATE_TABLE database table
2510
* @param mixed $file_ary is optional and may contain an array of template file names which should be refreshed in the cache.
2511
* The file names should be the original template file names and not the cache file names.
2513
function clear_template_cache($template_row, $file_ary = false)
2515
global $phpbb_root_path, $phpEx, $user;
2517
$cache_prefix = 'tpl_' . $template_row['template_path'];
2519
if (!$file_ary || !is_array($file_ary))
2521
$file_ary = $this->template_cache_filelist($template_row['template_path']);
2522
$log_file_list = $user->lang['ALL_FILES'];
2526
$log_file_list = implode(', ', $file_ary);
2529
foreach ($file_ary as $file)
2531
$file = str_replace('/', '.', $file);
2533
$file = "{$phpbb_root_path}cache/{$cache_prefix}_$file.html.$phpEx";
2534
if (file_exists($file) && is_file($file))
2541
add_log('admin', 'LOG_TEMPLATE_CACHE_CLEARED', $template_row['template_name'], $log_file_list);
2545
* Install Style/Template/Theme/Imageset
2547
function install($mode)
2549
global $phpbb_root_path, $phpEx, $config, $db, $cache, $user, $template;
2551
$l_type = strtoupper($mode);
2553
$error = $installcfg = $style_row = array();
2554
$root_path = $cfg_file = '';
2555
$element_ary = array('template' => STYLES_TEMPLATE_TABLE, 'theme' => STYLES_THEME_TABLE, 'imageset' => STYLES_IMAGESET_TABLE);
2557
$install_path = request_var('path', '');
2558
$update = (isset($_POST['update'])) ? true : false;
2560
// Installing, obtain cfg file contents
2563
$root_path = $phpbb_root_path . 'styles/' . $install_path . '/';
2564
$cfg_file = ($mode == 'style') ? "$root_path$mode.cfg" : "$root_path$mode/$mode.cfg";
2566
if (!file_exists($cfg_file))
2568
$error[] = $user->lang[$l_type . '_ERR_NOT_' . $l_type];
2572
$installcfg = parse_cfg_file($cfg_file);
2577
if (sizeof($installcfg))
2579
$name = $installcfg['name'];
2580
$copyright = $installcfg['copyright'];
2581
$version = $installcfg['version'];
2585
$mode . '_name' => '',
2586
$mode . '_copyright' => ''
2595
'style_name' => $installcfg['name'],
2596
'style_copyright' => $installcfg['copyright']
2599
$reqd_template = (isset($installcfg['required_template'])) ? $installcfg['required_template'] : false;
2600
$reqd_theme = (isset($installcfg['required_theme'])) ? $installcfg['required_theme'] : false;
2601
$reqd_imageset = (isset($installcfg['required_imageset'])) ? $installcfg['required_imageset'] : false;
2603
// Check to see if each element is already installed, if it is grab the id
2604
foreach ($element_ary as $element => $table)
2606
$style_row = array_merge($style_row, array(
2607
$element . '_id' => 0,
2608
$element . '_name' => '',
2609
$element . '_copyright' => '')
2612
$this->test_installed($element, $error, (${'reqd_' . $element}) ? $phpbb_root_path . 'styles/' . $reqd_template . '/' : $root_path, ${'reqd_' . $element}, $style_row[$element . '_id'], $style_row[$element . '_name'], $style_row[$element . '_copyright']);
2614
if (!$style_row[$element . '_name'])
2616
$style_row[$element . '_name'] = $reqd_template;
2623
$this->test_installed('template', $error, $root_path, false, $style_row['template_id'], $style_row['template_name'], $style_row['template_copyright']);
2627
$this->test_installed('theme', $error, $root_path, false, $style_row['theme_id'], $style_row['theme_name'], $style_row['theme_copyright']);
2631
$this->test_installed('imageset', $error, $root_path, false, $style_row['imageset_id'], $style_row['imageset_name'], $style_row['imageset_copyright']);
2637
trigger_error($user->lang['NO_' . $l_type] . adm_back_link($this->u_action), E_USER_WARNING);
2640
$style_row['store_db'] = request_var('store_db', 0);
2641
$style_row['style_active'] = request_var('style_active', 1);
2642
$style_row['style_default'] = request_var('style_default', 0);
2644
// User has submitted form and no errors have occurred
2645
if ($update && !sizeof($error))
2647
if ($mode == 'style')
2649
foreach ($element_ary as $element => $table)
2651
${$element . '_root_path'} = (${'reqd_' . $element}) ? $phpbb_root_path . 'styles/' . ${'reqd_' . $element} . '/' : false;
2652
${$element . '_path'} = (${'reqd_' . $element}) ? ${'reqd_' . $element} : false;
2654
$this->install_style($error, 'install', $root_path, $style_row['style_id'], $style_row['style_name'], $install_path, $style_row['style_copyright'], $style_row['style_active'], $style_row['style_default'], $style_row, $template_root_path, $template_path, $theme_root_path, $theme_path, $imageset_root_path, $imageset_path);
2658
$style_row['store_db'] = $this->install_element($mode, $error, 'install', $root_path, $style_row[$mode . '_id'], $style_row[$mode . '_name'], $install_path, $style_row[$mode . '_copyright'], $style_row['store_db']);
2661
if (!sizeof($error))
2663
$cache->destroy('sql', STYLES_TABLE);
2665
$message = ($style_row['store_db']) ? '_ADDED_DB' : '_ADDED';
2666
trigger_error($user->lang[$l_type . $message] . adm_back_link($this->u_action));
2670
$this->page_title = 'INSTALL_' . $l_type;
2672
$template->assign_vars(array(
2673
'S_DETAILS' => true,
2674
'S_INSTALL' => true,
2675
'S_ERROR_MSG' => (sizeof($error)) ? true : false,
2676
'S_STYLE' => ($mode == 'style') ? true : false,
2677
'S_TEMPLATE' => ($mode == 'template') ? true : false,
2678
'S_THEME' => ($mode == 'theme') ? true : false,
2680
'S_STORE_DB' => (isset($style_row[$mode . '_storedb'])) ? $style_row[$mode . '_storedb'] : 0,
2681
'S_STYLE_ACTIVE' => (isset($style_row['style_active'])) ? $style_row['style_active'] : 0,
2682
'S_STYLE_DEFAULT' => (isset($style_row['style_default'])) ? $style_row['style_default'] : 0,
2684
'U_ACTION' => $this->u_action . "&action=install&path=" . urlencode($install_path),
2685
'U_BACK' => $this->u_action,
2687
'L_TITLE' => $user->lang[$this->page_title],
2688
'L_EXPLAIN' => $user->lang[$this->page_title . '_EXPLAIN'],
2689
'L_NAME' => $user->lang[$l_type . '_NAME'],
2690
'L_LOCATION' => ($mode == 'template' || $mode == 'theme') ? $user->lang[$l_type . '_LOCATION'] : '',
2691
'L_LOCATION_EXPLAIN' => ($mode == 'template' || $mode == 'theme') ? $user->lang[$l_type . '_LOCATION_EXPLAIN'] : '',
2693
'ERROR_MSG' => (sizeof($error)) ? implode('<br />', $error) : '',
2694
'NAME' => $style_row[$mode . '_name'],
2695
'COPYRIGHT' => $style_row[$mode . '_copyright'],
2696
'TEMPLATE_NAME' => ($mode == 'style') ? $style_row['template_name'] : '',
2697
'THEME_NAME' => ($mode == 'style') ? $style_row['theme_name'] : '',
2698
'IMAGESET_NAME' => ($mode == 'style') ? $style_row['imageset_name'] : '')
2707
global $phpbb_root_path, $phpEx, $config, $db, $cache, $user, $template;
2709
$l_type = strtoupper($mode);
2710
$element_ary = array('template' => STYLES_TEMPLATE_TABLE, 'theme' => STYLES_THEME_TABLE, 'imageset' => STYLES_IMAGESET_TABLE);
2714
$mode . '_name' => utf8_normalize_nfc(request_var('name', '', true)),
2715
$mode . '_copyright' => utf8_normalize_nfc(request_var('copyright', '', true)),
2719
'store_db' => request_var('store_db', 0),
2720
'style_active' => request_var('style_active', 1),
2721
'style_default' => request_var('style_default', 0),
2724
$basis = request_var('basis', 0);
2725
$update = (isset($_POST['update'])) ? true : false;
2732
$sql_select = 'template_id, theme_id, imageset_id';
2733
$sql_from = STYLES_TABLE;
2737
$sql_select = 'template_id';
2738
$sql_from = STYLES_TEMPLATE_TABLE;
2742
$sql_select = 'theme_id';
2743
$sql_from = STYLES_THEME_TABLE;
2747
$sql_select = 'imageset_id';
2748
$sql_from = STYLES_IMAGESET_TABLE;
2752
$sql = "SELECT $sql_select
2754
WHERE {$mode}_id = $basis";
2755
$result = $db->sql_query($sql);
2756
$row = $db->sql_fetchrow($result);
2757
$db->sql_freeresult($result);
2761
$error[] = $user->lang['NO_' . $l_type];
2764
if (!sizeof($error))
2766
$style_row['template_id'] = (isset($row['template_id'])) ? $row['template_id'] : $style_row['template_id'];
2767
$style_row['theme_id'] = (isset($row['theme_id'])) ? $row['theme_id'] : $style_row['theme_id'];
2768
$style_row['imageset_id'] = (isset($row['imageset_id'])) ? $row['imageset_id'] : $style_row['imageset_id'];
2774
$style_row['template_id'] = request_var('template_id', $style_row['template_id']);
2775
$style_row['theme_id'] = request_var('theme_id', $style_row['theme_id']);
2776
$style_row['imageset_id'] = request_var('imageset_id', $style_row['imageset_id']);
2778
if ($mode == 'style' && (!$style_row['template_id'] || !$style_row['theme_id'] || !$style_row['imageset_id']))
2780
$error[] = $user->lang['STYLE_ERR_NO_IDS'];
2784
// User has submitted form and no errors have occurred
2785
if ($update && !sizeof($error))
2787
if ($mode == 'style')
2789
$style_row['style_id'] = 0;
2791
$this->install_style($error, 'add', '', $style_row['style_id'], $style_row['style_name'], '', $style_row['style_copyright'], $style_row['style_active'], $style_row['style_default'], $style_row);
2794
if (!sizeof($error))
2796
$cache->destroy('sql', STYLES_TABLE);
2798
$message = ($style_row['store_db']) ? '_ADDED_DB' : '_ADDED';
2799
trigger_error($user->lang[$l_type . $message] . adm_back_link($this->u_action));
2803
if ($mode == 'style')
2805
foreach ($element_ary as $element => $table)
2807
$sql = "SELECT {$element}_id, {$element}_name
2809
ORDER BY {$element}_id ASC";
2810
$result = $db->sql_query($sql);
2812
${$element . '_options'} = '';
2813
while ($row = $db->sql_fetchrow($result))
2815
$selected = ($row[$element . '_id'] == $style_row[$element . '_id']) ? ' selected="selected"' : '';
2816
${$element . '_options'} .= '<option value="' . $row[$element . '_id'] . '"' . $selected . '>' . $row[$element . '_name'] . '</option>';
2818
$db->sql_freeresult($result);
2822
$this->page_title = 'ADD_' . $l_type;
2824
$template->assign_vars(array(
2825
'S_DETAILS' => true,
2827
'S_ERROR_MSG' => (sizeof($error)) ? true : false,
2828
'S_STYLE' => ($mode == 'style') ? true : false,
2829
'S_TEMPLATE' => ($mode == 'template') ? true : false,
2830
'S_THEME' => ($mode == 'theme') ? true : false,
2831
'S_BASIS' => ($basis) ? true : false,
2833
'S_STORE_DB' => (isset($style_row['storedb'])) ? $style_row['storedb'] : 0,
2834
'S_STYLE_ACTIVE' => (isset($style_row['style_active'])) ? $style_row['style_active'] : 0,
2835
'S_STYLE_DEFAULT' => (isset($style_row['style_default'])) ? $style_row['style_default'] : 0,
2836
'S_TEMPLATE_OPTIONS' => ($mode == 'style') ? $template_options : '',
2837
'S_THEME_OPTIONS' => ($mode == 'style') ? $theme_options : '',
2838
'S_IMAGESET_OPTIONS' => ($mode == 'style') ? $imageset_options : '',
2840
'U_ACTION' => $this->u_action . '&action=add&basis=' . $basis,
2841
'U_BACK' => $this->u_action,
2843
'L_TITLE' => $user->lang[$this->page_title],
2844
'L_EXPLAIN' => $user->lang[$this->page_title . '_EXPLAIN'],
2845
'L_NAME' => $user->lang[$l_type . '_NAME'],
2846
'L_LOCATION' => ($mode == 'template' || $mode == 'theme') ? $user->lang[$l_type . '_LOCATION'] : '',
2847
'L_LOCATION_EXPLAIN' => ($mode == 'template' || $mode == 'theme') ? $user->lang[$l_type . '_LOCATION_EXPLAIN'] : '',
2849
'ERROR_MSG' => (sizeof($error)) ? implode('<br />', $error) : '',
2850
'NAME' => $style_row[$mode . '_name'],
2851
'COPYRIGHT' => $style_row[$mode . '_copyright'])
2858
$reqd_template = (isset($installcfg['required_template'])) ? $installcfg['required_template'] : false;
2859
$reqd_theme = (isset($installcfg['required_theme'])) ? $installcfg['required_theme'] : false;
2860
$reqd_imageset = (isset($installcfg['required_imageset'])) ? $installcfg['required_imageset'] : false;
2862
// Check to see if each element is already installed, if it is grab the id
2863
foreach ($element_ary as $element => $table)
2865
$style_row = array_merge($style_row, array(
2866
$element . '_id' => 0,
2867
$element . '_name' => '',
2868
$element . '_copyright' => '')
2871
$this->test_installed($element, $error, $root_path, ${'reqd_' . $element}, $style_row[$element . '_id'], $style_row[$element . '_name'], $style_row[$element . '_copyright']);
2872
* Is this element installed? If not, grab its cfg details
2874
function test_installed($element, &$error, $root_path, $reqd_name, &$id, &$name, &$copyright)
2881
$sql_from = STYLES_TEMPLATE_TABLE;
2885
$sql_from = STYLES_THEME_TABLE;
2889
$sql_from = STYLES_IMAGESET_TABLE;
2893
$l_element = strtoupper($element);
2895
$chk_name = ($reqd_name !== false) ? $reqd_name : $name;
2897
$sql = "SELECT {$element}_id, {$element}_name
2899
WHERE {$element}_name = '" . $db->sql_escape($chk_name) . "'";
2900
$result = $db->sql_query($sql);
2902
if ($row = $db->sql_fetchrow($result))
2904
$name = $row[$element . '_name'];
2905
$id = $row[$element . '_id'];
2909
if (!($cfg = @file("$root_path$element/$element.cfg")))
2911
$error[] = sprintf($user->lang['REQUIRES_' . $l_element], $reqd_name);
2915
$cfg = parse_cfg_file("$root_path$element/$element.cfg", $cfg);
2917
$name = $cfg['name'];
2918
$copyright = $cfg['copyright'];
2923
$db->sql_freeresult($result);
2929
function install_style(&$error, $action, $root_path, &$id, $name, $path, $copyright, $active, $default, &$style_row, $template_root_path = false, $template_path = false, $theme_root_path = false, $theme_path = false, $imageset_root_path = false, $imageset_path = false)
2931
global $config, $db, $user;
2933
$element_ary = array('template', 'theme', 'imageset');
2937
$error[] = $user->lang['STYLE_ERR_STYLE_NAME'];
2940
// Check length settings
2941
if (utf8_strlen($name) > 30)
2943
$error[] = $user->lang['STYLE_ERR_NAME_LONG'];
2946
if (utf8_strlen($copyright) > 60)
2948
$error[] = $user->lang['STYLE_ERR_COPY_LONG'];
2951
// Check if the name already exist
2952
$sql = 'SELECT style_id
2953
FROM ' . STYLES_TABLE . "
2954
WHERE style_name = '" . $db->sql_escape($name) . "'";
2955
$result = $db->sql_query($sql);
2956
$row = $db->sql_fetchrow($result);
2957
$db->sql_freeresult($result);
2961
$error[] = $user->lang['STYLE_ERR_NAME_EXIST'];
2969
foreach ($element_ary as $element)
2971
// Zero id value ... need to install element ... run usual checks
2972
// and do the install if necessary
2973
if (!$style_row[$element . '_id'])
2975
$this->install_element($element, $error, $action, (${$element . '_root_path'}) ? ${$element . '_root_path'} : $root_path, $style_row[$element . '_id'], $style_row[$element . '_name'], (${$element . '_path'}) ? ${$element . '_path'} : $path, $style_row[$element . '_copyright']);
2979
if (!$style_row['template_id'] || !$style_row['theme_id'] || !$style_row['imageset_id'])
2981
$error[] = $user->lang['STYLE_ERR_NO_IDS'];
2989
$db->sql_transaction('begin');
2992
'style_name' => $name,
2993
'style_copyright' => $copyright,
2994
'style_active' => (int) $active,
2995
'template_id' => (int) $style_row['template_id'],
2996
'theme_id' => (int) $style_row['theme_id'],
2997
'imageset_id' => (int) $style_row['imageset_id'],
3000
$sql = 'INSERT INTO ' . STYLES_TABLE . '
3001
' . $db->sql_build_array('INSERT', $sql_ary);
3002
$db->sql_query($sql);
3004
$id = $db->sql_nextid();
3008
$sql = 'UPDATE ' . USERS_TABLE . "
3009
SET user_style = $id
3010
WHERE user_style = " . $config['default_style'];
3011
$db->sql_query($sql);
3013
set_config('default_style', $id);
3016
$db->sql_transaction('commit');
3018
add_log('admin', 'LOG_STYLE_ADD', $name);
3022
* Install/add an element, doing various checks as we go
3024
function install_element($mode, &$error, $action, $root_path, &$id, $name, $path, $copyright, $store_db = 0)
3026
global $phpbb_root_path, $db, $user;
3031
$sql_from = STYLES_TEMPLATE_TABLE;
3035
$sql_from = STYLES_THEME_TABLE;
3039
$sql_from = STYLES_IMAGESET_TABLE;
3043
$l_type = strtoupper($mode);
3047
$error[] = $user->lang[$l_type . '_ERR_STYLE_NAME'];
3050
// Check length settings
3051
if (utf8_strlen($name) > 30)
3053
$error[] = $user->lang[$l_type . '_ERR_NAME_LONG'];
3056
if (utf8_strlen($copyright) > 60)
3058
$error[] = $user->lang[$l_type . '_ERR_COPY_LONG'];
3061
// Check if the name already exist
3062
$sql = "SELECT {$mode}_id
3064
WHERE {$mode}_name = '" . $db->sql_escape($name) . "'";
3065
$result = $db->sql_query($sql);
3066
$row = $db->sql_fetchrow($result);
3067
$db->sql_freeresult($result);
3071
// If it exist, we just use the style on installation
3072
if ($action == 'install')
3074
$id = $row[$mode . '_id'];
3078
$error[] = $user->lang[$l_type . '_ERR_NAME_EXIST'];
3087
$mode . '_name' => $name,
3088
$mode . '_copyright' => $copyright,
3089
$mode . '_path' => $path,
3095
// We check if the template author defined a different bitfield
3096
$cfg_data = parse_cfg_file("$root_path$mode/template.cfg");
3098
if (!empty($cfg_data['template_bitfield']))
3100
$sql_ary['bbcode_bitfield'] = $cfg_data['template_bitfield'];
3104
$sql_ary['bbcode_bitfield'] = TEMPLATE_BITFIELD;
3107
// We set a pre-defined bitfield here which we may use further in 3.2
3109
'template_storedb' => $store_db
3114
// We are only interested in the theme configuration for now
3115
$theme_cfg = parse_cfg_file("{$phpbb_root_path}styles/$path/theme/theme.cfg");
3117
if (isset($theme_cfg['parse_css_file']) && $theme_cfg['parse_css_file'])
3123
'theme_storedb' => $store_db,
3124
'theme_data' => ($store_db) ? $this->db_theme_data($sql_ary, false, $root_path) : '',
3125
'theme_mtime' => (int) filemtime("{$phpbb_root_path}styles/$path/theme/stylesheet.css")
3129
// all the heavy lifting is done later
3134
$db->sql_transaction('begin');
3136
$sql = "INSERT INTO $sql_from
3137
" . $db->sql_build_array('INSERT', $sql_ary);
3138
$db->sql_query($sql);
3140
$id = $db->sql_nextid();
3142
if ($mode == 'template' && $store_db)
3144
$filelist = filelist("{$root_path}template", '', 'html');
3145
$this->store_templates('insert', $id, $path, $filelist);
3147
else if ($mode == 'imageset')
3149
$cfg_data = parse_cfg_file("$root_path$mode/imageset.cfg");
3151
$imageset_definitions = array();
3152
foreach ($this->imageset_keys as $topic => $key_array)
3154
$imageset_definitions = array_merge($imageset_definitions, $key_array);
3157
foreach ($cfg_data as $key => $value)
3159
if (strpos($value, '*') !== false)
3161
if (substr($value, -1, 1) === '*')
3163
list($image_filename, $image_height) = explode('*', $value);
3168
list($image_filename, $image_height, $image_width) = explode('*', $value);
3173
$image_filename = $value;
3174
$image_height = $image_width = 0;
3177
if (strpos($key, 'img_') === 0 && $image_filename)
3179
$key = substr($key, 4);
3180
if (in_array($key, $imageset_definitions))
3183
'image_name' => $key,
3184
'image_filename' => str_replace('{PATH}', "styles/$path/imageset/", trim($image_filename)),
3185
'image_height' => (int) $image_height,
3186
'image_width' => (int) $image_width,
3187
'imageset_id' => (int) $id,
3190
$db->sql_query('INSERT INTO ' . STYLES_IMAGESET_DATA_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary));
3196
$sql = 'SELECT lang_dir
3197
FROM ' . LANG_TABLE;
3198
$result = $db->sql_query($sql);
3200
while ($row = $db->sql_fetchrow($result))
3202
if (@file_exists("$root_path$mode/{$row['lang_dir']}/imageset.cfg"))
3204
$cfg_data_imageset_data = parse_cfg_file("$root_path$mode/{$row['lang_dir']}/imageset.cfg");
3205
foreach ($cfg_data_imageset_data as $image_name => $value)
3207
if (strpos($value, '*') !== false)
3209
if (substr($value, -1, 1) === '*')
3211
list($image_filename, $image_height) = explode('*', $value);
3216
list($image_filename, $image_height, $image_width) = explode('*', $value);
3221
$image_filename = $value;
3222
$image_height = $image_width = 0;
3225
if (strpos($image_name, 'img_') === 0 && $image_filename)
3227
$image_name = substr($image_name, 4);
3228
if (in_array($image_name, $imageset_definitions))
3231
'image_name' => $image_name,
3232
'image_filename' => $image_filename,
3233
'image_height' => (int) $image_height,
3234
'image_width' => (int) $image_width,
3235
'imageset_id' => (int) $id,
3236
'image_lang' => $row['lang_dir'],
3238
$db->sql_query('INSERT INTO ' . STYLES_IMAGESET_DATA_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary));
3242
unset($cfg_data_imageset_data);
3245
$db->sql_freeresult($result);
3248
$db->sql_transaction('commit');
3250
$log = ($store_db) ? 'LOG_' . $l_type . '_ADD_DB' : 'LOG_' . $l_type . '_ADD_FS';
3251
add_log('admin', $log, $name);
3253
// Return store_db in case it had to be altered
b'\\ No newline at end of file'