Verzeichnisstruktur phpBB-3.0.0


Veröffentlicht
12.12.2007

So funktioniert es


Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück

Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis.
Auf den Verzeichnisnamen klicken, dies zeigt nur das Verzeichnis mit Inhalt an

(Beispiel Datei-Icons)

Auf das Icon klicken um den Quellcode anzuzeigen

acp_styles.php

Zuletzt modifiziert: 09.10.2024, 12:51 - Dateigröße: 96.54 KiB


0001  <?php
0002  /**
0003  *
0004  * @package acp
0005  * @version $Id$
0006  * @copyright (c) 2005 phpBB Group
0007  * @license http://opensource.org/licenses/gpl-license.php GNU Public License
0008  *
0009  */
0010   
0011  /**
0012  * @ignore
0013  */
0014  if (!defined('IN_PHPBB'))
0015  {
0016      exit;
0017  }
0018   
0019  /**
0020  * @package acp
0021  */
0022  class acp_styles
0023  {
0024      var $u_action;
0025   
0026      var $style_cfg;
0027      var $template_cfg;
0028      var $theme_cfg;
0029      var $imageset_cfg;
0030      var $imageset_keys;
0031   
0032      function main($id, $mode)
0033      {
0034          global $db, $user, $auth, $template, $cache;
0035          global $config, $phpbb_root_path, $phpbb_admin_path, $phpEx;
0036   
0037          // Hardcoded template bitfield to add for new templates
0038          $bitfield = new bitfield();
0039          $bitfield->set(0);
0040          $bitfield->set(3);
0041          $bitfield->set(8);
0042          $bitfield->set(9);
0043          $bitfield->set(11);
0044          $bitfield->set(12);
0045          define('TEMPLATE_BITFIELD', $bitfield->get_base64());
0046          unset($bitfield);
0047   
0048          $user->add_lang('acp/styles');
0049   
0050          $this->tpl_name = 'acp_styles';
0051          $this->page_title = 'ACP_CAT_STYLES';
0052   
0053          $action = request_var('action', '');
0054          $action = (isset($_POST['add'])) ? 'add' : $action;
0055          $style_id = request_var('id', 0);
0056   
0057          // Fill the configuration variables
0058          $this->style_cfg = $this->template_cfg = $this->theme_cfg = $this->imageset_cfg = '
0059  #
0060  # phpBB {MODE} configuration file
0061  #
0062  # @package phpBB3
0063  # @copyright (c) 2005 phpBB Group
0064  # @license http://opensource.org/licenses/gpl-license.php GNU Public License
0065  #
0066  #
0067  # At the left is the name, please do not change this
0068  # At the right the value is entered
0069  # For on/off options the valid values are on, off, 1, 0, true and false
0070  #
0071  # Values get trimmed, if you want to add a space in front or at the end of
0072  # the value, then enclose the value with single or double quotes.
0073  # Single and double quotes do not need to be escaped.
0074  #
0075  #
0076   
0077  # General Information about this {MODE}
0078  name = {NAME}
0079  copyright = {COPYRIGHT}
0080  version = {VERSION}
0081  ';
0082   
0083          $this->theme_cfg .= '
0084  # Some configuration options
0085   
0086  #
0087  # You have to turn this option on if you want to use the
0088  # path template variables ({T_IMAGESET_PATH} for example) within
0089  # your css file.
0090  # This is mostly the case if you want to use language specific
0091  # images within your css file.
0092  #
0093  parse_css_file = {PARSE_CSS_FILE}
0094  ';
0095   
0096          $this->imageset_keys = array(
0097              'logos' => array(
0098                  'site_logo',
0099              ),
0100              'buttons'    => array(
0101                  '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',
0102              ),
0103              'icons'        => array(
0104                  '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',
0105              ),
0106              'forums'    => array(
0107                  'forum_link', 'forum_read', 'forum_read_locked', 'forum_read_subforum', 'forum_unread', 'forum_unread_locked', 'forum_unread_subforum', 'subforum_read', 'subforum_unread'
0108              ),
0109              'folders'    => array(
0110                  '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',
0111              ),
0112              'polls'        => array(
0113                  'poll_left', 'poll_center', 'poll_right',
0114              ),
0115              'ui'        => array(
0116                  'upload_bar',
0117              ),
0118              'user'        => array(
0119                  'user_icon1', 'user_icon2', 'user_icon3', 'user_icon4', 'user_icon5', 'user_icon6', 'user_icon7', 'user_icon8', 'user_icon9', 'user_icon10',
0120              ),
0121          );
0122   
0123          // Execute overall actions
0124          switch ($action)
0125          {
0126              case 'delete':
0127                  if ($style_id)
0128                  {
0129                      $this->remove($mode, $style_id);
0130                      return;
0131                  }
0132              break;
0133   
0134              case 'export':
0135                  if ($style_id)
0136                  {
0137                      $this->export($mode, $style_id);
0138                      return;
0139                  }
0140              break;
0141   
0142              case 'install':
0143                  $this->install($mode);
0144                  return;
0145              break;
0146   
0147              case 'add':
0148                  $this->add($mode);
0149                  return;
0150              break;
0151   
0152              case 'details':
0153                  if ($style_id)
0154                  {
0155                      $this->details($mode, $style_id);
0156                      return;
0157                  }
0158              break;
0159   
0160              case 'edit':
0161                  if ($style_id)
0162                  {
0163                      switch ($mode)
0164                      {
0165                          case 'imageset':
0166                              return $this->edit_imageset($style_id);
0167                          case 'template':
0168                              return $this->edit_template($style_id);
0169                          case 'theme':
0170                              return $this->edit_theme($style_id);
0171                      }
0172                  }
0173              break;
0174   
0175              case 'cache':
0176                  if ($style_id)
0177                  {
0178                      switch ($mode)
0179                      {
0180                          case 'template':
0181                              return $this->template_cache($style_id);
0182                      }
0183                  }
0184              break;
0185          }
0186   
0187          switch ($mode)
0188          {
0189              case 'style':
0190   
0191                  switch ($action)
0192                  {
0193                      case 'activate':
0194                      case 'deactivate':
0195   
0196                          if ($style_id == $config['default_style'])
0197                          {
0198                              trigger_error($user->lang['DEACTIVATE_DEFAULT'] . adm_back_link($this->u_action), E_USER_WARNING);
0199                          }
0200   
0201                          $sql = 'UPDATE ' . STYLES_TABLE . '
0202                              SET style_active = ' . (($action == 'activate') ? 1 : 0) . '
0203                              WHERE style_id = ' . $style_id;
0204                          $db->sql_query($sql);
0205   
0206                          // Set style to default for any member using deactivated style
0207                          if ($action == 'deactivate')
0208                          {
0209                              $sql = 'UPDATE ' . USERS_TABLE . '
0210                                  SET user_style = ' . $config['default_style'] . "
0211                                  WHERE user_style = $style_id";
0212                              $db->sql_query($sql);
0213   
0214                              $sql = 'UPDATE ' . FORUMS_TABLE . '
0215                                  SET forum_style = 0
0216                                  WHERE forum_style = ' . $style_id;
0217                              $db->sql_query($sql);
0218                          }
0219                      break;
0220                  }
0221   
0222                  $this->frontend('style', array('details'), array('export', 'delete'));
0223              break;
0224   
0225              case 'template':
0226   
0227                  switch ($action)
0228                  {
0229                      // Refresh template data stored in db and clear cache
0230                      case 'refresh':
0231   
0232                          $sql = 'SELECT *
0233                              FROM ' . STYLES_TEMPLATE_TABLE . "
0234                              WHERE template_id = $style_id";
0235                          $result = $db->sql_query($sql);
0236                          $template_row = $db->sql_fetchrow($result);
0237                          $db->sql_freeresult($result);
0238   
0239                          if (!$template_row)
0240                          {
0241                              trigger_error($user->lang['NO_TEMPLATE'] . adm_back_link($this->u_action), E_USER_WARNING);
0242                          }
0243   
0244                          if (confirm_box(true))
0245                          {
0246                              $template_refreshed = '';
0247   
0248                              // Only refresh database if the template is stored in the database
0249                              if ($template_row['template_storedb'] && file_exists("{$phpbb_root_path}styles/{$template_row['template_path']}/template/"))
0250                              {
0251                                  $filelist = array('' => array());
0252   
0253                                  $sql = 'SELECT template_filename, template_mtime
0254                                      FROM ' . STYLES_TEMPLATE_DATA_TABLE . "
0255                                      WHERE template_id = $style_id";
0256                                  $result = $db->sql_query($sql);
0257   
0258                                  while ($row = $db->sql_fetchrow($result))
0259                                  {
0260  //                                    if (@filemtime("{$phpbb_root_path}styles/{$template_row['template_path']}/template/" . $row['template_filename']) > $row['template_mtime'])
0261  //                                    {
0262                                          // get folder info from the filename
0263                                          if (($slash_pos = strrpos($row['template_filename'], '/')) === false)
0264                                          {
0265                                              $filelist[''][] = $row['template_filename'];
0266                                          }
0267                                          else
0268                                          {
0269                                              $filelist[substr($row['template_filename'], 0, $slash_pos + 1)][] = substr($row['template_filename'], $slash_pos + 1, strlen($row['template_filename']) - $slash_pos - 1);
0270                                          }
0271  //                                    }
0272                                  }
0273                                  $db->sql_freeresult($result);
0274   
0275                                  $this->store_templates('update', $style_id, $template_row['template_path'], $filelist);
0276                                  unset($filelist);
0277   
0278                                  $template_refreshed = $user->lang['TEMPLATE_REFRESHED'] . '<br />';
0279                                  add_log('admin', 'LOG_TEMPLATE_REFRESHED', $template_row['template_name']);
0280                              }
0281   
0282                              $this->clear_template_cache($template_row);
0283   
0284                              trigger_error($template_refreshed . $user->lang['TEMPLATE_CACHE_CLEARED'] . adm_back_link($this->u_action));
0285                          }
0286                          else
0287                          {
0288                              confirm_box(false, ($template_row['template_storedb']) ? $user->lang['CONFIRM_TEMPLATE_REFRESH'] : $user->lang['CONFIRM_TEMPLATE_CLEAR_CACHE'], build_hidden_fields(array(
0289                                  'i'            => $id,
0290                                  'mode'        => $mode,
0291                                  'action'    => $action,
0292                                  'id'        => $style_id
0293                              )));
0294                          }
0295   
0296                      break;
0297                  }
0298   
0299                  $this->frontend('template', array('edit', 'cache', 'details'), array('refresh', 'export', 'delete'));
0300              break;
0301   
0302              case 'theme':
0303   
0304                  switch ($action)
0305                  {
0306                      // Refresh theme data stored in the database
0307                      case 'refresh':
0308   
0309                          $sql = 'SELECT *
0310                              FROM ' . STYLES_THEME_TABLE . "
0311                              WHERE theme_id = $style_id";
0312                          $result = $db->sql_query($sql);
0313                          $theme_row = $db->sql_fetchrow($result);
0314                          $db->sql_freeresult($result);
0315   
0316                          if (!$theme_row)
0317                          {
0318                              trigger_error($user->lang['NO_THEME'] . adm_back_link($this->u_action), E_USER_WARNING);
0319                          }
0320   
0321                          if (!$theme_row['theme_storedb'])
0322                          {
0323                              trigger_error($user->lang['THEME_ERR_REFRESH_FS'] . adm_back_link($this->u_action), E_USER_WARNING);
0324                          }
0325   
0326                          if (confirm_box(true))
0327                          {
0328                              if ($theme_row['theme_storedb'] && file_exists("{$phpbb_root_path}styles/{$theme_row['theme_path']}/theme/stylesheet.css"))
0329                              {
0330                                  // Save CSS contents
0331                                  $sql_ary = array(
0332                                      'theme_mtime'    => (int) filemtime("{$phpbb_root_path}styles/{$theme_row['theme_path']}/theme/stylesheet.css"),
0333                                      'theme_data'    => $this->db_theme_data($theme_row)
0334                                  );
0335   
0336                                  $sql = 'UPDATE ' . STYLES_THEME_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $sql_ary) . "
0337                                      WHERE theme_id = $style_id";
0338                                  $db->sql_query($sql);
0339   
0340                                  $cache->destroy('sql', STYLES_THEME_TABLE);
0341   
0342                                  add_log('admin', 'LOG_THEME_REFRESHED', $theme_row['theme_name']);
0343                                  trigger_error($user->lang['THEME_REFRESHED'] . adm_back_link($this->u_action));
0344                              }
0345                          }
0346                          else
0347                          {
0348                              confirm_box(false, $user->lang['CONFIRM_THEME_REFRESH'], build_hidden_fields(array(
0349                                  'i'            => $id,
0350                                  'mode'        => $mode,
0351                                  'action'    => $action,
0352                                  'id'        => $style_id
0353                              )));
0354                          }
0355                      break;
0356                  }
0357   
0358                  $this->frontend('theme', array('edit', 'details'), array('refresh', 'export', 'delete'));
0359              break;
0360   
0361              case 'imageset':
0362   
0363                  switch ($action)
0364                  {
0365                      case 'refresh':
0366   
0367                          $sql = 'SELECT *
0368                              FROM ' . STYLES_IMAGESET_TABLE . "
0369                              WHERE imageset_id = $style_id";
0370                          $result = $db->sql_query($sql);
0371                          $imageset_row = $db->sql_fetchrow($result);
0372                          $db->sql_freeresult($result);
0373   
0374                          if (!$imageset_row)
0375                          {
0376                              trigger_error($user->lang['NO_IMAGESET'] . adm_back_link($this->u_action), E_USER_WARNING);
0377                          }
0378   
0379                          if (confirm_box(true))
0380                          {
0381                              $sql_ary = array();
0382   
0383                              $imageset_definitions = array();
0384                              foreach ($this->imageset_keys as $topic => $key_array)
0385                              {
0386                                  $imageset_definitions = array_merge($imageset_definitions, $key_array);
0387                              }
0388   
0389                              $cfg_data_imageset = parse_cfg_file("{$phpbb_root_path}styles/{$imageset_row['imageset_path']}/imageset/imageset.cfg");
0390   
0391                              $db->sql_transaction('begin');
0392   
0393                              $sql = 'DELETE FROM ' . STYLES_IMAGESET_DATA_TABLE . '
0394                                  WHERE imageset_id = ' . $style_id;
0395                              $result = $db->sql_query($sql);
0396   
0397                              foreach ($cfg_data_imageset as $image_name => $value)
0398                              {
0399                                  if (strpos($value, '*') !== false)
0400                                  {
0401                                      if (substr($value, -1, 1) === '*')
0402                                      {
0403                                          list($image_filename, $image_height) = explode('*', $value);
0404                                          $image_width = 0;
0405                                      }
0406                                      else
0407                                      {
0408                                          list($image_filename, $image_height, $image_width) = explode('*', $value);
0409                                      }
0410                                  }
0411                                  else
0412                                  {
0413                                      $image_filename = $value;
0414                                      $image_height = $image_width = 0;
0415                                  }
0416   
0417                                  if (strpos($image_name, 'img_') === 0 && $image_filename)
0418                                  {
0419                                      $image_name = substr($image_name, 4);
0420                                      if (in_array($image_name, $imageset_definitions))
0421                                      {
0422                                          $sql_ary[] = array(
0423                                              'image_name'        => (string) $image_name,
0424                                              'image_filename'    => (string) $image_filename,
0425                                              'image_height'        => (int) $image_height,
0426                                              'image_width'        => (int) $image_width,
0427                                              'imageset_id'        => (int) $style_id,
0428                                              'image_lang'        => '',
0429                                          );
0430                                      }
0431                                  }
0432                              }
0433   
0434                              $sql = 'SELECT lang_dir
0435                                  FROM ' . LANG_TABLE;
0436                              $result = $db->sql_query($sql);
0437   
0438                              while ($row = $db->sql_fetchrow($result))
0439                              {
0440                                  if (@file_exists("{$phpbb_root_path}styles/{$imageset_row['imageset_path']}/imageset/{$row['lang_dir']}/imageset.cfg"))
0441                                  {
0442                                      $cfg_data_imageset_data = parse_cfg_file("{$phpbb_root_path}styles/{$imageset_row['imageset_path']}/imageset/{$row['lang_dir']}/imageset.cfg");
0443                                      foreach ($cfg_data_imageset_data as $image_name => $value)
0444                                      {
0445                                          if (strpos($value, '*') !== false)
0446                                          {
0447                                              if (substr($value, -1, 1) === '*')
0448                                              {
0449                                                  list($image_filename, $image_height) = explode('*', $value);
0450                                                  $image_width = 0;
0451                                              }
0452                                              else
0453                                              {
0454                                                  list($image_filename, $image_height, $image_width) = explode('*', $value);
0455                                              }
0456                                          }
0457                                          else
0458                                          {
0459                                              $image_filename = $value;
0460                                              $image_height = $image_width = 0;
0461                                          }
0462   
0463                                          if (strpos($image_name, 'img_') === 0 && $image_filename)
0464                                          {
0465                                              $image_name = substr($image_name, 4);
0466                                              if (in_array($image_name, $imageset_definitions))
0467                                              {
0468                                                  $sql_ary[] = array(
0469                                                      'image_name'        => (string) $image_name,
0470                                                      'image_filename'    => (string) $image_filename,
0471                                                      'image_height'        => (int) $image_height,
0472                                                      'image_width'        => (int) $image_width,
0473                                                      'imageset_id'        => (int) $style_id,
0474                                                      'image_lang'        => (string) $row['lang_dir'],
0475                                                  );
0476                                              }
0477                                          }
0478                                      }
0479                                  }
0480                              }
0481                              $db->sql_freeresult($result);
0482   
0483                              $db->sql_multi_insert(STYLES_IMAGESET_DATA_TABLE, $sql_ary);
0484   
0485                              $db->sql_transaction('commit');
0486   
0487                              $cache->destroy('sql', STYLES_IMAGESET_DATA_TABLE);
0488   
0489                              add_log('admin', 'LOG_IMAGESET_REFRESHED', $imageset_row['imageset_name']);
0490                              trigger_error($user->lang['IMAGESET_REFRESHED'] . adm_back_link($this->u_action));
0491                          }
0492                          else
0493                          {
0494                              confirm_box(false, $user->lang['CONFIRM_IMAGESET_REFRESH'], build_hidden_fields(array(
0495                                  'i'            => $id,
0496                                  'mode'        => $mode,
0497                                  'action'    => $action,
0498                                  'id'        => $style_id
0499                              )));
0500                          }
0501                      break;
0502                  }
0503   
0504                  $this->frontend('imageset', array('edit', 'details'), array('refresh', 'export', 'delete'));
0505              break;
0506          }
0507      }
0508   
0509      /**
0510      * Build Frontend with supplied options
0511      */
0512      function frontend($mode, $options, $actions)
0513      {
0514          global $user, $template, $db, $config, $phpbb_root_path, $phpEx;
0515   
0516          $sql_from = '';
0517          $style_count = array();
0518   
0519          switch ($mode)
0520          {
0521              case 'style':
0522                  $sql_from = STYLES_TABLE;
0523   
0524                  $sql = 'SELECT user_style, COUNT(user_style) AS style_count
0525                      FROM ' . USERS_TABLE . '
0526                      GROUP BY user_style';
0527                  $result = $db->sql_query($sql);
0528   
0529                  while ($row = $db->sql_fetchrow($result))
0530                  {
0531                      $style_count[$row['user_style']] = $row['style_count'];
0532                  }
0533                  $db->sql_freeresult($result);
0534   
0535              break;
0536   
0537              case 'template':
0538                  $sql_from = STYLES_TEMPLATE_TABLE;
0539              break;
0540   
0541              case 'theme':
0542                  $sql_from = STYLES_THEME_TABLE;
0543              break;
0544   
0545              case 'imageset':
0546                  $sql_from = STYLES_IMAGESET_TABLE;
0547              break;
0548          }
0549   
0550          $l_prefix = strtoupper($mode);
0551   
0552          $this->page_title = 'ACP_' . $l_prefix . 'S';
0553   
0554          $template->assign_vars(array(
0555              'S_FRONTEND'        => true,
0556              'S_STYLE'            => ($mode == 'style') ? true : false,
0557   
0558              'L_TITLE'            => $user->lang[$this->page_title],
0559              'L_EXPLAIN'            => $user->lang[$this->page_title . '_EXPLAIN'],
0560              'L_NAME'            => $user->lang[$l_prefix . '_NAME'],
0561              'L_INSTALLED'        => $user->lang['INSTALLED_' . $l_prefix],
0562              'L_UNINSTALLED'        => $user->lang['UNINSTALLED_' . $l_prefix],
0563              'L_NO_UNINSTALLED'    => $user->lang['NO_UNINSTALLED_' . $l_prefix],
0564              'L_CREATE'            => $user->lang['CREATE_' . $l_prefix],
0565   
0566              'U_ACTION'            => $this->u_action,
0567              )
0568          );
0569   
0570          $sql = "SELECT *
0571              FROM $sql_from";
0572          $result = $db->sql_query($sql);
0573   
0574          $installed = array();
0575   
0576          $basis_options = '<option class="sep" value="">' . $user->lang['OPTIONAL_BASIS'] . '</option>';
0577          while ($row = $db->sql_fetchrow($result))
0578          {
0579              $installed[] = $row[$mode . '_name'];
0580              $basis_options .= '<option value="' . $row[$mode . '_id'] . '">' . $row[$mode . '_name'] . '</option>';
0581   
0582              $stylevis = ($mode == 'style' && !$row['style_active']) ? 'activate' : 'deactivate';
0583   
0584              $s_options = array();
0585              foreach ($options as $option)
0586              {
0587                  $s_options[] = '<a href="' . $this->u_action . "&amp;action=$option&amp;id=" . $row[$mode . '_id'] . '">' . $user->lang[strtoupper($option)] . '</a>';
0588              }
0589   
0590              $s_actions = array();
0591              foreach ($actions as $option)
0592              {
0593                  $s_actions[] = '<a href="' . $this->u_action . "&amp;action=$option&amp;id=" . $row[$mode . '_id'] . '">' . $user->lang[strtoupper($option)] . '</a>';
0594              }
0595   
0596              $template->assign_block_vars('installed', array(
0597                  'S_DEFAULT_STYLE'        => ($mode == 'style' && $row['style_id'] == $config['default_style']) ? true : false,
0598                  'U_EDIT'                => $this->u_action . '&amp;action=' . (($mode == 'style') ? 'details' : 'edit') . '&amp;id=' . $row[$mode . '_id'],
0599                  'U_STYLE_ACT_DEACT'        => $this->u_action . '&amp;action=' . $stylevis . '&amp;id=' . $row[$mode . '_id'],
0600                  'L_STYLE_ACT_DEACT'        => $user->lang['STYLE_' . strtoupper($stylevis)],
0601                  'S_OPTIONS'                => implode(' | ', $s_options),
0602                  'S_ACTIONS'                => implode(' | ', $s_actions),
0603                  'U_PREVIEW'                => ($mode == 'style') ? append_sid("{$phpbb_root_path}index.$phpEx", "$mode=" . $row[$mode . '_id']) : '',
0604   
0605                  'NAME'                    => $row[$mode . '_name'],
0606                  'STYLE_COUNT'            => ($mode == 'style' && isset($style_count[$row['style_id']])) ? $style_count[$row['style_id']] : 0,
0607                  )
0608              );
0609          }
0610          $db->sql_freeresult($result);
0611   
0612          // Grab uninstalled items
0613          $new_ary = $cfg = array();
0614   
0615          $dp = @opendir("{$phpbb_root_path}styles");
0616   
0617          if ($dp)
0618          {
0619              while (($file = readdir($dp)) !== false)
0620              {
0621                  $subpath = ($mode != 'style') ? "$mode/" : '';
0622                  if ($file[0] != '.' && file_exists("{$phpbb_root_path}styles/$file/$subpath$mode.cfg"))
0623                  {
0624                      if ($cfg = file("{$phpbb_root_path}styles/$file/$subpath$mode.cfg"))
0625                      {
0626                          $items = parse_cfg_file('', $cfg);
0627                          $name = (isset($items['name'])) ? trim($items['name']) : false;
0628   
0629                          if ($name && !in_array($name, $installed))
0630                          {
0631                              $new_ary[] = array(
0632                                  'path'        => $file,
0633                                  'name'        => $name,
0634                                  'copyright'    => $items['copyright'],
0635                              );
0636                          }
0637                      }
0638                  }
0639              }
0640              closedir($dp);
0641          }
0642   
0643          unset($installed);
0644   
0645          if (sizeof($new_ary))
0646          {
0647              foreach ($new_ary as $cfg)
0648              {
0649                  $template->assign_block_vars('uninstalled', array(
0650                      'NAME'            => $cfg['name'],
0651                      'COPYRIGHT'        => $cfg['copyright'],
0652                      'U_INSTALL'        => $this->u_action . '&amp;action=install&amp;path=' . urlencode($cfg['path']))
0653                  );
0654              }
0655          }
0656          unset($new_ary);
0657   
0658          $template->assign_vars(array(
0659              'S_BASIS_OPTIONS'        => $basis_options)
0660          );
0661   
0662      }
0663   
0664      /**
0665      * Provides a template editor which allows saving changes to template files on the filesystem or in the database.
0666      *
0667      * @param int $template_id specifies which template set is being edited
0668      */
0669      function edit_template($template_id)
0670      {
0671          global $phpbb_root_path, $phpEx, $config, $db, $cache, $user, $template, $safe_mode;
0672   
0673          $this->page_title = 'EDIT_TEMPLATE';
0674   
0675          $filelist = $filelist_cats = array();
0676   
0677          $template_data    = utf8_normalize_nfc(request_var('template_data', '', true));
0678          $template_data    = htmlspecialchars_decode($template_data);
0679          $template_file    = utf8_normalize_nfc(request_var('template_file', '', true));
0680          $text_rows        = max(5, min(999, request_var('text_rows', 20)));
0681          $save_changes    = (isset($_POST['save'])) ? true : false;
0682   
0683          // make sure template_file path doesn't go upwards
0684          $template_file = str_replace('..', '.', $template_file);
0685          
0686          // Retrieve some information about the template
0687          $sql = 'SELECT template_storedb, template_path, template_name
0688              FROM ' . STYLES_TEMPLATE_TABLE . "
0689              WHERE template_id = $template_id";
0690          $result = $db->sql_query($sql);
0691          $template_info = $db->sql_fetchrow($result);
0692          $db->sql_freeresult($result);
0693   
0694          if (!$template_info)
0695          {
0696              trigger_error($user->lang['NO_TEMPLATE'] . adm_back_link($this->u_action), E_USER_WARNING);
0697          }
0698   
0699          // save changes to the template if the user submitted any
0700          if ($save_changes && $template_file)
0701          {
0702              // Get the filesystem location of the current file
0703              $file = "{$phpbb_root_path}styles/{$template_info['template_path']}/template/$template_file";
0704              $additional = '';
0705   
0706              // If the template is stored on the filesystem try to write the file else store it in the database
0707              if (!$safe_mode && !$template_info['template_storedb'] && file_exists($file) && @is_writable($file))
0708              {
0709                  if (!($fp = @fopen($file, 'wb')))
0710                  {
0711                      trigger_error($user->lang['NO_TEMPLATE'] . adm_back_link($this->u_action), E_USER_WARNING);
0712                  }
0713                  fwrite($fp, $template_data);
0714                  fclose($fp);
0715              }
0716              else
0717              {
0718                  $db->sql_transaction('begin');
0719   
0720                  // If it's not stored in the db yet, then update the template setting and store all template files in the db
0721                  if (!$template_info['template_storedb'])
0722                  {
0723                      $sql = 'UPDATE ' . STYLES_TEMPLATE_TABLE . '
0724                          SET template_storedb = 1
0725                          WHERE template_id = ' . $template_id;
0726                      $db->sql_query($sql);
0727   
0728                      $filelist = filelist("{$phpbb_root_path}styles/{$template_info['template_path']}/template", '', 'html');
0729                      $this->store_templates('insert', $template_id, $template_info['template_path'], $filelist);
0730   
0731                      add_log('admin', 'LOG_TEMPLATE_EDIT_DETAILS', $template_info['template_name']);
0732                      $additional .= '<br />' . $user->lang['EDIT_TEMPLATE_STORED_DB'];
0733                  }
0734   
0735                  // Update the template_data table entry for this template file
0736                  $sql = 'UPDATE ' . STYLES_TEMPLATE_DATA_TABLE . "
0737                      SET template_data = '" . $db->sql_escape($template_data) . "', template_mtime = " . time() . "
0738                      WHERE template_id = $template_id
0739                          AND template_filename = '" . $db->sql_escape($template_file) . "'";
0740                  $db->sql_query($sql);
0741   
0742                  $db->sql_transaction('commit');
0743              }
0744   
0745              // destroy the cached version of the template (filename without extension)
0746              $this->clear_template_cache($template_info, array(substr($template_file, 0, -5)));
0747   
0748              $cache->destroy('sql', STYLES_TABLE);
0749   
0750              add_log('admin', 'LOG_TEMPLATE_EDIT', $template_info['template_name'], $template_file);
0751              trigger_error($user->lang['TEMPLATE_FILE_UPDATED'] . $additional . adm_back_link($this->u_action . "&amp;action=edit&amp;id=$template_id&amp;text_rows=$text_rows&amp;template_file=$template_file"));
0752          }
0753   
0754          // Generate a category array containing template filenames
0755          if (!$template_info['template_storedb'])
0756          {
0757              $template_path = "{$phpbb_root_path}styles/{$template_info['template_path']}/template";
0758   
0759              $filelist = filelist($template_path, '', 'html');
0760              $filelist[''] = array_diff($filelist[''], array('bbcode.html'));
0761   
0762              if ($template_file)
0763              {
0764                  if (!file_exists($template_path . "/$template_file") || !($template_data = file_get_contents($template_path . "/$template_file")))
0765                  {
0766                      trigger_error($user->lang['NO_TEMPLATE'] . adm_back_link($this->u_action), E_USER_WARNING);
0767                  }
0768              }
0769          }
0770          else
0771          {
0772              $sql = 'SELECT *
0773                  FROM ' . STYLES_TEMPLATE_DATA_TABLE . "
0774                  WHERE template_id = $template_id";
0775              $result = $db->sql_query($sql);
0776   
0777              $filelist = array('' => array());
0778              while ($row = $db->sql_fetchrow($result))
0779              {
0780                  $file_info = pathinfo($row['template_filename']);
0781   
0782                  if (($file_info['basename'] != 'bbcode') && ($file_info['extension'] == 'html'))
0783                  {
0784                      if (($file_info['dirname'] == '.') || empty($file_info['dirname']))
0785                      {
0786                          $filelist[''][] = $row['template_filename'];
0787                      }
0788                      else
0789                      {
0790                          $filelist[$file_info['dirname'] . '/'][] = $file_info['basename'];
0791                      }
0792                  }
0793   
0794                  if ($row['template_filename'] == $template_file)
0795                  {
0796                      $template_data = $row['template_data'];
0797                  }
0798              }
0799              $db->sql_freeresult($result);
0800              unset($file_info);
0801          }
0802   
0803          // Now create the categories
0804          $filelist_cats[''] = array();
0805          foreach ($filelist as $pathfile => $file_ary)
0806          {
0807              // Use the directory name as category name
0808              if (!empty($pathfile))
0809              {
0810                  $filelist_cats[$pathfile] = array();
0811                  foreach ($file_ary as $file)
0812                  {
0813                      $filelist_cats[$pathfile][$pathfile . $file] = $file;
0814                  }
0815              }
0816              // or if it's in the main category use the word before the first underscore to group files
0817              else
0818              {
0819                  $cats = array();
0820                  foreach ($file_ary as $file)
0821                  {
0822                      $cats[] = substr($file, 0, strpos($file, '_'));
0823                      $filelist_cats[substr($file, 0, strpos($file, '_'))][$file] = $file;
0824                  }
0825   
0826                  $cats = array_values(array_unique($cats));
0827   
0828                  // we don't need any single element categories so put them into the misc '' category
0829                  for ($i = 0, $n = sizeof($cats); $i < $n; $i++)
0830                  {
0831                      if (sizeof($filelist_cats[$cats[$i]]) == 1 && $cats[$i] !== '')
0832                      {
0833                          $filelist_cats[''][key($filelist_cats[$cats[$i]])] = current($filelist_cats[$cats[$i]]);
0834                          unset($filelist_cats[$cats[$i]]);
0835                      }
0836                  }
0837                  unset($cats);
0838              }
0839          }
0840          unset($filelist);
0841   
0842          // Generate list of categorised template files
0843          $tpl_options = '';
0844          ksort($filelist_cats);
0845          foreach ($filelist_cats as $category => $tpl_ary)
0846          {
0847              ksort($tpl_ary);
0848   
0849              if (!empty($category))
0850              {
0851                  $tpl_options .= '<option class="sep" value="">' . $category . '</option>';
0852              }
0853   
0854              foreach ($tpl_ary as $filename => $file)
0855              {
0856                  $selected = ($template_file == $filename) ? ' selected="selected"' : '';
0857                  $tpl_options .= '<option value="' . $filename . '"' . $selected . '>' . $file . '</option>';
0858              }
0859          }
0860   
0861          $template->assign_vars(array(
0862              'S_EDIT_TEMPLATE'    => true,
0863              'S_HIDDEN_FIELDS'    => build_hidden_fields(array('template_file' => $template_file)),
0864              'S_TEMPLATES'        => $tpl_options,
0865   
0866              'U_ACTION'            => $this->u_action . "&amp;action=edit&amp;id=$template_id&amp;text_rows=$text_rows",
0867              'U_BACK'            => $this->u_action,
0868   
0869              'L_EDIT'            => $user->lang['EDIT_TEMPLATE'],
0870              'L_EDIT_EXPLAIN'    => $user->lang['EDIT_TEMPLATE_EXPLAIN'],
0871              'L_EDITOR'            => $user->lang['TEMPLATE_EDITOR'],
0872              'L_EDITOR_HEIGHT'    => $user->lang['TEMPLATE_EDITOR_HEIGHT'],
0873              'L_FILE'            => $user->lang['TEMPLATE_FILE'],
0874              'L_SELECT'            => $user->lang['SELECT_TEMPLATE'],
0875              'L_SELECTED'        => $user->lang['SELECTED_TEMPLATE'],
0876              'L_SELECTED_FILE'    => $user->lang['SELECTED_TEMPLATE_FILE'],
0877   
0878              'SELECTED_TEMPLATE'    => $template_info['template_name'],
0879              'TEMPLATE_FILE'        => $template_file,
0880              'TEMPLATE_DATA'        => utf8_htmlspecialchars($template_data),
0881              'TEXT_ROWS'            => $text_rows)
0882          );
0883      }
0884   
0885      /**
0886      * Allows the admin to view cached versions of template files and clear single template cache files
0887      *
0888      * @param int $template_id specifies which template's cache is shown
0889      */
0890      function template_cache($template_id)
0891      {
0892          global $phpbb_root_path, $phpEx, $config, $db, $cache, $user, $template;
0893   
0894          $source        = str_replace('/', '.', request_var('source', ''));
0895          $file_ary    = array_diff(request_var('delete', array('')), array(''));
0896          $submit        = isset($_POST['submit']) ? true : false;
0897   
0898          $sql = 'SELECT *
0899              FROM ' . STYLES_TEMPLATE_TABLE . "
0900              WHERE template_id = $template_id";
0901          $result = $db->sql_query($sql);
0902          $template_row = $db->sql_fetchrow($result);
0903          $db->sql_freeresult($result);
0904   
0905          if (!$template_row)
0906          {
0907              trigger_error($user->lang['NO_TEMPLATE'] . adm_back_link($this->u_action), E_USER_WARNING);
0908          }
0909   
0910          // User wants to delete one or more files ...
0911          if ($submit && $file_ary)
0912          {
0913              $this->clear_template_cache($template_row, $file_ary);
0914              trigger_error($user->lang['TEMPLATE_CACHE_CLEARED'] . adm_back_link($this->u_action . "&amp;action=cache&amp;id=$template_id"));
0915          }
0916   
0917          $cache_prefix = 'tpl_' . $template_row['template_path'];
0918   
0919          // Someone wants to see the cached source ... so we'll highlight it,
0920          // add line numbers and indent it appropriately. This could be nasty
0921          // on larger source files ...
0922          if ($source && file_exists("{$phpbb_root_path}cache/{$cache_prefix}_$source.html.$phpEx"))
0923          {
0924              adm_page_header($user->lang['TEMPLATE_CACHE']);
0925   
0926              $template->set_filenames(array(
0927                  'body'    => 'viewsource.html')
0928              );
0929   
0930              $template->assign_vars(array(
0931                  'FILENAME'    => str_replace('.', '/', $source) . '.html')
0932              );
0933   
0934              $code = str_replace(array("\r\n", "\r"), array("\n", "\n"), file_get_contents("{$phpbb_root_path}cache/{$cache_prefix}_$source.html.$phpEx"));
0935   
0936              $conf = array('highlight.bg', 'highlight.comment', 'highlight.default', 'highlight.html', 'highlight.keyword', 'highlight.string');
0937              foreach ($conf as $ini_var)
0938              {
0939                  @ini_set($ini_var, str_replace('highlight.', 'syntax', $ini_var));
0940              }
0941   
0942              $marker = 'MARKER' . time();
0943              $code = highlight_string(str_replace("\n", $marker, $code), true);
0944              $code = str_replace($marker, "\n", $code);
0945              $str_from = array('<span style="color: ', '<font color="syntax', '</font>', '<code>', '</code>','[', ']', '.', ':');
0946              $str_to = array('<span class="', '<span class="syntax', '</span>', '', '', '&#91;', '&#93;', '&#46;', '&#58;');
0947   
0948              $code = str_replace($str_from, $str_to, $code);
0949              $code = preg_replace('#^(<span class="[a-z_]+">)\n?(.*?)\n?(</span>)$#ism', '$1$2$3', $code);
0950              $code = substr($code, strlen('<span class="syntaxhtml">'));
0951              $code = substr($code, 0, -1 * strlen('</ span>'));
0952              $code = explode("\n", $code);
0953   
0954              foreach ($code as $key => $line)
0955              {
0956                  $template->assign_block_vars('source', array(
0957                      'LINENUM'    => $key + 1,
0958                      'LINE'        => preg_replace('#([^ ;])&nbsp;([^ &])#', '$1 $2', $line))
0959                  );
0960                  unset($code[$key]);
0961              }
0962   
0963              adm_page_footer();
0964          }
0965   
0966          $filemtime = array();
0967          if ($template_row['template_storedb'])
0968          {
0969              $sql = 'SELECT template_filename, template_mtime
0970                  FROM ' . STYLES_TEMPLATE_DATA_TABLE . "
0971                  WHERE template_id = $template_id";
0972              $result = $db->sql_query($sql);
0973   
0974              $filemtime = array();
0975              while ($row = $db->sql_fetchrow($result))
0976              {
0977                  $filemtime[$row['template_filename']] = $row['template_mtime'];
0978              }
0979              $db->sql_freeresult($result);
0980          }
0981   
0982          // Get a list of cached template files and then retrieve additional information about them
0983          $file_ary = $this->template_cache_filelist($template_row['template_path']);
0984   
0985          foreach ($file_ary as $file)
0986          {
0987              $file         = str_replace('/', '.', $file);
0988              
0989              // perform some dirty guessing to get the path right.
0990              // We assume that three dots in a row were '../'
0991              $tpl_file     = str_replace('.', '/', $file);
0992              $tpl_file     = str_replace('///', '../', $tpl_file);
0993              
0994              $filename = "{$cache_prefix}_$file.html.$phpEx";
0995   
0996              if (!file_exists("{$phpbb_root_path}cache/$filename"))
0997              {
0998                  continue;
0999              }
1000   
1001              $template->assign_block_vars('file', array(
1002                  'U_VIEWSOURCE'    => $this->u_action . "&amp;action=cache&amp;id=$template_id&amp;source=$file",
1003   
1004                  'CACHED'        => $user->format_date(filemtime("{$phpbb_root_path}cache/$filename")),
1005                  'FILENAME'        => $file,
1006                  'FILESIZE'        => sprintf('%.1f KB', filesize("{$phpbb_root_path}cache/$filename") / 1024),
1007                  'MODIFIED'        => $user->format_date((!$template_row['template_storedb']) ? filemtime("{$phpbb_root_path}styles/{$template_row['template_path']}/template/$tpl_file.html") : $filemtime[$file . '.html']))
1008              );
1009          }
1010          unset($filemtime);
1011   
1012          $template->assign_vars(array(
1013              'S_CACHE'            => true,
1014              'S_TEMPLATE'        => true,
1015   
1016              'U_ACTION'            => $this->u_action . "&amp;action=cache&amp;id=$template_id",
1017              'U_BACK'            => $this->u_action)
1018          );
1019      }
1020   
1021      /**
1022      * Provides a css editor and a basic easier to use stylesheet editing tool for less experienced (or lazy) users
1023      *
1024      * @param int $theme_id specifies which theme is being edited
1025      */
1026      function edit_theme($theme_id)
1027      {
1028          global $phpbb_root_path, $phpEx, $config, $db, $cache, $user, $template, $safe_mode;
1029   
1030          $this->page_title = 'EDIT_THEME';
1031   
1032          $filelist = $filelist_cats = array();
1033   
1034          $theme_data        = utf8_normalize_nfc(request_var('template_data', '', true));
1035          $theme_data        = htmlspecialchars_decode($theme_data);
1036          $theme_file        = utf8_normalize_nfc(request_var('template_file', '', true));
1037          $text_rows        = max(5, min(999, request_var('text_rows', 20)));
1038          $save_changes    = (isset($_POST['save'])) ? true : false;
1039   
1040          // make sure theme_file path doesn't go upwards
1041          $theme_file = str_replace('..', '.', $theme_file);
1042          
1043          // Retrieve some information about the theme
1044          $sql = 'SELECT theme_storedb, theme_path, theme_name, theme_data
1045              FROM ' . STYLES_THEME_TABLE . "
1046              WHERE theme_id = $theme_id";
1047          $result = $db->sql_query($sql);
1048   
1049          if (!($theme_info = $db->sql_fetchrow($result)))
1050          {
1051              trigger_error($user->lang['NO_THEME'] . adm_back_link($this->u_action), E_USER_WARNING);
1052          }
1053          $db->sql_freeresult($result);
1054   
1055          // save changes to the theme if the user submitted any
1056          if ($save_changes)
1057          {
1058              // Get the filesystem location of the current file
1059              $file = "{$phpbb_root_path}styles/{$theme_info['theme_path']}/theme/$theme_file";
1060              $additional = '';
1061              $message = $user->lang['THEME_UPDATED'];
1062   
1063              // If the theme is stored on the filesystem try to write the file else store it in the database
1064              if (!$safe_mode && !$theme_info['theme_storedb'] && file_exists($file) && @is_writable($file))
1065              {
1066                  if (!($fp = @fopen($file, 'wb')))
1067                  {
1068                      trigger_error($user->lang['NO_THEME'] . adm_back_link($this->u_action), E_USER_WARNING);
1069                  }
1070                  fwrite($fp, $theme_data);
1071                  fclose($fp);
1072              }
1073              else
1074              {
1075                  // Write stylesheet to db
1076                  $sql_ary = array(
1077                      'theme_mtime'        => time(),
1078                      'theme_storedb'        => 1,
1079                      'theme_data'        => $this->db_theme_data($theme_info, $theme_data),
1080                  );
1081                  $sql = 'UPDATE ' . STYLES_THEME_TABLE . '
1082                      SET ' . $db->sql_build_array('UPDATE', $sql_ary) . '
1083                      WHERE theme_id = ' . $theme_id;
1084                  $db->sql_query($sql);
1085   
1086                  $cache->destroy('sql', STYLES_THEME_TABLE);
1087   
1088                  // notify the user if the theme was not stored in the db before his modification
1089                  if (!$theme_info['theme_storedb'])
1090                  {
1091                      add_log('admin', 'LOG_THEME_EDIT_DETAILS', $theme_info['theme_name']);
1092                      $message .= '<br />' . $user->lang['EDIT_THEME_STORED_DB'];
1093                  }
1094              }
1095              $cache->destroy('sql', STYLES_THEME_TABLE);
1096              add_log('admin', (!$theme_info['theme_storedb']) ? 'LOG_THEME_EDIT_FILE' : 'LOG_THEME_EDIT', $theme_info['theme_name'], (!$theme_info['theme_storedb']) ? $theme_file : '');
1097   
1098              trigger_error($message . adm_back_link($this->u_action . "&amp;action=edit&amp;id=$theme_id&amp;template_file=$theme_file&amp;text_rows=$text_rows"));
1099          }
1100   
1101          // Generate a category array containing theme filenames
1102          if (!$theme_info['theme_storedb'])
1103          {
1104              $theme_path = "{$phpbb_root_path}styles/{$theme_info['theme_path']}/theme";
1105   
1106              $filelist = filelist($theme_path, '', 'css');
1107   
1108              if ($theme_file)
1109              {
1110                  if (!file_exists($theme_path . "/$theme_file") || !($theme_data = file_get_contents($theme_path . "/$theme_file")))
1111                  {
1112                      trigger_error($user->lang['NO_THEME'] . adm_back_link($this->u_action), E_USER_WARNING);
1113                  }
1114              }
1115          }
1116          else
1117          {
1118              $theme_data = &$theme_info['theme_data'];
1119          }
1120   
1121          // Now create the categories
1122          $filelist_cats[''] = array();
1123          foreach ($filelist as $pathfile => $file_ary)
1124          {
1125              // Use the directory name as category name
1126              if (!empty($pathfile))
1127              {
1128                  $filelist_cats[$pathfile] = array();
1129                  foreach ($file_ary as $file)
1130                  {
1131                      $filelist_cats[$pathfile][$pathfile . $file] = $file;
1132                  }
1133              }
1134              // or if it's in the main category use the word before the first underscore to group files
1135              else
1136              {
1137                  $cats = array();
1138                  foreach ($file_ary as $file)
1139                  {
1140                      $cats[] = substr($file, 0, strpos($file, '_'));
1141                      $filelist_cats[substr($file, 0, strpos($file, '_'))][$file] = $file;
1142                  }
1143   
1144                  $cats = array_values(array_unique($cats));
1145   
1146                  // we don't need any single element categories so put them into the misc '' category
1147                  for ($i = 0, $n = sizeof($cats); $i < $n; $i++)
1148                  {
1149                      if (sizeof($filelist_cats[$cats[$i]]) == 1 && $cats[$i] !== '')
1150                      {
1151                          $filelist_cats[''][key($filelist_cats[$cats[$i]])] = current($filelist_cats[$cats[$i]]);
1152                          unset($filelist_cats[$cats[$i]]);
1153                      }
1154                  }
1155                  unset($cats);
1156              }
1157          }
1158          unset($filelist);
1159   
1160          // Generate list of categorised theme files
1161          $tpl_options = '';
1162          ksort($filelist_cats);
1163          foreach ($filelist_cats as $category => $tpl_ary)
1164          {
1165              ksort($tpl_ary);
1166   
1167              if (!empty($category))
1168              {
1169                  $tpl_options .= '<option class="sep" value="">' . $category . '</option>';
1170              }
1171   
1172              foreach ($tpl_ary as $filename => $file)
1173              {
1174                  $selected = ($theme_file == $filename) ? ' selected="selected"' : '';
1175                  $tpl_options .= '<option value="' . $filename . '"' . $selected . '>' . $file . '</option>';
1176              }
1177          }
1178   
1179          $template->assign_vars(array(
1180              'S_EDIT_THEME'        => true,
1181              'S_HIDDEN_FIELDS'    => build_hidden_fields(array('template_file' => $theme_file)),
1182              'S_THEME_IN_DB'        => $theme_info['theme_storedb'],
1183              'S_TEMPLATES'        => $tpl_options,
1184   
1185              'U_ACTION'            => $this->u_action . "&amp;action=edit&amp;id=$theme_id&amp;text_rows=$text_rows",
1186              'U_BACK'            => $this->u_action,
1187   
1188              'L_EDIT'            => $user->lang['EDIT_THEME'],
1189              'L_EDIT_EXPLAIN'    => $user->lang['EDIT_THEME_EXPLAIN'],
1190              'L_EDITOR'            => $user->lang['THEME_EDITOR'],
1191              'L_EDITOR_HEIGHT'    => $user->lang['THEME_EDITOR_HEIGHT'],
1192              'L_FILE'            => $user->lang['THEME_FILE'],
1193              'L_SELECT'            => $user->lang['SELECT_THEME'],
1194              'L_SELECTED'        => $user->lang['SELECTED_THEME'],
1195              'L_SELECTED_FILE'    => $user->lang['SELECTED_THEME_FILE'],
1196   
1197              'SELECTED_TEMPLATE'    => $theme_info['theme_name'],
1198              'TEMPLATE_FILE'        => $theme_file,
1199              'TEMPLATE_DATA'        => utf8_htmlspecialchars($theme_data),
1200              'TEXT_ROWS'            => $text_rows)
1201          );
1202      }
1203   
1204   
1205      /**
1206      * Edit imagesets
1207      *
1208      * @param int $imageset_id specifies which imageset is being edited
1209      */
1210      function edit_imageset($imageset_id)
1211      {
1212          global $db, $user, $phpbb_root_path, $cache, $template;
1213   
1214          $this->page_title = 'EDIT_IMAGESET';
1215   
1216          $update        = (isset($_POST['update'])) ? true : false;
1217   
1218          $imgname    = request_var('imgname', '');
1219          $imgpath    = request_var('imgpath', '');
1220          $imgsize    = request_var('imgsize', false);
1221          $imgwidth    = request_var('imgwidth', 0);
1222          $imgheight    = request_var('imgheight', 0);
1223          
1224          $imgname    = preg_replace('#[^a-z0-9\-+_]#i', '', $imgname);
1225          $imgpath    = str_replace('..', '.', $imgpath);
1226   
1227          if ($imageset_id)
1228          {
1229              $sql = 'SELECT imageset_path, imageset_name
1230                  FROM ' . STYLES_IMAGESET_TABLE . "
1231                  WHERE imageset_id = $imageset_id";
1232              $result = $db->sql_query($sql);
1233              $imageset_row = $db->sql_fetchrow($result);
1234              $db->sql_freeresult($result);
1235   
1236              $imageset_path        = $imageset_row['imageset_path'];
1237              $imageset_name        = $imageset_row['imageset_name'];
1238   
1239              $sql_extra = '';
1240              if (strpos($imgname, '-') !== false)
1241              {
1242                  list($imgname, $imgnamelang) = explode('-', $imgname);
1243                  $sql_extra = " AND image_lang IN ('" . $db->sql_escape($imgnamelang) . "', '')";
1244              }
1245   
1246              $sql = 'SELECT image_filename, image_width, image_height, image_lang, image_id
1247                  FROM ' . STYLES_IMAGESET_DATA_TABLE . "
1248                  WHERE imageset_id = $imageset_id
1249                      AND image_name = '" . $db->sql_escape($imgname) . "'$sql_extra";
1250              $result = $db->sql_query($sql);
1251              $imageset_data_row = $db->sql_fetchrow($result);
1252              $db->sql_freeresult($result);
1253   
1254              $image_filename    = $imageset_data_row['image_filename'];
1255              $image_width    = $imageset_data_row['image_width'];
1256              $image_height    = $imageset_data_row['image_height'];
1257              $image_lang        = $imageset_data_row['image_lang'];
1258              $image_id        = $imageset_data_row['image_id'];
1259   
1260              if (!$imageset_row)
1261              {
1262                  trigger_error($user->lang['NO_IMAGESET'] . adm_back_link($this->u_action), E_USER_WARNING);
1263              }
1264   
1265              // Check to see whether the selected image exists in the table
1266              $valid_name = ($update) ? false : true;
1267   
1268              foreach ($this->imageset_keys as $category => $img_ary)
1269              {
1270                  if (in_array($imgname, $img_ary))
1271                  {
1272                      $valid_name = true;
1273                      break;
1274                  }
1275              }
1276   
1277              if ($update && isset($_POST['imgpath']))
1278              {
1279                  if ($valid_name)
1280                  {
1281                      // If imgwidth and imgheight are non-zero grab the actual size
1282                      // from the image itself ... we ignore width settings for the poll center image
1283                      $imgwidth    = request_var('imgwidth', 0);
1284                      $imgheight    = request_var('imgheight', 0);
1285                      $imglang = '';
1286   
1287                      if ($imgpath && !file_exists("{$phpbb_root_path}styles/$imageset_path/imageset/$imgpath"))
1288                      {
1289                          trigger_error($user->lang['NO_IMAGE_ERROR'] . adm_back_link($this->u_action), E_USER_WARNING);
1290                      }
1291   
1292                      if ($imgsize && $imgpath)
1293                      {
1294                          if (!$imgwidth || !$imgheight)
1295                          {
1296                              list($imgwidth_file, $imgheight_file) = getimagesize("{$phpbb_root_path}styles/$imageset_path/imageset/$imgpath");
1297                              $imgwidth = ($imgwidth) ? $imgwidth : $imgwidth_file;
1298                              $imgheight = ($imgheight) ? $imgheight : $imgheight_file;
1299                          }
1300                          $imgwidth    = ($imgname != 'poll_center') ? (int) $imgwidth : 0;
1301                          $imgheight    = (int) $imgheight;
1302                      }
1303   
1304   
1305                      if (strpos($imgpath, '/') !== false)
1306                      {
1307                          list($imglang, $imgfilename) = explode('/', $imgpath);
1308                      }
1309                      else
1310                      {
1311                          $imgfilename = $imgpath;
1312                      }
1313   
1314                      $sql_ary = array(
1315                          'image_filename'    => (string) $imgfilename,
1316                          'image_width'        => (int) $imgwidth,
1317                          'image_height'        => (int) $imgheight,
1318                          'image_lang'        => (string) $imglang,
1319                      );
1320   
1321                      // already exists
1322                      if ($imageset_data_row)
1323                      {
1324                          $sql = 'UPDATE ' . STYLES_IMAGESET_DATA_TABLE . '
1325                              SET ' . $db->sql_build_array('UPDATE', $sql_ary) . "
1326                              WHERE image_id = $image_id";
1327                          $db->sql_query($sql);
1328                      }
1329                      // does not exist
1330                      else if (!$imageset_data_row)
1331                      {
1332                          $sql_ary['image_name']    = $imgname;
1333                          $sql_ary['imageset_id']    = (int) $imageset_id;
1334                          $db->sql_query('INSERT INTO ' . STYLES_IMAGESET_DATA_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary));
1335                      }
1336   
1337                      $cache->destroy('sql', STYLES_IMAGESET_DATA_TABLE);
1338   
1339                      add_log('admin', 'LOG_IMAGESET_EDIT', $imageset_name);
1340   
1341                      $template->assign_var('SUCCESS', true);
1342   
1343                      $image_filename = $imgfilename;
1344                      $image_width    = $imgwidth;
1345                      $image_height    = $imgheight;
1346                      $image_lang        = $imglang;
1347                  }
1348              }
1349          }
1350   
1351          $imglang = '';
1352          $imagesetlist = array('nolang' => array(), 'lang' => array());
1353          $langs = array();
1354   
1355          $dir = "{$phpbb_root_path}styles/$imageset_path/imageset";
1356          $dp = @opendir($dir);
1357   
1358          if ($dp)
1359          {
1360              while (($file = readdir($dp)) !== false)
1361              {
1362                  if ($file[0] != '.' && strtoupper($file) != 'CVS' && !is_file($dir . '/' . $file) && !is_link($dir . '/' . $file))
1363                  {
1364                      $langs[] = $file;
1365                  }
1366                  else if (preg_match('#\.(?:gif|jpg|png)$#', $file))
1367                  {
1368                      $imagesetlist['nolang'][] = $file;
1369                  }
1370              }
1371   
1372              if ($sql_extra)
1373              {
1374                  $dp2 = @opendir("$dir/$imgnamelang");
1375   
1376                  if ($dp2)
1377                  {
1378                      while (($file2 = readdir($dp2)) !== false)
1379                      {
1380                          if (preg_match('#\.(?:gif|jpg|png)$#', $file2))
1381                          {
1382                              $imagesetlist['lang'][] = "$imgnamelang/$file2";
1383                          }
1384                      }
1385                      closedir($dp2);
1386                  }
1387              }
1388              closedir($dp);
1389          }
1390   
1391          // Generate list of image options
1392          $img_options = '';
1393          foreach ($this->imageset_keys as $category => $img_ary)
1394          {
1395              $template->assign_block_vars('category', array(
1396                  'NAME'            => $user->lang['IMG_CAT_' . strtoupper($category)]
1397              ));
1398   
1399              foreach ($img_ary as $img)
1400              {
1401                  if ($category == 'buttons')
1402                  {
1403                      foreach ($langs as $language)
1404                      {
1405                          $template->assign_block_vars('category.images', array(
1406                              'SELECTED'            => ($img == $imgname && $language == $imgnamelang),
1407                              'VALUE'                => $img . '-' . $language,
1408                              'TEXT'                => $user->lang['IMG_' . strtoupper($img)] . ' [ ' . $language . ' ]'
1409                          ));
1410                      }
1411                  }
1412                  else
1413                  {
1414                      $template->assign_block_vars('category.images', array(
1415                          'SELECTED'            => ($img == $imgname),
1416                          'VALUE'                => $img,
1417                          'TEXT'                => (($category == 'custom') ? $img : $user->lang['IMG_' . strtoupper($img)])
1418                      ));
1419                  }
1420              }
1421          }
1422   
1423          // Make sure the list of possible images is sorted alphabetically
1424          sort($imagesetlist['lang']);
1425          sort($imagesetlist['nolang']);
1426   
1427          $image_found = false;
1428          $img_val = '';
1429          foreach ($imagesetlist as $type => $img_ary)
1430          {
1431              if ($type !== 'lang' || $sql_extra)
1432              {
1433                  $template->assign_block_vars('imagesetlist', array(
1434                      'TYPE'    => ($type == 'lang')
1435                  ));
1436              }
1437   
1438              foreach ($img_ary as $img)
1439              {
1440                  $imgtext = preg_replace('/^([^\/]+\/)/', '', $img);
1441                  $selected = (!empty($imgname) && strpos($image_filename, $imgtext) !== false);
1442                  if ($selected)
1443                  {
1444                      $image_found = true;
1445                      $img_val = htmlspecialchars($img);
1446                  }
1447                  $template->assign_block_vars('imagesetlist.images', array(
1448                      'SELECTED'            => $selected,
1449                      'TEXT'                => $imgtext,
1450                      'VALUE'                => htmlspecialchars($img)
1451                  ));
1452              }
1453          }
1454   
1455          $imgsize_bool = (!empty($imgname) && $image_width && $image_height) ? true : false;
1456          $image_request = '../styles/' . $imageset_path . '/imageset/' . ($image_lang ? $imgnamelang . '/' : '') . $image_filename;
1457   
1458          $template->assign_vars(array(
1459              'S_EDIT_IMAGESET'    => true,
1460              'L_TITLE'            => $user->lang[$this->page_title],
1461              'L_EXPLAIN'            => $user->lang[$this->page_title . '_EXPLAIN'],
1462              'IMAGE_OPTIONS'        => $img_options,
1463              'IMAGE_SIZE'        => $image_width,
1464              'IMAGE_HEIGHT'        => $image_height,
1465              'IMAGE_REQUEST'        => (empty($image_filename)) ? 'images/no_image.png' : $image_request,
1466              'U_ACTION'            => $this->u_action . "&amp;action=edit&amp;id=$imageset_id",
1467              'U_BACK'            => $this->u_action,
1468              'NAME'                => $imageset_name,
1469              'A_NAME'            => addslashes($imageset_name),
1470              'ERROR'                => !$valid_name,
1471              'IMG_SRC'            => ($image_found) ? '../styles/' . $imageset_path . '/imageset/' . $img_val : 'images/no_image.png',
1472              'IMAGE_SELECT'        => $image_found
1473          ));
1474      }
1475   
1476      /**
1477      * Remove style/template/theme/imageset
1478      */
1479      function remove($mode, $style_id)
1480      {
1481          global $db, $template, $user, $phpbb_root_path, $cache, $config;
1482   
1483          $new_id = request_var('new_id', 0);
1484          $update = (isset($_POST['update'])) ? true : false;
1485          $sql_where = '';
1486   
1487          switch ($mode)
1488          {
1489              case 'style':
1490                  $sql_from = STYLES_TABLE;
1491                  $sql_select = 'style_name';
1492                  $sql_where = 'AND style_active = 1';
1493              break;
1494   
1495              case 'template':
1496                  $sql_from = STYLES_TEMPLATE_TABLE;
1497                  $sql_select = 'template_name, template_path, template_storedb';
1498              break;
1499   
1500              case 'theme':
1501                  $sql_from = STYLES_THEME_TABLE;
1502                  $sql_select = 'theme_name, theme_path, theme_storedb';
1503              break;
1504   
1505              case 'imageset':
1506                  $sql_from = STYLES_IMAGESET_TABLE;
1507                  $sql_select = 'imageset_name, imageset_path';
1508              break;
1509          }
1510   
1511          $l_prefix = strtoupper($mode);
1512   
1513          $sql = "SELECT $sql_select
1514              FROM $sql_from
1515              WHERE {$mode}_id = $style_id";
1516          $result = $db->sql_query($sql);
1517          $style_row = $db->sql_fetchrow($result);
1518          $db->sql_freeresult($result);
1519   
1520          if (!$style_row)
1521          {
1522              trigger_error($user->lang['NO_' . $l_prefix] . adm_back_link($this->u_action), E_USER_WARNING);
1523          }
1524   
1525          $sql = "SELECT {$mode}_id, {$mode}_name
1526              FROM $sql_from
1527              WHERE {$mode}_id <> $style_id
1528              $sql_where
1529              ORDER BY {$mode}_name ASC";
1530          $result = $db->sql_query($sql);
1531   
1532          $s_options = '';
1533   
1534          if ($row = $db->sql_fetchrow($result))
1535          {
1536              do
1537              {
1538                  $s_options .= '<option value="' . $row[$mode . '_id'] . '">' . $row[$mode . '_name'] . '</option>';
1539              }
1540              while ($row = $db->sql_fetchrow($result));
1541          }
1542          else
1543          {
1544              trigger_error($user->lang['ONLY_' . $l_prefix] . adm_back_link($this->u_action), E_USER_WARNING);
1545          }
1546          $db->sql_freeresult($result);
1547   
1548          if ($update)
1549          {
1550              $sql = "DELETE FROM $sql_from
1551                  WHERE {$mode}_id = $style_id";
1552              $db->sql_query($sql);
1553   
1554              if ($mode == 'style')
1555              {
1556                  $sql = 'UPDATE ' . USERS_TABLE . "
1557                      SET user_style = $new_id
1558                      WHERE user_style = $style_id";
1559                  $db->sql_query($sql);
1560   
1561                  $sql = 'UPDATE ' . FORUMS_TABLE . "
1562                      SET forum_style = $new_id
1563                      WHERE forum_style = $style_id";
1564                  $db->sql_query($sql);
1565   
1566                  if ($style_id == $config['default_style'])
1567                  {
1568                      set_config('default_style', $new_id);
1569                  }
1570              }
1571              else
1572              {
1573                  if ($mode == 'imageset')
1574                  {
1575                      $sql = 'DELETE FROM ' . STYLES_IMAGESET_DATA_TABLE . "
1576                          WHERE imageset_id = $style_id";
1577                      $db->sql_query($sql);
1578                  }
1579                  $sql = 'UPDATE ' . STYLES_TABLE . "
1580                      SET {$mode}_id = $new_id
1581                      WHERE {$mode}_id = $style_id";
1582                  $db->sql_query($sql);
1583              }
1584   
1585              $cache->destroy('sql', STYLES_TABLE);
1586   
1587              add_log('admin', 'LOG_' . $l_prefix . '_DELETE', $style_row[$mode . '_name']);
1588              $message = ($mode != 'style') ? $l_prefix . '_DELETED_FS' : $l_prefix . '_DELETED';
1589              trigger_error($user->lang[$message] . adm_back_link($this->u_action));
1590          }
1591   
1592          $this->page_title = 'DELETE_' . $l_prefix;
1593   
1594          $template->assign_vars(array(
1595              'S_DELETE'            => true,
1596              'S_REPLACE_OPTIONS'    => $s_options,
1597   
1598              'L_TITLE'            => $user->lang[$this->page_title],
1599              'L_EXPLAIN'            => $user->lang[$this->page_title . '_EXPLAIN'],
1600              'L_NAME'            => $user->lang[$l_prefix . '_NAME'],
1601              'L_REPLACE'            => $user->lang['REPLACE_' . $l_prefix],
1602              'L_REPLACE_EXPLAIN'    => $user->lang['REPLACE_' . $l_prefix . '_EXPLAIN'],
1603   
1604              'U_ACTION'        => $this->u_action . "&amp;action=delete&amp;id=$style_id",
1605              'U_BACK'        => $this->u_action,
1606   
1607              'NAME'            => $style_row[$mode . '_name'],
1608              )
1609          );
1610      }
1611   
1612      /**
1613      * Export style or style elements
1614      */
1615      function export($mode, $style_id)
1616      {
1617          global $db, $template, $user, $phpbb_root_path, $cache, $phpEx, $config;
1618   
1619          $update = (isset($_POST['update'])) ? true : false;
1620   
1621          $inc_template = request_var('inc_template', 0);
1622          $inc_theme = request_var('inc_theme', 0);
1623          $inc_imageset = request_var('inc_imageset', 0);
1624          $store = request_var('store', 0);
1625          $format = request_var('format', '');
1626   
1627          $error = array();
1628          $methods = array('tar');
1629   
1630          $available_methods = array('tar.gz' => 'zlib', 'tar.bz2' => 'bz2', 'zip' => 'zlib');
1631          foreach ($available_methods as $type => $module)
1632          {
1633              if (!@extension_loaded($module))
1634              {
1635                  continue;
1636              }
1637   
1638              $methods[] = $type;
1639          }
1640   
1641          if (!in_array($format, $methods))
1642          {
1643              $format = 'tar';
1644          }
1645   
1646          switch ($mode)
1647          {
1648              case 'style':
1649                  if ($update && ($inc_template + $inc_theme + $inc_imageset) < 1)
1650                  {
1651                      $error[] = $user->lang['STYLE_ERR_MORE_ELEMENTS'];
1652                  }
1653   
1654                  $name = 'style_name';
1655   
1656                  $sql_select = 's.style_id, s.style_name, s.style_copyright';
1657                  $sql_select .= ($inc_template) ? ', t.*' : ', t.template_name';
1658                  $sql_select .= ($inc_theme) ? ', c.*' : ', c.theme_name';
1659                  $sql_select .= ($inc_imageset) ? ', i.*' : ', i.imageset_name';
1660                  $sql_from = STYLES_TABLE . ' s, ' . STYLES_TEMPLATE_TABLE . ' t, ' . STYLES_THEME_TABLE . ' c, ' . STYLES_IMAGESET_TABLE . ' i';
1661                  $sql_where = "s.style_id = $style_id AND t.template_id = s.template_id AND c.theme_id = s.theme_id AND i.imageset_id = s.imageset_id";
1662   
1663                  $l_prefix = 'STYLE';
1664              break;
1665   
1666              case 'template':
1667                  $name = 'template_name';
1668   
1669                  $sql_select = '*';
1670                  $sql_from = STYLES_TEMPLATE_TABLE;
1671                  $sql_where = "template_id = $style_id";
1672   
1673                  $l_prefix = 'TEMPLATE';
1674              break;
1675   
1676              case 'theme':
1677                  $name = 'theme_name';
1678   
1679                  $sql_select = '*';
1680                  $sql_from = STYLES_THEME_TABLE;
1681                  $sql_where = "theme_id = $style_id";
1682   
1683                  $l_prefix = 'THEME';
1684              break;
1685   
1686              case 'imageset':
1687                  $name = 'imageset_name';
1688   
1689                  $sql_select = '*';
1690                  $sql_from = STYLES_IMAGESET_TABLE;
1691                  $sql_where = "imageset_id = $style_id";
1692   
1693                  $l_prefix = 'IMAGESET';
1694              break;
1695          }
1696   
1697          if ($update && !sizeof($error))
1698          {
1699              $sql = "SELECT $sql_select
1700                  FROM $sql_from
1701                  WHERE $sql_where";
1702              $result = $db->sql_query($sql);
1703              $style_row = $db->sql_fetchrow($result);
1704              $db->sql_freeresult($result);
1705   
1706              if (!$style_row)
1707              {
1708                  trigger_error($user->lang['NO_' . $l_prefix] . adm_back_link($this->u_action), E_USER_WARNING);
1709              }
1710   
1711              $var_ary = array('style_id', 'style_name', 'style_copyright', 'template_id', 'template_name', 'template_path', 'template_copyright', 'template_storedb', 'bbcode_bitfield', 'theme_id', 'theme_name', 'theme_path', 'theme_copyright', 'theme_storedb', 'theme_mtime', 'theme_data', 'imageset_id', 'imageset_name', 'imageset_path', 'imageset_copyright');
1712   
1713              foreach ($var_ary as $var)
1714              {
1715                  if (!isset($style_row[$var]))
1716                  {
1717                      $style_row[$var] = '';
1718                  }
1719              }
1720   
1721              $files = $data = array();
1722   
1723              if ($mode == 'style')
1724              {
1725                  $style_cfg = str_replace(array('{MODE}', '{NAME}', '{COPYRIGHT}', '{VERSION}'), array($mode, $style_row['style_name'], $style_row['style_copyright'], $config['version']), $this->style_cfg);
1726   
1727                  $style_cfg .= (!$inc_template) ? "\nrequired_template = {$style_row['template_name']}" : '';
1728                  $style_cfg .= (!$inc_theme) ? "\nrequired_theme = {$style_row['theme_name']}" : '';
1729                  $style_cfg .= (!$inc_imageset) ? "\nrequired_imageset = {$style_row['imageset_name']}" : '';
1730   
1731                  $data[] = array(
1732                      'src'        => $style_cfg,
1733                      'prefix'    => 'style.cfg'
1734                  );
1735   
1736                  unset($style_cfg);
1737              }
1738   
1739              // Export template core code
1740              if ($mode == 'template' || $inc_template)
1741              {
1742                  $template_cfg = str_replace(array('{MODE}', '{NAME}', '{COPYRIGHT}', '{VERSION}'), array($mode, $style_row['template_name'], $style_row['template_copyright'], $config['version']), $this->template_cfg);
1743                  $template_cfg .= "\nbbcode_bitfield = {$style_row['bbcode_bitfield']}";
1744   
1745                  $data[] = array(
1746                      'src'        => $template_cfg,
1747                      'prefix'    => 'template/template.cfg'
1748                  );
1749   
1750                  // This is potentially nasty memory-wise ...
1751                  if (!$style_row['template_storedb'])
1752                  {
1753                      $files[] = array(
1754                          'src'        => "styles/{$style_row['template_path']}/template/",
1755                          'prefix-'    => "styles/{$style_row['template_path']}/",
1756                          'prefix+'    => false,
1757                          'exclude'    => 'template.cfg'
1758                      );
1759                  }
1760                  else
1761                  {
1762                      $sql = 'SELECT template_filename, template_data
1763                          FROM ' . STYLES_TEMPLATE_DATA_TABLE . "
1764                          WHERE template_id = {$style_row['template_id']}";
1765                      $result = $db->sql_query($sql);
1766   
1767                      while ($row = $db->sql_fetchrow($result))
1768                      {
1769                          $data[] = array(
1770                              'src' => $row['template_data'],
1771                              'prefix' => 'template/' . $row['template_filename']
1772                          );
1773                      }
1774                      $db->sql_freeresult($result);
1775                  }
1776                  unset($template_cfg);
1777              }
1778   
1779              // Export theme core code
1780              if ($mode == 'theme' || $inc_theme)
1781              {
1782                  $theme_cfg = str_replace(array('{MODE}', '{NAME}', '{COPYRIGHT}', '{VERSION}'), array($mode, $style_row['theme_name'], $style_row['theme_copyright'], $config['version']), $this->theme_cfg);
1783   
1784                  // Read old cfg file
1785                  $items = $cache->obtain_cfg_items($style_row);
1786                  $items = $items['theme'];
1787   
1788                  if (!isset($items['parse_css_file']))
1789                  {
1790                      $items['parse_css_file'] = 'off';
1791                  }
1792   
1793                  $theme_cfg = str_replace(array('{PARSE_CSS_FILE}'), array($items['parse_css_file']), $theme_cfg);
1794   
1795                  $files[] = array(
1796                      'src'        => "styles/{$style_row['theme_path']}/theme/",
1797                      'prefix-'    => "styles/{$style_row['theme_path']}/",
1798                      'prefix+'    => false,
1799                      'exclude'    => ($style_row['theme_storedb']) ? 'stylesheet.css,theme.cfg' : 'theme.cfg'
1800                  );
1801   
1802                  $data[] = array(
1803                      'src'        => $theme_cfg,
1804                      'prefix'    => 'theme/theme.cfg'
1805                  );
1806   
1807                  if ($style_row['theme_storedb'])
1808                  {
1809                      $data[] = array(
1810                          'src'        => $style_row['theme_data'],
1811                          'prefix'    => 'theme/stylesheet.css'
1812                      );
1813                  }
1814   
1815                  unset($items, $theme_cfg);
1816              }
1817   
1818              // Export imageset core code
1819              if ($mode == 'imageset' || $inc_imageset)
1820              {
1821                  $imageset_cfg = str_replace(array('{MODE}', '{NAME}', '{COPYRIGHT}', '{VERSION}'), array($mode, $style_row['imageset_name'], $style_row['imageset_copyright'], $config['version']), $this->imageset_cfg);
1822   
1823                  $imageset_main = array();
1824   
1825                  $sql = 'SELECT image_filename, image_name, image_height, image_width
1826                      FROM ' . STYLES_IMAGESET_DATA_TABLE . "
1827                      WHERE imageset_id = $style_id
1828                          AND image_lang = ''";
1829                  $result = $db->sql_query($sql);
1830                  while ($row = $db->sql_fetchrow($result))
1831                  {
1832                      $imageset_main[$row['image_name']] = $row['image_filename'] . ($row['image_height'] ? '*' . $row['image_height']: '') . ($row['image_width'] ? '*' . $row['image_width']: '');
1833                  }
1834                  $db->sql_freeresult($result);
1835   
1836                  foreach ($this->imageset_keys as $topic => $key_array)
1837                  {
1838                      foreach ($key_array as $key)
1839                      {
1840                          if (isset($imageset_main[$key]))
1841                          {
1842                              $imageset_cfg .= "\nimg_" . $key . ' = ' . str_replace("styles/{$style_row['imageset_path']}/imageset/", '{PATH}', $imageset_main[$key]);
1843                          }
1844                      }
1845                  }
1846   
1847                  $files[] = array(
1848                      'src'        => "styles/{$style_row['imageset_path']}/imageset/",
1849                      'prefix-'    => "styles/{$style_row['imageset_path']}/",
1850                      'prefix+'    => false,
1851                      'exclude'    => 'imageset.cfg'
1852                  );
1853   
1854                  $data[] = array(
1855                      'src'        => trim($imageset_cfg),
1856                      'prefix'    => 'imageset/imageset.cfg'
1857                  );
1858   
1859                  end($data);
1860   
1861                  $imageset_root = "{$phpbb_root_path}styles/{$style_row['imageset_path']}/imageset/";
1862   
1863                  if ($dh = @opendir($imageset_root))
1864                  {
1865                      while (($fname = readdir($dh)) !== false)
1866                      {
1867                          if ($fname[0] != '.' && $fname != 'CVS' && is_dir("$imageset_root$fname"))
1868                          {
1869                              $files[key($files)]['exclude'] .= ',' . $fname . '/imageset.cfg';
1870                          }
1871                      }
1872                      closedir($dh);
1873                  }
1874   
1875                  $imageset_lang = array();
1876   
1877                  $sql = 'SELECT image_filename, image_name, image_height, image_width, image_lang
1878                      FROM ' . STYLES_IMAGESET_DATA_TABLE . "
1879                      WHERE imageset_id = $style_id
1880                          AND image_lang <> ''";
1881                  $result = $db->sql_query($sql);
1882                  while ($row = $db->sql_fetchrow($result))
1883                  {
1884                      $imageset_lang[$row['image_lang']][$row['image_name']] = $row['image_filename'] . ($row['image_height'] ? '*' . $row['image_height']: '') . ($row['image_width'] ? '*' . $row['image_width']: '');
1885                  }
1886                  $db->sql_freeresult($result);
1887   
1888                  foreach ($imageset_lang as $lang => $imageset_localized)
1889                  {
1890                      $imageset_cfg = str_replace(array('{MODE}', '{NAME}', '{COPYRIGHT}', '{VERSION}'), array($mode, $style_row['imageset_name'], $style_row['imageset_copyright'], $config['version']), $this->imageset_cfg);
1891   
1892                      foreach ($this->imageset_keys as $topic => $key_array)
1893                      {
1894                          foreach ($key_array as $key)
1895                          {
1896                              if (isset($imageset_localized[$key]))
1897                              {
1898                                  $imageset_cfg .= "\nimg_" . $key . ' = ' . str_replace("styles/{$style_row['imageset_path']}/imageset/", '{PATH}', $imageset_localized[$key]);
1899                              }
1900                          }
1901                      }
1902   
1903                      $data[] = array(
1904                          'src'        => trim($imageset_cfg),
1905                          'prefix'    => 'imageset/' . $lang . '/imageset.cfg'
1906                      );
1907                  }
1908   
1909                  unset($imageset_cfg);
1910              }
1911   
1912              switch ($format)
1913              {
1914                  case 'tar':
1915                      $ext = '.tar';
1916                      $mimetype = 'x-tar';
1917                      $compress = 'compress_tar';
1918                  break;
1919   
1920                  case 'zip':
1921                      $ext = '.zip';
1922                      $mimetype = 'zip';
1923                  break;
1924   
1925                  case 'tar.gz':
1926                      $ext = '.tar.gz';
1927                      $mimetype = 'x-gzip';
1928                  break;
1929   
1930                  case 'tar.bz2':
1931                      $ext = '.tar.bz2';
1932                      $mimetype = 'x-bzip2';
1933                  break;
1934   
1935                  default:
1936                      $error[] = $user->lang[$l_prefix . '_ERR_ARCHIVE'];
1937              }
1938   
1939              if (!sizeof($error))
1940              {
1941                  include($phpbb_root_path . 'includes/functions_compress.' . $phpEx);
1942   
1943                  if ($mode == 'style')
1944                  {
1945                      $path = preg_replace('#[^\w-]+#', '_', $style_row['style_name']);
1946                  }
1947                  else
1948                  {
1949                      $path = $style_row[$mode . '_path'];
1950                  }
1951   
1952                  if ($format == 'zip')
1953                  {
1954                      $compress = new compress_zip('w', $phpbb_root_path . "store/$path$ext");
1955                  }
1956                  else
1957                  {
1958                      $compress = new compress_tar('w', $phpbb_root_path . "store/$path$ext", $ext);
1959                  }
1960   
1961                  if (sizeof($files))
1962                  {
1963                      foreach ($files as $file_ary)
1964                      {
1965                          $compress->add_file($file_ary['src'], $file_ary['prefix-'], $file_ary['prefix+'], $file_ary['exclude']);
1966                      }
1967                  }
1968   
1969                  if (sizeof($data))
1970                  {
1971                      foreach ($data as $data_ary)
1972                      {
1973                          $compress->add_data($data_ary['src'], $data_ary['prefix']);
1974                      }
1975                  }
1976   
1977                  $compress->close();
1978   
1979                  add_log('admin', 'LOG_' . $l_prefix . '_EXPORT', $style_row[$mode . '_name']);
1980   
1981                  if (!$store)
1982                  {
1983                      $compress->download($path);
1984                      @unlink("{$phpbb_root_path}store/$path$ext");
1985                      exit;
1986                  }
1987   
1988                  trigger_error(sprintf($user->lang[$l_prefix . '_EXPORTED'], "store/$path$ext") . adm_back_link($this->u_action));
1989              }
1990          }
1991   
1992          $sql = "SELECT {$mode}_id, {$mode}_name
1993              FROM " . (($mode == 'style') ? STYLES_TABLE : $sql_from) . "
1994              WHERE {$mode}_id = $style_id";
1995          $result = $db->sql_query($sql);
1996          $style_row = $db->sql_fetchrow($result);
1997          $db->sql_freeresult($result);
1998   
1999          if (!$style_row)
2000          {
2001              trigger_error($user->lang['NO_' . $l_prefix] . adm_back_link($this->u_action), E_USER_WARNING);
2002          }
2003   
2004          $this->page_title = $l_prefix . '_EXPORT';
2005   
2006          $format_buttons = '';
2007          foreach ($methods as $method)
2008          {
2009              $format_buttons .= '<label><input type="radio"' . ((!$format_buttons) ? ' id="format"' : '') . ' class="radio" value="' . $method . '" name="format"' . (($method == $format) ? ' checked="checked"' : '') . ' /> ' . $method . '</label>';
2010          }
2011   
2012          $template->assign_vars(array(
2013              'S_EXPORT'        => true,
2014              'S_ERROR_MSG'    => (sizeof($error)) ? true : false,
2015              'S_STYLE'        => ($mode == 'style') ? true : false,
2016   
2017              'L_TITLE'        => $user->lang[$this->page_title],
2018              'L_EXPLAIN'        => $user->lang[$this->page_title . '_EXPLAIN'],
2019              'L_NAME'        => $user->lang[$l_prefix . '_NAME'],
2020   
2021              'U_ACTION'        => $this->u_action . '&amp;action=export&amp;id=' . $style_id,
2022              'U_BACK'        => $this->u_action,
2023   
2024              'ERROR_MSG'            => (sizeof($error)) ? implode('<br />', $error) : '',
2025              'NAME'                => $style_row[$mode . '_name'],
2026              'FORMAT_BUTTONS'    => $format_buttons)
2027          );
2028      }
2029   
2030      /**
2031      * Display details
2032      */
2033      function details($mode, $style_id)
2034      {
2035          global $template, $db, $config, $user, $safe_mode, $cache, $phpbb_root_path;
2036   
2037          $update = (isset($_POST['update'])) ? true : false;
2038          $l_type = strtoupper($mode);
2039   
2040          $error = array();
2041          $element_ary = array('template' => STYLES_TEMPLATE_TABLE, 'theme' => STYLES_THEME_TABLE, 'imageset' => STYLES_IMAGESET_TABLE);
2042   
2043          switch ($mode)
2044          {
2045              case 'style':
2046                  $sql_from = STYLES_TABLE;
2047              break;
2048   
2049              case 'template':
2050                  $sql_from = STYLES_TEMPLATE_TABLE;
2051              break;
2052   
2053              case 'theme':
2054                  $sql_from = STYLES_THEME_TABLE;
2055              break;
2056   
2057              case 'imageset':
2058                  $sql_from = STYLES_IMAGESET_TABLE;
2059              break;
2060          }
2061   
2062          $sql = "SELECT *
2063              FROM $sql_from
2064              WHERE {$mode}_id = $style_id";
2065          $result = $db->sql_query($sql);
2066          $style_row = $db->sql_fetchrow($result);
2067          $db->sql_freeresult($result);
2068   
2069          if (!$style_row)
2070          {
2071              trigger_error($user->lang['NO_' . $l_type] . adm_back_link($this->u_action), E_USER_WARNING);
2072          }
2073   
2074          $style_row['style_default'] = ($mode == 'style' && $config['default_style'] == $style_id) ? 1 : 0;
2075   
2076          if ($update)
2077          {
2078              $name = utf8_normalize_nfc(request_var('name', '', true));
2079              $copyright = utf8_normalize_nfc(request_var('copyright', '', true));
2080   
2081              $template_id = request_var('template_id', 0);
2082              $theme_id = request_var('theme_id', 0);
2083              $imageset_id = request_var('imageset_id', 0);
2084   
2085              $style_active = request_var('style_active', 0);
2086              $style_default = request_var('style_default', 0);
2087              $store_db = request_var('store_db', 0);
2088   
2089              if ($mode == 'style' && (!$template_id || !$theme_id || !$imageset_id))
2090              {
2091                  $error[] = $user->lang['STYLE_ERR_NO_IDS'];
2092              }
2093   
2094              if ($mode == 'style' && $style_row['style_active'] && !$style_active && $config['default_style'] == $style_id)
2095              {
2096                  $error[] = $user->lang['DEACTIVATE_DEFAULT'];
2097              }
2098   
2099              if (!$name)
2100              {
2101                  $error[] = $user->lang[$l_type . '_ERR_STYLE_NAME'];
2102              }
2103   
2104              if ($mode === 'theme' || $mode === 'template')
2105              {
2106                  // a rather elaborate check we have to do here once to avoid trouble later
2107                  $check = "{$phpbb_root_path}styles/" . $style_row["{$mode}_path"] . (($mode === 'theme') ? '/theme/stylesheet.css' : '/template');
2108                  if (($style_row["{$mode}_storedb"] != $store_db) && !$store_db && ($safe_mode || !@is_writable($check)))
2109                  {
2110                      $error[] = $user->lang['EDIT_' . strtoupper($mode) . '_STORED_DB'];
2111                      $store_db = 1;
2112                  }
2113   
2114                  // themes which have to be parsed have to go into db
2115                  if ($mode == 'theme')
2116                  {
2117                      $cfg = parse_cfg_file("{$phpbb_root_path}styles/" . $style_row["{$mode}_path"] . "/theme/theme.cfg");
2118   
2119                      if (isset($cfg['parse_css_file']) && $cfg['parse_css_file'] && !$store_db)
2120                      {
2121                          $error[] = $user->lang['EDIT_THEME_STORE_PARSED'];
2122                          $store_db = 1;
2123                      }
2124                  }
2125              }
2126              
2127              if (!sizeof($error))
2128              {
2129                  // Check length settings
2130                  if (utf8_strlen($name) > 30)
2131                  {
2132                      $error[] = $user->lang[$l_type . '_ERR_NAME_LONG'];
2133                  }
2134   
2135                  if (utf8_strlen($copyright) > 60)
2136                  {
2137                      $error[] = $user->lang[$l_type . '_ERR_COPY_LONG'];
2138                  }
2139              }
2140          }
2141   
2142          if ($update && sizeof($error))
2143          {
2144              $style_row = array_merge($style_row, array(
2145                  'template_id'            => $template_id,
2146                  'theme_id'                => $theme_id,
2147                  'imageset_id'            => $imageset_id,
2148                  'style_active'            => $style_active,
2149                  $mode . '_storedb'        => $store_db,
2150                  $mode . '_name'            => $name,
2151                  $mode . '_copyright'    => $copyright)
2152              );
2153          }
2154   
2155          // User has submitted form and no errors have occurred
2156          if ($update && !sizeof($error))
2157          {
2158              $sql_ary = array(
2159                  $mode . '_name'            => $name,
2160                  $mode . '_copyright'    => $copyright
2161              );
2162   
2163              switch ($mode)
2164              {
2165                  case 'style':
2166   
2167                      $sql_ary += array(
2168                          'template_id'        => (int) $template_id,
2169                          'theme_id'            => (int) $theme_id,
2170                          'imageset_id'        => (int) $imageset_id,
2171                          'style_active'        => (int) $style_active,
2172                      );
2173                  break;
2174   
2175                  case 'imageset':
2176                  break;
2177   
2178                  case 'theme':
2179   
2180                      if ($style_row['theme_storedb'] != $store_db)
2181                      {
2182                          $theme_data = '';
2183   
2184                          if (!$style_row['theme_storedb'])
2185                          {
2186                              $theme_data = $this->db_theme_data($style_row);
2187                          }
2188                          else if (!$store_db && !$safe_mode && @is_writable("{$phpbb_root_path}styles/{$style_row['theme_path']}/theme/stylesheet.css"))
2189                          {
2190                              $store_db = 1;
2191                              $theme_data = $style_row['theme_data'];
2192   
2193                              if ($fp = @fopen("{$phpbb_root_path}styles/{$style_row['theme_path']}/theme/stylesheet.css", 'wb'))
2194                              {
2195                                  $store_db = (@fwrite($fp, str_replace("styles/{$style_row['theme_path']}/theme/", './', $theme_data))) ? 0 : 1;
2196                              }
2197                              fclose($fp);
2198                          }
2199   
2200                          $sql_ary += array(
2201                              'theme_mtime'    => ($store_db) ? filemtime("{$phpbb_root_path}styles/{$style_row['theme_path']}/theme/stylesheet.css") : 0,
2202                              'theme_storedb'    => $store_db,
2203                              'theme_data'    => ($store_db) ? $theme_data : '',
2204                          );
2205                      }
2206                  break;
2207   
2208                  case 'template':
2209   
2210                      if ($style_row['template_storedb'] != $store_db)
2211                      {
2212                          if (!$store_db && !$safe_mode && @is_writable("{$phpbb_root_path}styles/{$style_row['template_path']}/template"))
2213                          {
2214                              $sql = 'SELECT *
2215                                  FROM ' . STYLES_TEMPLATE_DATA_TABLE . "
2216                                  WHERE template_id = $style_id";
2217                              $result = $db->sql_query($sql);
2218   
2219                              while ($row = $db->sql_fetchrow($result))
2220                              {
2221                                  if (!($fp = @fopen("{$phpbb_root_path}styles/{$style_row['template_path']}/template/" . $row['template_filename'], 'wb')))
2222                                  {
2223                                      $store_db = 1;
2224                                      $error[] = $user->lang['EDIT_TEMPLATE_STORED_DB'];
2225                                      break;
2226                                  }
2227   
2228                                  fwrite($fp, $row['template_data']);
2229                                  fclose($fp);
2230                              }
2231                              $db->sql_freeresult($result);
2232   
2233                              if (!$store_db)
2234                              {
2235                                  $sql = 'DELETE FROM ' . STYLES_TEMPLATE_DATA_TABLE . "
2236                                      WHERE template_id = $style_id";
2237                                  $db->sql_query($sql);
2238                              }
2239                          }
2240                          else if ($store_db)
2241                          {
2242                              $filelist = filelist("{$phpbb_root_path}styles/{$style_row['template_path']}/template", '', 'html');
2243                              $this->store_templates('insert', $style_id, $style_row['template_path'], $filelist);
2244                          }
2245                          else
2246                          {
2247                              // We no longer store within the db, but are also not able to update the file structure
2248                              // Since the admin want to switch this, we adhere to his decision. But we also need to remove the cache
2249                              $sql = 'DELETE FROM ' . STYLES_TEMPLATE_DATA_TABLE . "
2250                                  WHERE template_id = $style_id";
2251                              $db->sql_query($sql);
2252                          }
2253   
2254                          $sql_ary += array(
2255                              'template_storedb'    => $store_db,
2256                          );
2257                      }
2258                  break;
2259              }
2260   
2261              if (sizeof($sql_ary))
2262              {
2263                  $sql = "UPDATE $sql_from
2264                      SET " . $db->sql_build_array('UPDATE', $sql_ary) . "
2265                      WHERE {$mode}_id = $style_id";
2266                  $db->sql_query($sql);
2267   
2268                  // Making this the default style?
2269                  if ($mode == 'style' && $style_default)
2270                  {
2271                      set_config('default_style', $style_id);
2272                  }
2273              }
2274   
2275              $cache->destroy('sql', STYLES_TABLE);
2276   
2277              add_log('admin', 'LOG_' . $l_type . '_EDIT_DETAILS', $name);
2278              if (sizeof($error))
2279              {
2280                  trigger_error(implode('<br />', $error) . adm_back_link($this->u_action), E_USER_WARNING);
2281              }
2282              else
2283              {
2284                  trigger_error($user->lang[$l_type . '_DETAILS_UPDATED'] . adm_back_link($this->u_action));
2285              }
2286          }
2287   
2288          if ($mode == 'style')
2289          {
2290              foreach ($element_ary as $element => $table)
2291              {
2292                  $sql = "SELECT {$element}_id, {$element}_name
2293                      FROM $table
2294                      ORDER BY {$element}_id ASC";
2295                  $result = $db->sql_query($sql);
2296   
2297                  ${$element . '_options'} = '';
2298                  while ($row = $db->sql_fetchrow($result))
2299                  {
2300                      $selected = ($row[$element . '_id'] == $style_row[$element . '_id']) ? ' selected="selected"' : '';
2301                      ${$element . '_options'} .= '<option value="' . $row[$element . '_id'] . '"' . $selected . '>' . $row[$element . '_name'] . '</option>';
2302                  }
2303                  $db->sql_freeresult($result);
2304              }
2305          }
2306   
2307          $this->page_title = 'EDIT_DETAILS_' . $l_type;
2308   
2309          $template->assign_vars(array(
2310              'S_DETAILS'                => true,
2311              'S_ERROR_MSG'            => (sizeof($error)) ? true : false,
2312              'S_STYLE'                => ($mode == 'style') ? true : false,
2313              'S_TEMPLATE'            => ($mode == 'template') ? true : false,
2314              'S_THEME'                => ($mode == 'theme') ? true : false,
2315              'S_IMAGESET'            => ($mode == 'imageset') ? true : false,
2316              'S_STORE_DB'            => (isset($style_row[$mode . '_storedb'])) ? $style_row[$mode . '_storedb'] : 0,
2317              'S_STYLE_ACTIVE'        => (isset($style_row['style_active'])) ? $style_row['style_active'] : 0,
2318              'S_STYLE_DEFAULT'        => (isset($style_row['style_default'])) ? $style_row['style_default'] : 0,
2319   
2320              'S_TEMPLATE_OPTIONS'    => ($mode == 'style') ? $template_options : '',
2321              'S_THEME_OPTIONS'        => ($mode == 'style') ? $theme_options : '',
2322              'S_IMAGESET_OPTIONS'    => ($mode == 'style') ? $imageset_options : '',
2323   
2324              'U_ACTION'        => $this->u_action . '&amp;action=details&amp;id=' . $style_id,
2325              'U_BACK'        => $this->u_action,
2326   
2327              'L_TITLE'                => $user->lang[$this->page_title],
2328              'L_EXPLAIN'                => $user->lang[$this->page_title . '_EXPLAIN'],
2329              'L_NAME'                => $user->lang[$l_type . '_NAME'],
2330              'L_LOCATION'            => ($mode == 'template' || $mode == 'theme') ? $user->lang[$l_type . '_LOCATION'] : '',
2331              'L_LOCATION_EXPLAIN'    => ($mode == 'template' || $mode == 'theme') ? $user->lang[$l_type . '_LOCATION_EXPLAIN'] : '',
2332   
2333              'ERROR_MSG'        => (sizeof($error)) ? implode('<br />', $error) : '',
2334              'NAME'            => $style_row[$mode . '_name'],
2335              'COPYRIGHT'        => $style_row[$mode . '_copyright'],
2336              )
2337          );
2338      }
2339   
2340      /**
2341      * Load css file contents
2342      */
2343      function load_css_file($path, $filename)
2344      {
2345          global $phpbb_root_path;
2346   
2347          $file = "{$phpbb_root_path}styles/$path/theme/$filename";
2348   
2349          if (file_exists($file) && ($content = file_get_contents($file)))
2350          {
2351              $content = trim($content);
2352          }
2353          else
2354          {
2355              $content = '';
2356          }
2357   
2358          return $content;
2359      }
2360   
2361      /**
2362      * Returns a string containing the value that should be used for the theme_data column in the theme database table.
2363      * Includes contents of files loaded via @import
2364      *
2365      * @param array $theme_row is an associative array containing the theme's current database entry
2366      * @param mixed $stylesheet can either be the new content for the stylesheet or false to load from the standard file
2367      * @param string $root_path should only be used in case you want to use a different root path than "{$phpbb_root_path}styles/{$theme_row['theme_path']}"
2368      *
2369      * @return string Stylesheet data for theme_data column in the theme table
2370      */
2371      function db_theme_data($theme_row, $stylesheet = false, $root_path = '')
2372      {
2373          global $phpbb_root_path;
2374   
2375          if (!$root_path)
2376          {
2377              $root_path = $phpbb_root_path . 'styles/' . $theme_row['theme_path'];
2378          }
2379   
2380          if (!$stylesheet)
2381          {
2382              $stylesheet = '';
2383              if (file_exists($root_path . '/theme/stylesheet.css'))
2384              {
2385                  $stylesheet = file_get_contents($root_path . '/theme/stylesheet.css');
2386              }
2387          }
2388   
2389          // Match CSS imports
2390          $matches = array();
2391          preg_match_all('/@import url\(["\'](.*)["\']\);/i', $stylesheet, $matches);
2392   
2393          if (sizeof($matches))
2394          {
2395              foreach ($matches[0] as $idx => $match)
2396              {
2397                  $stylesheet = str_replace($match, acp_styles::load_css_file($theme_row['theme_path'], $matches[1][$idx]), $stylesheet);
2398              }
2399          }
2400   
2401          // adjust paths
2402          return str_replace('./', 'styles/' . $theme_row['theme_path'] . '/theme/', $stylesheet);
2403      }
2404   
2405      /**
2406      * Store template files into db
2407      */
2408      function store_templates($mode, $style_id, $template_path, $filelist)
2409      {
2410          global $phpbb_root_path, $phpEx, $db;
2411   
2412          $template_path = $template_path . '/template/';
2413          $includes = array();
2414          foreach ($filelist as $pathfile => $file_ary)
2415          {
2416              foreach ($file_ary as $file)
2417              {
2418                  if (!($fp = @fopen("{$phpbb_root_path}styles/$template_path$pathfile$file", 'r')))
2419                  {
2420                      trigger_error("Could not open {$phpbb_root_path}styles/$template_path$pathfile$file", E_USER_ERROR);
2421                  }
2422                  $template_data = fread($fp, filesize("{$phpbb_root_path}styles/$template_path$pathfile$file"));
2423                  fclose($fp);
2424   
2425                  if (preg_match_all('#<!-- INCLUDE (.*?\.html) -->#is', $template_data, $matches))
2426                  {
2427                      foreach ($matches[1] as $match)
2428                      {
2429                          $includes[trim($match)][] = $file;
2430                      }
2431                  }
2432              }
2433          }
2434   
2435          foreach ($filelist as $pathfile => $file_ary)
2436          {
2437              foreach ($file_ary as $file)
2438              {
2439                  // Skip index.
2440                  if (strpos($file, 'index.') === 0)
2441                  {
2442                      continue;
2443                  }
2444   
2445                  // We could do this using extended inserts ... but that could be one
2446                  // heck of a lot of data ...
2447                  $sql_ary = array(
2448                      'template_id'            => (int) $style_id,
2449                      'template_filename'        => "$pathfile$file",
2450                      'template_included'        => (isset($includes[$file])) ? implode(':', $includes[$file]) . ':' : '',
2451                      'template_mtime'        => (int) filemtime("{$phpbb_root_path}styles/$template_path$pathfile$file"),
2452                      'template_data'            => (string) file_get_contents("{$phpbb_root_path}styles/$template_path$pathfile$file"),
2453                  );
2454   
2455                  if ($mode == 'insert')
2456                  {
2457                      $sql = 'INSERT INTO ' . STYLES_TEMPLATE_DATA_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary);
2458                  }
2459                  else
2460                  {
2461                      $sql = 'UPDATE ' . STYLES_TEMPLATE_DATA_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $sql_ary) . "
2462                          WHERE template_id = $style_id
2463                              AND template_filename = '" . $db->sql_escape("$pathfile$file") . "'";
2464                  }
2465                  $db->sql_query($sql);
2466              }
2467          }
2468      }
2469   
2470      /**
2471      * Returns an array containing all template filenames for one template that are currently cached.
2472      *
2473      * @param string $template_path contains the name of the template's folder in /styles/
2474      *
2475      * @return array of filenames that exist in /styles/$template_path/template/ (without extension!)
2476      */
2477      function template_cache_filelist($template_path)
2478      {
2479          global $phpbb_root_path, $phpEx, $user;
2480   
2481          $cache_prefix = 'tpl_' . $template_path;
2482   
2483          if (!($dp = @opendir("{$phpbb_root_path}cache")))
2484          {
2485              trigger_error($user->lang['TEMPLATE_ERR_CACHE_READ'] . adm_back_link($this->u_action), E_USER_WARNING);
2486          }
2487   
2488          $file_ary = array();
2489          while ($file = readdir($dp))
2490          {
2491              if ($file[0] == '.')
2492              {
2493                  continue;
2494              }
2495   
2496              if (is_file($phpbb_root_path . 'cache/' . $file) && (strpos($file, $cache_prefix) === 0))
2497              {
2498                  $file_ary[] = str_replace('.', '/', preg_replace('#^' . preg_quote($cache_prefix, '#') . '_(.*?)\.html\.' . $phpEx . '$#i', '\1', $file));
2499              }
2500          }
2501          closedir($dp);
2502   
2503          return $file_ary;
2504      }
2505   
2506      /**
2507      * Destroys cached versions of template files
2508      *
2509      * @param array $template_row contains the template's row in the STYLES_TEMPLATE_TABLE database table
2510      * @param mixed $file_ary is optional and may contain an array of template file names which should be refreshed in the cache.
2511      *    The file names should be the original template file names and not the cache file names.
2512      */
2513      function clear_template_cache($template_row, $file_ary = false)
2514      {
2515          global $phpbb_root_path, $phpEx, $user;
2516   
2517          $cache_prefix = 'tpl_' . $template_row['template_path'];
2518   
2519          if (!$file_ary || !is_array($file_ary))
2520          {
2521              $file_ary = $this->template_cache_filelist($template_row['template_path']);
2522              $log_file_list = $user->lang['ALL_FILES'];
2523          }
2524          else
2525          {
2526              $log_file_list = implode(', ', $file_ary);
2527          }
2528   
2529          foreach ($file_ary as $file)
2530          {
2531              $file = str_replace('/', '.', $file);
2532   
2533              $file = "{$phpbb_root_path}cache/{$cache_prefix}_$file.html.$phpEx";
2534              if (file_exists($file) && is_file($file))
2535              {
2536                  @unlink($file);
2537              }
2538          }
2539          unset($file_ary);
2540   
2541          add_log('admin', 'LOG_TEMPLATE_CACHE_CLEARED', $template_row['template_name'], $log_file_list);
2542      }
2543   
2544      /**
2545      * Install Style/Template/Theme/Imageset
2546      */
2547      function install($mode)
2548      {
2549          global $phpbb_root_path, $phpEx, $config, $db, $cache, $user, $template;
2550   
2551          $l_type = strtoupper($mode);
2552   
2553          $error = $installcfg = $style_row = array();
2554          $root_path = $cfg_file = '';
2555          $element_ary = array('template' => STYLES_TEMPLATE_TABLE, 'theme' => STYLES_THEME_TABLE, 'imageset' => STYLES_IMAGESET_TABLE);
2556   
2557          $install_path = request_var('path', '');
2558          $update = (isset($_POST['update'])) ? true : false;
2559   
2560          // Installing, obtain cfg file contents
2561          if ($install_path)
2562          {
2563              $root_path = $phpbb_root_path . 'styles/' . $install_path . '/';
2564              $cfg_file = ($mode == 'style') ? "$root_path$mode.cfg" : "$root_path$mode/$mode.cfg";
2565   
2566              if (!file_exists($cfg_file))
2567              {
2568                  $error[] = $user->lang[$l_type . '_ERR_NOT_' . $l_type];
2569              }
2570              else
2571              {
2572                  $installcfg = parse_cfg_file($cfg_file);
2573              }
2574          }
2575   
2576          // Installing
2577          if (sizeof($installcfg))
2578          {
2579              $name        = $installcfg['name'];
2580              $copyright    = $installcfg['copyright'];
2581              $version    = $installcfg['version'];
2582   
2583              $style_row = array(
2584                  $mode . '_id'            => 0,
2585                  $mode . '_name'            => '',
2586                  $mode . '_copyright'    => ''
2587              );
2588   
2589              switch ($mode)
2590              {
2591                  case 'style':
2592   
2593                      $style_row = array(
2594                          'style_id'            => 0,
2595                          'style_name'        => $installcfg['name'],
2596                          'style_copyright'    => $installcfg['copyright']
2597                      );
2598   
2599                      $reqd_template = (isset($installcfg['required_template'])) ? $installcfg['required_template'] : false;
2600                      $reqd_theme = (isset($installcfg['required_theme'])) ? $installcfg['required_theme'] : false;
2601                      $reqd_imageset = (isset($installcfg['required_imageset'])) ? $installcfg['required_imageset'] : false;
2602   
2603                      // Check to see if each element is already installed, if it is grab the id
2604                      foreach ($element_ary as $element => $table)
2605                      {
2606                          $style_row = array_merge($style_row, array(
2607                              $element . '_id'            => 0,
2608                              $element . '_name'            => '',
2609                              $element . '_copyright'        => '')
2610                          );
2611   
2612                           $this->test_installed($element, $error, (${'reqd_' . $element}) ? $phpbb_root_path . 'styles/' . $reqd_template . '/' : $root_path, ${'reqd_' . $element}, $style_row[$element . '_id'], $style_row[$element . '_name'], $style_row[$element . '_copyright']);
2613   
2614                          if (!$style_row[$element . '_name'])
2615                          {
2616                              $style_row[$element . '_name'] = $reqd_template;
2617                          }
2618                      }
2619   
2620                  break;
2621   
2622                  case 'template':
2623                      $this->test_installed('template', $error, $root_path, false, $style_row['template_id'], $style_row['template_name'], $style_row['template_copyright']);
2624                  break;
2625   
2626                  case 'theme':
2627                      $this->test_installed('theme', $error, $root_path, false, $style_row['theme_id'], $style_row['theme_name'], $style_row['theme_copyright']);
2628                  break;
2629   
2630                  case 'imageset':
2631                      $this->test_installed('imageset', $error, $root_path, false, $style_row['imageset_id'], $style_row['imageset_name'], $style_row['imageset_copyright']);
2632                  break;
2633              }
2634          }
2635          else
2636          {
2637              trigger_error($user->lang['NO_' . $l_type] . adm_back_link($this->u_action), E_USER_WARNING);
2638          }
2639   
2640          $style_row['store_db'] = request_var('store_db', 0);
2641          $style_row['style_active'] = request_var('style_active', 1);
2642          $style_row['style_default'] = request_var('style_default', 0);
2643   
2644          // User has submitted form and no errors have occurred
2645          if ($update && !sizeof($error))
2646          {
2647              if ($mode == 'style')
2648              {
2649                  foreach ($element_ary as $element => $table)
2650                  {
2651                      ${$element . '_root_path'} = (${'reqd_' . $element}) ? $phpbb_root_path . 'styles/' . ${'reqd_' . $element} . '/' : false;
2652                      ${$element . '_path'} = (${'reqd_' . $element}) ? ${'reqd_' . $element} : false;
2653                  }
2654                  $this->install_style($error, 'install', $root_path, $style_row['style_id'], $style_row['style_name'], $install_path, $style_row['style_copyright'], $style_row['style_active'], $style_row['style_default'], $style_row, $template_root_path, $template_path, $theme_root_path, $theme_path, $imageset_root_path, $imageset_path);
2655              }
2656              else
2657              {
2658                  $style_row['store_db'] = $this->install_element($mode, $error, 'install', $root_path, $style_row[$mode . '_id'], $style_row[$mode . '_name'], $install_path, $style_row[$mode . '_copyright'], $style_row['store_db']);
2659              }
2660   
2661              if (!sizeof($error))
2662              {
2663                  $cache->destroy('sql', STYLES_TABLE);
2664   
2665                  $message = ($style_row['store_db']) ? '_ADDED_DB' : '_ADDED';
2666                  trigger_error($user->lang[$l_type . $message] . adm_back_link($this->u_action));
2667              }
2668          }
2669   
2670          $this->page_title = 'INSTALL_' . $l_type;
2671   
2672          $template->assign_vars(array(
2673              'S_DETAILS'            => true,
2674              'S_INSTALL'            => true,
2675              'S_ERROR_MSG'        => (sizeof($error)) ? true : false,
2676              'S_STYLE'            => ($mode == 'style') ? true : false,
2677              'S_TEMPLATE'        => ($mode == 'template') ? true : false,
2678              'S_THEME'            => ($mode == 'theme') ? true : false,
2679   
2680              'S_STORE_DB'            => (isset($style_row[$mode . '_storedb'])) ? $style_row[$mode . '_storedb'] : 0,
2681              'S_STYLE_ACTIVE'        => (isset($style_row['style_active'])) ? $style_row['style_active'] : 0,
2682              'S_STYLE_DEFAULT'        => (isset($style_row['style_default'])) ? $style_row['style_default'] : 0,
2683   
2684              'U_ACTION'            => $this->u_action . "&amp;action=install&amp;path=" . urlencode($install_path),
2685              'U_BACK'            => $this->u_action,
2686   
2687              'L_TITLE'                => $user->lang[$this->page_title],
2688              'L_EXPLAIN'                => $user->lang[$this->page_title . '_EXPLAIN'],
2689              'L_NAME'                => $user->lang[$l_type . '_NAME'],
2690              'L_LOCATION'            => ($mode == 'template' || $mode == 'theme') ? $user->lang[$l_type . '_LOCATION'] : '',
2691              'L_LOCATION_EXPLAIN'    => ($mode == 'template' || $mode == 'theme') ? $user->lang[$l_type . '_LOCATION_EXPLAIN'] : '',
2692   
2693              'ERROR_MSG'            => (sizeof($error)) ? implode('<br />', $error) : '',
2694              'NAME'                => $style_row[$mode . '_name'],
2695              'COPYRIGHT'            => $style_row[$mode . '_copyright'],
2696              'TEMPLATE_NAME'        => ($mode == 'style') ? $style_row['template_name'] : '',
2697              'THEME_NAME'        => ($mode == 'style') ? $style_row['theme_name'] : '',
2698              'IMAGESET_NAME'        => ($mode == 'style') ? $style_row['imageset_name'] : '')
2699          );
2700      }
2701   
2702      /**
2703      * Add new style
2704      */
2705      function add($mode)
2706      {
2707          global $phpbb_root_path, $phpEx, $config, $db, $cache, $user, $template;
2708   
2709          $l_type = strtoupper($mode);
2710          $element_ary = array('template' => STYLES_TEMPLATE_TABLE, 'theme' => STYLES_THEME_TABLE, 'imageset' => STYLES_IMAGESET_TABLE);
2711          $error = array();
2712   
2713          $style_row = array(
2714              $mode . '_name'            => utf8_normalize_nfc(request_var('name', '', true)),
2715              $mode . '_copyright'    => utf8_normalize_nfc(request_var('copyright', '', true)),
2716              'template_id'            => 0,
2717              'theme_id'                => 0,
2718              'imageset_id'            => 0,
2719              'store_db'                => request_var('store_db', 0),
2720              'style_active'            => request_var('style_active', 1),
2721              'style_default'            => request_var('style_default', 0),
2722          );
2723   
2724          $basis = request_var('basis', 0);
2725          $update = (isset($_POST['update'])) ? true : false;
2726   
2727          if ($basis)
2728          {
2729              switch ($mode)
2730              {
2731                  case 'style':
2732                      $sql_select = 'template_id, theme_id, imageset_id';
2733                      $sql_from = STYLES_TABLE;
2734                  break;
2735   
2736                  case 'template':
2737                      $sql_select = 'template_id';
2738                      $sql_from = STYLES_TEMPLATE_TABLE;
2739                  break;
2740   
2741                  case 'theme':
2742                      $sql_select = 'theme_id';
2743                      $sql_from = STYLES_THEME_TABLE;
2744                  break;
2745   
2746                  case 'imageset':
2747                      $sql_select = 'imageset_id';
2748                      $sql_from = STYLES_IMAGESET_TABLE;
2749                  break;
2750              }
2751   
2752              $sql = "SELECT $sql_select
2753                  FROM $sql_from
2754                  WHERE {$mode}_id = $basis";
2755              $result = $db->sql_query($sql);
2756              $row = $db->sql_fetchrow($result);
2757              $db->sql_freeresult($result);
2758   
2759              if (!$row)
2760              {
2761                  $error[] = $user->lang['NO_' . $l_type];
2762              }
2763   
2764              if (!sizeof($error))
2765              {
2766                  $style_row['template_id']    = (isset($row['template_id'])) ? $row['template_id'] : $style_row['template_id'];
2767                  $style_row['theme_id']        = (isset($row['theme_id'])) ? $row['theme_id'] : $style_row['theme_id'];
2768                  $style_row['imageset_id']    = (isset($row['imageset_id'])) ? $row['imageset_id'] : $style_row['imageset_id'];
2769              }
2770          }
2771   
2772          if ($update)
2773          {
2774              $style_row['template_id'] = request_var('template_id', $style_row['template_id']);
2775              $style_row['theme_id'] = request_var('theme_id', $style_row['theme_id']);
2776              $style_row['imageset_id'] = request_var('imageset_id', $style_row['imageset_id']);
2777   
2778              if ($mode == 'style' && (!$style_row['template_id'] || !$style_row['theme_id'] || !$style_row['imageset_id']))
2779              {
2780                  $error[] = $user->lang['STYLE_ERR_NO_IDS'];
2781              }
2782          }
2783   
2784          // User has submitted form and no errors have occurred
2785          if ($update && !sizeof($error))
2786          {
2787              if ($mode == 'style')
2788              {
2789                  $style_row['style_id'] = 0;
2790   
2791                  $this->install_style($error, 'add', '', $style_row['style_id'], $style_row['style_name'], '', $style_row['style_copyright'], $style_row['style_active'], $style_row['style_default'], $style_row);
2792              }
2793   
2794              if (!sizeof($error))
2795              {
2796                  $cache->destroy('sql', STYLES_TABLE);
2797   
2798                  $message = ($style_row['store_db']) ? '_ADDED_DB' : '_ADDED';
2799                  trigger_error($user->lang[$l_type . $message] . adm_back_link($this->u_action));
2800              }
2801          }
2802   
2803          if ($mode == 'style')
2804          {
2805              foreach ($element_ary as $element => $table)
2806              {
2807                  $sql = "SELECT {$element}_id, {$element}_name
2808                      FROM $table
2809                      ORDER BY {$element}_id ASC";
2810                  $result = $db->sql_query($sql);
2811   
2812                  ${$element . '_options'} = '';
2813                  while ($row = $db->sql_fetchrow($result))
2814                  {
2815                      $selected = ($row[$element . '_id'] == $style_row[$element . '_id']) ? ' selected="selected"' : '';
2816                      ${$element . '_options'} .= '<option value="' . $row[$element . '_id'] . '"' . $selected . '>' . $row[$element . '_name'] . '</option>';
2817                  }
2818                  $db->sql_freeresult($result);
2819              }
2820          }
2821   
2822          $this->page_title = 'ADD_' . $l_type;
2823   
2824          $template->assign_vars(array(
2825              'S_DETAILS'            => true,
2826              'S_ADD'                => true,
2827              'S_ERROR_MSG'        => (sizeof($error)) ? true : false,
2828              'S_STYLE'            => ($mode == 'style') ? true : false,
2829              'S_TEMPLATE'        => ($mode == 'template') ? true : false,
2830              'S_THEME'            => ($mode == 'theme') ? true : false,
2831              'S_BASIS'            => ($basis) ? true : false,
2832   
2833              'S_STORE_DB'            => (isset($style_row['storedb'])) ? $style_row['storedb'] : 0,
2834              'S_STYLE_ACTIVE'        => (isset($style_row['style_active'])) ? $style_row['style_active'] : 0,
2835              'S_STYLE_DEFAULT'        => (isset($style_row['style_default'])) ? $style_row['style_default'] : 0,
2836              'S_TEMPLATE_OPTIONS'    => ($mode == 'style') ? $template_options : '',
2837              'S_THEME_OPTIONS'        => ($mode == 'style') ? $theme_options : '',
2838              'S_IMAGESET_OPTIONS'    => ($mode == 'style') ? $imageset_options : '',
2839   
2840              'U_ACTION'            => $this->u_action . '&amp;action=add&amp;basis=' . $basis,
2841              'U_BACK'            => $this->u_action,
2842   
2843              'L_TITLE'                => $user->lang[$this->page_title],
2844              'L_EXPLAIN'                => $user->lang[$this->page_title . '_EXPLAIN'],
2845              'L_NAME'                => $user->lang[$l_type . '_NAME'],
2846              'L_LOCATION'            => ($mode == 'template' || $mode == 'theme') ? $user->lang[$l_type . '_LOCATION'] : '',
2847              'L_LOCATION_EXPLAIN'    => ($mode == 'template' || $mode == 'theme') ? $user->lang[$l_type . '_LOCATION_EXPLAIN'] : '',
2848   
2849              'ERROR_MSG'            => (sizeof($error)) ? implode('<br />', $error) : '',
2850              'NAME'                => $style_row[$mode . '_name'],
2851              'COPYRIGHT'            => $style_row[$mode . '_copyright'])
2852          );
2853   
2854      }
2855   
2856      /**
2857   
2858                      $reqd_template = (isset($installcfg['required_template'])) ? $installcfg['required_template'] : false;
2859                      $reqd_theme = (isset($installcfg['required_theme'])) ? $installcfg['required_theme'] : false;
2860                      $reqd_imageset = (isset($installcfg['required_imageset'])) ? $installcfg['required_imageset'] : false;
2861   
2862                      // Check to see if each element is already installed, if it is grab the id
2863                      foreach ($element_ary as $element => $table)
2864                      {
2865                          $style_row = array_merge($style_row, array(
2866                              $element . '_id'            => 0,
2867                              $element . '_name'            => '',
2868                              $element . '_copyright'        => '')
2869                          );
2870   
2871                           $this->test_installed($element, $error, $root_path, ${'reqd_' . $element}, $style_row[$element . '_id'], $style_row[$element . '_name'], $style_row[$element . '_copyright']);
2872      * Is this element installed? If not, grab its cfg details
2873      */
2874      function test_installed($element, &$error, $root_path, $reqd_name, &$id, &$name, &$copyright)
2875      {
2876          global $db, $user;
2877   
2878          switch ($element)
2879          {
2880              case 'template':
2881                  $sql_from = STYLES_TEMPLATE_TABLE;
2882              break;
2883   
2884              case 'theme':
2885                  $sql_from = STYLES_THEME_TABLE;
2886              break;
2887   
2888              case 'imageset':
2889                  $sql_from = STYLES_IMAGESET_TABLE;
2890              break;
2891          }
2892   
2893          $l_element = strtoupper($element);
2894   
2895          $chk_name = ($reqd_name !== false) ? $reqd_name : $name;
2896   
2897          $sql = "SELECT {$element}_id, {$element}_name
2898              FROM $sql_from
2899              WHERE {$element}_name = '" . $db->sql_escape($chk_name) . "'";
2900          $result = $db->sql_query($sql);
2901   
2902          if ($row = $db->sql_fetchrow($result))
2903          {
2904              $name = $row[$element . '_name'];
2905              $id = $row[$element . '_id'];
2906          }
2907          else
2908          {
2909              if (!($cfg = @file("$root_path$element/$element.cfg")))
2910              {
2911                  $error[] = sprintf($user->lang['REQUIRES_' . $l_element], $reqd_name);
2912                  return false;
2913              }
2914   
2915              $cfg = parse_cfg_file("$root_path$element/$element.cfg", $cfg);
2916   
2917              $name = $cfg['name'];
2918              $copyright = $cfg['copyright'];
2919              $id = 0;
2920   
2921              unset($cfg);
2922          }
2923          $db->sql_freeresult($result);
2924      }
2925   
2926      /**
2927      * Install/Add style
2928      */
2929      function install_style(&$error, $action, $root_path, &$id, $name, $path, $copyright, $active, $default, &$style_row, $template_root_path = false, $template_path = false, $theme_root_path = false, $theme_path = false, $imageset_root_path = false, $imageset_path = false)
2930      {
2931          global $config, $db, $user;
2932   
2933          $element_ary = array('template', 'theme', 'imageset');
2934   
2935          if (!$name)
2936          {
2937              $error[] = $user->lang['STYLE_ERR_STYLE_NAME'];
2938          }
2939   
2940          // Check length settings
2941          if (utf8_strlen($name) > 30)
2942          {
2943              $error[] = $user->lang['STYLE_ERR_NAME_LONG'];
2944          }
2945   
2946          if (utf8_strlen($copyright) > 60)
2947          {
2948              $error[] = $user->lang['STYLE_ERR_COPY_LONG'];
2949          }
2950   
2951          // Check if the name already exist
2952          $sql = 'SELECT style_id
2953              FROM ' . STYLES_TABLE . "
2954              WHERE style_name = '" . $db->sql_escape($name) . "'";
2955          $result = $db->sql_query($sql);
2956          $row = $db->sql_fetchrow($result);
2957          $db->sql_freeresult($result);
2958   
2959          if ($row)
2960          {
2961              $error[] = $user->lang['STYLE_ERR_NAME_EXIST'];
2962          }
2963   
2964          if (sizeof($error))
2965          {
2966              return false;
2967          }
2968   
2969          foreach ($element_ary as $element)
2970          {
2971              // Zero id value ... need to install element ... run usual checks
2972              // and do the install if necessary
2973              if (!$style_row[$element . '_id'])
2974              {
2975                  $this->install_element($element, $error, $action, (${$element . '_root_path'}) ? ${$element . '_root_path'} : $root_path, $style_row[$element . '_id'], $style_row[$element . '_name'], (${$element . '_path'}) ? ${$element . '_path'} : $path, $style_row[$element . '_copyright']);
2976              }
2977          }
2978   
2979          if (!$style_row['template_id'] || !$style_row['theme_id'] || !$style_row['imageset_id'])
2980          {
2981              $error[] = $user->lang['STYLE_ERR_NO_IDS'];
2982          }
2983   
2984          if (sizeof($error))
2985          {
2986              return false;
2987          }
2988   
2989          $db->sql_transaction('begin');
2990   
2991          $sql_ary = array(
2992              'style_name'        => $name,
2993              'style_copyright'    => $copyright,
2994              'style_active'        => (int) $active,
2995              'template_id'        => (int) $style_row['template_id'],
2996              'theme_id'            => (int) $style_row['theme_id'],
2997              'imageset_id'        => (int) $style_row['imageset_id'],
2998          );
2999   
3000          $sql = 'INSERT INTO ' . STYLES_TABLE . '
3001              ' . $db->sql_build_array('INSERT', $sql_ary);
3002          $db->sql_query($sql);
3003   
3004          $id = $db->sql_nextid();
3005   
3006          if ($default)
3007          {
3008              $sql = 'UPDATE ' . USERS_TABLE . "
3009                  SET user_style = $id
3010                  WHERE user_style = " . $config['default_style'];
3011              $db->sql_query($sql);
3012   
3013              set_config('default_style', $id);
3014          }
3015   
3016          $db->sql_transaction('commit');
3017   
3018          add_log('admin', 'LOG_STYLE_ADD', $name);
3019      }
3020   
3021      /**
3022      * Install/add an element, doing various checks as we go
3023      */
3024      function install_element($mode, &$error, $action, $root_path, &$id, $name, $path, $copyright, $store_db = 0)
3025      {
3026          global $phpbb_root_path, $db, $user;
3027   
3028          switch ($mode)
3029          {
3030              case 'template':
3031                  $sql_from = STYLES_TEMPLATE_TABLE;
3032              break;
3033   
3034              case 'theme':
3035                  $sql_from = STYLES_THEME_TABLE;
3036              break;
3037   
3038              case 'imageset':
3039                  $sql_from = STYLES_IMAGESET_TABLE;
3040              break;
3041          }
3042   
3043          $l_type = strtoupper($mode);
3044   
3045          if (!$name)
3046          {
3047              $error[] = $user->lang[$l_type . '_ERR_STYLE_NAME'];
3048          }
3049   
3050          // Check length settings
3051          if (utf8_strlen($name) > 30)
3052          {
3053              $error[] = $user->lang[$l_type . '_ERR_NAME_LONG'];
3054          }
3055   
3056          if (utf8_strlen($copyright) > 60)
3057          {
3058              $error[] = $user->lang[$l_type . '_ERR_COPY_LONG'];
3059          }
3060   
3061          // Check if the name already exist
3062          $sql = "SELECT {$mode}_id
3063              FROM $sql_from
3064              WHERE {$mode}_name = '" . $db->sql_escape($name) . "'";
3065          $result = $db->sql_query($sql);
3066          $row = $db->sql_fetchrow($result);
3067          $db->sql_freeresult($result);
3068   
3069          if ($row)
3070          {
3071              // If it exist, we just use the style on installation
3072              if ($action == 'install')
3073              {
3074                  $id = $row[$mode . '_id'];
3075                  return false;
3076              }
3077   
3078              $error[] = $user->lang[$l_type . '_ERR_NAME_EXIST'];
3079          }
3080   
3081          if (sizeof($error))
3082          {
3083              return false;
3084          }
3085   
3086          $sql_ary = array(
3087              $mode . '_name'            => $name,
3088              $mode . '_copyright'    => $copyright,
3089              $mode . '_path'            => $path,
3090          );
3091   
3092          switch ($mode)
3093          {
3094              case 'template':
3095                  // We check if the template author defined a different bitfield
3096                  $cfg_data = parse_cfg_file("$root_path$mode/template.cfg");
3097   
3098                  if (!empty($cfg_data['template_bitfield']))
3099                  {
3100                      $sql_ary['bbcode_bitfield'] = $cfg_data['template_bitfield'];
3101                  }
3102                  else
3103                  {
3104                      $sql_ary['bbcode_bitfield'] = TEMPLATE_BITFIELD;
3105                  }
3106   
3107                  // We set a pre-defined bitfield here which we may use further in 3.2
3108                  $sql_ary += array(
3109                      'template_storedb'    => $store_db
3110                  );
3111              break;
3112   
3113              case 'theme':
3114                  // We are only interested in the theme configuration for now
3115                  $theme_cfg = parse_cfg_file("{$phpbb_root_path}styles/$path/theme/theme.cfg");
3116   
3117                  if (isset($theme_cfg['parse_css_file']) && $theme_cfg['parse_css_file'])
3118                  {
3119                      $store_db = 1;
3120                  }
3121   
3122                  $sql_ary += array(
3123                      'theme_storedb'    => $store_db,
3124                      'theme_data'    => ($store_db) ? $this->db_theme_data($sql_ary, false, $root_path) : '',
3125                      'theme_mtime'    => (int) filemtime("{$phpbb_root_path}styles/$path/theme/stylesheet.css")
3126                  );
3127              break;
3128   
3129              // all the heavy lifting is done later
3130              case 'imageset':
3131              break;
3132          }
3133   
3134          $db->sql_transaction('begin');
3135   
3136          $sql = "INSERT INTO $sql_from
3137              " . $db->sql_build_array('INSERT', $sql_ary);
3138          $db->sql_query($sql);
3139   
3140          $id = $db->sql_nextid();
3141   
3142          if ($mode == 'template' && $store_db)
3143          {
3144              $filelist = filelist("{$root_path}template", '', 'html');
3145              $this->store_templates('insert', $id, $path, $filelist);
3146          }
3147          else if ($mode == 'imageset')
3148          {
3149              $cfg_data = parse_cfg_file("$root_path$mode/imageset.cfg");
3150   
3151              $imageset_definitions = array();
3152              foreach ($this->imageset_keys as $topic => $key_array)
3153              {
3154                  $imageset_definitions = array_merge($imageset_definitions, $key_array);
3155              }
3156   
3157              foreach ($cfg_data as $key => $value)
3158              {
3159                  if (strpos($value, '*') !== false)
3160                  {
3161                      if (substr($value, -1, 1) === '*')
3162                      {
3163                          list($image_filename, $image_height) = explode('*', $value);
3164                          $image_width = 0;
3165                      }
3166                      else
3167                      {
3168                          list($image_filename, $image_height, $image_width) = explode('*', $value);
3169                      }
3170                  }
3171                  else
3172                  {
3173                      $image_filename = $value;
3174                      $image_height = $image_width = 0;
3175                  }
3176   
3177                  if (strpos($key, 'img_') === 0 && $image_filename)
3178                  {
3179                      $key = substr($key, 4);
3180                      if (in_array($key, $imageset_definitions))
3181                      {
3182                          $sql_ary = array(
3183                              'image_name'        => $key,
3184                              'image_filename'    => str_replace('{PATH}', "styles/$path/imageset/", trim($image_filename)),
3185                              'image_height'        => (int) $image_height,
3186                              'image_width'        => (int) $image_width,
3187                              'imageset_id'        => (int) $id,
3188                              'image_lang'        => '',
3189                          );
3190                          $db->sql_query('INSERT INTO ' . STYLES_IMAGESET_DATA_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary));
3191                      }
3192                  }
3193              }
3194              unset($cfg_data);
3195   
3196              $sql = 'SELECT lang_dir
3197                  FROM ' . LANG_TABLE;
3198              $result = $db->sql_query($sql);
3199   
3200              while ($row = $db->sql_fetchrow($result))
3201              {
3202                  if (@file_exists("$root_path$mode/{$row['lang_dir']}/imageset.cfg"))
3203                  {
3204                      $cfg_data_imageset_data = parse_cfg_file("$root_path$mode/{$row['lang_dir']}/imageset.cfg");
3205                      foreach ($cfg_data_imageset_data as $image_name => $value)
3206                      {
3207                          if (strpos($value, '*') !== false)
3208                          {
3209                              if (substr($value, -1, 1) === '*')
3210                              {
3211                                  list($image_filename, $image_height) = explode('*', $value);
3212                                  $image_width = 0;
3213                              }
3214                              else
3215                              {
3216                                  list($image_filename, $image_height, $image_width) = explode('*', $value);
3217                              }
3218                          }
3219                          else
3220                          {
3221                              $image_filename = $value;
3222                              $image_height = $image_width = 0;
3223                          }
3224   
3225                          if (strpos($image_name, 'img_') === 0 && $image_filename)
3226                          {
3227                              $image_name = substr($image_name, 4);
3228                              if (in_array($image_name, $imageset_definitions))
3229                              {
3230                                  $sql_ary = array(
3231                                      'image_name'        => $image_name,
3232                                      'image_filename'    => $image_filename,
3233                                      'image_height'        => (int) $image_height,
3234                                      'image_width'        => (int) $image_width,
3235                                      'imageset_id'        => (int) $id,
3236                                      'image_lang'        => $row['lang_dir'],
3237                                  );
3238                                  $db->sql_query('INSERT INTO ' . STYLES_IMAGESET_DATA_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary));
3239                              }
3240                          }
3241                      }
3242                      unset($cfg_data_imageset_data);
3243                  }
3244              }
3245              $db->sql_freeresult($result);
3246          }
3247   
3248          $db->sql_transaction('commit');
3249   
3250          $log = ($store_db) ? 'LOG_' . $l_type . '_ADD_DB' : 'LOG_' . $l_type . '_ADD_FS';
3251          add_log('admin', $log, $name);
3252   
3253          // Return store_db in case it had to be altered
3254          return $store_db;
3255      }
3256   
3257  }
3258   
3259  ?>