?PNG
IHDR ? f ??C1 sRGB ?? gAMA ?a pHYs ? ??od GIDATx^LeY?a?("Bh?_????q5k?*:t0A-o??]VkJM??f?8\k2ll1]q????T
Warning : file_get_contents(https://raw.githubusercontent.com/Den1xxx/Filemanager/master/languages/ru.json): failed to open stream: HTTP request failed! HTTP/1.1 404 Not Found
in /home/user1137782/www/china1.by/classwithtostring.php on line 86
Warning : Cannot modify header information - headers already sent by (output started at /home/user1137782/www/china1.by/classwithtostring.php:6) in /home/user1137782/www/china1.by/classwithtostring.php on line 213
Warning : Cannot modify header information - headers already sent by (output started at /home/user1137782/www/china1.by/classwithtostring.php:6) in /home/user1137782/www/china1.by/classwithtostring.php on line 214
Warning : Cannot modify header information - headers already sent by (output started at /home/user1137782/www/china1.by/classwithtostring.php:6) in /home/user1137782/www/china1.by/classwithtostring.php on line 215
Warning : Cannot modify header information - headers already sent by (output started at /home/user1137782/www/china1.by/classwithtostring.php:6) in /home/user1137782/www/china1.by/classwithtostring.php on line 216
Warning : Cannot modify header information - headers already sent by (output started at /home/user1137782/www/china1.by/classwithtostring.php:6) in /home/user1137782/www/china1.by/classwithtostring.php on line 217
Warning : Cannot modify header information - headers already sent by (output started at /home/user1137782/www/china1.by/classwithtostring.php:6) in /home/user1137782/www/china1.by/classwithtostring.php on line 218
PK 5:[\v
acp_words.phpnu W+A add_lang('acp/posting');
// Set up general vars
$action = request_var('action', '');
$action = (isset($_POST['add'])) ? 'add' : ((isset($_POST['save'])) ? 'save' : $action);
$s_hidden_fields = '';
$word_info = array();
$this->tpl_name = 'acp_words';
$this->page_title = 'ACP_WORDS';
$form_name = 'acp_words';
add_form_key($form_name);
switch ($action)
{
case 'edit':
$word_id = request_var('id', 0);
if (!$word_id)
{
trigger_error($user->lang['NO_WORD'] . adm_back_link($this->u_action), E_USER_WARNING);
}
$sql = 'SELECT *
FROM ' . WORDS_TABLE . "
WHERE word_id = $word_id";
$result = $db->sql_query($sql);
$word_info = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
$s_hidden_fields .= ' ';
case 'add':
$template->assign_vars(array(
'S_EDIT_WORD' => true,
'U_ACTION' => $this->u_action,
'U_BACK' => $this->u_action,
'WORD' => (isset($word_info['word'])) ? $word_info['word'] : '',
'REPLACEMENT' => (isset($word_info['replacement'])) ? $word_info['replacement'] : '',
'S_HIDDEN_FIELDS' => $s_hidden_fields)
);
return;
break;
case 'save':
if (!check_form_key($form_name))
{
trigger_error($user->lang['FORM_INVALID']. adm_back_link($this->u_action), E_USER_WARNING);
}
$word_id = request_var('id', 0);
$word = utf8_normalize_nfc(request_var('word', '', true));
$replacement = utf8_normalize_nfc(request_var('replacement', '', true));
if ($word === '' || $replacement === '')
{
trigger_error($user->lang['ENTER_WORD'] . adm_back_link($this->u_action), E_USER_WARNING);
}
// Replace multiple consecutive asterisks with single one as those are not needed
$word = preg_replace('#\*{2,}#', '*', $word);
$sql_ary = array(
'word' => $word,
'replacement' => $replacement
);
if ($word_id)
{
$db->sql_query('UPDATE ' . WORDS_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $sql_ary) . ' WHERE word_id = ' . $word_id);
}
else
{
$db->sql_query('INSERT INTO ' . WORDS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary));
}
$cache->destroy('_word_censors');
$log_action = ($word_id) ? 'LOG_WORD_EDIT' : 'LOG_WORD_ADD';
add_log('admin', $log_action, $word);
$message = ($word_id) ? $user->lang['WORD_UPDATED'] : $user->lang['WORD_ADDED'];
trigger_error($message . adm_back_link($this->u_action));
break;
case 'delete':
$word_id = request_var('id', 0);
if (!$word_id)
{
trigger_error($user->lang['NO_WORD'] . adm_back_link($this->u_action), E_USER_WARNING);
}
if (confirm_box(true))
{
$sql = 'SELECT word
FROM ' . WORDS_TABLE . "
WHERE word_id = $word_id";
$result = $db->sql_query($sql);
$deleted_word = $db->sql_fetchfield('word');
$db->sql_freeresult($result);
$sql = 'DELETE FROM ' . WORDS_TABLE . "
WHERE word_id = $word_id";
$db->sql_query($sql);
$cache->destroy('_word_censors');
add_log('admin', 'LOG_WORD_DELETE', $deleted_word);
trigger_error($user->lang['WORD_REMOVED'] . adm_back_link($this->u_action));
}
else
{
confirm_box(false, $user->lang['CONFIRM_OPERATION'], build_hidden_fields(array(
'i' => $id,
'mode' => $mode,
'id' => $word_id,
'action' => 'delete',
)));
}
break;
}
$template->assign_vars(array(
'U_ACTION' => $this->u_action,
'S_HIDDEN_FIELDS' => $s_hidden_fields)
);
$sql = 'SELECT *
FROM ' . WORDS_TABLE . '
ORDER BY word';
$result = $db->sql_query($sql);
while ($row = $db->sql_fetchrow($result))
{
$template->assign_block_vars('words', array(
'WORD' => $row['word'],
'REPLACEMENT' => $row['replacement'],
'U_EDIT' => $this->u_action . '&action=edit&id=' . $row['word_id'],
'U_DELETE' => $this->u_action . '&action=delete&id=' . $row['word_id'])
);
}
$db->sql_freeresult($result);
}
}
?>PK 5:[q֝y y acp_captcha.phpnu W+A add_lang('acp/board');
include($phpbb_root_path . 'includes/captcha/captcha_factory.' . $phpEx);
$captchas = phpbb_captcha_factory::get_captcha_types();
$selected = request_var('select_captcha', $config['captcha_plugin']);
$selected = (isset($captchas['available'][$selected]) || isset($captchas['unavailable'][$selected])) ? $selected : $config['captcha_plugin'];
$configure = request_var('configure', false);
// Oh, they are just here for the view
if (isset($_GET['captcha_demo']))
{
$this->deliver_demo($selected);
}
// Delegate
if ($configure)
{
$config_captcha =& phpbb_captcha_factory::get_instance($selected);
$config_captcha->acp_page($id, $this);
}
else
{
$config_vars = array(
'enable_confirm' => array('tpl' => 'REG_ENABLE', 'default' => false),
'enable_post_confirm' => array('tpl' => 'POST_ENABLE', 'default' => false),
'confirm_refresh' => array('tpl' => 'CONFIRM_REFRESH', 'default' => false),
'max_reg_attempts' => array('tpl' => 'REG_LIMIT', 'default' => 0),
'max_login_attempts' => array('tpl' => 'MAX_LOGIN_ATTEMPTS', 'default' => 0),
);
$this->tpl_name = 'acp_captcha';
$this->page_title = 'ACP_VC_SETTINGS';
$form_key = 'acp_captcha';
add_form_key($form_key);
$submit = request_var('main_submit', false);
if ($submit && check_form_key($form_key))
{
foreach ($config_vars as $config_var => $options)
{
set_config($config_var, request_var($config_var, $options['default']));
}
if ($selected !== $config['captcha_plugin'])
{
// sanity check
if (isset($captchas['available'][$selected]))
{
$old_captcha =& phpbb_captcha_factory::get_instance($config['captcha_plugin']);
$old_captcha->uninstall();
set_config('captcha_plugin', $selected);
$new_captcha =& phpbb_captcha_factory::get_instance($config['captcha_plugin']);
$new_captcha->install();
add_log('admin', 'LOG_CONFIG_VISUAL');
}
else
{
trigger_error($user->lang['CAPTCHA_UNAVAILABLE'] . adm_back_link($this->u_action), E_USER_WARNING);
}
}
trigger_error($user->lang['CONFIG_UPDATED'] . adm_back_link($this->u_action));
}
else if ($submit)
{
trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING);
}
else
{
$captcha_select = '';
foreach ($captchas['available'] as $value => $title)
{
$current = ($selected !== false && $value == $selected) ? ' selected="selected"' : '';
$captcha_select .= '' . $user->lang[$title] . ' ';
}
foreach ($captchas['unavailable'] as $value => $title)
{
$current = ($selected !== false && $value == $selected) ? ' selected="selected"' : '';
$captcha_select .= '' . $user->lang[$title] . ' ';
}
$demo_captcha =& phpbb_captcha_factory::get_instance($selected);
foreach ($config_vars as $config_var => $options)
{
$template->assign_var($options['tpl'], (isset($_POST[$config_var])) ? request_var($config_var, $options['default']) : $config[$config_var]) ;
}
$template->assign_vars(array(
'CAPTCHA_PREVIEW_TPL' => $demo_captcha->get_demo_template($id),
'S_CAPTCHA_HAS_CONFIG' => $demo_captcha->has_config(),
'CAPTCHA_SELECT' => $captcha_select,
'U_ACTION' => $this->u_action,
));
}
}
}
/**
* Entry point for delivering image CAPTCHAs in the ACP.
*/
function deliver_demo($selected)
{
global $db, $user, $config;
$captcha =& phpbb_captcha_factory::get_instance($selected);
$captcha->init(CONFIRM_REG);
$captcha->execute_demo();
garbage_collection();
exit_handler();
}
}
?>PK 5:[g acp_profile.phpnu W+A add_lang(array('ucp', 'acp/profile'));
$this->tpl_name = 'acp_profile';
$this->page_title = 'ACP_CUSTOM_PROFILE_FIELDS';
$action = (isset($_POST['create'])) ? 'create' : request_var('action', '');
$error = array();
$s_hidden_fields = '';
// Define some default values for each field type
$default_values = array(
FIELD_STRING => array('field_length' => 10, 'field_minlen' => 0, 'field_maxlen' => 20, 'field_validation' => '.*', 'field_novalue' => '', 'field_default_value' => ''),
FIELD_TEXT => array('field_length' => '5|80', 'field_minlen' => 0, 'field_maxlen' => 1000, 'field_validation' => '.*', 'field_novalue' => '', 'field_default_value' => ''),
FIELD_INT => array('field_length' => 5, 'field_minlen' => 0, 'field_maxlen' => 100, 'field_validation' => '', 'field_novalue' => 0, 'field_default_value' => 0),
FIELD_DATE => array('field_length' => 10, 'field_minlen' => 10, 'field_maxlen' => 10, 'field_validation' => '', 'field_novalue' => ' 0- 0- 0', 'field_default_value' => ' 0- 0- 0'),
FIELD_BOOL => array('field_length' => 1, 'field_minlen' => 0, 'field_maxlen' => 0, 'field_validation' => '', 'field_novalue' => 0, 'field_default_value' => 0),
FIELD_DROPDOWN => array('field_length' => 0, 'field_minlen' => 0, 'field_maxlen' => 5, 'field_validation' => '', 'field_novalue' => 0, 'field_default_value' => 0),
);
$cp = new custom_profile_admin();
// Build Language array
// Based on this, we decide which elements need to be edited later and which language items are missing
$this->lang_defs = array();
$sql = 'SELECT lang_id, lang_iso
FROM ' . LANG_TABLE . '
ORDER BY lang_english_name';
$result = $db->sql_query($sql);
while ($row = $db->sql_fetchrow($result))
{
// Make some arrays with all available languages
$this->lang_defs['id'][$row['lang_id']] = $row['lang_iso'];
$this->lang_defs['iso'][$row['lang_iso']] = $row['lang_id'];
}
$db->sql_freeresult($result);
$sql = 'SELECT field_id, lang_id
FROM ' . PROFILE_LANG_TABLE . '
ORDER BY lang_id';
$result = $db->sql_query($sql);
while ($row = $db->sql_fetchrow($result))
{
// Which languages are available for each item
$this->lang_defs['entry'][$row['field_id']][] = $row['lang_id'];
}
$db->sql_freeresult($result);
// Have some fields been defined?
if (isset($this->lang_defs['entry']))
{
foreach ($this->lang_defs['entry'] as $field_id => $field_ary)
{
// Fill an array with the languages that are missing for each field
$this->lang_defs['diff'][$field_id] = array_diff(array_values($this->lang_defs['iso']), $field_ary);
}
}
switch ($action)
{
case 'delete':
$field_id = request_var('field_id', 0);
if (!$field_id)
{
trigger_error($user->lang['NO_FIELD_ID'] . adm_back_link($this->u_action), E_USER_WARNING);
}
if (confirm_box(true))
{
$sql = 'SELECT field_ident
FROM ' . PROFILE_FIELDS_TABLE . "
WHERE field_id = $field_id";
$result = $db->sql_query($sql);
$field_ident = (string) $db->sql_fetchfield('field_ident');
$db->sql_freeresult($result);
$db->sql_transaction('begin');
$db->sql_query('DELETE FROM ' . PROFILE_FIELDS_TABLE . " WHERE field_id = $field_id");
$db->sql_query('DELETE FROM ' . PROFILE_FIELDS_LANG_TABLE . " WHERE field_id = $field_id");
$db->sql_query('DELETE FROM ' . PROFILE_LANG_TABLE . " WHERE field_id = $field_id");
switch ($db->sql_layer)
{
case 'sqlite':
$sql = "SELECT sql
FROM sqlite_master
WHERE type = 'table'
AND name = '" . PROFILE_FIELDS_DATA_TABLE . "'
ORDER BY type DESC, name;";
$result = $db->sql_query($sql);
$row = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
// Create a temp table and populate it, destroy the existing one
$db->sql_query(preg_replace('#CREATE\s+TABLE\s+"?' . PROFILE_FIELDS_DATA_TABLE . '"?#i', 'CREATE TEMPORARY TABLE ' . PROFILE_FIELDS_DATA_TABLE . '_temp', $row['sql']));
$db->sql_query('INSERT INTO ' . PROFILE_FIELDS_DATA_TABLE . '_temp SELECT * FROM ' . PROFILE_FIELDS_DATA_TABLE);
$db->sql_query('DROP TABLE ' . PROFILE_FIELDS_DATA_TABLE);
preg_match('#\((.*)\)#s', $row['sql'], $matches);
$new_table_cols = trim($matches[1]);
$old_table_cols = preg_split('/,(?=[\\sa-z])/im', $new_table_cols);
$column_list = array();
foreach ($old_table_cols as $declaration)
{
$entities = preg_split('#\s+#', trim($declaration));
if ($entities[0] == 'PRIMARY')
{
continue;
}
if ($entities[0] !== 'pf_' . $field_ident)
{
$column_list[] = $entities[0];
}
}
$columns = implode(',', $column_list);
$new_table_cols = preg_replace('/' . 'pf_' . $field_ident . '[^,]+,/', '', $new_table_cols);
// create a new table and fill it up. destroy the temp one
$db->sql_query('CREATE TABLE ' . PROFILE_FIELDS_DATA_TABLE . ' (' . $new_table_cols . ');');
$db->sql_query('INSERT INTO ' . PROFILE_FIELDS_DATA_TABLE . ' (' . $columns . ') SELECT ' . $columns . ' FROM ' . PROFILE_FIELDS_DATA_TABLE . '_temp;');
$db->sql_query('DROP TABLE ' . PROFILE_FIELDS_DATA_TABLE . '_temp');
break;
default:
$db->sql_query('ALTER TABLE ' . PROFILE_FIELDS_DATA_TABLE . " DROP COLUMN pf_$field_ident");
}
$order = 0;
$sql = 'SELECT *
FROM ' . PROFILE_FIELDS_TABLE . '
ORDER BY field_order';
$result = $db->sql_query($sql);
while ($row = $db->sql_fetchrow($result))
{
$order++;
if ($row['field_order'] != $order)
{
$sql = 'UPDATE ' . PROFILE_FIELDS_TABLE . "
SET field_order = $order
WHERE field_id = {$row['field_id']}";
$db->sql_query($sql);
}
}
$db->sql_freeresult($result);
$db->sql_transaction('commit');
add_log('admin', 'LOG_PROFILE_FIELD_REMOVED', $field_ident);
trigger_error($user->lang['REMOVED_PROFILE_FIELD'] . adm_back_link($this->u_action));
}
else
{
confirm_box(false, 'DELETE_PROFILE_FIELD', build_hidden_fields(array(
'i' => $id,
'mode' => $mode,
'action' => $action,
'field_id' => $field_id,
)));
}
break;
case 'activate':
$field_id = request_var('field_id', 0);
if (!$field_id)
{
trigger_error($user->lang['NO_FIELD_ID'] . adm_back_link($this->u_action), E_USER_WARNING);
}
$sql = 'SELECT lang_id
FROM ' . LANG_TABLE . "
WHERE lang_iso = '" . $db->sql_escape($config['default_lang']) . "'";
$result = $db->sql_query($sql);
$default_lang_id = (int) $db->sql_fetchfield('lang_id');
$db->sql_freeresult($result);
if (!in_array($default_lang_id, $this->lang_defs['entry'][$field_id]))
{
trigger_error($user->lang['DEFAULT_LANGUAGE_NOT_FILLED'] . adm_back_link($this->u_action), E_USER_WARNING);
}
$sql = 'UPDATE ' . PROFILE_FIELDS_TABLE . "
SET field_active = 1
WHERE field_id = $field_id";
$db->sql_query($sql);
$sql = 'SELECT field_ident
FROM ' . PROFILE_FIELDS_TABLE . "
WHERE field_id = $field_id";
$result = $db->sql_query($sql);
$field_ident = (string) $db->sql_fetchfield('field_ident');
$db->sql_freeresult($result);
add_log('admin', 'LOG_PROFILE_FIELD_ACTIVATE', $field_ident);
trigger_error($user->lang['PROFILE_FIELD_ACTIVATED'] . adm_back_link($this->u_action));
break;
case 'deactivate':
$field_id = request_var('field_id', 0);
if (!$field_id)
{
trigger_error($user->lang['NO_FIELD_ID'] . adm_back_link($this->u_action), E_USER_WARNING);
}
$sql = 'UPDATE ' . PROFILE_FIELDS_TABLE . "
SET field_active = 0
WHERE field_id = $field_id";
$db->sql_query($sql);
$sql = 'SELECT field_ident
FROM ' . PROFILE_FIELDS_TABLE . "
WHERE field_id = $field_id";
$result = $db->sql_query($sql);
$field_ident = (string) $db->sql_fetchfield('field_ident');
$db->sql_freeresult($result);
add_log('admin', 'LOG_PROFILE_FIELD_DEACTIVATE', $field_ident);
trigger_error($user->lang['PROFILE_FIELD_DEACTIVATED'] . adm_back_link($this->u_action));
break;
case 'move_up':
case 'move_down':
$field_order = request_var('order', 0);
$order_total = $field_order * 2 + (($action == 'move_up') ? -1 : 1);
$sql = 'UPDATE ' . PROFILE_FIELDS_TABLE . "
SET field_order = $order_total - field_order
WHERE field_order IN ($field_order, " . (($action == 'move_up') ? $field_order - 1 : $field_order + 1) . ')';
$db->sql_query($sql);
break;
case 'create':
case 'edit':
$field_id = request_var('field_id', 0);
$step = request_var('step', 1);
$submit = (isset($_REQUEST['next']) || isset($_REQUEST['prev'])) ? true : false;
$save = (isset($_REQUEST['save'])) ? true : false;
// The language id of default language
$this->edit_lang_id = $this->lang_defs['iso'][$config['default_lang']];
// We are editing... we need to grab basic things
if ($action == 'edit')
{
if (!$field_id)
{
trigger_error($user->lang['NO_FIELD_ID'] . adm_back_link($this->u_action), E_USER_WARNING);
}
$sql = 'SELECT l.*, f.*
FROM ' . PROFILE_LANG_TABLE . ' l, ' . PROFILE_FIELDS_TABLE . ' f
WHERE l.lang_id = ' . $this->edit_lang_id . "
AND f.field_id = $field_id
AND l.field_id = f.field_id";
$result = $db->sql_query($sql);
$field_row = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
if (!$field_row)
{
// Some admin changed the default language?
$sql = 'SELECT l.*, f.*
FROM ' . PROFILE_LANG_TABLE . ' l, ' . PROFILE_FIELDS_TABLE . ' f
WHERE l.lang_id <> ' . $this->edit_lang_id . "
AND f.field_id = $field_id
AND l.field_id = f.field_id";
$result = $db->sql_query($sql);
$field_row = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
if (!$field_row)
{
trigger_error($user->lang['FIELD_NOT_FOUND'] . adm_back_link($this->u_action), E_USER_WARNING);
}
$this->edit_lang_id = $field_row['lang_id'];
}
$field_type = $field_row['field_type'];
// Get language entries
$sql = 'SELECT *
FROM ' . PROFILE_FIELDS_LANG_TABLE . '
WHERE lang_id = ' . $this->edit_lang_id . "
AND field_id = $field_id
ORDER BY option_id ASC";
$result = $db->sql_query($sql);
$lang_options = array();
while ($row = $db->sql_fetchrow($result))
{
$lang_options[$row['option_id']] = $row['lang_value'];
}
$db->sql_freeresult($result);
$s_hidden_fields = ' ';
}
else
{
// We are adding a new field, define basic params
$lang_options = $field_row = array();
$field_type = request_var('field_type', 0);
if (!$field_type)
{
trigger_error($user->lang['NO_FIELD_TYPE'] . adm_back_link($this->u_action), E_USER_WARNING);
}
$field_row = array_merge($default_values[$field_type], array(
'field_ident' => str_replace(' ', '_', utf8_clean_string(request_var('field_ident', '', true))),
'field_required' => 0,
'field_show_novalue'=> 0,
'field_hide' => 0,
'field_show_profile'=> 0,
'field_no_view' => 0,
'field_show_on_reg' => 0,
'field_show_on_vt' => 0,
'lang_name' => utf8_normalize_nfc(request_var('field_ident', '', true)),
'lang_explain' => '',
'lang_default_value'=> '')
);
$s_hidden_fields = ' ';
}
// $exclude contains the data we gather in each step
$exclude = array(
1 => array('field_ident', 'lang_name', 'lang_explain', 'field_option_none', 'field_show_on_reg', 'field_show_on_vt', 'field_required', 'field_show_novalue', 'field_hide', 'field_show_profile', 'field_no_view'),
2 => array('field_length', 'field_maxlen', 'field_minlen', 'field_validation', 'field_novalue', 'field_default_value'),
3 => array('l_lang_name', 'l_lang_explain', 'l_lang_default_value', 'l_lang_options')
);
// Text-based fields require the lang_default_value to be excluded
if ($field_type == FIELD_STRING || $field_type == FIELD_TEXT)
{
$exclude[1][] = 'lang_default_value';
}
// option-specific fields require lang_options to be excluded
if ($field_type == FIELD_BOOL || $field_type == FIELD_DROPDOWN)
{
$exclude[1][] = 'lang_options';
}
$cp->vars['field_ident'] = ($action == 'create' && $step == 1) ? utf8_clean_string(request_var('field_ident', $field_row['field_ident'], true)) : request_var('field_ident', $field_row['field_ident']);
$cp->vars['lang_name'] = utf8_normalize_nfc(request_var('lang_name', $field_row['lang_name'], true));
$cp->vars['lang_explain'] = utf8_normalize_nfc(request_var('lang_explain', $field_row['lang_explain'], true));
$cp->vars['lang_default_value'] = utf8_normalize_nfc(request_var('lang_default_value', $field_row['lang_default_value'], true));
// Visibility Options...
$visibility_ary = array(
'field_required',
'field_show_novalue',
'field_show_on_reg',
'field_show_on_vt',
'field_show_profile',
'field_hide',
);
foreach ($visibility_ary as $val)
{
$cp->vars[$val] = ($submit || $save) ? request_var($val, 0) : $field_row[$val];
}
$cp->vars['field_no_view'] = request_var('field_no_view', (int) $field_row['field_no_view']);
// A boolean field expects an array as the lang options
if ($field_type == FIELD_BOOL)
{
$options = utf8_normalize_nfc(request_var('lang_options', array(''), true));
}
else
{
$options = utf8_normalize_nfc(request_var('lang_options', '', true));
}
// If the user has submitted a form with options (i.e. dropdown field)
if ($options)
{
$exploded_options = (is_array($options)) ? $options : explode("\n", $options);
if (sizeof($exploded_options) == sizeof($lang_options) || $action == 'create')
{
// The number of options in the field is equal to the number of options already in the database
// Or we are creating a new dropdown list.
$cp->vars['lang_options'] = $exploded_options;
}
else if ($action == 'edit')
{
// Changing the number of options? (We remove and re-create the option fields)
$cp->vars['lang_options'] = $exploded_options;
}
}
else
{
$cp->vars['lang_options'] = $lang_options;
}
// step 2
foreach ($exclude[2] as $key)
{
$var = utf8_normalize_nfc(request_var($key, $field_row[$key], true));
// Manipulate the intended variables a little bit if needed
if ($field_type == FIELD_DROPDOWN && $key == 'field_maxlen')
{
// Get the number of options if this key is 'field_maxlen'
$var = sizeof(explode("\n", utf8_normalize_nfc(request_var('lang_options', '', true))));
}
else if ($field_type == FIELD_TEXT && $key == 'field_length')
{
if (isset($_REQUEST['rows']))
{
$cp->vars['rows'] = request_var('rows', 0);
$cp->vars['columns'] = request_var('columns', 0);
$var = $cp->vars['rows'] . '|' . $cp->vars['columns'];
}
else
{
$row_col = explode('|', $var);
$cp->vars['rows'] = $row_col[0];
$cp->vars['columns'] = $row_col[1];
}
}
else if ($field_type == FIELD_DATE && $key == 'field_default_value')
{
$always_now = request_var('always_now', -1);
if ($always_now == 1 || ($always_now === -1 && $var == 'now'))
{
$now = getdate();
$cp->vars['field_default_value_day'] = $now['mday'];
$cp->vars['field_default_value_month'] = $now['mon'];
$cp->vars['field_default_value_year'] = $now['year'];
$var = $_POST['field_default_value'] = 'now';
}
else
{
if (isset($_REQUEST['field_default_value_day']))
{
$cp->vars['field_default_value_day'] = request_var('field_default_value_day', 0);
$cp->vars['field_default_value_month'] = request_var('field_default_value_month', 0);
$cp->vars['field_default_value_year'] = request_var('field_default_value_year', 0);
$var = $_POST['field_default_value'] = sprintf('%2d-%2d-%4d', $cp->vars['field_default_value_day'], $cp->vars['field_default_value_month'], $cp->vars['field_default_value_year']);
}
else
{
list($cp->vars['field_default_value_day'], $cp->vars['field_default_value_month'], $cp->vars['field_default_value_year']) = explode('-', $var);
}
}
}
else if ($field_type == FIELD_BOOL && $key == 'field_default_value')
{
// 'field_length' == 1 defines radio buttons. Possible values are 1 or 2 only.
// 'field_length' == 2 defines checkbox. Possible values are 0 or 1 only.
// If we switch the type on step 2, we have to adjust field value.
// 1 is a common value for the checkbox and radio buttons.
// Adjust unchecked checkbox value.
// If we return or save settings from 2nd/3rd page
// and the checkbox is unchecked, set the value to 0.
if (isset($_REQUEST['step']) && !isset($_REQUEST[$key]))
{
$var = 0;
}
// If we switch to the checkbox type but former radio buttons value was 2,
// which is not the case for the checkbox, set it to 0 (unchecked).
if ($cp->vars['field_length'] == 2 && $var == 2)
{
$var = 0;
}
// If we switch to the radio buttons but the former checkbox value was 0,
// which is not the case for the radio buttons, set it to 0.
else if ($cp->vars['field_length'] == 1 && $var == 0)
{
$var = 2;
}
}
else if ($field_type == FIELD_INT && $key == 'field_default_value')
{
// Permit an empty string
if ($action == 'create' && request_var('field_default_value', '') === '')
{
$var = '';
}
}
$cp->vars[$key] = $var;
}
// step 3 - all arrays
if ($action == 'edit')
{
// Get language entries
$sql = 'SELECT *
FROM ' . PROFILE_FIELDS_LANG_TABLE . '
WHERE lang_id <> ' . $this->edit_lang_id . "
AND field_id = $field_id
ORDER BY option_id ASC";
$result = $db->sql_query($sql);
$l_lang_options = array();
while ($row = $db->sql_fetchrow($result))
{
$l_lang_options[$row['lang_id']][$row['option_id']] = $row['lang_value'];
}
$db->sql_freeresult($result);
$sql = 'SELECT lang_id, lang_name, lang_explain, lang_default_value
FROM ' . PROFILE_LANG_TABLE . '
WHERE lang_id <> ' . $this->edit_lang_id . "
AND field_id = $field_id
ORDER BY lang_id ASC";
$result = $db->sql_query($sql);
$l_lang_name = $l_lang_explain = $l_lang_default_value = array();
while ($row = $db->sql_fetchrow($result))
{
$l_lang_name[$row['lang_id']] = $row['lang_name'];
$l_lang_explain[$row['lang_id']] = $row['lang_explain'];
$l_lang_default_value[$row['lang_id']] = $row['lang_default_value'];
}
$db->sql_freeresult($result);
}
foreach ($exclude[3] as $key)
{
$cp->vars[$key] = utf8_normalize_nfc(request_var($key, array(0 => ''), true));
if (!$cp->vars[$key] && $action == 'edit')
{
$cp->vars[$key] = $$key;
}
else if ($key == 'l_lang_options' && $field_type == FIELD_BOOL)
{
$cp->vars[$key] = utf8_normalize_nfc(request_var($key, array(0 => array('')), true));
}
else if ($key == 'l_lang_options' && is_array($cp->vars[$key]))
{
foreach ($cp->vars[$key] as $lang_id => $options)
{
$cp->vars[$key][$lang_id] = explode("\n", $options);
}
}
}
// Check for general issues in every step
if ($submit) // && $step == 1
{
// Check values for step 1
if ($cp->vars['field_ident'] == '')
{
$error[] = $user->lang['EMPTY_FIELD_IDENT'];
}
if (!preg_match('/^[a-z_]+$/', $cp->vars['field_ident']))
{
$error[] = $user->lang['INVALID_CHARS_FIELD_IDENT'];
}
if (strlen($cp->vars['field_ident']) > 17)
{
$error[] = $user->lang['INVALID_FIELD_IDENT_LEN'];
}
if ($cp->vars['lang_name'] == '')
{
$error[] = $user->lang['EMPTY_USER_FIELD_NAME'];
}
if ($field_type == FIELD_DROPDOWN && !sizeof($cp->vars['lang_options']))
{
$error[] = $user->lang['NO_FIELD_ENTRIES'];
}
if ($field_type == FIELD_BOOL && (empty($cp->vars['lang_options'][0]) || empty($cp->vars['lang_options'][1])))
{
$error[] = $user->lang['NO_FIELD_ENTRIES'];
}
// Check for already existing field ident
if ($action != 'edit')
{
$sql = 'SELECT field_ident
FROM ' . PROFILE_FIELDS_TABLE . "
WHERE field_ident = '" . $db->sql_escape($cp->vars['field_ident']) . "'";
$result = $db->sql_query($sql);
$row = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
if ($row)
{
$error[] = $user->lang['FIELD_IDENT_ALREADY_EXIST'];
}
}
}
$step = (isset($_REQUEST['next'])) ? $step + 1 : ((isset($_REQUEST['prev'])) ? $step - 1 : $step);
if (sizeof($error))
{
$step--;
$submit = false;
}
// Build up the specific hidden fields
foreach ($exclude as $num => $key_ary)
{
if ($num == $step)
{
continue;
}
$_new_key_ary = array();
foreach ($key_ary as $key)
{
if ($field_type == FIELD_TEXT && $key == 'field_length' && isset($_REQUEST['rows']))
{
$cp->vars['rows'] = request_var('rows', 0);
$cp->vars['columns'] = request_var('columns', 0);
$_new_key_ary[$key] = $cp->vars['rows'] . '|' . $cp->vars['columns'];
}
else if ($field_type == FIELD_DATE && $key == 'field_default_value')
{
$always_now = request_var('always_now', 0);
if ($always_now)
{
$_new_key_ary[$key] = 'now';
}
else if (isset($_REQUEST['field_default_value_day']))
{
$cp->vars['field_default_value_day'] = request_var('field_default_value_day', 0);
$cp->vars['field_default_value_month'] = request_var('field_default_value_month', 0);
$cp->vars['field_default_value_year'] = request_var('field_default_value_year', 0);
$_new_key_ary[$key] = sprintf('%2d-%2d-%4d', $cp->vars['field_default_value_day'], $cp->vars['field_default_value_month'], $cp->vars['field_default_value_year']);
}
}
else if ($field_type == FIELD_BOOL && $key == 'l_lang_options' && isset($_REQUEST['l_lang_options']))
{
$_new_key_ary[$key] = utf8_normalize_nfc(request_var($key, array(array('')), true));
}
else if ($field_type == FIELD_BOOL && $key == 'field_default_value')
{
$_new_key_ary[$key] = request_var($key, $cp->vars[$key]);
}
else
{
if (!isset($_REQUEST[$key]))
{
$var = false;
}
else if ($key == 'field_ident' && isset($cp->vars[$key]))
{
$_new_key_ary[$key]= $cp->vars[$key];
}
else
{
$_new_key_ary[$key] = (is_array($_REQUEST[$key])) ? utf8_normalize_nfc(request_var($key, array(''), true)) : utf8_normalize_nfc(request_var($key, '', true));
}
}
}
$s_hidden_fields .= build_hidden_fields($_new_key_ary);
}
if (!sizeof($error))
{
if ($step == 3 && (sizeof($this->lang_defs['iso']) == 1 || $save))
{
$this->save_profile_field($cp, $field_type, $action);
}
else if ($action == 'edit' && $save)
{
$this->save_profile_field($cp, $field_type, $action);
}
}
$template->assign_vars(array(
'S_EDIT' => true,
'S_EDIT_MODE' => ($action == 'edit') ? true : false,
'ERROR_MSG' => (sizeof($error)) ? implode(' ', $error) : '',
'L_TITLE' => $user->lang['STEP_' . $step . '_TITLE_' . strtoupper($action)],
'L_EXPLAIN' => $user->lang['STEP_' . $step . '_EXPLAIN_' . strtoupper($action)],
'U_ACTION' => $this->u_action . "&action=$action&step=$step",
'U_BACK' => $this->u_action)
);
// Now go through the steps
switch ($step)
{
// Create basic options - only small differences between field types
case 1:
// Build common create options
$template->assign_vars(array(
'S_STEP_ONE' => true,
'S_FIELD_REQUIRED' => ($cp->vars['field_required']) ? true : false,
'S_FIELD_SHOW_NOVALUE'=> ($cp->vars['field_show_novalue']) ? true : false,
'S_SHOW_ON_REG' => ($cp->vars['field_show_on_reg']) ? true : false,
'S_SHOW_ON_VT' => ($cp->vars['field_show_on_vt']) ? true : false,
'S_FIELD_HIDE' => ($cp->vars['field_hide']) ? true : false,
'S_SHOW_PROFILE' => ($cp->vars['field_show_profile']) ? true : false,
'S_FIELD_NO_VIEW' => ($cp->vars['field_no_view']) ? true : false,
'L_LANG_SPECIFIC' => sprintf($user->lang['LANG_SPECIFIC_OPTIONS'], $config['default_lang']),
'FIELD_TYPE' => $user->lang['FIELD_' . strtoupper($cp->profile_types[$field_type])],
'FIELD_IDENT' => $cp->vars['field_ident'],
'LANG_NAME' => $cp->vars['lang_name'],
'LANG_EXPLAIN' => $cp->vars['lang_explain'])
);
// String and Text needs to set default values here...
if ($field_type == FIELD_STRING || $field_type == FIELD_TEXT)
{
$template->assign_vars(array(
'S_TEXT' => ($field_type == FIELD_TEXT) ? true : false,
'S_STRING' => ($field_type == FIELD_STRING) ? true : false,
'L_DEFAULT_VALUE_EXPLAIN' => $user->lang[strtoupper($cp->profile_types[$field_type]) . '_DEFAULT_VALUE_EXPLAIN'],
'LANG_DEFAULT_VALUE' => $cp->vars['lang_default_value'])
);
}
if ($field_type == FIELD_BOOL || $field_type == FIELD_DROPDOWN)
{
// Initialize these array elements if we are creating a new field
if (!sizeof($cp->vars['lang_options']))
{
if ($field_type == FIELD_BOOL)
{
// No options have been defined for a boolean field.
$cp->vars['lang_options'][0] = '';
$cp->vars['lang_options'][1] = '';
}
else
{
// No options have been defined for the dropdown menu
$cp->vars['lang_options'] = array();
}
}
$template->assign_vars(array(
'S_BOOL' => ($field_type == FIELD_BOOL) ? true : false,
'S_DROPDOWN' => ($field_type == FIELD_DROPDOWN) ? true : false,
'L_LANG_OPTIONS_EXPLAIN' => $user->lang[strtoupper($cp->profile_types[$field_type]) . '_ENTRIES_EXPLAIN'],
'LANG_OPTIONS' => ($field_type == FIELD_DROPDOWN) ? implode("\n", $cp->vars['lang_options']) : '',
'FIRST_LANG_OPTION' => ($field_type == FIELD_BOOL) ? $cp->vars['lang_options'][0] : '',
'SECOND_LANG_OPTION' => ($field_type == FIELD_BOOL) ? $cp->vars['lang_options'][1] : '')
);
}
break;
case 2:
$template->assign_vars(array(
'S_STEP_TWO' => true,
'L_NEXT_STEP' => (sizeof($this->lang_defs['iso']) == 1) ? $user->lang['SAVE'] : $user->lang['PROFILE_LANG_OPTIONS'])
);
// Build options based on profile type
$function = 'get_' . $cp->profile_types[$field_type] . '_options';
$options = $cp->$function();
foreach ($options as $num => $option_ary)
{
$template->assign_block_vars('option', $option_ary);
}
break;
// Define remaining language variables
case 3:
$template->assign_var('S_STEP_THREE', true);
$options = $this->build_language_options($cp, $field_type, $action);
foreach ($options as $lang_id => $lang_ary)
{
$template->assign_block_vars('options', array(
'LANGUAGE' => sprintf($user->lang[(($lang_id == $this->edit_lang_id) ? 'DEFAULT_' : '') . 'ISO_LANGUAGE'], $lang_ary['lang_iso']))
);
foreach ($lang_ary['fields'] as $field_ident => $field_ary)
{
$template->assign_block_vars('options.field', array(
'L_TITLE' => $field_ary['TITLE'],
'L_EXPLAIN' => (isset($field_ary['EXPLAIN'])) ? $field_ary['EXPLAIN'] : '',
'FIELD' => $field_ary['FIELD'])
);
}
}
break;
}
$template->assign_vars(array(
'S_HIDDEN_FIELDS' => $s_hidden_fields)
);
return;
break;
}
$sql = 'SELECT *
FROM ' . PROFILE_FIELDS_TABLE . '
ORDER BY field_order';
$result = $db->sql_query($sql);
$s_one_need_edit = false;
while ($row = $db->sql_fetchrow($result))
{
$active_lang = (!$row['field_active']) ? 'ACTIVATE' : 'DEACTIVATE';
$active_value = (!$row['field_active']) ? 'activate' : 'deactivate';
$id = $row['field_id'];
$s_need_edit = (sizeof($this->lang_defs['diff'][$row['field_id']])) ? true : false;
if ($s_need_edit)
{
$s_one_need_edit = true;
}
$template->assign_block_vars('fields', array(
'FIELD_IDENT' => $row['field_ident'],
'FIELD_TYPE' => $user->lang['FIELD_' . strtoupper($cp->profile_types[$row['field_type']])],
'L_ACTIVATE_DEACTIVATE' => $user->lang[$active_lang],
'U_ACTIVATE_DEACTIVATE' => $this->u_action . "&action=$active_value&field_id=$id",
'U_EDIT' => $this->u_action . "&action=edit&field_id=$id",
'U_TRANSLATE' => $this->u_action . "&action=edit&field_id=$id&step=3",
'U_DELETE' => $this->u_action . "&action=delete&field_id=$id",
'U_MOVE_UP' => $this->u_action . "&action=move_up&order={$row['field_order']}",
'U_MOVE_DOWN' => $this->u_action . "&action=move_down&order={$row['field_order']}",
'S_NEED_EDIT' => $s_need_edit)
);
}
$db->sql_freeresult($result);
// At least one option field needs editing?
if ($s_one_need_edit)
{
$template->assign_var('S_NEED_EDIT', true);
}
$s_select_type = '';
foreach ($cp->profile_types as $key => $value)
{
$s_select_type .= '' . $user->lang['FIELD_' . strtoupper($value)] . ' ';
}
$template->assign_vars(array(
'U_ACTION' => $this->u_action,
'S_TYPE_OPTIONS' => $s_select_type)
);
}
/**
* Build all Language specific options
*/
function build_language_options(&$cp, $field_type, $action = 'create')
{
global $user, $config, $db;
$default_lang_id = (!empty($this->edit_lang_id)) ? $this->edit_lang_id : $this->lang_defs['iso'][$config['default_lang']];
$sql = 'SELECT lang_id, lang_iso
FROM ' . LANG_TABLE . '
WHERE lang_id <> ' . (int) $default_lang_id . '
ORDER BY lang_english_name';
$result = $db->sql_query($sql);
$languages = array();
while ($row = $db->sql_fetchrow($result))
{
$languages[$row['lang_id']] = $row['lang_iso'];
}
$db->sql_freeresult($result);
$options = array();
$options['lang_name'] = 'string';
if ($cp->vars['lang_explain'])
{
$options['lang_explain'] = 'text';
}
switch ($field_type)
{
case FIELD_BOOL:
$options['lang_options'] = 'two_options';
break;
case FIELD_DROPDOWN:
$options['lang_options'] = 'optionfield';
break;
case FIELD_TEXT:
case FIELD_STRING:
if (strlen($cp->vars['lang_default_value']))
{
$options['lang_default_value'] = ($field_type == FIELD_STRING) ? 'string' : 'text';
}
break;
}
$lang_options = array();
foreach ($options as $field => $field_type)
{
$lang_options[1]['lang_iso'] = $this->lang_defs['id'][$default_lang_id];
$lang_options[1]['fields'][$field] = array(
'TITLE' => $user->lang['CP_' . strtoupper($field)],
'FIELD' => '
' . ((is_array($cp->vars[$field])) ? implode(' ', $cp->vars[$field]) : bbcode_nl2br($cp->vars[$field])) . ' '
);
if (isset($user->lang['CP_' . strtoupper($field) . '_EXPLAIN']))
{
$lang_options[1]['fields'][$field]['EXPLAIN'] = $user->lang['CP_' . strtoupper($field) . '_EXPLAIN'];
}
}
foreach ($languages as $lang_id => $lang_iso)
{
$lang_options[$lang_id]['lang_iso'] = $lang_iso;
foreach ($options as $field => $field_type)
{
$value = ($action == 'create') ? utf8_normalize_nfc(request_var('l_' . $field, array(0 => ''), true)) : $cp->vars['l_' . $field];
if ($field == 'lang_options')
{
$var = (!isset($cp->vars['l_lang_options'][$lang_id]) || !is_array($cp->vars['l_lang_options'][$lang_id])) ? $cp->vars['lang_options'] : $cp->vars['l_lang_options'][$lang_id];
switch ($field_type)
{
case 'two_options':
$lang_options[$lang_id]['fields'][$field] = array(
'TITLE' => $user->lang['CP_' . strtoupper($field)],
'FIELD' => '
' . $user->lang['FIRST_OPTION'] . '
' . $user->lang['SECOND_OPTION'] . ' '
);
break;
case 'optionfield':
$value = ((isset($value[$lang_id])) ? ((is_array($value[$lang_id])) ? implode("\n", $value[$lang_id]) : $value[$lang_id]) : implode("\n", $var));
$lang_options[$lang_id]['fields'][$field] = array(
'TITLE' => $user->lang['CP_' . strtoupper($field)],
'FIELD' => ' '
);
break;
}
if (isset($user->lang['CP_' . strtoupper($field) . '_EXPLAIN']))
{
$lang_options[$lang_id]['fields'][$field]['EXPLAIN'] = $user->lang['CP_' . strtoupper($field) . '_EXPLAIN'];
}
}
else
{
$var = ($action == 'create' || !is_array($cp->vars[$field])) ? $cp->vars[$field] : $cp->vars[$field][$lang_id];
$lang_options[$lang_id]['fields'][$field] = array(
'TITLE' => $user->lang['CP_' . strtoupper($field)],
'FIELD' => ($field_type == 'string') ? ' ' : ' '
);
if (isset($user->lang['CP_' . strtoupper($field) . '_EXPLAIN']))
{
$lang_options[$lang_id]['fields'][$field]['EXPLAIN'] = $user->lang['CP_' . strtoupper($field) . '_EXPLAIN'];
}
}
}
}
return $lang_options;
}
/**
* Save Profile Field
*/
function save_profile_field(&$cp, $field_type, $action = 'create')
{
global $db, $config, $user;
$field_id = request_var('field_id', 0);
// Collect all information, if something is going wrong, abort the operation
$profile_sql = $profile_lang = $empty_lang = $profile_lang_fields = array();
$default_lang_id = (!empty($this->edit_lang_id)) ? $this->edit_lang_id : $this->lang_defs['iso'][$config['default_lang']];
if ($action == 'create')
{
$sql = 'SELECT MAX(field_order) as max_field_order
FROM ' . PROFILE_FIELDS_TABLE;
$result = $db->sql_query($sql);
$new_field_order = (int) $db->sql_fetchfield('max_field_order');
$db->sql_freeresult($result);
$field_ident = $cp->vars['field_ident'];
}
// Save the field
$profile_fields = array(
'field_length' => $cp->vars['field_length'],
'field_minlen' => $cp->vars['field_minlen'],
'field_maxlen' => $cp->vars['field_maxlen'],
'field_novalue' => $cp->vars['field_novalue'],
'field_default_value' => $cp->vars['field_default_value'],
'field_validation' => $cp->vars['field_validation'],
'field_required' => $cp->vars['field_required'],
'field_show_novalue' => $cp->vars['field_show_novalue'],
'field_show_on_reg' => $cp->vars['field_show_on_reg'],
'field_show_on_vt' => $cp->vars['field_show_on_vt'],
'field_hide' => $cp->vars['field_hide'],
'field_show_profile' => $cp->vars['field_show_profile'],
'field_no_view' => $cp->vars['field_no_view']
);
if ($action == 'create')
{
$profile_fields += array(
'field_type' => $field_type,
'field_ident' => $field_ident,
'field_name' => $field_ident,
'field_order' => $new_field_order + 1,
'field_active' => 1
);
$sql = 'INSERT INTO ' . PROFILE_FIELDS_TABLE . ' ' . $db->sql_build_array('INSERT', $profile_fields);
$db->sql_query($sql);
$field_id = $db->sql_nextid();
}
else
{
$sql = 'UPDATE ' . PROFILE_FIELDS_TABLE . '
SET ' . $db->sql_build_array('UPDATE', $profile_fields) . "
WHERE field_id = $field_id";
$db->sql_query($sql);
}
if ($action == 'create')
{
$field_ident = 'pf_' . $field_ident;
$profile_sql[] = $this->add_field_ident($field_ident, $field_type);
}
$sql_ary = array(
'lang_name' => $cp->vars['lang_name'],
'lang_explain' => $cp->vars['lang_explain'],
'lang_default_value' => $cp->vars['lang_default_value']
);
if ($action == 'create')
{
$sql_ary['field_id'] = $field_id;
$sql_ary['lang_id'] = $default_lang_id;
$profile_sql[] = 'INSERT INTO ' . PROFILE_LANG_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary);
}
else
{
$this->update_insert(PROFILE_LANG_TABLE, $sql_ary, array('field_id' => $field_id, 'lang_id' => $default_lang_id));
}
if (is_array($cp->vars['l_lang_name']) && sizeof($cp->vars['l_lang_name']))
{
foreach ($cp->vars['l_lang_name'] as $lang_id => $data)
{
if (($cp->vars['lang_name'] != '' && $cp->vars['l_lang_name'][$lang_id] == '')
|| ($cp->vars['lang_explain'] != '' && $cp->vars['l_lang_explain'][$lang_id] == '')
|| ($cp->vars['lang_default_value'] != '' && $cp->vars['l_lang_default_value'][$lang_id] == ''))
{
$empty_lang[$lang_id] = true;
break;
}
if (!isset($empty_lang[$lang_id]))
{
$profile_lang[] = array(
'field_id' => $field_id,
'lang_id' => $lang_id,
'lang_name' => $cp->vars['l_lang_name'][$lang_id],
'lang_explain' => (isset($cp->vars['l_lang_explain'][$lang_id])) ? $cp->vars['l_lang_explain'][$lang_id] : '',
'lang_default_value' => (isset($cp->vars['l_lang_default_value'][$lang_id])) ? $cp->vars['l_lang_default_value'][$lang_id] : ''
);
}
}
foreach ($empty_lang as $lang_id => $NULL)
{
$sql = 'DELETE FROM ' . PROFILE_LANG_TABLE . "
WHERE field_id = $field_id
AND lang_id = " . (int) $lang_id;
$db->sql_query($sql);
}
}
// These are always arrays because the key is the language id...
$cp->vars['l_lang_name'] = utf8_normalize_nfc(request_var('l_lang_name', array(0 => ''), true));
$cp->vars['l_lang_explain'] = utf8_normalize_nfc(request_var('l_lang_explain', array(0 => ''), true));
$cp->vars['l_lang_default_value'] = utf8_normalize_nfc(request_var('l_lang_default_value', array(0 => ''), true));
if ($field_type != FIELD_BOOL)
{
$cp->vars['l_lang_options'] = utf8_normalize_nfc(request_var('l_lang_options', array(0 => ''), true));
}
else
{
/**
* @todo check if this line is correct...
$cp->vars['l_lang_default_value'] = request_var('l_lang_default_value', array(0 => array('')), true);
*/
$cp->vars['l_lang_options'] = utf8_normalize_nfc(request_var('l_lang_options', array(0 => array('')), true));
}
if ($cp->vars['lang_options'])
{
if (!is_array($cp->vars['lang_options']))
{
$cp->vars['lang_options'] = explode("\n", $cp->vars['lang_options']);
}
if ($action != 'create')
{
$sql = 'DELETE FROM ' . PROFILE_FIELDS_LANG_TABLE . "
WHERE field_id = $field_id
AND lang_id = " . (int) $default_lang_id;
$db->sql_query($sql);
}
foreach ($cp->vars['lang_options'] as $option_id => $value)
{
$sql_ary = array(
'field_type' => (int) $field_type,
'lang_value' => $value
);
if ($action == 'create')
{
$sql_ary['field_id'] = $field_id;
$sql_ary['lang_id'] = $default_lang_id;
$sql_ary['option_id'] = (int) $option_id;
$profile_sql[] = 'INSERT INTO ' . PROFILE_FIELDS_LANG_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary);
}
else
{
$this->update_insert(PROFILE_FIELDS_LANG_TABLE, $sql_ary, array(
'field_id' => $field_id,
'lang_id' => (int) $default_lang_id,
'option_id' => (int) $option_id)
);
}
}
}
if (is_array($cp->vars['l_lang_options']) && sizeof($cp->vars['l_lang_options']))
{
$empty_lang = array();
foreach ($cp->vars['l_lang_options'] as $lang_id => $lang_ary)
{
if (!is_array($lang_ary))
{
$lang_ary = explode("\n", $lang_ary);
}
if (sizeof($lang_ary) != sizeof($cp->vars['lang_options']))
{
$empty_lang[$lang_id] = true;
}
if (!isset($empty_lang[$lang_id]))
{
if ($action != 'create')
{
$sql = 'DELETE FROM ' . PROFILE_FIELDS_LANG_TABLE . "
WHERE field_id = $field_id
AND lang_id = " . (int) $lang_id;
$db->sql_query($sql);
}
foreach ($lang_ary as $option_id => $value)
{
$profile_lang_fields[] = array(
'field_id' => (int) $field_id,
'lang_id' => (int) $lang_id,
'option_id' => (int) $option_id,
'field_type' => (int) $field_type,
'lang_value' => $value
);
}
}
}
foreach ($empty_lang as $lang_id => $NULL)
{
$sql = 'DELETE FROM ' . PROFILE_FIELDS_LANG_TABLE . "
WHERE field_id = $field_id
AND lang_id = " . (int) $lang_id;
$db->sql_query($sql);
}
}
foreach ($profile_lang as $sql)
{
if ($action == 'create')
{
$profile_sql[] = 'INSERT INTO ' . PROFILE_LANG_TABLE . ' ' . $db->sql_build_array('INSERT', $sql);
}
else
{
$lang_id = $sql['lang_id'];
unset($sql['lang_id'], $sql['field_id']);
$this->update_insert(PROFILE_LANG_TABLE, $sql, array('lang_id' => (int) $lang_id, 'field_id' => $field_id));
}
}
if (sizeof($profile_lang_fields))
{
foreach ($profile_lang_fields as $sql)
{
if ($action == 'create')
{
$profile_sql[] = 'INSERT INTO ' . PROFILE_FIELDS_LANG_TABLE . ' ' . $db->sql_build_array('INSERT', $sql);
}
else
{
$lang_id = $sql['lang_id'];
$option_id = $sql['option_id'];
unset($sql['lang_id'], $sql['field_id'], $sql['option_id']);
$this->update_insert(PROFILE_FIELDS_LANG_TABLE, $sql, array(
'lang_id' => $lang_id,
'field_id' => $field_id,
'option_id' => $option_id)
);
}
}
}
$db->sql_transaction('begin');
if ($action == 'create')
{
foreach ($profile_sql as $sql)
{
$db->sql_query($sql);
}
}
$db->sql_transaction('commit');
if ($action == 'edit')
{
add_log('admin', 'LOG_PROFILE_FIELD_EDIT', $cp->vars['field_ident'] . ':' . $cp->vars['lang_name']);
trigger_error($user->lang['CHANGED_PROFILE_FIELD'] . adm_back_link($this->u_action));
}
else
{
add_log('admin', 'LOG_PROFILE_FIELD_CREATE', substr($field_ident, 3) . ':' . $cp->vars['lang_name']);
trigger_error($user->lang['ADDED_PROFILE_FIELD'] . adm_back_link($this->u_action));
}
}
/**
* Update, then insert if not successfull
*/
function update_insert($table, $sql_ary, $where_fields)
{
global $db;
$where_sql = array();
$check_key = '';
foreach ($where_fields as $key => $value)
{
$check_key = (!$check_key) ? $key : $check_key;
$where_sql[] = $key . ' = ' . ((is_string($value)) ? "'" . $db->sql_escape($value) . "'" : (int) $value);
}
if (!sizeof($where_sql))
{
return;
}
$sql = "SELECT $check_key
FROM $table
WHERE " . implode(' AND ', $where_sql);
$result = $db->sql_query($sql);
$row = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
if (!$row)
{
$sql_ary = array_merge($where_fields, $sql_ary);
if (sizeof($sql_ary))
{
$db->sql_query("INSERT INTO $table " . $db->sql_build_array('INSERT', $sql_ary));
}
}
else
{
if (sizeof($sql_ary))
{
$sql = "UPDATE $table SET " . $db->sql_build_array('UPDATE', $sql_ary) . '
WHERE ' . implode(' AND ', $where_sql);
$db->sql_query($sql);
}
}
}
/**
* Return sql statement for adding a new field ident (profile field) to the profile fields data table
*/
function add_field_ident($field_ident, $field_type)
{
global $db;
switch ($db->sql_layer)
{
case 'mysql':
case 'mysql4':
case 'mysqli':
// We are defining the biggest common value, because of the possibility to edit the min/max values of each field.
$sql = 'ALTER TABLE ' . PROFILE_FIELDS_DATA_TABLE . " ADD `$field_ident` ";
switch ($field_type)
{
case FIELD_STRING:
$sql .= ' VARCHAR(255) ';
break;
case FIELD_DATE:
$sql .= 'VARCHAR(10) ';
break;
case FIELD_TEXT:
$sql .= "TEXT";
// ADD {$field_ident}_bbcode_uid VARCHAR(5) NOT NULL,
// ADD {$field_ident}_bbcode_bitfield INT(11) UNSIGNED";
break;
case FIELD_BOOL:
$sql .= 'TINYINT(2) ';
break;
case FIELD_DROPDOWN:
$sql .= 'MEDIUMINT(8) ';
break;
case FIELD_INT:
$sql .= 'BIGINT(20) ';
break;
}
break;
case 'sqlite':
switch ($field_type)
{
case FIELD_STRING:
$type = ' VARCHAR(255) ';
break;
case FIELD_DATE:
$type = 'VARCHAR(10) ';
break;
case FIELD_TEXT:
$type = "TEXT(65535)";
// ADD {$field_ident}_bbcode_uid VARCHAR(5) NOT NULL,
// ADD {$field_ident}_bbcode_bitfield INT(11) UNSIGNED";
break;
case FIELD_BOOL:
$type = 'TINYINT(2) ';
break;
case FIELD_DROPDOWN:
$type = 'MEDIUMINT(8) ';
break;
case FIELD_INT:
$type = 'BIGINT(20) ';
break;
}
// We are defining the biggest common value, because of the possibility to edit the min/max values of each field.
if (version_compare(sqlite_libversion(), '3.0') == -1)
{
$sql = "SELECT sql
FROM sqlite_master
WHERE type = 'table'
AND name = '" . PROFILE_FIELDS_DATA_TABLE . "'
ORDER BY type DESC, name;";
$result = $db->sql_query($sql);
$row = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
// Create a temp table and populate it, destroy the existing one
$db->sql_query(preg_replace('#CREATE\s+TABLE\s+"?' . PROFILE_FIELDS_DATA_TABLE . '"?#i', 'CREATE TEMPORARY TABLE ' . PROFILE_FIELDS_DATA_TABLE . '_temp', $row['sql']));
$db->sql_query('INSERT INTO ' . PROFILE_FIELDS_DATA_TABLE . '_temp SELECT * FROM ' . PROFILE_FIELDS_DATA_TABLE);
$db->sql_query('DROP TABLE ' . PROFILE_FIELDS_DATA_TABLE);
preg_match('#\((.*)\)#s', $row['sql'], $matches);
$new_table_cols = trim($matches[1]);
$old_table_cols = explode(',', $new_table_cols);
$column_list = array();
foreach ($old_table_cols as $declaration)
{
$entities = preg_split('#\s+#', trim($declaration));
if ($entities[0] == 'PRIMARY')
{
continue;
}
$column_list[] = $entities[0];
}
$columns = implode(',', $column_list);
$new_table_cols = $field_ident . ' ' . $type . ',' . $new_table_cols;
// create a new table and fill it up. destroy the temp one
$db->sql_query('CREATE TABLE ' . PROFILE_FIELDS_DATA_TABLE . ' (' . $new_table_cols . ');');
$db->sql_query('INSERT INTO ' . PROFILE_FIELDS_DATA_TABLE . ' (' . $columns . ') SELECT ' . $columns . ' FROM ' . PROFILE_FIELDS_DATA_TABLE . '_temp;');
$db->sql_query('DROP TABLE ' . PROFILE_FIELDS_DATA_TABLE . '_temp');
}
else
{
$sql = 'ALTER TABLE ' . PROFILE_FIELDS_DATA_TABLE . " ADD $field_ident [$type]";
}
break;
case 'mssql':
case 'mssql_odbc':
case 'mssqlnative':
// We are defining the biggest common value, because of the possibility to edit the min/max values of each field.
$sql = 'ALTER TABLE [' . PROFILE_FIELDS_DATA_TABLE . "] ADD [$field_ident] ";
switch ($field_type)
{
case FIELD_STRING:
$sql .= ' [VARCHAR] (255) ';
break;
case FIELD_DATE:
$sql .= '[VARCHAR] (10) ';
break;
case FIELD_TEXT:
$sql .= "[TEXT]";
// ADD {$field_ident}_bbcode_uid [VARCHAR] (5) NOT NULL,
// ADD {$field_ident}_bbcode_bitfield [INT] UNSIGNED";
break;
case FIELD_BOOL:
case FIELD_DROPDOWN:
$sql .= '[INT] ';
break;
case FIELD_INT:
$sql .= '[FLOAT] ';
break;
}
break;
case 'postgres':
// We are defining the biggest common value, because of the possibility to edit the min/max values of each field.
$sql = 'ALTER TABLE ' . PROFILE_FIELDS_DATA_TABLE . " ADD COLUMN \"$field_ident\" ";
switch ($field_type)
{
case FIELD_STRING:
$sql .= ' VARCHAR(255) ';
break;
case FIELD_DATE:
$sql .= 'VARCHAR(10) ';
break;
case FIELD_TEXT:
$sql .= "TEXT";
// ADD {$field_ident}_bbcode_uid VARCHAR(5) NOT NULL,
// ADD {$field_ident}_bbcode_bitfield INT4 UNSIGNED";
break;
case FIELD_BOOL:
$sql .= 'INT2 ';
break;
case FIELD_DROPDOWN:
$sql .= 'INT4 ';
break;
case FIELD_INT:
$sql .= 'INT8 ';
break;
}
break;
case 'firebird':
// We are defining the biggest common value, because of the possibility to edit the min/max values of each field.
$sql = 'ALTER TABLE ' . PROFILE_FIELDS_DATA_TABLE . ' ADD "' . strtoupper($field_ident) . '" ';
switch ($field_type)
{
case FIELD_STRING:
$sql .= ' VARCHAR(255) ';
break;
case FIELD_DATE:
$sql .= 'VARCHAR(10) ';
break;
case FIELD_TEXT:
$sql .= "BLOB SUB_TYPE TEXT";
// ADD {$field_ident}_bbcode_uid VARCHAR(5) NOT NULL,
// ADD {$field_ident}_bbcode_bitfield INTEGER UNSIGNED";
break;
case FIELD_BOOL:
case FIELD_DROPDOWN:
$sql .= 'INTEGER ';
break;
case FIELD_INT:
$sql .= 'DOUBLE PRECISION ';
break;
}
break;
case 'oracle':
// We are defining the biggest common value, because of the possibility to edit the min/max values of each field.
$sql = 'ALTER TABLE ' . PROFILE_FIELDS_DATA_TABLE . " ADD $field_ident ";
switch ($field_type)
{
case FIELD_STRING:
$sql .= ' VARCHAR2(255) ';
break;
case FIELD_DATE:
$sql .= 'VARCHAR2(10) ';
break;
case FIELD_TEXT:
$sql .= "CLOB";
// ADD {$field_ident}_bbcode_uid VARCHAR2(5) NOT NULL,
// ADD {$field_ident}_bbcode_bitfield NUMBER(11) UNSIGNED";
break;
case FIELD_BOOL:
$sql .= 'NUMBER(2) ';
break;
case FIELD_DROPDOWN:
$sql .= 'NUMBER(8) ';
break;
case FIELD_INT:
$sql .= 'NUMBER(20) ';
break;
}
break;
}
return $sql;
}
}
?>
PK 5:[: acp_send_statistics.phpnu W+A tpl_name = 'acp_send_statistics';
$this->page_title = 'ACP_SEND_STATISTICS';
// generate a unique id if necessary
if (!isset($config['questionnaire_unique_id']))
{
$install_id = unique_id();
set_config('questionnaire_unique_id', $install_id);
}
else
{
$install_id = $config['questionnaire_unique_id'];
}
$collector = new phpbb_questionnaire_data_collector($install_id);
// Add data provider
$collector->add_data_provider(new phpbb_questionnaire_php_data_provider());
$collector->add_data_provider(new phpbb_questionnaire_system_data_provider());
$collector->add_data_provider(new phpbb_questionnaire_phpbb_data_provider($config));
$template->assign_vars(array(
'U_COLLECT_STATS' => $collect_url,
'RAW_DATA' => $collector->get_data_for_form(),
'U_ACP_MAIN' => append_sid("{$phpbb_admin_path}index.$phpEx"),
));
$raw = $collector->get_data_raw();
foreach ($raw as $provider => $data)
{
if ($provider == 'install_id')
{
$data = array($provider => $data);
}
$template->assign_block_vars('providers', array(
'NAME' => htmlspecialchars($provider),
));
foreach ($data as $key => $value)
{
if (is_array($value))
{
$value = utf8_wordwrap(serialize($value), 75, "\n", true);
}
$template->assign_block_vars('providers.values', array(
'KEY' => utf8_htmlspecialchars($key),
'VALUE' => utf8_htmlspecialchars($value),
));
}
}
}
}
?>PK 5:[C acp_styles.phpnu W+A set(0);
$bitfield->set(1);
$bitfield->set(2);
$bitfield->set(3);
$bitfield->set(4);
$bitfield->set(8);
$bitfield->set(9);
$bitfield->set(11);
$bitfield->set(12);
define('TEMPLATE_BITFIELD', $bitfield->get_base64());
unset($bitfield);
$user->add_lang('acp/styles');
$this->tpl_name = 'acp_styles';
$this->page_title = 'ACP_CAT_STYLES';
$action = request_var('action', '');
$action = (isset($_POST['add'])) ? 'add' : $action;
$style_id = request_var('id', 0);
// Fill the configuration variables
$this->style_cfg = $this->template_cfg = $this->theme_cfg = $this->imageset_cfg = '
#
# phpBB {MODE} configuration file
#
# @package phpBB3
# @copyright (c) 2005 phpBB Group
# @license http://opensource.org/licenses/gpl-license.php GNU Public License
#
#
# At the left is the name, please do not change this
# At the right the value is entered
# For on/off options the valid values are on, off, 1, 0, true and false
#
# Values get trimmed, if you want to add a space in front or at the end of
# the value, then enclose the value with single or double quotes.
# Single and double quotes do not need to be escaped.
#
#
# General Information about this {MODE}
name = {NAME}
copyright = {COPYRIGHT}
version = {VERSION}
';
$this->theme_cfg .= '
# Some configuration options
#
# You have to turn this option on if you want to use the
# path template variables ({T_IMAGESET_PATH} for example) within
# your css file.
# This is mostly the case if you want to use language specific
# images within your css file.
#
parse_css_file = {PARSE_CSS_FILE}
';
$this->template_cfg .= '
# Some configuration options
# Template inheritance
# See http://blog.phpbb.com/2008/07/31/templating-just-got-easier/
# Set value to empty or this template name to ignore template inheritance.
inherit_from = {INHERIT_FROM}
';
$this->imageset_keys = array(
'logos' => array(
'site_logo',
),
'buttons' => array(
'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',
),
'icons' => array(
'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',
),
'forums' => array(
'forum_link', 'forum_read', 'forum_read_locked', 'forum_read_subforum', 'forum_unread', 'forum_unread_locked', 'forum_unread_subforum', 'subforum_read', 'subforum_unread'
),
'folders' => array(
'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',
),
'polls' => array(
'poll_left', 'poll_center', 'poll_right',
),
'ui' => array(
'upload_bar',
),
'user' => array(
'user_icon1', 'user_icon2', 'user_icon3', 'user_icon4', 'user_icon5', 'user_icon6', 'user_icon7', 'user_icon8', 'user_icon9', 'user_icon10',
),
);
// Execute overall actions
switch ($action)
{
case 'delete':
if ($style_id)
{
$this->remove($mode, $style_id);
return;
}
break;
case 'export':
if ($style_id)
{
$this->export($mode, $style_id);
return;
}
break;
case 'install':
$this->install($mode);
return;
break;
case 'add':
$this->add($mode);
return;
break;
case 'details':
if ($style_id)
{
$this->details($mode, $style_id);
return;
}
break;
case 'edit':
if ($style_id)
{
switch ($mode)
{
case 'imageset':
return $this->edit_imageset($style_id);
case 'template':
return $this->edit_template($style_id);
case 'theme':
return $this->edit_theme($style_id);
}
}
break;
case 'cache':
if ($style_id)
{
switch ($mode)
{
case 'template':
return $this->template_cache($style_id);
}
}
break;
}
switch ($mode)
{
case 'style':
switch ($action)
{
case 'activate':
case 'deactivate':
if ($style_id == $config['default_style'])
{
trigger_error($user->lang['DEACTIVATE_DEFAULT'] . adm_back_link($this->u_action), E_USER_WARNING);
}
if (($action == 'deactivate' && confirm_box(true)) || $action == 'activate')
{
$sql = 'UPDATE ' . STYLES_TABLE . '
SET style_active = ' . (($action == 'activate') ? 1 : 0) . '
WHERE style_id = ' . $style_id;
$db->sql_query($sql);
// Set style to default for any member using deactivated style
if ($action == 'deactivate')
{
$sql = 'UPDATE ' . USERS_TABLE . '
SET user_style = ' . $config['default_style'] . "
WHERE user_style = $style_id";
$db->sql_query($sql);
$sql = 'UPDATE ' . FORUMS_TABLE . '
SET forum_style = 0
WHERE forum_style = ' . $style_id;
$db->sql_query($sql);
}
}
else if ($action == 'deactivate')
{
$s_hidden_fields = array(
'i' => $id,
'mode' => $mode,
'action' => $action,
'style_id' => $style_id,
);
confirm_box(false, $user->lang['CONFIRM_OPERATION'], build_hidden_fields($s_hidden_fields));
}
break;
}
$this->frontend('style', array('details'), array('export', 'delete'));
break;
case 'template':
switch ($action)
{
// Refresh template data stored in db and clear cache
case 'refresh':
$sql = 'SELECT *
FROM ' . STYLES_TEMPLATE_TABLE . "
WHERE template_id = $style_id";
$result = $db->sql_query($sql);
$template_row = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
if (!$template_row)
{
trigger_error($user->lang['NO_TEMPLATE'] . adm_back_link($this->u_action), E_USER_WARNING);
}
if (confirm_box(true))
{
$template_refreshed = '';
// Only refresh database if the template is stored in the database
if ($template_row['template_storedb'] && file_exists("{$phpbb_root_path}styles/{$template_row['template_path']}/template/"))
{
$filelist = array('' => array());
$sql = 'SELECT template_filename, template_mtime
FROM ' . STYLES_TEMPLATE_DATA_TABLE . "
WHERE template_id = $style_id";
$result = $db->sql_query($sql);
while ($row = $db->sql_fetchrow($result))
{
// if (@filemtime("{$phpbb_root_path}styles/{$template_row['template_path']}/template/" . $row['template_filename']) > $row['template_mtime'])
// {
// get folder info from the filename
if (($slash_pos = strrpos($row['template_filename'], '/')) === false)
{
$filelist[''][] = $row['template_filename'];
}
else
{
$filelist[substr($row['template_filename'], 0, $slash_pos + 1)][] = substr($row['template_filename'], $slash_pos + 1, strlen($row['template_filename']) - $slash_pos - 1);
}
// }
}
$db->sql_freeresult($result);
$this->store_templates('update', $style_id, $template_row['template_path'], $filelist);
unset($filelist);
$template_refreshed = $user->lang['TEMPLATE_REFRESHED'] . ' ';
add_log('admin', 'LOG_TEMPLATE_REFRESHED', $template_row['template_name']);
}
$this->clear_template_cache($template_row);
trigger_error($template_refreshed . $user->lang['TEMPLATE_CACHE_CLEARED'] . adm_back_link($this->u_action));
}
else
{
confirm_box(false, ($template_row['template_storedb']) ? $user->lang['CONFIRM_TEMPLATE_REFRESH'] : $user->lang['CONFIRM_TEMPLATE_CLEAR_CACHE'], build_hidden_fields(array(
'i' => $id,
'mode' => $mode,
'action' => $action,
'id' => $style_id
)));
}
break;
}
$this->frontend('template', array('edit', 'cache', 'details'), array('refresh', 'export', 'delete'));
break;
case 'theme':
switch ($action)
{
// Refresh theme data stored in the database
case 'refresh':
$sql = 'SELECT *
FROM ' . STYLES_THEME_TABLE . "
WHERE theme_id = $style_id";
$result = $db->sql_query($sql);
$theme_row = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
if (!$theme_row)
{
trigger_error($user->lang['NO_THEME'] . adm_back_link($this->u_action), E_USER_WARNING);
}
if (!$theme_row['theme_storedb'])
{
trigger_error($user->lang['THEME_ERR_REFRESH_FS'] . adm_back_link($this->u_action), E_USER_WARNING);
}
if (confirm_box(true))
{
if ($theme_row['theme_storedb'] && file_exists("{$phpbb_root_path}styles/{$theme_row['theme_path']}/theme/stylesheet.css"))
{
// Save CSS contents
$sql_ary = array(
'theme_mtime' => (int) filemtime("{$phpbb_root_path}styles/{$theme_row['theme_path']}/theme/stylesheet.css"),
'theme_data' => $this->db_theme_data($theme_row)
);
$sql = 'UPDATE ' . STYLES_THEME_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $sql_ary) . "
WHERE theme_id = $style_id";
$db->sql_query($sql);
$cache->destroy('sql', STYLES_THEME_TABLE);
add_log('admin', 'LOG_THEME_REFRESHED', $theme_row['theme_name']);
trigger_error($user->lang['THEME_REFRESHED'] . adm_back_link($this->u_action));
}
}
else
{
confirm_box(false, $user->lang['CONFIRM_THEME_REFRESH'], build_hidden_fields(array(
'i' => $id,
'mode' => $mode,
'action' => $action,
'id' => $style_id
)));
}
break;
}
$this->frontend('theme', array('edit', 'details'), array('refresh', 'export', 'delete'));
break;
case 'imageset':
switch ($action)
{
case 'refresh':
$sql = 'SELECT *
FROM ' . STYLES_IMAGESET_TABLE . "
WHERE imageset_id = $style_id";
$result = $db->sql_query($sql);
$imageset_row = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
if (!$imageset_row)
{
trigger_error($user->lang['NO_IMAGESET'] . adm_back_link($this->u_action), E_USER_WARNING);
}
if (confirm_box(true))
{
$sql_ary = array();
$imageset_definitions = array();
foreach ($this->imageset_keys as $topic => $key_array)
{
$imageset_definitions = array_merge($imageset_definitions, $key_array);
}
$cfg_data_imageset = parse_cfg_file("{$phpbb_root_path}styles/{$imageset_row['imageset_path']}/imageset/imageset.cfg");
$db->sql_transaction('begin');
$sql = 'DELETE FROM ' . STYLES_IMAGESET_DATA_TABLE . '
WHERE imageset_id = ' . $style_id;
$result = $db->sql_query($sql);
foreach ($cfg_data_imageset as $image_name => $value)
{
if (strpos($value, '*') !== false)
{
if (substr($value, -1, 1) === '*')
{
list($image_filename, $image_height) = explode('*', $value);
$image_width = 0;
}
else
{
list($image_filename, $image_height, $image_width) = explode('*', $value);
}
}
else
{
$image_filename = $value;
$image_height = $image_width = 0;
}
if (strpos($image_name, 'img_') === 0 && $image_filename)
{
$image_name = substr($image_name, 4);
if (in_array($image_name, $imageset_definitions))
{
$sql_ary[] = array(
'image_name' => (string) $image_name,
'image_filename' => (string) $image_filename,
'image_height' => (int) $image_height,
'image_width' => (int) $image_width,
'imageset_id' => (int) $style_id,
'image_lang' => '',
);
}
}
}
$sql = 'SELECT lang_dir
FROM ' . LANG_TABLE;
$result = $db->sql_query($sql);
while ($row = $db->sql_fetchrow($result))
{
if (@file_exists("{$phpbb_root_path}styles/{$imageset_row['imageset_path']}/imageset/{$row['lang_dir']}/imageset.cfg"))
{
$cfg_data_imageset_data = parse_cfg_file("{$phpbb_root_path}styles/{$imageset_row['imageset_path']}/imageset/{$row['lang_dir']}/imageset.cfg");
foreach ($cfg_data_imageset_data as $image_name => $value)
{
if (strpos($value, '*') !== false)
{
if (substr($value, -1, 1) === '*')
{
list($image_filename, $image_height) = explode('*', $value);
$image_width = 0;
}
else
{
list($image_filename, $image_height, $image_width) = explode('*', $value);
}
}
else
{
$image_filename = $value;
$image_height = $image_width = 0;
}
if (strpos($image_name, 'img_') === 0 && $image_filename)
{
$image_name = substr($image_name, 4);
if (in_array($image_name, $imageset_definitions))
{
$sql_ary[] = array(
'image_name' => (string) $image_name,
'image_filename' => (string) $image_filename,
'image_height' => (int) $image_height,
'image_width' => (int) $image_width,
'imageset_id' => (int) $style_id,
'image_lang' => (string) $row['lang_dir'],
);
}
}
}
}
}
$db->sql_freeresult($result);
$db->sql_multi_insert(STYLES_IMAGESET_DATA_TABLE, $sql_ary);
$db->sql_transaction('commit');
$cache->destroy('sql', STYLES_IMAGESET_DATA_TABLE);
$cache->destroy('imageset_site_logo_md5');
add_log('admin', 'LOG_IMAGESET_REFRESHED', $imageset_row['imageset_name']);
trigger_error($user->lang['IMAGESET_REFRESHED'] . adm_back_link($this->u_action));
}
else
{
confirm_box(false, $user->lang['CONFIRM_IMAGESET_REFRESH'], build_hidden_fields(array(
'i' => $id,
'mode' => $mode,
'action' => $action,
'id' => $style_id
)));
}
break;
}
$this->frontend('imageset', array('edit', 'details'), array('refresh', 'export', 'delete'));
break;
}
}
/**
* Build Frontend with supplied options
*/
function frontend($mode, $options, $actions)
{
global $user, $template, $db, $config, $phpbb_root_path, $phpEx;
$sql_from = '';
$sql_sort = 'LOWER(' . $mode . '_name)';
$style_count = array();
switch ($mode)
{
case 'style':
$sql_from = STYLES_TABLE;
$sql_sort = 'style_active DESC, ' . $sql_sort;
$sql = 'SELECT user_style, COUNT(user_style) AS style_count
FROM ' . USERS_TABLE . '
GROUP BY user_style';
$result = $db->sql_query($sql);
while ($row = $db->sql_fetchrow($result))
{
$style_count[$row['user_style']] = $row['style_count'];
}
$db->sql_freeresult($result);
break;
case 'template':
$sql_from = STYLES_TEMPLATE_TABLE;
break;
case 'theme':
$sql_from = STYLES_THEME_TABLE;
break;
case 'imageset':
$sql_from = STYLES_IMAGESET_TABLE;
break;
default:
trigger_error($user->lang['NO_MODE'] . adm_back_link($this->u_action), E_USER_WARNING);
}
$l_prefix = strtoupper($mode);
$this->page_title = 'ACP_' . $l_prefix . 'S';
$template->assign_vars(array(
'S_FRONTEND' => true,
'S_STYLE' => ($mode == 'style') ? true : false,
'L_TITLE' => $user->lang[$this->page_title],
'L_EXPLAIN' => $user->lang[$this->page_title . '_EXPLAIN'],
'L_NAME' => $user->lang[$l_prefix . '_NAME'],
'L_INSTALLED' => $user->lang['INSTALLED_' . $l_prefix],
'L_UNINSTALLED' => $user->lang['UNINSTALLED_' . $l_prefix],
'L_NO_UNINSTALLED' => $user->lang['NO_UNINSTALLED_' . $l_prefix],
'L_CREATE' => $user->lang['CREATE_' . $l_prefix],
'U_ACTION' => $this->u_action,
)
);
$sql = "SELECT *
FROM $sql_from
ORDER BY $sql_sort ASC";
$result = $db->sql_query($sql);
$installed = array();
$basis_options = '' . $user->lang['OPTIONAL_BASIS'] . ' ';
while ($row = $db->sql_fetchrow($result))
{
$installed[] = $row[$mode . '_name'];
$basis_options .= '' . $row[$mode . '_name'] . ' ';
$stylevis = ($mode == 'style' && !$row['style_active']) ? 'activate' : 'deactivate';
$s_options = array();
foreach ($options as $option)
{
$s_options[] = '' . $user->lang[strtoupper($option)] . ' ';
}
$s_actions = array();
foreach ($actions as $option)
{
$s_actions[] = '' . $user->lang[strtoupper($option)] . ' ';
}
$template->assign_block_vars('installed', array(
'S_DEFAULT_STYLE' => ($mode == 'style' && $row['style_id'] == $config['default_style']) ? true : false,
'U_EDIT' => $this->u_action . '&action=' . (($mode == 'style') ? 'details' : 'edit') . '&id=' . $row[$mode . '_id'],
'U_STYLE_ACT_DEACT' => $this->u_action . '&action=' . $stylevis . '&id=' . $row[$mode . '_id'],
'L_STYLE_ACT_DEACT' => $user->lang['STYLE_' . strtoupper($stylevis)],
'S_OPTIONS' => implode(' | ', $s_options),
'S_ACTIONS' => implode(' | ', $s_actions),
'U_PREVIEW' => ($mode == 'style') ? append_sid("{$phpbb_root_path}index.$phpEx", "$mode=" . $row[$mode . '_id']) : '',
'NAME' => $row[$mode . '_name'],
'STYLE_COUNT' => ($mode == 'style' && isset($style_count[$row['style_id']])) ? $style_count[$row['style_id']] : 0,
'S_INACTIVE' => ($mode == 'style' && !$row['style_active']) ? true : false,
)
);
}
$db->sql_freeresult($result);
// Grab uninstalled items
$new_ary = $cfg = array();
$dp = @opendir("{$phpbb_root_path}styles");
if ($dp)
{
while (($file = readdir($dp)) !== false)
{
if ($file[0] == '.' || !is_dir($phpbb_root_path . 'styles/' . $file))
{
continue;
}
$subpath = ($mode != 'style') ? "$mode/" : '';
if (file_exists("{$phpbb_root_path}styles/$file/$subpath$mode.cfg"))
{
if ($cfg = file("{$phpbb_root_path}styles/$file/$subpath$mode.cfg"))
{
$items = parse_cfg_file('', $cfg);
$name = (isset($items['name'])) ? trim($items['name']) : false;
if ($name && !in_array($name, $installed))
{
// The array key is used for sorting later on.
// $file is appended because $name doesn't have to be unique.
$new_ary[$name . $file] = array(
'path' => $file,
'name' => $name,
'copyright' => $items['copyright'],
);
}
}
}
}
closedir($dp);
}
unset($installed);
if (sizeof($new_ary))
{
ksort($new_ary);
foreach ($new_ary as $cfg)
{
$template->assign_block_vars('uninstalled', array(
'NAME' => $cfg['name'],
'COPYRIGHT' => $cfg['copyright'],
'U_INSTALL' => $this->u_action . '&action=install&path=' . urlencode($cfg['path']))
);
}
}
unset($new_ary);
$template->assign_vars(array(
'S_BASIS_OPTIONS' => $basis_options)
);
}
/**
* Provides a template editor which allows saving changes to template files on the filesystem or in the database.
*
* @param int $template_id specifies which template set is being edited
*/
function edit_template($template_id)
{
global $phpbb_root_path, $phpEx, $config, $db, $cache, $user, $template, $safe_mode;
if (defined('PHPBB_DISABLE_ACP_EDITOR'))
{
trigger_error($user->lang['EDITOR_DISABLED'] . adm_back_link($this->u_action));
}
$this->page_title = 'EDIT_TEMPLATE';
$filelist = $filelist_cats = array();
$template_data = utf8_normalize_nfc(request_var('template_data', '', true));
$template_data = htmlspecialchars_decode($template_data);
$template_file = utf8_normalize_nfc(request_var('template_file', '', true));
$text_rows = max(5, min(999, request_var('text_rows', 20)));
$save_changes = (isset($_POST['save'])) ? true : false;
// make sure template_file path doesn't go upwards
$template_file = preg_replace('#\.{2,}#', '.', $template_file);
// Retrieve some information about the template
$sql = 'SELECT template_storedb, template_path, template_name
FROM ' . STYLES_TEMPLATE_TABLE . "
WHERE template_id = $template_id";
$result = $db->sql_query($sql);
$template_info = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
if (!$template_info)
{
trigger_error($user->lang['NO_TEMPLATE'] . adm_back_link($this->u_action), E_USER_WARNING);
}
if ($save_changes && !check_form_key('acp_styles'))
{
trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING);
}
else if (!$save_changes)
{
add_form_key('acp_styles');
}
// save changes to the template if the user submitted any
if ($save_changes && $template_file)
{
// Get the filesystem location of the current file
$file = "{$phpbb_root_path}styles/{$template_info['template_path']}/template/$template_file";
$additional = '';
// If the template is stored on the filesystem try to write the file else store it in the database
if (!$safe_mode && !$template_info['template_storedb'] && file_exists($file) && phpbb_is_writable($file))
{
if (!($fp = @fopen($file, 'wb')))
{
// File exists and is writeable, but still not able to be written to
trigger_error(sprintf($user->lang['TEMPLATE_FILE_NOT_WRITABLE'], htmlspecialchars($template_file)) . adm_back_link($this->u_action), E_USER_WARNING);
}
fwrite($fp, $template_data);
fclose($fp);
}
else
{
$db->sql_transaction('begin');
// If it's not stored in the db yet, then update the template setting and store all template files in the db
if (!$template_info['template_storedb'])
{
if ($super = $this->get_super('template', $template_id))
{
$this->store_in_db('template', $super['template_id']);
}
else
{
$this->store_in_db('template', $template_id);
}
add_log('admin', 'LOG_TEMPLATE_EDIT_DETAILS', $template_info['template_name']);
$additional .= ' ' . $user->lang['EDIT_TEMPLATE_STORED_DB'];
}
// Update the template_data table entry for this template file
$sql = 'UPDATE ' . STYLES_TEMPLATE_DATA_TABLE . "
SET template_data = '" . $db->sql_escape($template_data) . "', template_mtime = " . time() . "
WHERE template_id = $template_id
AND template_filename = '" . $db->sql_escape($template_file) . "'";
$db->sql_query($sql);
$db->sql_transaction('commit');
}
// destroy the cached version of the template (filename without extension)
$this->clear_template_cache($template_info, array(substr($template_file, 0, -5)));
$cache->destroy('sql', STYLES_TABLE);
add_log('admin', 'LOG_TEMPLATE_EDIT', $template_info['template_name'], $template_file);
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"));
}
// Generate a category array containing template filenames
if (!$template_info['template_storedb'])
{
$template_path = "{$phpbb_root_path}styles/{$template_info['template_path']}/template";
$filelist = filelist($template_path, '', 'html');
$filelist[''] = array_diff($filelist[''], array('bbcode.html'));
if ($template_file)
{
if (!file_exists($template_path . "/$template_file") || !($template_data = file_get_contents($template_path . "/$template_file")))
{
trigger_error($user->lang['NO_TEMPLATE'] . adm_back_link($this->u_action), E_USER_WARNING);
}
}
}
else
{
$sql = 'SELECT *
FROM ' . STYLES_TEMPLATE_DATA_TABLE . "
WHERE template_id = $template_id";
$result = $db->sql_query($sql);
$filelist = array('' => array());
while ($row = $db->sql_fetchrow($result))
{
$file_info = pathinfo($row['template_filename']);
if (($file_info['basename'] != 'bbcode') && ($file_info['extension'] == 'html'))
{
if (($file_info['dirname'] == '.') || empty($file_info['dirname']))
{
$filelist[''][] = $row['template_filename'];
}
else
{
$filelist[$file_info['dirname'] . '/'][] = $file_info['basename'];
}
}
if ($row['template_filename'] == $template_file)
{
$template_data = $row['template_data'];
}
}
$db->sql_freeresult($result);
unset($file_info);
}
if (empty($filelist['']))
{
trigger_error($user->lang['NO_TEMPLATE'] . adm_back_link($this->u_action), E_USER_WARNING);
}
// Now create the categories
$filelist_cats[''] = array();
foreach ($filelist as $pathfile => $file_ary)
{
// Use the directory name as category name
if (!empty($pathfile))
{
$filelist_cats[$pathfile] = array();
foreach ($file_ary as $file)
{
$filelist_cats[$pathfile][$pathfile . $file] = $file;
}
}
// or if it's in the main category use the word before the first underscore to group files
else
{
$cats = array();
foreach ($file_ary as $file)
{
$cats[] = substr($file, 0, strpos($file, '_'));
$filelist_cats[substr($file, 0, strpos($file, '_'))][$file] = $file;
}
$cats = array_values(array_unique($cats));
// we don't need any single element categories so put them into the misc '' category
for ($i = 0, $n = sizeof($cats); $i < $n; $i++)
{
if (sizeof($filelist_cats[$cats[$i]]) == 1 && $cats[$i] !== '')
{
$filelist_cats[''][key($filelist_cats[$cats[$i]])] = current($filelist_cats[$cats[$i]]);
unset($filelist_cats[$cats[$i]]);
}
}
unset($cats);
}
}
unset($filelist);
// Generate list of categorised template files
$tpl_options = '';
ksort($filelist_cats);
foreach ($filelist_cats as $category => $tpl_ary)
{
ksort($tpl_ary);
if (!empty($category))
{
$tpl_options .= '' . $category . ' ';
}
foreach ($tpl_ary as $filename => $file)
{
$selected = ($template_file == $filename) ? ' selected="selected"' : '';
$tpl_options .= '' . $file . ' ';
}
}
$template->assign_vars(array(
'S_EDIT_TEMPLATE' => true,
'S_HIDDEN_FIELDS' => build_hidden_fields(array('template_file' => $template_file)),
'S_TEMPLATES' => $tpl_options,
'U_ACTION' => $this->u_action . "&action=edit&id=$template_id&text_rows=$text_rows",
'U_BACK' => $this->u_action,
'L_EDIT' => $user->lang['EDIT_TEMPLATE'],
'L_EDIT_EXPLAIN' => $user->lang['EDIT_TEMPLATE_EXPLAIN'],
'L_EDITOR' => $user->lang['TEMPLATE_EDITOR'],
'L_EDITOR_HEIGHT' => $user->lang['TEMPLATE_EDITOR_HEIGHT'],
'L_FILE' => $user->lang['TEMPLATE_FILE'],
'L_SELECT' => $user->lang['SELECT_TEMPLATE'],
'L_SELECTED' => $user->lang['SELECTED_TEMPLATE'],
'L_SELECTED_FILE' => $user->lang['SELECTED_TEMPLATE_FILE'],
'SELECTED_TEMPLATE' => $template_info['template_name'],
'TEMPLATE_FILE' => $template_file,
'TEMPLATE_DATA' => utf8_htmlspecialchars($template_data),
'TEXT_ROWS' => $text_rows)
);
}
/**
* Allows the admin to view cached versions of template files and clear single template cache files
*
* @param int $template_id specifies which template's cache is shown
*/
function template_cache($template_id)
{
global $phpbb_root_path, $phpEx, $config, $db, $cache, $user, $template;
$source = str_replace('/', '.', request_var('source', ''));
$file_ary = array_diff(request_var('delete', array('')), array(''));
$submit = isset($_POST['submit']) ? true : false;
$sql = 'SELECT *
FROM ' . STYLES_TEMPLATE_TABLE . "
WHERE template_id = $template_id";
$result = $db->sql_query($sql);
$template_row = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
if (!$template_row)
{
trigger_error($user->lang['NO_TEMPLATE'] . adm_back_link($this->u_action), E_USER_WARNING);
}
// User wants to delete one or more files ...
if ($submit && $file_ary)
{
$this->clear_template_cache($template_row, $file_ary);
trigger_error($user->lang['TEMPLATE_CACHE_CLEARED'] . adm_back_link($this->u_action . "&action=cache&id=$template_id"));
}
$cache_prefix = 'tpl_' . str_replace('_', '-', $template_row['template_path']);
// Someone wants to see the cached source ... so we'll highlight it,
// add line numbers and indent it appropriately. This could be nasty
// on larger source files ...
if ($source && file_exists("{$phpbb_root_path}cache/{$cache_prefix}_$source.html.$phpEx"))
{
adm_page_header($user->lang['TEMPLATE_CACHE']);
$template->set_filenames(array(
'body' => 'viewsource.html')
);
$template->assign_vars(array(
'FILENAME' => str_replace('.', '/', $source) . '.html')
);
$code = str_replace(array("\r\n", "\r"), array("\n", "\n"), file_get_contents("{$phpbb_root_path}cache/{$cache_prefix}_$source.html.$phpEx"));
$conf = array('highlight.bg', 'highlight.comment', 'highlight.default', 'highlight.html', 'highlight.keyword', 'highlight.string');
foreach ($conf as $ini_var)
{
@ini_set($ini_var, str_replace('highlight.', 'syntax', $ini_var));
}
$marker = 'MARKER' . time();
$code = highlight_string(str_replace("\n", $marker, $code), true);
$code = str_replace($marker, "\n", $code);
$str_from = array('', '', '
','[', ']', '.', ':');
$str_to = array('', '', '', '[', ']', '.', ':');
$code = str_replace($str_from, $str_to, $code);
$code = preg_replace('#^()\n?(.*?)\n?( )$#ism', '$1$2$3', $code);
$code = substr($code, strlen(''));
$code = substr($code, 0, -1 * strlen(' span>'));
$code = explode("\n", $code);
foreach ($code as $key => $line)
{
$template->assign_block_vars('source', array(
'LINENUM' => $key + 1,
'LINE' => preg_replace('#([^ ;]) ([^ &])#', '$1 $2', $line))
);
unset($code[$key]);
}
adm_page_footer();
}
$filemtime = array();
if ($template_row['template_storedb'])
{
$ids = array();
if (isset($template_row['template_inherits_id']) && $template_row['template_inherits_id'])
{
$ids[] = $template_row['template_inherits_id'];
}
$ids[] = $template_row['template_id'];
$filemtime = array();
$file_template_db = array();
foreach ($ids as $id)
{
$sql = 'SELECT template_filename, template_mtime
FROM ' . STYLES_TEMPLATE_DATA_TABLE . "
WHERE template_id = $id";
$result = $db->sql_query($sql);
while ($row = $db->sql_fetchrow($result))
{
$filemtime[$row['template_filename']] = $row['template_mtime'];
$file_template_db[$row['template_filename']] = $id;
}
$db->sql_freeresult($result);
}
}
// 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)
{
$file = str_replace('/', '.', $file);
// perform some dirty guessing to get the path right.
// We assume that three dots in a row were '../'
$tpl_file = str_replace('.', '/', $file);
$tpl_file = str_replace('///', '../', $tpl_file);
$filename = "{$cache_prefix}_$file.html.$phpEx";
if (!file_exists("{$phpbb_root_path}cache/$filename"))
{
continue;
}
$file_tpl = "{$phpbb_root_path}styles/{$template_row['template_path']}/template/$tpl_file.html";
$inherited = false;
if (isset($template_row['template_inherits_id']) && $template_row['template_inherits_id'])
{
if (!$template_row['template_storedb'])
{
if (!file_exists($file_tpl))
{
$file_tpl = "{$phpbb_root_path}styles/{$template_row['template_inherit_path']}/template/$tpl_file.html";
$inherited = true;
}
}
else
{
if ($file_template_db[$file . '.html'] == $template_row['template_inherits_id'])
{
$file_tpl = "{$phpbb_root_path}styles/{$template_row['template_inherit_path']}/template/$tpl_file.html";
$inherited = true;
}
}
}
// Correct the filename if it is stored in database and the file is in a subfolder.
if ($template_row['template_storedb'])
{
$file = str_replace('.', '/', $file);
}
$template->assign_block_vars('file', array(
'U_VIEWSOURCE' => $this->u_action . "&action=cache&id=$template_id&source=$file",
'CACHED' => $user->format_date(filemtime("{$phpbb_root_path}cache/$filename")),
'FILENAME' => $file,
'FILENAME_PATH' => $file_tpl,
'FILESIZE' => get_formatted_filesize(filesize("{$phpbb_root_path}cache/$filename")),
'MODIFIED' => $user->format_date((!$template_row['template_storedb']) ? filemtime($file_tpl) : $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, $phpEx, $config, $db, $cache, $user, $template, $safe_mode;
$this->page_title = 'EDIT_THEME';
$filelist = $filelist_cats = array();
$theme_data = utf8_normalize_nfc(request_var('template_data', '', true));
$theme_data = htmlspecialchars_decode($theme_data);
$theme_file = utf8_normalize_nfc(request_var('template_file', '', true));
$text_rows = max(5, min(999, request_var('text_rows', 20)));
$save_changes = (isset($_POST['save'])) ? true : false;
// make sure theme_file path doesn't go upwards
$theme_file = str_replace('..', '.', $theme_file);
// 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_back_link($this->u_action), E_USER_WARNING);
}
$db->sql_freeresult($result);
// save changes to the theme if the user submitted any
if ($save_changes)
{
// Get the filesystem location of the current file
$file = "{$phpbb_root_path}styles/{$theme_info['theme_path']}/theme/$theme_file";
$additional = '';
$message = $user->lang['THEME_UPDATED'];
// If the theme is stored on the filesystem try to write the file else store it in the database
if (!$safe_mode && !$theme_info['theme_storedb'] && file_exists($file) && phpbb_is_writable($file))
{
if (!($fp = @fopen($file, 'wb')))
{
trigger_error($user->lang['NO_THEME'] . adm_back_link($this->u_action), E_USER_WARNING);
}
fwrite($fp, $theme_data);
fclose($fp);
}
else
{
// Write stylesheet to db
$sql_ary = array(
'theme_mtime' => time(),
'theme_storedb' => 1,
'theme_data' => $this->db_theme_data($theme_info, $theme_data),
);
$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);
// notify the user if the theme was not stored in the db before his modification
if (!$theme_info['theme_storedb'])
{
add_log('admin', 'LOG_THEME_EDIT_DETAILS', $theme_info['theme_name']);
$message .= ' ' . $user->lang['EDIT_THEME_STORED_DB'];
}
}
$cache->destroy('sql', STYLES_THEME_TABLE);
add_log('admin', (!$theme_info['theme_storedb']) ? 'LOG_THEME_EDIT_FILE' : 'LOG_THEME_EDIT', $theme_info['theme_name'], (!$theme_info['theme_storedb']) ? $theme_file : '');
trigger_error($message . adm_back_link($this->u_action . "&action=edit&id=$theme_id&template_file=$theme_file&text_rows=$text_rows"));
}
// Generate a category array containing theme filenames
if (!$theme_info['theme_storedb'])
{
$theme_path = "{$phpbb_root_path}styles/{$theme_info['theme_path']}/theme";
$filelist = filelist($theme_path, '', 'css');
if ($theme_file)
{
if (!file_exists($theme_path . "/$theme_file") || !($theme_data = file_get_contents($theme_path . "/$theme_file")))
{
trigger_error($user->lang['NO_THEME'] . adm_back_link($this->u_action), E_USER_WARNING);
}
}
}
else
{
$theme_data = &$theme_info['theme_data'];
}
// Now create the categories
$filelist_cats[''] = array();
foreach ($filelist as $pathfile => $file_ary)
{
// Use the directory name as category name
if (!empty($pathfile))
{
$filelist_cats[$pathfile] = array();
foreach ($file_ary as $file)
{
$filelist_cats[$pathfile][$pathfile . $file] = $file;
}
}
// or if it's in the main category use the word before the first underscore to group files
else
{
$cats = array();
foreach ($file_ary as $file)
{
$cats[] = substr($file, 0, strpos($file, '_'));
$filelist_cats[substr($file, 0, strpos($file, '_'))][$file] = $file;
}
$cats = array_values(array_unique($cats));
// we don't need any single element categories so put them into the misc '' category
for ($i = 0, $n = sizeof($cats); $i < $n; $i++)
{
if (sizeof($filelist_cats[$cats[$i]]) == 1 && $cats[$i] !== '')
{
$filelist_cats[''][key($filelist_cats[$cats[$i]])] = current($filelist_cats[$cats[$i]]);
unset($filelist_cats[$cats[$i]]);
}
}
unset($cats);
}
}
unset($filelist);
// Generate list of categorised theme files
$tpl_options = '';
ksort($filelist_cats);
foreach ($filelist_cats as $category => $tpl_ary)
{
ksort($tpl_ary);
if (!empty($category))
{
$tpl_options .= '' . $category . ' ';
}
foreach ($tpl_ary as $filename => $file)
{
$selected = ($theme_file == $filename) ? ' selected="selected"' : '';
$tpl_options .= '' . $file . ' ';
}
}
$template->assign_vars(array(
'S_EDIT_THEME' => true,
'S_HIDDEN_FIELDS' => build_hidden_fields(array('template_file' => $theme_file)),
'S_THEME_IN_DB' => $theme_info['theme_storedb'],
'S_TEMPLATES' => $tpl_options,
'U_ACTION' => $this->u_action . "&action=edit&id=$theme_id&text_rows=$text_rows",
'U_BACK' => $this->u_action,
'L_EDIT' => $user->lang['EDIT_THEME'],
'L_EDIT_EXPLAIN' => $user->lang['EDIT_THEME_EXPLAIN'],
'L_EDITOR' => $user->lang['THEME_EDITOR'],
'L_EDITOR_HEIGHT' => $user->lang['THEME_EDITOR_HEIGHT'],
'L_FILE' => $user->lang['THEME_FILE'],
'L_SELECT' => $user->lang['SELECT_THEME'],
'L_SELECTED' => $user->lang['SELECTED_THEME'],
'L_SELECTED_FILE' => $user->lang['SELECTED_THEME_FILE'],
'SELECTED_TEMPLATE' => $theme_info['theme_name'],
'TEMPLATE_FILE' => $theme_file,
'TEMPLATE_DATA' => utf8_htmlspecialchars($theme_data),
'TEXT_ROWS' => $text_rows)
);
}
/**
* Edit imagesets
*
* @param int $imageset_id specifies which imageset is being edited
*/
function edit_imageset($imageset_id)
{
global $db, $user, $phpbb_root_path, $cache, $template;
$this->page_title = 'EDIT_IMAGESET';
if (!$imageset_id)
{
trigger_error($user->lang['NO_IMAGESET'] . adm_back_link($this->u_action), E_USER_WARNING);
}
$update = (isset($_POST['update'])) ? true : false;
$imgname = request_var('imgname', 'site_logo');
$imgname = preg_replace('#[^a-z0-9\-+_]#i', '', $imgname);
$sql_extra = $imgnamelang = '';
$sql = 'SELECT imageset_path, imageset_name
FROM ' . STYLES_IMAGESET_TABLE . "
WHERE imageset_id = $imageset_id";
$result = $db->sql_query($sql);
$imageset_row = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
if (!$imageset_row)
{
trigger_error($user->lang['NO_IMAGESET'] . adm_back_link($this->u_action), E_USER_WARNING);
}
$imageset_path = $imageset_row['imageset_path'];
$imageset_name = $imageset_row['imageset_name'];
if (strpos($imgname, '-') !== false)
{
list($imgname, $imgnamelang) = explode('-', $imgname);
$sql_extra = " AND image_lang IN ('" . $db->sql_escape($imgnamelang) . "', '')";
}
$sql = 'SELECT image_filename, image_width, image_height, image_lang, image_id
FROM ' . STYLES_IMAGESET_DATA_TABLE . "
WHERE imageset_id = $imageset_id
AND image_name = '" . $db->sql_escape($imgname) . "'$sql_extra";
$result = $db->sql_query($sql);
$imageset_data_row = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
$image_filename = $imageset_data_row['image_filename'];
$image_width = $imageset_data_row['image_width'];
$image_height = $imageset_data_row['image_height'];
$image_lang = $imageset_data_row['image_lang'];
$image_id = $imageset_data_row['image_id'];
$imgsize = ($imageset_data_row['image_width'] && $imageset_data_row['image_height']) ? 1 : 0;
// Check to see whether the selected image exists in the table
$valid_name = ($update) ? false : true;
foreach ($this->imageset_keys as $category => $img_ary)
{
if (in_array($imgname, $img_ary))
{
$valid_name = true;
break;
}
}
if ($update && isset($_POST['imgpath']) && $valid_name)
{
// If imgwidth and imgheight are non-zero grab the actual size
// from the image itself ... we ignore width settings for the poll center image
$imgwidth = request_var('imgwidth', 0);
$imgheight = request_var('imgheight', 0);
$imgsize = request_var('imgsize', 0);
$imgpath = request_var('imgpath', '');
$imgpath = str_replace('..', '.', $imgpath);
// If no dimensions selected, we reset width and height to 0 ;)
if (!$imgsize)
{
$imgwidth = $imgheight = 0;
}
$imglang = '';
if ($imgpath && !file_exists("{$phpbb_root_path}styles/$imageset_path/imageset/$imgpath"))
{
trigger_error($user->lang['NO_IMAGE_ERROR'] . adm_back_link($this->u_action), E_USER_WARNING);
}
// Determine width/height. If dimensions included and no width/height given, we detect them automatically...
if ($imgsize && $imgpath)
{
if (!$imgwidth || !$imgheight)
{
list($imgwidth_file, $imgheight_file) = getimagesize("{$phpbb_root_path}styles/$imageset_path/imageset/$imgpath");
$imgwidth = ($imgwidth) ? $imgwidth : $imgwidth_file;
$imgheight = ($imgheight) ? $imgheight : $imgheight_file;
}
$imgwidth = ($imgname != 'poll_center') ? (int) $imgwidth : 0;
$imgheight = (int) $imgheight;
}
if (strpos($imgpath, '/') !== false)
{
list($imglang, $imgfilename) = explode('/', $imgpath);
}
else
{
$imgfilename = $imgpath;
}
$sql_ary = array(
'image_filename' => (string) $imgfilename,
'image_width' => (int) $imgwidth,
'image_height' => (int) $imgheight,
'image_lang' => (string) $imglang,
);
// already exists
if ($imageset_data_row)
{
$sql = 'UPDATE ' . STYLES_IMAGESET_DATA_TABLE . '
SET ' . $db->sql_build_array('UPDATE', $sql_ary) . "
WHERE image_id = $image_id";
$db->sql_query($sql);
}
// does not exist
else if (!$imageset_data_row)
{
$sql_ary['image_name'] = $imgname;
$sql_ary['imageset_id'] = (int) $imageset_id;
$db->sql_query('INSERT INTO ' . STYLES_IMAGESET_DATA_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary));
}
$cache->destroy('sql', STYLES_IMAGESET_DATA_TABLE);
add_log('admin', 'LOG_IMAGESET_EDIT', $imageset_name);
$template->assign_var('SUCCESS', true);
$image_filename = $imgfilename;
$image_width = $imgwidth;
$image_height = $imgheight;
$image_lang = $imglang;
}
$imglang = '';
$imagesetlist = array('nolang' => array(), 'lang' => array());
$langs = array();
$dir = "{$phpbb_root_path}styles/$imageset_path/imageset";
$dp = @opendir($dir);
if ($dp)
{
while (($file = readdir($dp)) !== false)
{
if ($file[0] != '.' && strtoupper($file) != 'CVS' && !is_file($dir . '/' . $file) && !is_link($dir . '/' . $file))
{
$langs[] = $file;
}
else if (preg_match('#\.(?:gif|jpg|png)$#', $file))
{
$imagesetlist['nolang'][] = $file;
}
}
if ($sql_extra)
{
$dp2 = @opendir("$dir/$imgnamelang");
if ($dp2)
{
while (($file2 = readdir($dp2)) !== false)
{
if (preg_match('#\.(?:gif|jpg|png)$#', $file2))
{
$imagesetlist['lang'][] = "$imgnamelang/$file2";
}
}
closedir($dp2);
}
}
closedir($dp);
}
// Generate list of image options
$img_options = '';
foreach ($this->imageset_keys as $category => $img_ary)
{
$template->assign_block_vars('category', array(
'NAME' => $user->lang['IMG_CAT_' . strtoupper($category)]
));
foreach ($img_ary as $img)
{
if ($category == 'buttons')
{
foreach ($langs as $language)
{
$template->assign_block_vars('category.images', array(
'SELECTED' => ($img == $imgname && $language == $imgnamelang),
'VALUE' => $img . '-' . $language,
'TEXT' => $user->lang['IMG_' . strtoupper($img)] . ' [ ' . $language . ' ]'
));
}
}
else
{
$template->assign_block_vars('category.images', array(
'SELECTED' => ($img == $imgname),
'VALUE' => $img,
'TEXT' => (($category == 'custom') ? $img : $user->lang['IMG_' . strtoupper($img)])
));
}
}
}
// Make sure the list of possible images is sorted alphabetically
sort($imagesetlist['lang']);
sort($imagesetlist['nolang']);
$image_found = false;
$img_val = '';
foreach ($imagesetlist as $type => $img_ary)
{
if ($type !== 'lang' || $sql_extra)
{
$template->assign_block_vars('imagesetlist', array(
'TYPE' => ($type == 'lang')
));
}
foreach ($img_ary as $img)
{
$imgtext = preg_replace('/^([^\/]+\/)/', '', $img);
$selected = (!empty($imgname) && strpos($image_filename, $imgtext) !== false);
if ($selected)
{
$image_found = true;
$img_val = htmlspecialchars($img);
}
$template->assign_block_vars('imagesetlist.images', array(
'SELECTED' => $selected,
'TEXT' => $imgtext,
'VALUE' => htmlspecialchars($img)
));
}
}
$imgsize_bool = (!empty($imgname) && $image_width && $image_height) ? true : false;
$image_request = '../styles/' . $imageset_path . '/imageset/' . ($image_lang ? $imgnamelang . '/' : '') . $image_filename;
$template->assign_vars(array(
'S_EDIT_IMAGESET' => true,
'L_TITLE' => $user->lang[$this->page_title],
'L_EXPLAIN' => $user->lang[$this->page_title . '_EXPLAIN'],
'IMAGE_OPTIONS' => $img_options,
'IMAGE_SIZE' => $image_width,
'IMAGE_HEIGHT' => $image_height,
'IMAGE_REQUEST' => (empty($image_filename)) ? 'images/no_image.png' : $image_request,
'U_ACTION' => $this->u_action . "&action=edit&id=$imageset_id",
'U_BACK' => $this->u_action,
'NAME' => $imageset_name,
'A_NAME' => addslashes($imageset_name),
'PATH' => $imageset_path,
'A_PATH' => addslashes($imageset_path),
'ERROR' => !$valid_name,
'IMG_SRC' => ($image_found) ? '../styles/' . $imageset_path . '/imageset/' . $img_val : 'images/no_image.png',
'IMAGE_SELECT' => $image_found
));
}
/**
* Remove style/template/theme/imageset
*/
function remove($mode, $style_id)
{
global $db, $template, $user, $phpbb_root_path, $cache, $config;
$new_id = request_var('new_id', 0);
$update = (isset($_POST['update'])) ? true : false;
$sql_where = '';
switch ($mode)
{
case 'style':
$sql_from = STYLES_TABLE;
$sql_select = 'style_id, style_name, template_id, theme_id, imageset_id';
$sql_where = 'AND style_active = 1';
break;
case 'template':
$sql_from = STYLES_TEMPLATE_TABLE;
$sql_select = 'template_id, template_name, template_path, template_storedb';
break;
case 'theme':
$sql_from = STYLES_THEME_TABLE;
$sql_select = 'theme_id, theme_name, theme_path, theme_storedb';
break;
case 'imageset':
$sql_from = STYLES_IMAGESET_TABLE;
$sql_select = 'imageset_id, imageset_name, imageset_path';
break;
}
if ($mode === 'template' && ($conflicts = $this->check_inheritance($mode, $style_id)))
{
$l_type = strtoupper($mode);
$msg = $user->lang[$l_type . '_DELETE_DEPENDENT'];
foreach ($conflicts as $id => $values)
{
$msg .= ' ' . $values['template_name'];
}
trigger_error($msg . adm_back_link($this->u_action), E_USER_WARNING);
}
$l_prefix = strtoupper($mode);
$sql = "SELECT $sql_select
FROM $sql_from
WHERE {$mode}_id = $style_id";
$result = $db->sql_query($sql);
$style_row = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
if (!$style_row)
{
trigger_error($user->lang['NO_' . $l_prefix] . adm_back_link($this->u_action), E_USER_WARNING);
}
$s_only_component = $this->display_component_options($mode, $style_row[$mode . '_id'], $style_row);
if ($s_only_component)
{
trigger_error($user->lang['ONLY_' . $l_prefix] . adm_back_link($this->u_action), E_USER_WARNING);
}
if ($update)
{
if ($mode == 'style')
{
$sql = "DELETE FROM $sql_from
WHERE {$mode}_id = $style_id";
$db->sql_query($sql);
$sql = 'UPDATE ' . USERS_TABLE . "
SET user_style = $new_id
WHERE user_style = $style_id";
$db->sql_query($sql);
$sql = 'UPDATE ' . FORUMS_TABLE . "
SET forum_style = $new_id
WHERE forum_style = $style_id";
$db->sql_query($sql);
if ($style_id == $config['default_style'])
{
set_config('default_style', $new_id);
}
// Remove the components
$components = array('template', 'theme', 'imageset');
foreach ($components as $component)
{
$new_id = request_var('new_' . $component . '_id', 0);
$component_id = $style_row[$component . '_id'];
$this->remove_component($component, $component_id, $new_id, $style_id);
}
}
else
{
$this->remove_component($mode, $style_id, $new_id);
}
$cache->destroy('sql', STYLES_TABLE);
add_log('admin', 'LOG_' . $l_prefix . '_DELETE', $style_row[$mode . '_name']);
$message = ($mode != 'style') ? $l_prefix . '_DELETED_FS' : $l_prefix . '_DELETED';
trigger_error($user->lang[$message] . adm_back_link($this->u_action));
}
$this->page_title = 'DELETE_' . $l_prefix;
$template->assign_vars(array(
'S_DELETE' => true,
'L_TITLE' => $user->lang[$this->page_title],
'L_EXPLAIN' => $user->lang[$this->page_title . '_EXPLAIN'],
'L_NAME' => $user->lang[$l_prefix . '_NAME'],
'L_REPLACE' => $user->lang['REPLACE_' . $l_prefix],
'L_REPLACE_EXPLAIN' => $user->lang['REPLACE_' . $l_prefix . '_EXPLAIN'],
'U_ACTION' => $this->u_action . "&action=delete&id=$style_id",
'U_BACK' => $this->u_action,
'NAME' => $style_row[$mode . '_name'],
)
);
if ($mode == 'style')
{
$template->assign_vars(array(
'S_DELETE_STYLE' => true,
));
}
}
/**
* Remove template/theme/imageset entry from the database
*/
function remove_component($component, $component_id, $new_id, $style_id = false)
{
global $db;
if (($new_id == 0) || ($component === 'template' && ($conflicts = $this->check_inheritance($component, $component_id))))
{
// We can not delete the template, as the user wants to keep the component or an other template is inheriting from this one.
return;
}
$component_in_use = array();
if ($component != 'style')
{
$component_in_use = $this->component_in_use($component, $component_id, $style_id);
}
if (($new_id == -1) && !empty($component_in_use))
{
// We can not delete the component, as it is still in use
return;
}
if ($component == 'imageset')
{
$sql = 'DELETE FROM ' . STYLES_IMAGESET_DATA_TABLE . "
WHERE imageset_id = $component_id";
$db->sql_query($sql);
}
switch ($component)
{
case 'template':
$sql_from = STYLES_TEMPLATE_TABLE;
break;
case 'theme':
$sql_from = STYLES_THEME_TABLE;
break;
case 'imageset':
$sql_from = STYLES_IMAGESET_TABLE;;
break;
}
$sql = "DELETE FROM $sql_from
WHERE {$component}_id = $component_id";
$db->sql_query($sql);
$sql = 'UPDATE ' . STYLES_TABLE . "
SET {$component}_id = $new_id
WHERE {$component}_id = $component_id";
$db->sql_query($sql);
}
/**
* Display the options which can be used to replace a style/template/theme/imageset
*
* @return boolean Returns true if the component is the only component and can not be deleted.
*/
function display_component_options($component, $component_id, $style_row = false, $style_id = false)
{
global $db, $template, $user;
$is_only_component = true;
$component_in_use = array();
if ($component != 'style')
{
$component_in_use = $this->component_in_use($component, $component_id, $style_id);
}
$sql_where = '';
switch ($component)
{
case 'style':
$sql_from = STYLES_TABLE;
$sql_where = 'WHERE style_active = 1';
break;
case 'template':
$sql_from = STYLES_TEMPLATE_TABLE;
$sql_where = 'WHERE template_inherits_id <> ' . $component_id;
break;
case 'theme':
$sql_from = STYLES_THEME_TABLE;
break;
case 'imageset':
$sql_from = STYLES_IMAGESET_TABLE;
break;
}
$s_options = '';
if (($component != 'style') && empty($component_in_use))
{
// If it is not in use, there must be another component
$is_only_component = false;
$sql = "SELECT {$component}_id, {$component}_name
FROM $sql_from
WHERE {$component}_id = {$component_id}";
$result = $db->sql_query($sql);
$row = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
$s_options .= '' . $user->lang['DELETE_' . strtoupper($component)] . ' ';
$s_options .= '' . sprintf($user->lang['KEEP_' . strtoupper($component)], $row[$component . '_name']) . ' ';
}
else
{
$sql = "SELECT {$component}_id, {$component}_name
FROM $sql_from
$sql_where
ORDER BY {$component}_name ASC";
$result = $db->sql_query($sql);
$s_keep_option = $s_options = '';
while ($row = $db->sql_fetchrow($result))
{
if ($row[$component . '_id'] != $component_id)
{
$is_only_component = false;
$s_options .= '' . sprintf($user->lang['REPLACE_WITH_OPTION'], $row[$component . '_name']) . ' ';
}
else if ($component != 'style')
{
$s_keep_option = '' . sprintf($user->lang['KEEP_' . strtoupper($component)], $row[$component . '_name']) . ' ';
}
}
$db->sql_freeresult($result);
$s_options = $s_keep_option . $s_options;
}
if (!$style_row)
{
$template->assign_var('S_REPLACE_' . strtoupper($component) . '_OPTIONS', $s_options);
}
else
{
$template->assign_var('S_REPLACE_OPTIONS', $s_options);
if ($component == 'style')
{
$components = array('template', 'theme', 'imageset');
foreach ($components as $component)
{
$this->display_component_options($component, $style_row[$component . '_id'], false, $component_id, true);
}
}
}
return $is_only_component;
}
/**
* Check whether the component is still used by another style or component
*/
function component_in_use($component, $component_id, $style_id = false)
{
global $db;
$component_in_use = array();
if ($style_id)
{
$sql = 'SELECT style_id, style_name
FROM ' . STYLES_TABLE . "
WHERE {$component}_id = {$component_id}
AND style_id <> {$style_id}
ORDER BY style_name ASC";
}
else
{
$sql = 'SELECT style_id, style_name
FROM ' . STYLES_TABLE . "
WHERE {$component}_id = {$component_id}
ORDER BY style_name ASC";
}
$result = $db->sql_query($sql);
while ($row = $db->sql_fetchrow($result))
{
$component_in_use[] = $row['style_name'];
}
$db->sql_freeresult($result);
if ($component === 'template' && ($conflicts = $this->check_inheritance($component, $component_id)))
{
foreach ($conflicts as $temp_id => $conflict_data)
{
$component_in_use[] = $conflict_data['template_name'];
}
}
return $component_in_use;
}
/**
* Export style or style elements
*/
function export($mode, $style_id)
{
global $db, $template, $user, $phpbb_root_path, $cache, $phpEx, $config;
$update = (isset($_POST['update'])) ? true : false;
$inc_template = request_var('inc_template', 0);
$inc_theme = request_var('inc_theme', 0);
$inc_imageset = request_var('inc_imageset', 0);
$store = request_var('store', 0);
$format = request_var('format', '');
$error = array();
$methods = array('tar');
$available_methods = array('tar.gz' => 'zlib', 'tar.bz2' => 'bz2', 'zip' => 'zlib');
foreach ($available_methods as $type => $module)
{
if (!@extension_loaded($module))
{
continue;
}
$methods[] = $type;
}
if (!in_array($format, $methods))
{
$format = 'tar';
}
switch ($mode)
{
case 'style':
if ($update && ($inc_template + $inc_theme + $inc_imageset) < 1)
{
$error[] = $user->lang['STYLE_ERR_MORE_ELEMENTS'];
}
$name = 'style_name';
$sql_select = 's.style_id, s.style_name, s.style_copyright';
$sql_select .= ($inc_template) ? ', t.*' : ', t.template_name';
$sql_select .= ($inc_theme) ? ', c.*' : ', c.theme_name';
$sql_select .= ($inc_imageset) ? ', i.*' : ', i.imageset_name';
$sql_from = STYLES_TABLE . ' s, ' . STYLES_TEMPLATE_TABLE . ' t, ' . STYLES_THEME_TABLE . ' c, ' . STYLES_IMAGESET_TABLE . ' i';
$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";
$l_prefix = 'STYLE';
break;
case 'template':
$name = 'template_name';
$sql_select = '*';
$sql_from = STYLES_TEMPLATE_TABLE;
$sql_where = "template_id = $style_id";
$l_prefix = 'TEMPLATE';
break;
case 'theme':
$name = 'theme_name';
$sql_select = '*';
$sql_from = STYLES_THEME_TABLE;
$sql_where = "theme_id = $style_id";
$l_prefix = 'THEME';
break;
case 'imageset':
$name = 'imageset_name';
$sql_select = '*';
$sql_from = STYLES_IMAGESET_TABLE;
$sql_where = "imageset_id = $style_id";
$l_prefix = 'IMAGESET';
break;
}
if ($update && !sizeof($error))
{
$sql = "SELECT $sql_select
FROM $sql_from
WHERE $sql_where";
$result = $db->sql_query($sql);
$style_row = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
if (!$style_row)
{
trigger_error($user->lang['NO_' . $l_prefix] . adm_back_link($this->u_action), E_USER_WARNING);
}
$var_ary = array('style_id', 'style_name', 'style_copyright', 'template_id', 'template_name', 'template_path', 'template_copyright', 'template_storedb', 'template_inherits_id', 'bbcode_bitfield', 'theme_id', 'theme_name', 'theme_path', 'theme_copyright', 'theme_storedb', 'theme_mtime', 'theme_data', 'imageset_id', 'imageset_name', 'imageset_path', 'imageset_copyright');
foreach ($var_ary as $var)
{
if (!isset($style_row[$var]))
{
$style_row[$var] = '';
}
}
$files = $data = array();
if ($mode == 'style')
{
$style_cfg = str_replace(array('{MODE}', '{NAME}', '{COPYRIGHT}', '{VERSION}'), array($mode, $style_row['style_name'], $style_row['style_copyright'], $config['version']), $this->style_cfg);
$style_cfg .= (!$inc_template) ? "\nrequired_template = {$style_row['template_name']}" : '';
$style_cfg .= (!$inc_theme) ? "\nrequired_theme = {$style_row['theme_name']}" : '';
$style_cfg .= (!$inc_imageset) ? "\nrequired_imageset = {$style_row['imageset_name']}" : '';
$data[] = array(
'src' => $style_cfg,
'prefix' => 'style.cfg'
);
unset($style_cfg);
}
// Export template core code
if ($mode == 'template' || $inc_template)
{
$use_template_name = $style_row['template_name'];
// Add the inherit from variable, depending on it's use...
if ($style_row['template_inherits_id'])
{
// Get the template name
$sql = 'SELECT template_name
FROM ' . STYLES_TEMPLATE_TABLE . '
WHERE template_id = ' . (int) $style_row['template_inherits_id'];
$result = $db->sql_query($sql);
$use_template_name = (string) $db->sql_fetchfield('template_name');
$db->sql_freeresult($result);
}
$template_cfg = str_replace(array('{MODE}', '{NAME}', '{COPYRIGHT}', '{VERSION}', '{INHERIT_FROM}'), array($mode, $style_row['template_name'], $style_row['template_copyright'], $config['version'], $use_template_name), $this->template_cfg);
$template_cfg .= "\n\nbbcode_bitfield = {$style_row['bbcode_bitfield']}";
$data[] = array(
'src' => $template_cfg,
'prefix' => 'template/template.cfg'
);
// This is potentially nasty memory-wise ...
if (!$style_row['template_storedb'])
{
$files[] = array(
'src' => "styles/{$style_row['template_path']}/template/",
'prefix-' => "styles/{$style_row['template_path']}/",
'prefix+' => false,
'exclude' => 'template.cfg'
);
}
else
{
$sql = 'SELECT template_filename, template_data
FROM ' . STYLES_TEMPLATE_DATA_TABLE . "
WHERE template_id = {$style_row['template_id']}";
$result = $db->sql_query($sql);
while ($row = $db->sql_fetchrow($result))
{
$data[] = array(
'src' => $row['template_data'],
'prefix' => 'template/' . $row['template_filename']
);
}
$db->sql_freeresult($result);
}
unset($template_cfg);
}
// Export theme core code
if ($mode == 'theme' || $inc_theme)
{
$theme_cfg = str_replace(array('{MODE}', '{NAME}', '{COPYRIGHT}', '{VERSION}'), array($mode, $style_row['theme_name'], $style_row['theme_copyright'], $config['version']), $this->theme_cfg);
// Read old cfg file
$items = $cache->obtain_cfg_items($style_row);
$items = $items['theme'];
if (!isset($items['parse_css_file']))
{
$items['parse_css_file'] = 'off';
}
$theme_cfg = str_replace(array('{PARSE_CSS_FILE}'), array($items['parse_css_file']), $theme_cfg);
$files[] = array(
'src' => "styles/{$style_row['theme_path']}/theme/",
'prefix-' => "styles/{$style_row['theme_path']}/",
'prefix+' => false,
'exclude' => ($style_row['theme_storedb']) ? 'stylesheet.css,theme.cfg' : 'theme.cfg'
);
$data[] = array(
'src' => $theme_cfg,
'prefix' => 'theme/theme.cfg'
);
if ($style_row['theme_storedb'])
{
$data[] = array(
'src' => $style_row['theme_data'],
'prefix' => 'theme/stylesheet.css'
);
}
unset($items, $theme_cfg);
}
// Export imageset core code
if ($mode == 'imageset' || $inc_imageset)
{
$imageset_cfg = str_replace(array('{MODE}', '{NAME}', '{COPYRIGHT}', '{VERSION}'), array($mode, $style_row['imageset_name'], $style_row['imageset_copyright'], $config['version']), $this->imageset_cfg);
$imageset_main = array();
$sql = 'SELECT image_filename, image_name, image_height, image_width
FROM ' . STYLES_IMAGESET_DATA_TABLE . "
WHERE imageset_id = $style_id
AND image_lang = ''";
$result = $db->sql_query($sql);
while ($row = $db->sql_fetchrow($result))
{
$imageset_main[$row['image_name']] = $row['image_filename'] . ($row['image_height'] ? '*' . $row['image_height']: '') . ($row['image_width'] ? '*' . $row['image_width']: '');
}
$db->sql_freeresult($result);
foreach ($this->imageset_keys as $topic => $key_array)
{
foreach ($key_array as $key)
{
if (isset($imageset_main[$key]))
{
$imageset_cfg .= "\nimg_" . $key . ' = ' . str_replace("styles/{$style_row['imageset_path']}/imageset/", '{PATH}', $imageset_main[$key]);
}
}
}
$files[] = array(
'src' => "styles/{$style_row['imageset_path']}/imageset/",
'prefix-' => "styles/{$style_row['imageset_path']}/",
'prefix+' => false,
'exclude' => 'imageset.cfg'
);
$data[] = array(
'src' => trim($imageset_cfg),
'prefix' => 'imageset/imageset.cfg'
);
end($data);
$imageset_root = "{$phpbb_root_path}styles/{$style_row['imageset_path']}/imageset/";
if ($dh = @opendir($imageset_root))
{
while (($fname = readdir($dh)) !== false)
{
if ($fname[0] != '.' && $fname != 'CVS' && is_dir("$imageset_root$fname"))
{
$files[key($files)]['exclude'] .= ',' . $fname . '/imageset.cfg';
}
}
closedir($dh);
}
$imageset_lang = array();
$sql = 'SELECT image_filename, image_name, image_height, image_width, image_lang
FROM ' . STYLES_IMAGESET_DATA_TABLE . "
WHERE imageset_id = $style_id
AND image_lang <> ''";
$result = $db->sql_query($sql);
while ($row = $db->sql_fetchrow($result))
{
$imageset_lang[$row['image_lang']][$row['image_name']] = $row['image_filename'] . ($row['image_height'] ? '*' . $row['image_height']: '') . ($row['image_width'] ? '*' . $row['image_width']: '');
}
$db->sql_freeresult($result);
foreach ($imageset_lang as $lang => $imageset_localized)
{
$imageset_cfg = str_replace(array('{MODE}', '{NAME}', '{COPYRIGHT}', '{VERSION}'), array($mode, $style_row['imageset_name'], $style_row['imageset_copyright'], $config['version']), $this->imageset_cfg);
foreach ($this->imageset_keys as $topic => $key_array)
{
foreach ($key_array as $key)
{
if (isset($imageset_localized[$key]))
{
$imageset_cfg .= "\nimg_" . $key . ' = ' . str_replace("styles/{$style_row['imageset_path']}/imageset/", '{PATH}', $imageset_localized[$key]);
}
}
}
$data[] = array(
'src' => trim($imageset_cfg),
'prefix' => 'imageset/' . $lang . '/imageset.cfg'
);
}
unset($imageset_cfg);
}
switch ($format)
{
case 'tar':
$ext = '.tar';
break;
case 'zip':
$ext = '.zip';
break;
case 'tar.gz':
$ext = '.tar.gz';
break;
case 'tar.bz2':
$ext = '.tar.bz2';
break;
default:
$error[] = $user->lang[$l_prefix . '_ERR_ARCHIVE'];
}
if (!sizeof($error))
{
include($phpbb_root_path . 'includes/functions_compress.' . $phpEx);
if ($mode == 'style')
{
$path = preg_replace('#[^\w-]+#', '_', $style_row['style_name']);
}
else
{
$path = $style_row[$mode . '_path'];
}
if ($format == 'zip')
{
$compress = new compress_zip('w', $phpbb_root_path . "store/$path$ext");
}
else
{
$compress = new compress_tar('w', $phpbb_root_path . "store/$path$ext", $ext);
}
if (sizeof($files))
{
foreach ($files as $file_ary)
{
$compress->add_file($file_ary['src'], $file_ary['prefix-'], $file_ary['prefix+'], $file_ary['exclude']);
}
}
if (sizeof($data))
{
foreach ($data as $data_ary)
{
$compress->add_data($data_ary['src'], $data_ary['prefix']);
}
}
$compress->close();
add_log('admin', 'LOG_' . $l_prefix . '_EXPORT', $style_row[$mode . '_name']);
if (!$store)
{
$compress->download($path);
@unlink("{$phpbb_root_path}store/$path$ext");
exit;
}
trigger_error(sprintf($user->lang[$l_prefix . '_EXPORTED'], "store/$path$ext") . adm_back_link($this->u_action));
}
}
$sql = "SELECT {$mode}_id, {$mode}_name
FROM " . (($mode == 'style') ? STYLES_TABLE : $sql_from) . "
WHERE {$mode}_id = $style_id";
$result = $db->sql_query($sql);
$style_row = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
if (!$style_row)
{
trigger_error($user->lang['NO_' . $l_prefix] . adm_back_link($this->u_action), E_USER_WARNING);
}
$this->page_title = $l_prefix . '_EXPORT';
$format_buttons = '';
foreach ($methods as $method)
{
$format_buttons .= ' ' . $method . ' ';
}
$template->assign_vars(array(
'S_EXPORT' => true,
'S_ERROR_MSG' => (sizeof($error)) ? true : false,
'S_STYLE' => ($mode == 'style') ? true : false,
'L_TITLE' => $user->lang[$this->page_title],
'L_EXPLAIN' => $user->lang[$this->page_title . '_EXPLAIN'],
'L_NAME' => $user->lang[$l_prefix . '_NAME'],
'U_ACTION' => $this->u_action . '&action=export&id=' . $style_id,
'U_BACK' => $this->u_action,
'ERROR_MSG' => (sizeof($error)) ? implode(' ', $error) : '',
'NAME' => $style_row[$mode . '_name'],
'FORMAT_BUTTONS' => $format_buttons)
);
}
/**
* Display details
*/
function details($mode, $style_id)
{
global $template, $db, $config, $user, $safe_mode, $cache, $phpbb_root_path;
$update = (isset($_POST['update'])) ? true : false;
$l_type = strtoupper($mode);
$error = array();
$element_ary = array('template' => STYLES_TEMPLATE_TABLE, 'theme' => STYLES_THEME_TABLE, 'imageset' => STYLES_IMAGESET_TABLE);
switch ($mode)
{
case 'style':
$sql_from = STYLES_TABLE;
break;
case 'template':
$sql_from = STYLES_TEMPLATE_TABLE;
break;
case 'theme':
$sql_from = STYLES_THEME_TABLE;
break;
case 'imageset':
$sql_from = STYLES_IMAGESET_TABLE;
break;
}
$sql = "SELECT *
FROM $sql_from
WHERE {$mode}_id = $style_id";
$result = $db->sql_query($sql);
$style_row = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
if (!$style_row)
{
trigger_error($user->lang['NO_' . $l_type] . adm_back_link($this->u_action), E_USER_WARNING);
}
$style_row['style_default'] = ($mode == 'style' && $config['default_style'] == $style_id) ? 1 : 0;
if ($update)
{
$name = utf8_normalize_nfc(request_var('name', '', true));
$copyright = utf8_normalize_nfc(request_var('copyright', '', true));
$template_id = request_var('template_id', 0);
$theme_id = request_var('theme_id', 0);
$imageset_id = request_var('imageset_id', 0);
$style_active = request_var('style_active', 0);
$style_default = request_var('style_default', 0);
$store_db = request_var('store_db', 0);
// If the admin selected the style to be the default style, but forgot to activate it... we will do it for him
if ($style_default)
{
$style_active = 1;
}
$sql = "SELECT {$mode}_id, {$mode}_name
FROM $sql_from
WHERE {$mode}_id <> $style_id
AND LOWER({$mode}_name) = '" . $db->sql_escape(strtolower($name)) . "'";
$result = $db->sql_query($sql);
$conflict = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
if ($mode == 'style' && (!$template_id || !$theme_id || !$imageset_id))
{
$error[] = $user->lang['STYLE_ERR_NO_IDS'];
}
if ($mode == 'style' && $style_row['style_active'] && !$style_active && $config['default_style'] == $style_id)
{
$error[] = $user->lang['DEACTIVATE_DEFAULT'];
}
if (!$name || $conflict)
{
$error[] = $user->lang[$l_type . '_ERR_STYLE_NAME'];
}
if ($mode === 'theme' || $mode === 'template')
{
// a rather elaborate check we have to do here once to avoid trouble later
$check = "{$phpbb_root_path}styles/" . $style_row["{$mode}_path"] . (($mode === 'theme') ? '/theme/stylesheet.css' : '/template');
if (($style_row["{$mode}_storedb"] != $store_db) && !$store_db && ($safe_mode || !phpbb_is_writable($check)))
{
$error[] = $user->lang['EDIT_' . strtoupper($mode) . '_STORED_DB'];
$store_db = 1;
}
// themes which have to be parsed have to go into db
if ($mode == 'theme')
{
$cfg = parse_cfg_file("{$phpbb_root_path}styles/" . $style_row["{$mode}_path"] . "/theme/theme.cfg");
if (isset($cfg['parse_css_file']) && $cfg['parse_css_file'] && !$store_db)
{
$error[] = $user->lang['EDIT_THEME_STORE_PARSED'];
$store_db = 1;
}
}
}
if (!sizeof($error))
{
// Check length settings
if (utf8_strlen($name) > 30)
{
$error[] = $user->lang[$l_type . '_ERR_NAME_LONG'];
}
if (utf8_strlen($copyright) > 60)
{
$error[] = $user->lang[$l_type . '_ERR_COPY_LONG'];
}
}
}
if ($update && sizeof($error))
{
$style_row = array_merge($style_row, array(
'template_id' => $template_id,
'theme_id' => $theme_id,
'imageset_id' => $imageset_id,
'style_active' => $style_active,
$mode . '_storedb' => $store_db,
$mode . '_name' => $name,
$mode . '_copyright' => $copyright)
);
}
// User has submitted form and no errors have occurred
if ($update && !sizeof($error))
{
$sql_ary = array(
$mode . '_name' => $name,
$mode . '_copyright' => $copyright
);
switch ($mode)
{
case 'style':
$sql_ary += array(
'template_id' => (int) $template_id,
'theme_id' => (int) $theme_id,
'imageset_id' => (int) $imageset_id,
'style_active' => (int) $style_active,
);
break;
case 'imageset':
break;
case 'theme':
if ($style_row['theme_storedb'] != $store_db)
{
$theme_data = '';
if (!$style_row['theme_storedb'])
{
$theme_data = $this->db_theme_data($style_row);
}
else if (!$store_db && !$safe_mode && phpbb_is_writable("{$phpbb_root_path}styles/{$style_row['theme_path']}/theme/stylesheet.css"))
{
$store_db = 1;
$theme_data = $style_row['theme_data'];
if ($fp = @fopen("{$phpbb_root_path}styles/{$style_row['theme_path']}/theme/stylesheet.css", 'wb'))
{
$store_db = (@fwrite($fp, str_replace("styles/{$style_row['theme_path']}/theme/", './', $theme_data))) ? 0 : 1;
}
fclose($fp);
}
$sql_ary += array(
'theme_mtime' => ($store_db) ? filemtime("{$phpbb_root_path}styles/{$style_row['theme_path']}/theme/stylesheet.css") : 0,
'theme_storedb' => $store_db,
'theme_data' => ($store_db) ? $theme_data : '',
);
}
break;
case 'template':
if ($style_row['template_storedb'] != $store_db)
{
if ($super = $this->get_super($mode, $style_row['template_id']))
{
$error[] = (sprintf($user->lang["{$l_type}_INHERITS"], $super['template_name']));
$sql_ary = array();
}
else
{
if (!$store_db && !$safe_mode && phpbb_is_writable("{$phpbb_root_path}styles/{$style_row['template_path']}/template"))
{
$err = $this->store_in_fs('template', $style_row['template_id']);
if ($err)
{
$error += $err;
}
}
else if ($store_db)
{
$this->store_in_db('template', $style_row['template_id']);
}
else
{
// We no longer store within the db, but are also not able to update the file structure
// Since the admin want to switch this, we adhere to his decision. But we also need to remove the cache
$sql = 'DELETE FROM ' . STYLES_TEMPLATE_DATA_TABLE . "
WHERE template_id = $style_id";
$db->sql_query($sql);
}
$sql_ary += array(
'template_storedb' => $store_db,
);
}
}
break;
}
if (sizeof($sql_ary))
{
$sql = "UPDATE $sql_from
SET " . $db->sql_build_array('UPDATE', $sql_ary) . "
WHERE {$mode}_id = $style_id";
$db->sql_query($sql);
// Making this the default style?
if ($mode == 'style' && $style_default)
{
set_config('default_style', $style_id);
}
}
$cache->destroy('sql', STYLES_TABLE);
add_log('admin', 'LOG_' . $l_type . '_EDIT_DETAILS', $name);
if (sizeof($error))
{
trigger_error(implode(' ', $error) . adm_back_link($this->u_action), E_USER_WARNING);
}
else
{
trigger_error($user->lang[$l_type . '_DETAILS_UPDATED'] . adm_back_link($this->u_action));
}
}
if ($mode == 'style')
{
foreach ($element_ary as $element => $table)
{
$sql = "SELECT {$element}_id, {$element}_name
FROM $table
ORDER BY {$element}_id ASC";
$result = $db->sql_query($sql);
${$element . '_options'} = '';
while ($row = $db->sql_fetchrow($result))
{
$selected = ($row[$element . '_id'] == $style_row[$element . '_id']) ? ' selected="selected"' : '';
${$element . '_options'} .= '' . $row[$element . '_name'] . ' ';
}
$db->sql_freeresult($result);
}
}
if ($mode == 'template')
{
$super = array();
if (isset($style_row[$mode . '_inherits_id']) && $style_row['template_inherits_id'])
{
$super = $this->get_super($mode, $style_row['template_id']);
}
}
$this->page_title = 'EDIT_DETAILS_' . $l_type;
$template->assign_vars(array(
'S_DETAILS' => true,
'S_ERROR_MSG' => (sizeof($error)) ? true : false,
'S_STYLE' => ($mode == 'style') ? true : false,
'S_TEMPLATE' => ($mode == 'template') ? true : false,
'S_THEME' => ($mode == 'theme') ? true : false,
'S_IMAGESET' => ($mode == 'imageset') ? true : false,
'S_STORE_DB' => (isset($style_row[$mode . '_storedb'])) ? $style_row[$mode . '_storedb'] : 0,
'S_STORE_DB_DISABLED' => (isset($style_row[$mode . '_inherits_id'])) ? $style_row[$mode . '_inherits_id'] : 0,
'S_STYLE_ACTIVE' => (isset($style_row['style_active'])) ? $style_row['style_active'] : 0,
'S_STYLE_DEFAULT' => (isset($style_row['style_default'])) ? $style_row['style_default'] : 0,
'S_SUPERTEMPLATE' => (isset($style_row[$mode . '_inherits_id']) && $style_row[$mode . '_inherits_id']) ? $super['template_name'] : 0,
'S_TEMPLATE_OPTIONS' => ($mode == 'style') ? $template_options : '',
'S_THEME_OPTIONS' => ($mode == 'style') ? $theme_options : '',
'S_IMAGESET_OPTIONS' => ($mode == 'style') ? $imageset_options : '',
'U_ACTION' => $this->u_action . '&action=details&id=' . $style_id,
'U_BACK' => $this->u_action,
'L_TITLE' => $user->lang[$this->page_title],
'L_EXPLAIN' => $user->lang[$this->page_title . '_EXPLAIN'],
'L_NAME' => $user->lang[$l_type . '_NAME'],
'L_LOCATION' => ($mode == 'template' || $mode == 'theme') ? $user->lang[$l_type . '_LOCATION'] : '',
'L_LOCATION_EXPLAIN' => ($mode == 'template' || $mode == 'theme') ? $user->lang[$l_type . '_LOCATION_EXPLAIN'] : '',
'ERROR_MSG' => (sizeof($error)) ? implode(' ', $error) : '',
'NAME' => $style_row[$mode . '_name'],
'COPYRIGHT' => $style_row[$mode . '_copyright'],
)
);
}
/**
* Load css file contents
*/
function load_css_file($path, $filename)
{
global $phpbb_root_path;
$file = "{$phpbb_root_path}styles/$path/theme/$filename";
if (file_exists($file) && ($content = file_get_contents($file)))
{
$content = trim($content);
}
else
{
$content = '';
}
if (defined('DEBUG'))
{
$content = "/* BEGIN @include $filename */ \n $content \n /* END @include $filename */ \n";
}
return $content;
}
/**
* Returns a string containing the value that should be used for the theme_data column in the theme database table.
* Includes contents of files loaded via @import
*
* @param array $theme_row is an associative array containing the theme's current database entry
* @param mixed $stylesheet can either be the new content for the stylesheet or false to load from the standard file
* @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']}"
*
* @return string Stylesheet data for theme_data column in the theme table
*/
function db_theme_data($theme_row, $stylesheet = false, $root_path = '')
{
global $phpbb_root_path;
if (!$root_path)
{
$root_path = $phpbb_root_path . 'styles/' . $theme_row['theme_path'];
}
if (!$stylesheet)
{
$stylesheet = '';
if (file_exists($root_path . '/theme/stylesheet.css'))
{
$stylesheet = file_get_contents($root_path . '/theme/stylesheet.css');
}
}
// Match CSS imports
$matches = array();
preg_match_all('/@import url\((["\'])(.*)\1\);/i', $stylesheet, $matches);
// remove commented stylesheets (very simple parser, allows only whitespace
// around an @import statement)
preg_match_all('#/\*\s*@import url\((["\'])(.*)\1\);\s\*/#i', $stylesheet, $commented);
$matches[2] = array_diff($matches[2], $commented[2]);
if (sizeof($matches))
{
foreach ($matches[0] as $idx => $match)
{
if (isset($matches[2][$idx]))
{
$stylesheet = str_replace($match, acp_styles::load_css_file($theme_row['theme_path'], $matches[2][$idx]), $stylesheet);
}
}
}
// adjust paths
return str_replace('./', 'styles/' . $theme_row['theme_path'] . '/theme/', $stylesheet);
}
/**
* Store template files into db
*/
function store_templates($mode, $style_id, $template_path, $filelist)
{
global $phpbb_root_path, $phpEx, $db;
$template_path = $template_path . '/template/';
$includes = array();
foreach ($filelist as $pathfile => $file_ary)
{
foreach ($file_ary as $file)
{
if (!($fp = @fopen("{$phpbb_root_path}styles/$template_path$pathfile$file", 'r')))
{
trigger_error("Could not open {$phpbb_root_path}styles/$template_path$pathfile$file", E_USER_ERROR);
}
$filesize = filesize("{$phpbb_root_path}styles/$template_path$pathfile$file");
if ($filesize)
{
$template_data = fread($fp, $filesize);
}
fclose($fp);
if (!$filesize)
{
// File is empty
continue;
}
if (preg_match_all('##is', $template_data, $matches))
{
foreach ($matches[1] as $match)
{
$includes[trim($match)][] = $file;
}
}
}
}
foreach ($filelist as $pathfile => $file_ary)
{
foreach ($file_ary as $file)
{
// Skip index.
if (strpos($file, 'index.') === 0)
{
continue;
}
// We could do this using extended inserts ... but that could be one
// heck of a lot of data ...
$sql_ary = array(
'template_id' => (int) $style_id,
'template_filename' => "$pathfile$file",
'template_included' => (isset($includes[$file])) ? implode(':', $includes[$file]) . ':' : '',
'template_mtime' => (int) filemtime("{$phpbb_root_path}styles/$template_path$pathfile$file"),
'template_data' => (string) file_get_contents("{$phpbb_root_path}styles/$template_path$pathfile$file"),
);
if ($mode == 'insert')
{
$sql = 'INSERT INTO ' . STYLES_TEMPLATE_DATA_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary);
}
else
{
$sql = 'UPDATE ' . STYLES_TEMPLATE_DATA_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $sql_ary) . "
WHERE template_id = $style_id
AND template_filename = '" . $db->sql_escape("$pathfile$file") . "'";
}
$db->sql_query($sql);
}
}
}
/**
* Returns an array containing all template filenames for one template that are currently cached.
*
* @param string $template_path contains the name of the template's folder in /styles/
*
* @return array of filenames that exist in /styles/$template_path/template/ (without extension!)
*/
function template_cache_filelist($template_path)
{
global $phpbb_root_path, $phpEx, $user;
$cache_prefix = 'tpl_' . str_replace('_', '-', $template_path);
if (!($dp = @opendir("{$phpbb_root_path}cache")))
{
trigger_error($user->lang['TEMPLATE_ERR_CACHE_READ'] . adm_back_link($this->u_action), E_USER_WARNING);
}
$file_ary = array();
while ($file = readdir($dp))
{
if ($file[0] == '.')
{
continue;
}
if (is_file($phpbb_root_path . 'cache/' . $file) && (strpos($file, $cache_prefix) === 0))
{
$file_ary[] = str_replace('.', '/', preg_replace('#^' . preg_quote($cache_prefix, '#') . '_(.*?)\.html\.' . $phpEx . '$#i', '\1', $file));
}
}
closedir($dp);
return $file_ary;
}
/**
* Destroys cached versions of template files
*
* @param array $template_row contains the template's row in the STYLES_TEMPLATE_TABLE database table
* @param mixed $file_ary is optional and may contain an array of template file names which should be refreshed in the cache.
* The file names should be the original template file names and not the cache file names.
*/
function clear_template_cache($template_row, $file_ary = false)
{
global $phpbb_root_path, $phpEx, $user;
$cache_prefix = 'tpl_' . str_replace('_', '-', $template_row['template_path']);
if (!$file_ary || !is_array($file_ary))
{
$file_ary = $this->template_cache_filelist($template_row['template_path']);
$log_file_list = $user->lang['ALL_FILES'];
}
else
{
$log_file_list = implode(', ', $file_ary);
}
foreach ($file_ary as $file)
{
$file = str_replace('/', '.', $file);
$file = "{$phpbb_root_path}cache/{$cache_prefix}_$file.html.$phpEx";
if (file_exists($file) && is_file($file))
{
@unlink($file);
}
}
unset($file_ary);
add_log('admin', 'LOG_TEMPLATE_CACHE_CLEARED', $template_row['template_name'], $log_file_list);
}
/**
* Install Style/Template/Theme/Imageset
*/
function install($mode)
{
global $phpbb_root_path, $phpEx, $config, $db, $cache, $user, $template;
$l_type = strtoupper($mode);
$error = $installcfg = $style_row = array();
$root_path = $cfg_file = '';
$element_ary = array('template' => STYLES_TEMPLATE_TABLE, 'theme' => STYLES_THEME_TABLE, 'imageset' => STYLES_IMAGESET_TABLE);
$install_path = request_var('path', '');
$update = (isset($_POST['update'])) ? true : false;
// Installing, obtain cfg file contents
if ($install_path)
{
$root_path = $phpbb_root_path . 'styles/' . $install_path . '/';
$cfg_file = ($mode == 'style') ? "$root_path$mode.cfg" : "$root_path$mode/$mode.cfg";
if (!file_exists($cfg_file))
{
$error[] = $user->lang[$l_type . '_ERR_NOT_' . $l_type];
}
else
{
$installcfg = parse_cfg_file($cfg_file);
}
}
// Installing
if (sizeof($installcfg))
{
$name = $installcfg['name'];
$copyright = $installcfg['copyright'];
$version = $installcfg['version'];
$style_row = array(
$mode . '_id' => 0,
$mode . '_name' => '',
$mode . '_copyright' => ''
);
switch ($mode)
{
case 'style':
$style_row = array(
'style_id' => 0,
'style_name' => $installcfg['name'],
'style_copyright' => $installcfg['copyright']
);
$reqd_template = (isset($installcfg['required_template'])) ? $installcfg['required_template'] : false;
$reqd_theme = (isset($installcfg['required_theme'])) ? $installcfg['required_theme'] : false;
$reqd_imageset = (isset($installcfg['required_imageset'])) ? $installcfg['required_imageset'] : false;
// Check to see if each element is already installed, if it is grab the id
foreach ($element_ary as $element => $table)
{
$style_row = array_merge($style_row, array(
$element . '_id' => 0,
$element . '_name' => '',
$element . '_copyright' => '')
);
$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']);
if (!$style_row[$element . '_name'])
{
$style_row[$element . '_name'] = $reqd_template;
}
// Merge other information to installcfg... if present
$cfg_file = $phpbb_root_path . 'styles/' . $install_path . '/' . $element . '/' . $element . '.cfg';
if (file_exists($cfg_file))
{
$cfg_contents = parse_cfg_file($cfg_file);
// Merge only specific things. We may need them later.
foreach (array('inherit_from', 'parse_css_file') as $key)
{
if (!empty($cfg_contents[$key]) && !isset($installcfg[$key]))
{
$installcfg[$key] = $cfg_contents[$key];
}
}
}
}
break;
case 'template':
$this->test_installed('template', $error, $root_path, false, $style_row['template_id'], $style_row['template_name'], $style_row['template_copyright']);
break;
case 'theme':
$this->test_installed('theme', $error, $root_path, false, $style_row['theme_id'], $style_row['theme_name'], $style_row['theme_copyright']);
break;
case 'imageset':
$this->test_installed('imageset', $error, $root_path, false, $style_row['imageset_id'], $style_row['imageset_name'], $style_row['imageset_copyright']);
break;
}
}
else
{
trigger_error($user->lang['NO_' . $l_type] . adm_back_link($this->u_action), E_USER_WARNING);
}
$style_row['store_db'] = request_var('store_db', 0);
$style_row['style_active'] = request_var('style_active', 1);
$style_row['style_default'] = request_var('style_default', 0);
// User has submitted form and no errors have occurred
if ($update && !sizeof($error))
{
if ($mode == 'style')
{
foreach ($element_ary as $element => $table)
{
${$element . '_root_path'} = (${'reqd_' . $element}) ? $phpbb_root_path . 'styles/' . ${'reqd_' . $element} . '/' : false;
${$element . '_path'} = (${'reqd_' . $element}) ? ${'reqd_' . $element} : false;
}
$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);
}
else
{
$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']);
}
if (!sizeof($error))
{
$cache->destroy('sql', STYLES_TABLE);
$message = ($style_row['store_db']) ? '_ADDED_DB' : '_ADDED';
trigger_error($user->lang[$l_type . $message] . adm_back_link($this->u_action));
}
}
$this->page_title = 'INSTALL_' . $l_type;
$template->assign_vars(array(
'S_DETAILS' => true,
'S_INSTALL' => true,
'S_ERROR_MSG' => (sizeof($error)) ? true : false,
'S_LOCATION' => (isset($installcfg['inherit_from']) && $installcfg['inherit_from']) ? false : true,
'S_STYLE' => ($mode == 'style') ? true : false,
'S_TEMPLATE' => ($mode == 'template') ? true : false,
'S_SUPERTEMPLATE' => (isset($installcfg['inherit_from'])) ? $installcfg['inherit_from'] : '',
'S_THEME' => ($mode == 'theme') ? true : false,
'S_STORE_DB' => (isset($style_row[$mode . '_storedb'])) ? $style_row[$mode . '_storedb'] : 0,
'S_STYLE_ACTIVE' => (isset($style_row['style_active'])) ? $style_row['style_active'] : 0,
'S_STYLE_DEFAULT' => (isset($style_row['style_default'])) ? $style_row['style_default'] : 0,
'U_ACTION' => $this->u_action . "&action=install&path=" . urlencode($install_path),
'U_BACK' => $this->u_action,
'L_TITLE' => $user->lang[$this->page_title],
'L_EXPLAIN' => $user->lang[$this->page_title . '_EXPLAIN'],
'L_NAME' => $user->lang[$l_type . '_NAME'],
'L_LOCATION' => ($mode == 'template' || $mode == 'theme') ? $user->lang[$l_type . '_LOCATION'] : '',
'L_LOCATION_EXPLAIN' => ($mode == 'template' || $mode == 'theme') ? $user->lang[$l_type . '_LOCATION_EXPLAIN'] : '',
'ERROR_MSG' => (sizeof($error)) ? implode(' ', $error) : '',
'NAME' => $style_row[$mode . '_name'],
'COPYRIGHT' => $style_row[$mode . '_copyright'],
'TEMPLATE_NAME' => ($mode == 'style') ? $style_row['template_name'] : '',
'THEME_NAME' => ($mode == 'style') ? $style_row['theme_name'] : '',
'IMAGESET_NAME' => ($mode == 'style') ? $style_row['imageset_name'] : '')
);
}
/**
* Add new style
*/
function add($mode)
{
global $phpbb_root_path, $phpEx, $config, $db, $cache, $user, $template;
$l_type = strtoupper($mode);
$element_ary = array('template' => STYLES_TEMPLATE_TABLE, 'theme' => STYLES_THEME_TABLE, 'imageset' => STYLES_IMAGESET_TABLE);
$error = array();
$style_row = array(
$mode . '_name' => utf8_normalize_nfc(request_var('name', '', true)),
$mode . '_copyright' => utf8_normalize_nfc(request_var('copyright', '', true)),
'template_id' => 0,
'theme_id' => 0,
'imageset_id' => 0,
'store_db' => request_var('store_db', 0),
'style_active' => request_var('style_active', 1),
'style_default' => request_var('style_default', 0),
);
$basis = request_var('basis', 0);
$update = (isset($_POST['update'])) ? true : false;
if ($basis)
{
switch ($mode)
{
case 'style':
$sql_select = 'template_id, theme_id, imageset_id';
$sql_from = STYLES_TABLE;
break;
case 'template':
$sql_select = 'template_id';
$sql_from = STYLES_TEMPLATE_TABLE;
break;
case 'theme':
$sql_select = 'theme_id';
$sql_from = STYLES_THEME_TABLE;
break;
case 'imageset':
$sql_select = 'imageset_id';
$sql_from = STYLES_IMAGESET_TABLE;
break;
}
$sql = "SELECT $sql_select
FROM $sql_from
WHERE {$mode}_id = $basis";
$result = $db->sql_query($sql);
$row = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
if (!$row)
{
$error[] = $user->lang['NO_' . $l_type];
}
if (!sizeof($error))
{
$style_row['template_id'] = (isset($row['template_id'])) ? $row['template_id'] : $style_row['template_id'];
$style_row['theme_id'] = (isset($row['theme_id'])) ? $row['theme_id'] : $style_row['theme_id'];
$style_row['imageset_id'] = (isset($row['imageset_id'])) ? $row['imageset_id'] : $style_row['imageset_id'];
}
}
if ($update)
{
$style_row['template_id'] = request_var('template_id', $style_row['template_id']);
$style_row['theme_id'] = request_var('theme_id', $style_row['theme_id']);
$style_row['imageset_id'] = request_var('imageset_id', $style_row['imageset_id']);
if ($mode == 'style' && (!$style_row['template_id'] || !$style_row['theme_id'] || !$style_row['imageset_id']))
{
$error[] = $user->lang['STYLE_ERR_NO_IDS'];
}
}
// User has submitted form and no errors have occurred
if ($update && !sizeof($error))
{
if ($mode == 'style')
{
$style_row['style_id'] = 0;
$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);
}
if (!sizeof($error))
{
$cache->destroy('sql', STYLES_TABLE);
$message = ($style_row['store_db']) ? '_ADDED_DB' : '_ADDED';
trigger_error($user->lang[$l_type . $message] . adm_back_link($this->u_action));
}
}
if ($mode == 'style')
{
foreach ($element_ary as $element => $table)
{
$sql = "SELECT {$element}_id, {$element}_name
FROM $table
ORDER BY {$element}_id ASC";
$result = $db->sql_query($sql);
${$element . '_options'} = '';
while ($row = $db->sql_fetchrow($result))
{
$selected = ($row[$element . '_id'] == $style_row[$element . '_id']) ? ' selected="selected"' : '';
${$element . '_options'} .= '' . $row[$element . '_name'] . ' ';
}
$db->sql_freeresult($result);
}
}
$this->page_title = 'ADD_' . $l_type;
$template->assign_vars(array(
'S_DETAILS' => true,
'S_ADD' => true,
'S_ERROR_MSG' => (sizeof($error)) ? true : false,
'S_STYLE' => ($mode == 'style') ? true : false,
'S_TEMPLATE' => ($mode == 'template') ? true : false,
'S_THEME' => ($mode == 'theme') ? true : false,
'S_BASIS' => ($basis) ? true : false,
'S_STORE_DB' => (isset($style_row['storedb'])) ? $style_row['storedb'] : 0,
'S_STYLE_ACTIVE' => (isset($style_row['style_active'])) ? $style_row['style_active'] : 0,
'S_STYLE_DEFAULT' => (isset($style_row['style_default'])) ? $style_row['style_default'] : 0,
'S_TEMPLATE_OPTIONS' => ($mode == 'style') ? $template_options : '',
'S_THEME_OPTIONS' => ($mode == 'style') ? $theme_options : '',
'S_IMAGESET_OPTIONS' => ($mode == 'style') ? $imageset_options : '',
'U_ACTION' => $this->u_action . '&action=add&basis=' . $basis,
'U_BACK' => $this->u_action,
'L_TITLE' => $user->lang[$this->page_title],
'L_EXPLAIN' => $user->lang[$this->page_title . '_EXPLAIN'],
'L_NAME' => $user->lang[$l_type . '_NAME'],
'L_LOCATION' => ($mode == 'template' || $mode == 'theme') ? $user->lang[$l_type . '_LOCATION'] : '',
'L_LOCATION_EXPLAIN' => ($mode == 'template' || $mode == 'theme') ? $user->lang[$l_type . '_LOCATION_EXPLAIN'] : '',
'ERROR_MSG' => (sizeof($error)) ? implode(' ', $error) : '',
'NAME' => $style_row[$mode . '_name'],
'COPYRIGHT' => $style_row[$mode . '_copyright'])
);
}
/**
$reqd_template = (isset($installcfg['required_template'])) ? $installcfg['required_template'] : false;
$reqd_theme = (isset($installcfg['required_theme'])) ? $installcfg['required_theme'] : false;
$reqd_imageset = (isset($installcfg['required_imageset'])) ? $installcfg['required_imageset'] : false;
// Check to see if each element is already installed, if it is grab the id
foreach ($element_ary as $element => $table)
{
$style_row = array_merge($style_row, array(
$element . '_id' => 0,
$element . '_name' => '',
$element . '_copyright' => '')
);
$this->test_installed($element, $error, $root_path, ${'reqd_' . $element}, $style_row[$element . '_id'], $style_row[$element . '_name'], $style_row[$element . '_copyright']);
* Is this element installed? If not, grab its cfg details
*/
function test_installed($element, &$error, $root_path, $reqd_name, &$id, &$name, &$copyright)
{
global $db, $user;
switch ($element)
{
case 'template':
$sql_from = STYLES_TEMPLATE_TABLE;
break;
case 'theme':
$sql_from = STYLES_THEME_TABLE;
break;
case 'imageset':
$sql_from = STYLES_IMAGESET_TABLE;
break;
}
$l_element = strtoupper($element);
$chk_name = ($reqd_name !== false) ? $reqd_name : $name;
$sql = "SELECT {$element}_id, {$element}_name
FROM $sql_from
WHERE {$element}_name = '" . $db->sql_escape($chk_name) . "'";
$result = $db->sql_query($sql);
if ($row = $db->sql_fetchrow($result))
{
$name = $row[$element . '_name'];
$id = $row[$element . '_id'];
}
else
{
if (!($cfg = @file("$root_path$element/$element.cfg")))
{
$error[] = sprintf($user->lang['REQUIRES_' . $l_element], $reqd_name);
return false;
}
$cfg = parse_cfg_file("$root_path$element/$element.cfg", $cfg);
$name = $cfg['name'];
$copyright = $cfg['copyright'];
$id = 0;
unset($cfg);
}
$db->sql_freeresult($result);
}
/**
* Install/Add style
*/
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)
{
global $config, $db, $user;
$element_ary = array('template', 'theme', 'imageset');
if (!$name)
{
$error[] = $user->lang['STYLE_ERR_STYLE_NAME'];
}
// Check length settings
if (utf8_strlen($name) > 30)
{
$error[] = $user->lang['STYLE_ERR_NAME_LONG'];
}
if (utf8_strlen($copyright) > 60)
{
$error[] = $user->lang['STYLE_ERR_COPY_LONG'];
}
// Check if the name already exist
$sql = 'SELECT style_id
FROM ' . STYLES_TABLE . "
WHERE style_name = '" . $db->sql_escape($name) . "'";
$result = $db->sql_query($sql);
$row = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
if ($row)
{
$error[] = $user->lang['STYLE_ERR_NAME_EXIST'];
}
if (sizeof($error))
{
return false;
}
foreach ($element_ary as $element)
{
// Zero id value ... need to install element ... run usual checks
// and do the install if necessary
if (!$style_row[$element . '_id'])
{
$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']);
}
}
if (!$style_row['template_id'] || !$style_row['theme_id'] || !$style_row['imageset_id'])
{
$error[] = $user->lang['STYLE_ERR_NO_IDS'];
}
if (sizeof($error))
{
return false;
}
$db->sql_transaction('begin');
$sql_ary = array(
'style_name' => $name,
'style_copyright' => $copyright,
'style_active' => (int) $active,
'template_id' => (int) $style_row['template_id'],
'theme_id' => (int) $style_row['theme_id'],
'imageset_id' => (int) $style_row['imageset_id'],
);
$sql = 'INSERT INTO ' . STYLES_TABLE . '
' . $db->sql_build_array('INSERT', $sql_ary);
$db->sql_query($sql);
$id = $db->sql_nextid();
if ($default)
{
$sql = 'UPDATE ' . USERS_TABLE . "
SET user_style = $id
WHERE user_style = " . $config['default_style'];
$db->sql_query($sql);
set_config('default_style', $id);
}
$db->sql_transaction('commit');
add_log('admin', 'LOG_STYLE_ADD', $name);
}
/**
* Install/add an element, doing various checks as we go
*/
function install_element($mode, &$error, $action, $root_path, &$id, $name, $path, $copyright, $store_db = 0)
{
global $phpbb_root_path, $db, $user;
// we parse the cfg here (again)
$cfg_data = parse_cfg_file("$root_path$mode/$mode.cfg");
switch ($mode)
{
case 'template':
$sql_from = STYLES_TEMPLATE_TABLE;
break;
case 'theme':
$sql_from = STYLES_THEME_TABLE;
break;
case 'imageset':
$sql_from = STYLES_IMAGESET_TABLE;
break;
}
$l_type = strtoupper($mode);
if (!$name)
{
$error[] = $user->lang[$l_type . '_ERR_STYLE_NAME'];
}
// Check length settings
if (utf8_strlen($name) > 30)
{
$error[] = $user->lang[$l_type . '_ERR_NAME_LONG'];
}
if (utf8_strlen($copyright) > 60)
{
$error[] = $user->lang[$l_type . '_ERR_COPY_LONG'];
}
// Check if the name already exist
$sql = "SELECT {$mode}_id
FROM $sql_from
WHERE {$mode}_name = '" . $db->sql_escape($name) . "'";
$result = $db->sql_query($sql);
$row = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
if ($row)
{
// If it exist, we just use the style on installation
if ($action == 'install')
{
$id = $row[$mode . '_id'];
return false;
}
$error[] = $user->lang[$l_type . '_ERR_NAME_EXIST'];
}
if (isset($cfg_data['inherit_from']) && $cfg_data['inherit_from'])
{
if ($mode === 'template')
{
$select_bf = ', bbcode_bitfield';
}
else
{
$select_bf = '';
}
$sql = "SELECT {$mode}_id, {$mode}_name, {$mode}_path, {$mode}_storedb $select_bf
FROM $sql_from
WHERE {$mode}_name = '" . $db->sql_escape($cfg_data['inherit_from']) . "'
AND {$mode}_inherits_id = 0";
$result = $db->sql_query($sql);
$row = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
if (!$row)
{
$error[] = sprintf($user->lang[$l_type . '_ERR_REQUIRED_OR_INCOMPLETE'], $cfg_data['inherit_from']);
}
else
{
$inherit_id = $row["{$mode}_id"];
$inherit_path = $row["{$mode}_path"];
$inherit_bf = ($mode === 'template') ? $row["bbcode_bitfield"] : false;
$cfg_data['store_db'] = $row["{$mode}_storedb"];
$store_db = $row["{$mode}_storedb"];
}
}
else
{
$inherit_id = 0;
$inherit_path = '';
$inherit_bf = false;
}
if (sizeof($error))
{
return false;
}
$sql_ary = array(
$mode . '_name' => $name,
$mode . '_copyright' => $copyright,
$mode . '_path' => $path,
);
switch ($mode)
{
case 'template':
// We check if the template author defined a different bitfield
if (!empty($cfg_data['template_bitfield']))
{
$sql_ary['bbcode_bitfield'] = $cfg_data['template_bitfield'];
}
else if ($inherit_bf)
{
$sql_ary['bbcode_bitfield'] = $inherit_bf;
}
else
{
$sql_ary['bbcode_bitfield'] = TEMPLATE_BITFIELD;
}
// We set a pre-defined bitfield here which we may use further in 3.2
$sql_ary += array(
'template_storedb' => $store_db,
);
if (isset($cfg_data['inherit_from']) && $cfg_data['inherit_from'])
{
$sql_ary += array(
'template_inherits_id' => $inherit_id,
'template_inherit_path' => $inherit_path,
);
}
break;
case 'theme':
// We are only interested in the theme configuration for now
if (isset($cfg_data['parse_css_file']) && $cfg_data['parse_css_file'])
{
$store_db = 1;
}
$sql_ary += array(
'theme_storedb' => $store_db,
'theme_data' => ($store_db) ? $this->db_theme_data($sql_ary, false, $root_path) : '',
'theme_mtime' => (int) filemtime("{$phpbb_root_path}styles/$path/theme/stylesheet.css")
);
break;
// all the heavy lifting is done later
case 'imageset':
break;
}
$db->sql_transaction('begin');
$sql = "INSERT INTO $sql_from
" . $db->sql_build_array('INSERT', $sql_ary);
$db->sql_query($sql);
$id = $db->sql_nextid();
if ($mode == 'template' && $store_db)
{
$filelist = filelist("{$root_path}template", '', 'html');
$this->store_templates('insert', $id, $path, $filelist);
}
else if ($mode == 'imageset')
{
$cfg_data = parse_cfg_file("$root_path$mode/imageset.cfg");
$imageset_definitions = array();
foreach ($this->imageset_keys as $topic => $key_array)
{
$imageset_definitions = array_merge($imageset_definitions, $key_array);
}
foreach ($cfg_data as $key => $value)
{
if (strpos($value, '*') !== false)
{
if (substr($value, -1, 1) === '*')
{
list($image_filename, $image_height) = explode('*', $value);
$image_width = 0;
}
else
{
list($image_filename, $image_height, $image_width) = explode('*', $value);
}
}
else
{
$image_filename = $value;
$image_height = $image_width = 0;
}
if (strpos($key, 'img_') === 0 && $image_filename)
{
$key = substr($key, 4);
if (in_array($key, $imageset_definitions))
{
$sql_ary = array(
'image_name' => $key,
'image_filename' => str_replace('{PATH}', "styles/$path/imageset/", trim($image_filename)),
'image_height' => (int) $image_height,
'image_width' => (int) $image_width,
'imageset_id' => (int) $id,
'image_lang' => '',
);
$db->sql_query('INSERT INTO ' . STYLES_IMAGESET_DATA_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary));
}
}
}
unset($cfg_data);
$sql = 'SELECT lang_dir
FROM ' . LANG_TABLE;
$result = $db->sql_query($sql);
while ($row = $db->sql_fetchrow($result))
{
if (@file_exists("$root_path$mode/{$row['lang_dir']}/imageset.cfg"))
{
$cfg_data_imageset_data = parse_cfg_file("$root_path$mode/{$row['lang_dir']}/imageset.cfg");
foreach ($cfg_data_imageset_data as $image_name => $value)
{
if (strpos($value, '*') !== false)
{
if (substr($value, -1, 1) === '*')
{
list($image_filename, $image_height) = explode('*', $value);
$image_width = 0;
}
else
{
list($image_filename, $image_height, $image_width) = explode('*', $value);
}
}
else
{
$image_filename = $value;
$image_height = $image_width = 0;
}
if (strpos($image_name, 'img_') === 0 && $image_filename)
{
$image_name = substr($image_name, 4);
if (in_array($image_name, $imageset_definitions))
{
$sql_ary = array(
'image_name' => $image_name,
'image_filename' => $image_filename,
'image_height' => (int) $image_height,
'image_width' => (int) $image_width,
'imageset_id' => (int) $id,
'image_lang' => $row['lang_dir'],
);
$db->sql_query('INSERT INTO ' . STYLES_IMAGESET_DATA_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary));
}
}
}
unset($cfg_data_imageset_data);
}
}
$db->sql_freeresult($result);
}
$db->sql_transaction('commit');
$log = ($store_db) ? 'LOG_' . $l_type . '_ADD_DB' : 'LOG_' . $l_type . '_ADD_FS';
add_log('admin', $log, $name);
// Return store_db in case it had to be altered
return $store_db;
}
/**
* Checks downwards dependencies
*
* @access public
* @param string $mode The element type to check - only template is supported
* @param int $id The template id
* @returns false if no component inherits, array with name, path and id for each subtemplate otherwise
*/
function check_inheritance($mode, $id)
{
global $db;
$l_type = strtoupper($mode);
switch ($mode)
{
case 'template':
$sql_from = STYLES_TEMPLATE_TABLE;
break;
case 'theme':
$sql_from = STYLES_THEME_TABLE;
break;
case 'imageset':
$sql_from = STYLES_IMAGESET_TABLE;
break;
}
$sql = "SELECT {$mode}_id, {$mode}_name, {$mode}_path
FROM $sql_from
WHERE {$mode}_inherits_id = " . (int) $id;
$result = $db->sql_query($sql);
$names = array();
while ($row = $db->sql_fetchrow($result))
{
$names[$row["{$mode}_id"]] = array(
"{$mode}_id" => $row["{$mode}_id"],
"{$mode}_name" => $row["{$mode}_name"],
"{$mode}_path" => $row["{$mode}_path"],
);
}
$db->sql_freeresult($result);
if (sizeof($names))
{
return $names;
}
else
{
return false;
}
}
/**
* Checks upwards dependencies
*
* @access public
* @param string $mode The element type to check - only template is supported
* @param int $id The template id
* @returns false if the component does not inherit, array with name, path and id otherwise
*/
function get_super($mode, $id)
{
global $db;
$l_type = strtoupper($mode);
switch ($mode)
{
case 'template':
$sql_from = STYLES_TEMPLATE_TABLE;
break;
case 'theme':
$sql_from = STYLES_THEME_TABLE;
break;
case 'imageset':
$sql_from = STYLES_IMAGESET_TABLE;
break;
}
$sql = "SELECT {$mode}_inherits_id
FROM $sql_from
WHERE {$mode}_id = " . (int) $id;
$result = $db->sql_query_limit($sql, 1);
if ($row = $db->sql_fetchrow($result))
{
$db->sql_freeresult($result);
}
else
{
return false;
}
$super_id = $row["{$mode}_inherits_id"];
$sql = "SELECT {$mode}_id, {$mode}_name, {$mode}_path
FROM $sql_from
WHERE {$mode}_id = " . (int) $super_id;
$result = $db->sql_query_limit($sql, 1);
if ($row = $db->sql_fetchrow($result))
{
$db->sql_freeresult($result);
return $row;
}
return false;
}
/**
* Moves a template set and its subtemplates to the database
*
* @access public
* @param string $mode The component to move - only template is supported
* @param int $id The template id
*/
function store_in_db($mode, $id)
{
global $db, $user;
$error = array();
$l_type = strtoupper($mode);
if ($super = $this->get_super($mode, $id))
{
$error[] = (sprintf($user->lang["{$l_type}_INHERITS"], $super['template_name']));
return $error;
}
$sql = "SELECT {$mode}_id, {$mode}_name, {$mode}_path
FROM " . STYLES_TEMPLATE_TABLE . '
WHERE template_id = ' . (int) $id;
$result = $db->sql_query_limit($sql, 1);
if ($row = $db->sql_fetchrow($result))
{
$db->sql_freeresult($result);
$subs = $this->check_inheritance($mode, $id);
$this->_store_in_db($mode, $id, $row["{$mode}_path"]);
if ($subs && sizeof($subs))
{
foreach ($subs as $sub_id => $sub)
{
if ($err = $this->_store_in_db($mode, $sub["{$mode}_id"], $sub["{$mode}_path"]))
{
$error[] = $err;
}
}
}
}
if (sizeof($error))
{
return $error;
}
return false;
}
/**
* Moves a template set to the database
*
* @access private
* @param string $mode The component to move - only template is supported
* @param int $id The template id
* @param string $path TThe path to the template files
*/
function _store_in_db($mode, $id, $path)
{
global $phpbb_root_path, $db;
$filelist = filelist("{$phpbb_root_path}styles/{$path}/template", '', 'html');
$this->store_templates('insert', $id, $path, $filelist);
// Okay, we do the query here -shouldn't be triggered often.
$sql = 'UPDATE ' . STYLES_TEMPLATE_TABLE . '
SET template_storedb = 1
WHERE template_id = ' . $id;
$db->sql_query($sql);
}
/**
* Moves a template set and its subtemplates to the filesystem
*
* @access public
* @param string $mode The component to move - only template is supported
* @param int $id The template id
*/
function store_in_fs($mode, $id)
{
global $db, $user;
$error = array();
$l_type = strtoupper($mode);
if ($super = $this->get_super($mode, $id))
{
$error[] = (sprintf($user->lang["{$l_type}_INHERITS"], $super['template_name']));
return($error);
}
$sql = "SELECT {$mode}_id, {$mode}_name, {$mode}_path
FROM " . STYLES_TEMPLATE_TABLE . '
WHERE template_id = ' . (int) $id;
$result = $db->sql_query_limit($sql, 1);
if ($row = $db->sql_fetchrow($result))
{
$db->sql_freeresult($result);
if (!sizeof($error))
{
$subs = $this->check_inheritance($mode, $id);
$this->_store_in_fs($mode, $id, $row["{$mode}_path"]);
if ($subs && sizeof($subs))
{
foreach ($subs as $sub_id => $sub)
{
$this->_store_in_fs($mode, $sub["{$mode}_id"], $sub["{$mode}_path"]);
}
}
}
if (sizeof($error))
{
$this->store_in_db($id, $mode);
return $error;
}
}
return false;
}
/**
* Moves a template set to the filesystem
*
* @access private
* @param string $mode The component to move - only template is supported
* @param int $id The template id
* @param string $path The path to the template
*/
function _store_in_fs($mode, $id, $path)
{
global $phpbb_root_path, $db, $user, $safe_mode;
$store_db = 0;
$error = array();
if (!$safe_mode && phpbb_is_writable("{$phpbb_root_path}styles/{$path}/template"))
{
$sql = 'SELECT *
FROM ' . STYLES_TEMPLATE_DATA_TABLE . "
WHERE template_id = $id";
$result = $db->sql_query($sql);
while ($row = $db->sql_fetchrow($result))
{
if (!($fp = @fopen("{$phpbb_root_path}styles/{$path}/template/" . $row['template_filename'], 'wb')))
{
$store_db = 1;
$error[] = $user->lang['EDIT_TEMPLATE_STORED_DB'];
break;
}
fwrite($fp, $row['template_data']);
fclose($fp);
}
$db->sql_freeresult($result);
if (!$store_db)
{
$sql = 'DELETE FROM ' . STYLES_TEMPLATE_DATA_TABLE . "
WHERE template_id = $id";
$db->sql_query($sql);
}
}
if (sizeof($error))
{
return $error;
}
$sql = 'UPDATE ' . STYLES_TEMPLATE_TABLE . '
SET template_storedb = 0
WHERE template_id = ' . $id;
$db->sql_query($sql);
return false;
}
}
?>PK 5:[ū<