[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/includes/acp/ -> acp_styles.php (source)

   1  <?php
   2  /**
   3  *
   4  * @package acp
   5  * @version $Id$
   6  * @copyright (c) 2005 phpBB Group
   7  * @license http://opensource.org/licenses/gpl-license.php GNU Public License
   8  *
   9  */
  10  
  11  /**
  12  * @ignore
  13  */
  14  if (!defined('IN_PHPBB'))
  15  {
  16      exit;
  17  }
  18  
  19  /**
  20  * @package acp
  21  */
  22  class acp_styles
  23  {
  24      var $u_action;
  25  
  26      var $style_cfg;
  27      var $template_cfg;
  28      var $theme_cfg;
  29      var $imageset_cfg;
  30      var $imageset_keys;
  31  
  32  	function main($id, $mode)
  33      {
  34          global $db, $user, $auth, $template, $cache;
  35          global $config, $phpbb_root_path, $phpbb_admin_path, $phpEx;
  36  
  37          // Hardcoded template bitfield to add for new templates
  38          $bitfield = new bitfield();
  39          $bitfield->set(0);
  40          $bitfield->set(1);
  41          $bitfield->set(2);
  42          $bitfield->set(3);
  43          $bitfield->set(4);
  44          $bitfield->set(8);
  45          $bitfield->set(9);
  46          $bitfield->set(11);
  47          $bitfield->set(12);
  48          define('TEMPLATE_BITFIELD', $bitfield->get_base64());
  49          unset($bitfield);
  50  
  51          $user->add_lang('acp/styles');
  52  
  53          $this->tpl_name = 'acp_styles';
  54          $this->page_title = 'ACP_CAT_STYLES';
  55  
  56          $action = request_var('action', '');
  57          $action = (isset($_POST['add'])) ? 'add' : $action;
  58          $style_id = request_var('id', 0);
  59  
  60          // Fill the configuration variables
  61          $this->style_cfg = $this->template_cfg = $this->theme_cfg = $this->imageset_cfg = '
  62  #
  63  # phpBB {MODE} configuration file
  64  #
  65  # @package phpBB3
  66  # @copyright (c) 2005 phpBB Group
  67  # @license http://opensource.org/licenses/gpl-license.php GNU Public License
  68  #
  69  #
  70  # At the left is the name, please do not change this
  71  # At the right the value is entered
  72  # For on/off options the valid values are on, off, 1, 0, true and false
  73  #
  74  # Values get trimmed, if you want to add a space in front or at the end of
  75  # the value, then enclose the value with single or double quotes.
  76  # Single and double quotes do not need to be escaped.
  77  #
  78  #
  79  
  80  # General Information about this {MODE}
  81  name = {NAME}
  82  copyright = {COPYRIGHT}
  83  version = {VERSION}
  84  ';
  85  
  86          $this->theme_cfg .= '
  87  # Some configuration options
  88  
  89  #
  90  # You have to turn this option on if you want to use the
  91  # path template variables ({T_IMAGESET_PATH} for example) within
  92  # your css file.
  93  # This is mostly the case if you want to use language specific
  94  # images within your css file.
  95  #
  96  parse_css_file = {PARSE_CSS_FILE}
  97  ';
  98  
  99          $this->template_cfg .= '
 100  # Some configuration options
 101  
 102  # Template inheritance
 103  # See http://blog.phpbb.com/2008/07/31/templating-just-got-easier/
 104  # Set value to empty or this template name to ignore template inheritance.
 105  inherit_from = {INHERIT_FROM}
 106  ';
 107  
 108          $this->imageset_keys = array(
 109              'logos' => array(
 110                  'site_logo',
 111              ),
 112              'buttons'    => array(
 113                  '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',
 114              ),
 115              'icons'        => array(
 116                  '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',
 117              ),
 118              'forums'    => array(
 119                  'forum_link', 'forum_read', 'forum_read_locked', 'forum_read_subforum', 'forum_unread', 'forum_unread_locked', 'forum_unread_subforum', 'subforum_read', 'subforum_unread'
 120              ),
 121              'folders'    => array(
 122                  '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',
 123              ),
 124              'polls'        => array(
 125                  'poll_left', 'poll_center', 'poll_right',
 126              ),
 127              'ui'        => array(
 128                  'upload_bar',
 129              ),
 130              'user'        => array(
 131                  'user_icon1', 'user_icon2', 'user_icon3', 'user_icon4', 'user_icon5', 'user_icon6', 'user_icon7', 'user_icon8', 'user_icon9', 'user_icon10',
 132              ),
 133          );
 134  
 135          // Execute overall actions
 136          switch ($action)
 137          {
 138              case 'delete':
 139                  if ($style_id)
 140                  {
 141                      $this->remove($mode, $style_id);
 142                      return;
 143                  }
 144              break;
 145  
 146              case 'export':
 147                  if ($style_id)
 148                  {
 149                      $this->export($mode, $style_id);
 150                      return;
 151                  }
 152              break;
 153  
 154              case 'install':
 155                  $this->install($mode);
 156                  return;
 157              break;
 158  
 159              case 'add':
 160                  $this->add($mode);
 161                  return;
 162              break;
 163  
 164              case 'details':
 165                  if ($style_id)
 166                  {
 167                      $this->details($mode, $style_id);
 168                      return;
 169                  }
 170              break;
 171  
 172              case 'edit':
 173                  if ($style_id)
 174                  {
 175                      switch ($mode)
 176                      {
 177                          case 'imageset':
 178                              return $this->edit_imageset($style_id);
 179                          case 'template':
 180                              return $this->edit_template($style_id);
 181                          case 'theme':
 182                              return $this->edit_theme($style_id);
 183                      }
 184                  }
 185              break;
 186  
 187              case 'cache':
 188                  if ($style_id)
 189                  {
 190                      switch ($mode)
 191                      {
 192                          case 'template':
 193                              return $this->template_cache($style_id);
 194                      }
 195                  }
 196              break;
 197          }
 198  
 199          switch ($mode)
 200          {
 201              case 'style':
 202  
 203                  switch ($action)
 204                  {
 205                      case 'activate':
 206                      case 'deactivate':
 207  
 208                          if ($style_id == $config['default_style'])
 209                          {
 210                              trigger_error($user->lang['DEACTIVATE_DEFAULT'] . adm_back_link($this->u_action), E_USER_WARNING);
 211                          }
 212  
 213                          if (($action == 'deactivate' && confirm_box(true)) || $action == 'activate')
 214                          {
 215                              $sql = 'UPDATE ' . STYLES_TABLE . '
 216                                  SET style_active = ' . (($action == 'activate') ? 1 : 0) . '
 217                                  WHERE style_id = ' . $style_id;
 218                              $db->sql_query($sql);
 219  
 220                              // Set style to default for any member using deactivated style
 221                              if ($action == 'deactivate')
 222                              {
 223                                  $sql = 'UPDATE ' . USERS_TABLE . '
 224                                      SET user_style = ' . $config['default_style'] . "
 225                                      WHERE user_style = $style_id";
 226                                  $db->sql_query($sql);
 227  
 228                                  $sql = 'UPDATE ' . FORUMS_TABLE . '
 229                                      SET forum_style = 0
 230                                      WHERE forum_style = ' . $style_id;
 231                                  $db->sql_query($sql);
 232                              }
 233                          }
 234                          else if ($action == 'deactivate')
 235                          {
 236                              $s_hidden_fields = array(
 237                                  'i'            => $id,
 238                                  'mode'        => $mode,
 239                                  'action'    => $action,
 240                                  'style_id'    => $style_id,
 241                              );
 242                              confirm_box(false, $user->lang['CONFIRM_OPERATION'], build_hidden_fields($s_hidden_fields));
 243                          }
 244                      break;
 245                  }
 246  
 247                  $this->frontend('style', array('details'), array('export', 'delete'));
 248              break;
 249  
 250              case 'template':
 251  
 252                  switch ($action)
 253                  {
 254                      // Refresh template data stored in db and clear cache
 255                      case 'refresh':
 256  
 257                          $sql = 'SELECT *
 258                              FROM ' . STYLES_TEMPLATE_TABLE . "
 259                              WHERE template_id = $style_id";
 260                          $result = $db->sql_query($sql);
 261                          $template_row = $db->sql_fetchrow($result);
 262                          $db->sql_freeresult($result);
 263  
 264                          if (!$template_row)
 265                          {
 266                              trigger_error($user->lang['NO_TEMPLATE'] . adm_back_link($this->u_action), E_USER_WARNING);
 267                          }
 268  
 269                          if (confirm_box(true))
 270                          {
 271                              $template_refreshed = '';
 272  
 273                              // Only refresh database if the template is stored in the database
 274                              if ($template_row['template_storedb'] && file_exists("{$phpbb_root_path}styles/{$template_row['template_path']}/template/"))
 275                              {
 276                                  $filelist = array('' => array());
 277  
 278                                  $sql = 'SELECT template_filename, template_mtime
 279                                      FROM ' . STYLES_TEMPLATE_DATA_TABLE . "
 280                                      WHERE template_id = $style_id";
 281                                  $result = $db->sql_query($sql);
 282  
 283                                  while ($row = $db->sql_fetchrow($result))
 284                                  {
 285  //                                    if (@filemtime("{$phpbb_root_path}styles/{$template_row['template_path']}/template/" . $row['template_filename']) > $row['template_mtime'])
 286  //                                    {
 287                                          // get folder info from the filename
 288                                          if (($slash_pos = strrpos($row['template_filename'], '/')) === false)
 289                                          {
 290                                              $filelist[''][] = $row['template_filename'];
 291                                          }
 292                                          else
 293                                          {
 294                                              $filelist[substr($row['template_filename'], 0, $slash_pos + 1)][] = substr($row['template_filename'], $slash_pos + 1, strlen($row['template_filename']) - $slash_pos - 1);
 295                                          }
 296  //                                    }
 297                                  }
 298                                  $db->sql_freeresult($result);
 299  
 300                                  $this->store_templates('update', $style_id, $template_row['template_path'], $filelist);
 301                                  unset($filelist);
 302  
 303                                  $template_refreshed = $user->lang['TEMPLATE_REFRESHED'] . '<br />';
 304                                  add_log('admin', 'LOG_TEMPLATE_REFRESHED', $template_row['template_name']);
 305                              }
 306  
 307                              $this->clear_template_cache($template_row);
 308  
 309                              trigger_error($template_refreshed . $user->lang['TEMPLATE_CACHE_CLEARED'] . adm_back_link($this->u_action));
 310                          }
 311                          else
 312                          {
 313                              confirm_box(false, ($template_row['template_storedb']) ? $user->lang['CONFIRM_TEMPLATE_REFRESH'] : $user->lang['CONFIRM_TEMPLATE_CLEAR_CACHE'], build_hidden_fields(array(
 314                                  'i'            => $id,
 315                                  'mode'        => $mode,
 316                                  'action'    => $action,
 317                                  'id'        => $style_id
 318                              )));
 319                          }
 320  
 321                      break;
 322                  }
 323  
 324                  $this->frontend('template', array('edit', 'cache', 'details'), array('refresh', 'export', 'delete'));
 325              break;
 326  
 327              case 'theme':
 328  
 329                  switch ($action)
 330                  {
 331                      // Refresh theme data stored in the database
 332                      case 'refresh':
 333  
 334                          $sql = 'SELECT *
 335                              FROM ' . STYLES_THEME_TABLE . "
 336                              WHERE theme_id = $style_id";
 337                          $result = $db->sql_query($sql);
 338                          $theme_row = $db->sql_fetchrow($result);
 339                          $db->sql_freeresult($result);
 340  
 341                          if (!$theme_row)
 342                          {
 343                              trigger_error($user->lang['NO_THEME'] . adm_back_link($this->u_action), E_USER_WARNING);
 344                          }
 345  
 346                          if (!$theme_row['theme_storedb'])
 347                          {
 348                              trigger_error($user->lang['THEME_ERR_REFRESH_FS'] . adm_back_link($this->u_action), E_USER_WARNING);
 349                          }
 350  
 351                          if (confirm_box(true))
 352                          {
 353                              if ($theme_row['theme_storedb'] && file_exists("{$phpbb_root_path}styles/{$theme_row['theme_path']}/theme/stylesheet.css"))
 354                              {
 355                                  // Save CSS contents
 356                                  $sql_ary = array(
 357                                      'theme_mtime'    => (int) filemtime("{$phpbb_root_path}styles/{$theme_row['theme_path']}/theme/stylesheet.css"),
 358                                      'theme_data'    => $this->db_theme_data($theme_row)
 359                                  );
 360  
 361                                  $sql = 'UPDATE ' . STYLES_THEME_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $sql_ary) . "
 362                                      WHERE theme_id = $style_id";
 363                                  $db->sql_query($sql);
 364  
 365                                  $cache->destroy('sql', STYLES_THEME_TABLE);
 366  
 367                                  add_log('admin', 'LOG_THEME_REFRESHED', $theme_row['theme_name']);
 368                                  trigger_error($user->lang['THEME_REFRESHED'] . adm_back_link($this->u_action));
 369                              }
 370                          }
 371                          else
 372                          {
 373                              confirm_box(false, $user->lang['CONFIRM_THEME_REFRESH'], build_hidden_fields(array(
 374                                  'i'            => $id,
 375                                  'mode'        => $mode,
 376                                  'action'    => $action,
 377                                  'id'        => $style_id
 378                              )));
 379                          }
 380                      break;
 381                  }
 382  
 383                  $this->frontend('theme', array('edit', 'details'), array('refresh', 'export', 'delete'));
 384              break;
 385  
 386              case 'imageset':
 387  
 388                  switch ($action)
 389                  {
 390                      case 'refresh':
 391  
 392                          $sql = 'SELECT *
 393                              FROM ' . STYLES_IMAGESET_TABLE . "
 394                              WHERE imageset_id = $style_id";
 395                          $result = $db->sql_query($sql);
 396                          $imageset_row = $db->sql_fetchrow($result);
 397                          $db->sql_freeresult($result);
 398  
 399                          if (!$imageset_row)
 400                          {
 401                              trigger_error($user->lang['NO_IMAGESET'] . adm_back_link($this->u_action), E_USER_WARNING);
 402                          }
 403  
 404                          if (confirm_box(true))
 405                          {
 406                              $sql_ary = array();
 407  
 408                              $imageset_definitions = array();
 409                              foreach ($this->imageset_keys as $topic => $key_array)
 410                              {
 411                                  $imageset_definitions = array_merge($imageset_definitions, $key_array);
 412                              }
 413  
 414                              $cfg_data_imageset = parse_cfg_file("{$phpbb_root_path}styles/{$imageset_row['imageset_path']}/imageset/imageset.cfg");
 415  
 416                              $db->sql_transaction('begin');
 417  
 418                              $sql = 'DELETE FROM ' . STYLES_IMAGESET_DATA_TABLE . '
 419                                  WHERE imageset_id = ' . $style_id;
 420                              $result = $db->sql_query($sql);
 421  
 422                              foreach ($cfg_data_imageset as $image_name => $value)
 423                              {
 424                                  if (strpos($value, '*') !== false)
 425                                  {
 426                                      if (substr($value, -1, 1) === '*')
 427                                      {
 428                                          list($image_filename, $image_height) = explode('*', $value);
 429                                          $image_width = 0;
 430                                      }
 431                                      else
 432                                      {
 433                                          list($image_filename, $image_height, $image_width) = explode('*', $value);
 434                                      }
 435                                  }
 436                                  else
 437                                  {
 438                                      $image_filename = $value;
 439                                      $image_height = $image_width = 0;
 440                                  }
 441  
 442                                  if (strpos($image_name, 'img_') === 0 && $image_filename)
 443                                  {
 444                                      $image_name = substr($image_name, 4);
 445                                      if (in_array($image_name, $imageset_definitions))
 446                                      {
 447                                          $sql_ary[] = array(
 448                                              'image_name'        => (string) $image_name,
 449                                              'image_filename'    => (string) $image_filename,
 450                                              'image_height'        => (int) $image_height,
 451                                              'image_width'        => (int) $image_width,
 452                                              'imageset_id'        => (int) $style_id,
 453                                              'image_lang'        => '',
 454                                          );
 455                                      }
 456                                  }
 457                              }
 458  
 459                              $sql = 'SELECT lang_dir
 460                                  FROM ' . LANG_TABLE;
 461                              $result = $db->sql_query($sql);
 462  
 463                              while ($row = $db->sql_fetchrow($result))
 464                              {
 465                                  if (@file_exists("{$phpbb_root_path}styles/{$imageset_row['imageset_path']}/imageset/{$row['lang_dir']}/imageset.cfg"))
 466                                  {
 467                                      $cfg_data_imageset_data = parse_cfg_file("{$phpbb_root_path}styles/{$imageset_row['imageset_path']}/imageset/{$row['lang_dir']}/imageset.cfg");
 468                                      foreach ($cfg_data_imageset_data as $image_name => $value)
 469                                      {
 470                                          if (strpos($value, '*') !== false)
 471                                          {
 472                                              if (substr($value, -1, 1) === '*')
 473                                              {
 474                                                  list($image_filename, $image_height) = explode('*', $value);
 475                                                  $image_width = 0;
 476                                              }
 477                                              else
 478                                              {
 479                                                  list($image_filename, $image_height, $image_width) = explode('*', $value);
 480                                              }
 481                                          }
 482                                          else
 483                                          {
 484                                              $image_filename = $value;
 485                                              $image_height = $image_width = 0;
 486                                          }
 487  
 488                                          if (strpos($image_name, 'img_') === 0 && $image_filename)
 489                                          {
 490                                              $image_name = substr($image_name, 4);
 491                                              if (in_array($image_name, $imageset_definitions))
 492                                              {
 493                                                  $sql_ary[] = array(
 494                                                      'image_name'        => (string) $image_name,
 495                                                      'image_filename'    => (string) $image_filename,
 496                                                      'image_height'        => (int) $image_height,
 497                                                      'image_width'        => (int) $image_width,
 498                                                      'imageset_id'        => (int) $style_id,
 499                                                      'image_lang'        => (string) $row['lang_dir'],
 500                                                  );
 501                                              }
 502                                          }
 503                                      }
 504                                  }
 505                              }
 506                              $db->sql_freeresult($result);
 507  
 508                              $db->sql_multi_insert(STYLES_IMAGESET_DATA_TABLE, $sql_ary);
 509  
 510                              $db->sql_transaction('commit');
 511  
 512                              $cache->destroy('sql', STYLES_IMAGESET_DATA_TABLE);
 513                              $cache->destroy('imageset_site_logo_md5');
 514  
 515                              add_log('admin', 'LOG_IMAGESET_REFRESHED', $imageset_row['imageset_name']);
 516                              trigger_error($user->lang['IMAGESET_REFRESHED'] . adm_back_link($this->u_action));
 517                          }
 518                          else
 519                          {
 520                              confirm_box(false, $user->lang['CONFIRM_IMAGESET_REFRESH'], build_hidden_fields(array(
 521                                  'i'            => $id,
 522                                  'mode'        => $mode,
 523                                  'action'    => $action,
 524                                  'id'        => $style_id
 525                              )));
 526                          }
 527                      break;
 528                  }
 529  
 530                  $this->frontend('imageset', array('edit', 'details'), array('refresh', 'export', 'delete'));
 531              break;
 532          }
 533      }
 534  
 535      /**
 536      * Build Frontend with supplied options
 537      */
 538  	function frontend($mode, $options, $actions)
 539      {
 540          global $user, $template, $db, $config, $phpbb_root_path, $phpEx;
 541  
 542          $sql_from = '';
 543          $sql_sort = 'LOWER(' . $mode . '_name)';
 544          $style_count = array();
 545  
 546          switch ($mode)
 547          {
 548              case 'style':
 549                  $sql_from = STYLES_TABLE;
 550                  $sql_sort = 'style_active DESC, ' . $sql_sort;
 551  
 552                  $sql = 'SELECT user_style, COUNT(user_style) AS style_count
 553                      FROM ' . USERS_TABLE . '
 554                      GROUP BY user_style';
 555                  $result = $db->sql_query($sql);
 556  
 557                  while ($row = $db->sql_fetchrow($result))
 558                  {
 559                      $style_count[$row['user_style']] = $row['style_count'];
 560                  }
 561                  $db->sql_freeresult($result);
 562  
 563              break;
 564  
 565              case 'template':
 566                  $sql_from = STYLES_TEMPLATE_TABLE;
 567              break;
 568  
 569              case 'theme':
 570                  $sql_from = STYLES_THEME_TABLE;
 571              break;
 572  
 573              case 'imageset':
 574                  $sql_from = STYLES_IMAGESET_TABLE;
 575              break;
 576              
 577              default:
 578                  trigger_error($user->lang['NO_MODE'] . adm_back_link($this->u_action), E_USER_WARNING);
 579          }
 580  
 581          $l_prefix = strtoupper($mode);
 582  
 583          $this->page_title = 'ACP_' . $l_prefix . 'S';
 584  
 585          $template->assign_vars(array(
 586              'S_FRONTEND'        => true,
 587              'S_STYLE'            => ($mode == 'style') ? true : false,
 588  
 589              'L_TITLE'            => $user->lang[$this->page_title],
 590              'L_EXPLAIN'            => $user->lang[$this->page_title . '_EXPLAIN'],
 591              'L_NAME'            => $user->lang[$l_prefix . '_NAME'],
 592              'L_INSTALLED'        => $user->lang['INSTALLED_' . $l_prefix],
 593              'L_UNINSTALLED'        => $user->lang['UNINSTALLED_' . $l_prefix],
 594              'L_NO_UNINSTALLED'    => $user->lang['NO_UNINSTALLED_' . $l_prefix],
 595              'L_CREATE'            => $user->lang['CREATE_' . $l_prefix],
 596  
 597              'U_ACTION'            => $this->u_action,
 598              )
 599          );
 600  
 601          $sql = "SELECT *
 602              FROM $sql_from
 603              ORDER BY $sql_sort ASC";
 604          $result = $db->sql_query($sql);
 605  
 606          $installed = array();
 607  
 608          $basis_options = '<option class="sep" value="">' . $user->lang['OPTIONAL_BASIS'] . '</option>';
 609          while ($row = $db->sql_fetchrow($result))
 610          {
 611              $installed[] = $row[$mode . '_name'];
 612              $basis_options .= '<option value="' . $row[$mode . '_id'] . '">' . $row[$mode . '_name'] . '</option>';
 613  
 614              $stylevis = ($mode == 'style' && !$row['style_active']) ? 'activate' : 'deactivate';
 615  
 616              $s_options = array();
 617              foreach ($options as $option)
 618              {
 619                  $s_options[] = '<a href="' . $this->u_action . "&amp;action=$option&amp;id=" . $row[$mode . '_id'] . '">' . $user->lang[strtoupper($option)] . '</a>';
 620              }
 621  
 622              $s_actions = array();
 623              foreach ($actions as $option)
 624              {
 625                  $s_actions[] = '<a href="' . $this->u_action . "&amp;action=$option&amp;id=" . $row[$mode . '_id'] . '">' . $user->lang[strtoupper($option)] . '</a>';
 626              }
 627  
 628              $template->assign_block_vars('installed', array(
 629                  'S_DEFAULT_STYLE'        => ($mode == 'style' && $row['style_id'] == $config['default_style']) ? true : false,
 630                  'U_EDIT'                => $this->u_action . '&amp;action=' . (($mode == 'style') ? 'details' : 'edit') . '&amp;id=' . $row[$mode . '_id'],
 631                  'U_STYLE_ACT_DEACT'        => $this->u_action . '&amp;action=' . $stylevis . '&amp;id=' . $row[$mode . '_id'],
 632                  'L_STYLE_ACT_DEACT'        => $user->lang['STYLE_' . strtoupper($stylevis)],
 633                  'S_OPTIONS'                => implode(' | ', $s_options),
 634                  'S_ACTIONS'                => implode(' | ', $s_actions),
 635                  'U_PREVIEW'                => ($mode == 'style') ? append_sid("{$phpbb_root_path}index.$phpEx", "$mode=" . $row[$mode . '_id']) : '',
 636  
 637                  'NAME'                    => $row[$mode . '_name'],
 638                  'STYLE_COUNT'            => ($mode == 'style' && isset($style_count[$row['style_id']])) ? $style_count[$row['style_id']] : 0,
 639  
 640                  'S_INACTIVE'            => ($mode == 'style' && !$row['style_active']) ? true : false,
 641                  )
 642              );
 643          }
 644          $db->sql_freeresult($result);
 645  
 646          // Grab uninstalled items
 647          $new_ary = $cfg = array();
 648  
 649          $dp = @opendir("{$phpbb_root_path}styles");
 650  
 651          if ($dp)
 652          {
 653              while (($file = readdir($dp)) !== false)
 654              {
 655                  if ($file[0] == '.' || !is_dir($phpbb_root_path . 'styles/' . $file))
 656                  {
 657                      continue;
 658                  }
 659  
 660                  $subpath = ($mode != 'style') ? "$mode/" : '';
 661                  if (file_exists("{$phpbb_root_path}styles/$file/$subpath$mode.cfg"))
 662                  {
 663                      if ($cfg = file("{$phpbb_root_path}styles/$file/$subpath$mode.cfg"))
 664                      {
 665                          $items = parse_cfg_file('', $cfg);
 666                          $name = (isset($items['name'])) ? trim($items['name']) : false;
 667  
 668                          if ($name && !in_array($name, $installed))
 669                          {
 670                              // The array key is used for sorting later on.
 671                              // $file is appended because $name doesn't have to be unique.
 672                              $new_ary[$name . $file] = array(
 673                                  'path'        => $file,
 674                                  'name'        => $name,
 675                                  'copyright'    => $items['copyright'],
 676                              );
 677                          }
 678                      }
 679                  }
 680              }
 681              closedir($dp);
 682          }
 683  
 684          unset($installed);
 685  
 686          if (sizeof($new_ary))
 687          {
 688              ksort($new_ary);
 689  
 690              foreach ($new_ary as $cfg)
 691              {
 692                  $template->assign_block_vars('uninstalled', array(
 693                      'NAME'            => $cfg['name'],
 694                      'COPYRIGHT'        => $cfg['copyright'],
 695                      'U_INSTALL'        => $this->u_action . '&amp;action=install&amp;path=' . urlencode($cfg['path']))
 696                  );
 697              }
 698          }
 699          unset($new_ary);
 700  
 701          $template->assign_vars(array(
 702              'S_BASIS_OPTIONS'        => $basis_options)
 703          );
 704  
 705      }
 706  
 707      /**
 708      * Provides a template editor which allows saving changes to template files on the filesystem or in the database.
 709      *
 710      * @param int $template_id specifies which template set is being edited
 711      */
 712  	function edit_template($template_id)
 713      {
 714          global $phpbb_root_path, $phpEx, $config, $db, $cache, $user, $template, $safe_mode;
 715  
 716          if (defined('PHPBB_DISABLE_ACP_EDITOR'))
 717          {
 718              trigger_error($user->lang['EDITOR_DISABLED'] . adm_back_link($this->u_action));
 719          }
 720  
 721          $this->page_title = 'EDIT_TEMPLATE';
 722  
 723          $filelist = $filelist_cats = array();
 724  
 725          $template_data    = utf8_normalize_nfc(request_var('template_data', '', true));
 726          $template_data    = htmlspecialchars_decode($template_data);
 727          $template_file    = utf8_normalize_nfc(request_var('template_file', '', true));
 728          $text_rows        = max(5, min(999, request_var('text_rows', 20)));
 729          $save_changes    = (isset($_POST['save'])) ? true : false;
 730  
 731          // make sure template_file path doesn't go upwards
 732          $template_file = preg_replace('#\.{2,}#', '.', $template_file);
 733  
 734          // Retrieve some information about the template
 735          $sql = 'SELECT template_storedb, template_path, template_name
 736              FROM ' . STYLES_TEMPLATE_TABLE . "
 737              WHERE template_id = $template_id";
 738          $result = $db->sql_query($sql);
 739          $template_info = $db->sql_fetchrow($result);
 740          $db->sql_freeresult($result);
 741  
 742          if (!$template_info)
 743          {
 744              trigger_error($user->lang['NO_TEMPLATE'] . adm_back_link($this->u_action), E_USER_WARNING);
 745          }
 746  
 747          if ($save_changes && !check_form_key('acp_styles'))
 748          {
 749              trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING);
 750          }
 751          else if (!$save_changes)
 752          {
 753              add_form_key('acp_styles');
 754          }
 755  
 756          // save changes to the template if the user submitted any
 757          if ($save_changes && $template_file)
 758          {
 759              // Get the filesystem location of the current file
 760              $file = "{$phpbb_root_path}styles/{$template_info['template_path']}/template/$template_file";
 761              $additional = '';
 762  
 763              // If the template is stored on the filesystem try to write the file else store it in the database
 764              if (!$safe_mode && !$template_info['template_storedb'] && file_exists($file) && phpbb_is_writable($file))
 765              {
 766                  if (!($fp = @fopen($file, 'wb')))
 767                  {
 768                      // File exists and is writeable, but still not able to be written to
 769                      trigger_error(sprintf($user->lang['TEMPLATE_FILE_NOT_WRITABLE'], htmlspecialchars($template_file)) . adm_back_link($this->u_action), E_USER_WARNING);
 770                  }
 771                  fwrite($fp, $template_data);
 772                  fclose($fp);
 773              }
 774              else
 775              {
 776                  $db->sql_transaction('begin');
 777  
 778                  // If it's not stored in the db yet, then update the template setting and store all template files in the db
 779                  if (!$template_info['template_storedb'])
 780                  {
 781                      if ($super = $this->get_super('template', $template_id))
 782                      {
 783                          $this->store_in_db('template', $super['template_id']);
 784                      }
 785                      else
 786                      {
 787                          $this->store_in_db('template', $template_id);
 788                      }
 789  
 790                      add_log('admin', 'LOG_TEMPLATE_EDIT_DETAILS', $template_info['template_name']);
 791                      $additional .= '<br />' . $user->lang['EDIT_TEMPLATE_STORED_DB'];
 792                  }
 793  
 794                  // Update the template_data table entry for this template file
 795                  $sql = 'UPDATE ' . STYLES_TEMPLATE_DATA_TABLE . "
 796                      SET template_data = '" . $db->sql_escape($template_data) . "', template_mtime = " . time() . "
 797                      WHERE template_id = $template_id
 798                          AND template_filename = '" . $db->sql_escape($template_file) . "'";
 799                  $db->sql_query($sql);
 800  
 801                  $db->sql_transaction('commit');
 802              }
 803  
 804              // destroy the cached version of the template (filename without extension)
 805              $this->clear_template_cache($template_info, array(substr($template_file, 0, -5)));
 806  
 807              $cache->destroy('sql', STYLES_TABLE);
 808  
 809              add_log('admin', 'LOG_TEMPLATE_EDIT', $template_info['template_name'], $template_file);
 810              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"));
 811          }
 812  
 813          // Generate a category array containing template filenames
 814          if (!$template_info['template_storedb'])
 815          {
 816              $template_path = "{$phpbb_root_path}styles/{$template_info['template_path']}/template";
 817  
 818              $filelist = filelist($template_path, '', 'html');
 819              $filelist[''] = array_diff($filelist[''], array('bbcode.html'));
 820  
 821              if ($template_file)
 822              {
 823                  if (!file_exists($template_path . "/$template_file") || !($template_data = file_get_contents($template_path . "/$template_file")))
 824                  {
 825                      trigger_error($user->lang['NO_TEMPLATE'] . adm_back_link($this->u_action), E_USER_WARNING);
 826                  }
 827              }
 828          }
 829          else
 830          {
 831              $sql = 'SELECT *
 832                  FROM ' . STYLES_TEMPLATE_DATA_TABLE . "
 833                  WHERE template_id = $template_id";
 834              $result = $db->sql_query($sql);
 835  
 836              $filelist = array('' => array());
 837              while ($row = $db->sql_fetchrow($result))
 838              {
 839                  $file_info = pathinfo($row['template_filename']);
 840  
 841                  if (($file_info['basename'] != 'bbcode') && ($file_info['extension'] == 'html'))
 842                  {
 843                      if (($file_info['dirname'] == '.') || empty($file_info['dirname']))
 844                      {
 845                          $filelist[''][] = $row['template_filename'];
 846                      }
 847                      else
 848                      {
 849                          $filelist[$file_info['dirname'] . '/'][] = $file_info['basename'];
 850                      }
 851                  }
 852  
 853                  if ($row['template_filename'] == $template_file)
 854                  {
 855                      $template_data = $row['template_data'];
 856                  }
 857              }
 858              $db->sql_freeresult($result);
 859              unset($file_info);
 860          }
 861  
 862          if (empty($filelist['']))
 863          {
 864              trigger_error($user->lang['NO_TEMPLATE'] . adm_back_link($this->u_action), E_USER_WARNING);
 865          }
 866  
 867          // Now create the categories
 868          $filelist_cats[''] = array();
 869          foreach ($filelist as $pathfile => $file_ary)
 870          {
 871              // Use the directory name as category name
 872              if (!empty($pathfile))
 873              {
 874                  $filelist_cats[$pathfile] = array();
 875                  foreach ($file_ary as $file)
 876                  {
 877                      $filelist_cats[$pathfile][$pathfile . $file] = $file;
 878                  }
 879              }
 880              // or if it's in the main category use the word before the first underscore to group files
 881              else
 882              {
 883                  $cats = array();
 884                  foreach ($file_ary as $file)
 885                  {
 886                      $cats[] = substr($file, 0, strpos($file, '_'));
 887                      $filelist_cats[substr($file, 0, strpos($file, '_'))][$file] = $file;
 888                  }
 889  
 890                  $cats = array_values(array_unique($cats));
 891  
 892                  // we don't need any single element categories so put them into the misc '' category
 893                  for ($i = 0, $n = sizeof($cats); $i < $n; $i++)
 894                  {
 895                      if (sizeof($filelist_cats[$cats[$i]]) == 1 && $cats[$i] !== '')
 896                      {
 897                          $filelist_cats[''][key($filelist_cats[$cats[$i]])] = current($filelist_cats[$cats[$i]]);
 898                          unset($filelist_cats[$cats[$i]]);
 899                      }
 900                  }
 901                  unset($cats);
 902              }
 903          }
 904          unset($filelist);
 905  
 906          // Generate list of categorised template files
 907          $tpl_options = '';
 908          ksort($filelist_cats);
 909          foreach ($filelist_cats as $category => $tpl_ary)
 910          {
 911              ksort($tpl_ary);
 912  
 913              if (!empty($category))
 914              {
 915                  $tpl_options .= '<option class="sep" value="">' . $category . '</option>';
 916              }
 917  
 918              foreach ($tpl_ary as $filename => $file)
 919              {
 920                  $selected = ($template_file == $filename) ? ' selected="selected"' : '';
 921                  $tpl_options .= '<option value="' . $filename . '"' . $selected . '>' . $file . '</option>';
 922              }
 923          }
 924  
 925          $template->assign_vars(array(
 926              'S_EDIT_TEMPLATE'    => true,
 927              'S_HIDDEN_FIELDS'    => build_hidden_fields(array('template_file' => $template_file)),
 928              'S_TEMPLATES'        => $tpl_options,
 929  
 930              'U_ACTION'            => $this->u_action . "&amp;action=edit&amp;id=$template_id&amp;text_rows=$text_rows",
 931              'U_BACK'            => $this->u_action,
 932  
 933              'L_EDIT'            => $user->lang['EDIT_TEMPLATE'],
 934              'L_EDIT_EXPLAIN'    => $user->lang['EDIT_TEMPLATE_EXPLAIN'],
 935              'L_EDITOR'            => $user->lang['TEMPLATE_EDITOR'],
 936              'L_EDITOR_HEIGHT'    => $user->lang['TEMPLATE_EDITOR_HEIGHT'],
 937              'L_FILE'            => $user->lang['TEMPLATE_FILE'],
 938              'L_SELECT'            => $user->lang['SELECT_TEMPLATE'],
 939              'L_SELECTED'        => $user->lang['SELECTED_TEMPLATE'],
 940              'L_SELECTED_FILE'    => $user->lang['SELECTED_TEMPLATE_FILE'],
 941  
 942              'SELECTED_TEMPLATE'    => $template_info['template_name'],
 943              'TEMPLATE_FILE'        => $template_file,
 944              'TEMPLATE_DATA'        => utf8_htmlspecialchars($template_data),
 945              'TEXT_ROWS'            => $text_rows)
 946          );
 947      }
 948  
 949      /**
 950      * Allows the admin to view cached versions of template files and clear single template cache files
 951      *
 952      * @param int $template_id specifies which template's cache is shown
 953      */
 954  	function template_cache($template_id)
 955      {
 956          global $phpbb_root_path, $phpEx, $config, $db, $cache, $user, $template;
 957  
 958          $source        = str_replace('/', '.', request_var('source', ''));
 959          $file_ary    = array_diff(request_var('delete', array('')), array(''));
 960          $submit        = isset($_POST['submit']) ? true : false;
 961  
 962          $sql = 'SELECT *
 963              FROM ' . STYLES_TEMPLATE_TABLE . "
 964              WHERE template_id = $template_id";
 965          $result = $db->sql_query($sql);
 966          $template_row = $db->sql_fetchrow($result);
 967          $db->sql_freeresult($result);
 968  
 969          if (!$template_row)
 970          {
 971              trigger_error($user->lang['NO_TEMPLATE'] . adm_back_link($this->u_action), E_USER_WARNING);
 972          }
 973  
 974          // User wants to delete one or more files ...
 975          if ($submit && $file_ary)
 976          {
 977              $this->clear_template_cache($template_row, $file_ary);
 978              trigger_error($user->lang['TEMPLATE_CACHE_CLEARED'] . adm_back_link($this->u_action . "&amp;action=cache&amp;id=$template_id"));
 979          }
 980  
 981          $cache_prefix = 'tpl_' . str_replace('_', '-', $template_row['template_path']);
 982  
 983          // Someone wants to see the cached source ... so we'll highlight it,
 984          // add line numbers and indent it appropriately. This could be nasty
 985          // on larger source files ...
 986          if ($source && file_exists("{$phpbb_root_path}cache/{$cache_prefix}_$source.html.$phpEx"))
 987          {
 988              adm_page_header($user->lang['TEMPLATE_CACHE']);
 989  
 990              $template->set_filenames(array(
 991                  'body'    => 'viewsource.html')
 992              );
 993  
 994              $template->assign_vars(array(
 995                  'FILENAME'    => str_replace('.', '/', $source) . '.html')
 996              );
 997  
 998              $code = str_replace(array("\r\n", "\r"), array("\n", "\n"), file_get_contents("{$phpbb_root_path}cache/{$cache_prefix}_$source.html.$phpEx"));
 999  
1000              $conf = array('highlight.bg', 'highlight.comment', 'highlight.default', 'highlight.html', 'highlight.keyword', 'highlight.string');
1001              foreach ($conf as $ini_var)
1002              {
1003                  @ini_set($ini_var, str_replace('highlight.', 'syntax', $ini_var));
1004              }
1005  
1006              $marker = 'MARKER' . time();
1007              $code = highlight_string(str_replace("\n", $marker, $code), true);
1008              $code = str_replace($marker, "\n", $code);
1009              $str_from = array('<span style="color: ', '<font color="syntax', '</font>', '<code>', '</code>','[', ']', '.', ':');
1010              $str_to = array('<span class="', '<span class="syntax', '</span>', '', '', '&#91;', '&#93;', '&#46;', '&#58;');
1011  
1012              $code = str_replace($str_from, $str_to, $code);
1013              $code = preg_replace('#^(<span class="[a-z_]+">)\n?(.*?)\n?(</span>)$#ism', '$1$2$3', $code);
1014              $code = substr($code, strlen('<span class="syntaxhtml">'));
1015              $code = substr($code, 0, -1 * strlen('</ span>'));
1016              $code = explode("\n", $code);
1017  
1018              foreach ($code as $key => $line)
1019              {
1020                  $template->assign_block_vars('source', array(
1021                      'LINENUM'    => $key + 1,
1022                      'LINE'        => preg_replace('#([^ ;])&nbsp;([^ &])#', '$1 $2', $line))
1023                  );
1024                  unset($code[$key]);
1025              }
1026  
1027              adm_page_footer();
1028          }
1029  
1030          $filemtime = array();
1031          if ($template_row['template_storedb'])
1032          {
1033              $ids = array();
1034              if (isset($template_row['template_inherits_id']) && $template_row['template_inherits_id'])
1035              {
1036                  $ids[] = $template_row['template_inherits_id'];
1037              }
1038              $ids[] = $template_row['template_id'];
1039  
1040              $filemtime             = array();
1041              $file_template_db    = array();
1042  
1043              foreach ($ids as $id)
1044              {
1045                  $sql = 'SELECT template_filename, template_mtime
1046                      FROM ' . STYLES_TEMPLATE_DATA_TABLE . "
1047                      WHERE template_id = $id";
1048                  $result = $db->sql_query($sql);
1049  
1050                  while ($row = $db->sql_fetchrow($result))
1051                  {
1052                      $filemtime[$row['template_filename']] = $row['template_mtime'];
1053                      $file_template_db[$row['template_filename']] = $id;
1054                  }
1055                  $db->sql_freeresult($result);
1056              }
1057          }
1058  
1059          // Get a list of cached template files and then retrieve additional information about them
1060          $file_ary = $this->template_cache_filelist($template_row['template_path']);
1061  
1062          foreach ($file_ary as $file)
1063          {
1064              $file        = str_replace('/', '.', $file);
1065  
1066              // perform some dirty guessing to get the path right.
1067              // We assume that three dots in a row were '../'
1068              $tpl_file    = str_replace('.', '/', $file);
1069              $tpl_file    = str_replace('///', '../', $tpl_file);
1070  
1071              $filename = "{$cache_prefix}_$file.html.$phpEx";
1072  
1073              if (!file_exists("{$phpbb_root_path}cache/$filename"))
1074              {
1075                  continue;
1076              }
1077  
1078              $file_tpl = "{$phpbb_root_path}styles/{$template_row['template_path']}/template/$tpl_file.html";
1079              $inherited = false;
1080  
1081              if (isset($template_row['template_inherits_id']) && $template_row['template_inherits_id'])
1082              {
1083                  if (!$template_row['template_storedb'])
1084                  {
1085                      if (!file_exists($file_tpl))
1086                      {
1087                          $file_tpl = "{$phpbb_root_path}styles/{$template_row['template_inherit_path']}/template/$tpl_file.html";
1088                          $inherited = true;
1089                      }
1090                  }
1091                  else
1092                  {
1093                      if ($file_template_db[$file . '.html'] == $template_row['template_inherits_id'])
1094                      {
1095                          $file_tpl = "{$phpbb_root_path}styles/{$template_row['template_inherit_path']}/template/$tpl_file.html";
1096                          $inherited = true;
1097                      }
1098                  }
1099              }
1100  
1101              // Correct the filename if it is stored in database and the file is in a subfolder.
1102              if ($template_row['template_storedb'])
1103              {
1104                  $file = str_replace('.', '/', $file);
1105              }
1106  
1107              $template->assign_block_vars('file', array(
1108                  'U_VIEWSOURCE'    => $this->u_action . "&amp;action=cache&amp;id=$template_id&amp;source=$file",
1109  
1110                  'CACHED'        => $user->format_date(filemtime("{$phpbb_root_path}cache/$filename")),
1111                  'FILENAME'        => $file,
1112                  'FILENAME_PATH'    => $file_tpl,
1113                  'FILESIZE'        => get_formatted_filesize(filesize("{$phpbb_root_path}cache/$filename")),
1114                  'MODIFIED'        => $user->format_date((!$template_row['template_storedb']) ? filemtime($file_tpl) : $filemtime[$file . '.html']))
1115              );
1116          }
1117          unset($filemtime);
1118  
1119          $template->assign_vars(array(
1120              'S_CACHE'            => true,
1121              'S_TEMPLATE'        => true,
1122  
1123              'U_ACTION'            => $this->u_action . "&amp;action=cache&amp;id=$template_id",
1124              'U_BACK'            => $this->u_action)
1125          );
1126      }
1127  
1128      /**
1129      * Provides a css editor and a basic easier to use stylesheet editing tool for less experienced (or lazy) users
1130      *
1131      * @param int $theme_id specifies which theme is being edited
1132      */
1133  	function edit_theme($theme_id)
1134      {
1135          global $phpbb_root_path, $phpEx, $config, $db, $cache, $user, $template, $safe_mode;
1136  
1137          $this->page_title = 'EDIT_THEME';
1138  
1139          $filelist = $filelist_cats = array();
1140  
1141          $theme_data        = utf8_normalize_nfc(request_var('template_data', '', true));
1142          $theme_data        = htmlspecialchars_decode($theme_data);
1143          $theme_file        = utf8_normalize_nfc(request_var('template_file', '', true));
1144          $text_rows        = max(5, min(999, request_var('text_rows', 20)));
1145          $save_changes    = (isset($_POST['save'])) ? true : false;
1146  
1147          // make sure theme_file path doesn't go upwards
1148          $theme_file = str_replace('..', '.', $theme_file);
1149  
1150          // Retrieve some information about the theme
1151          $sql = 'SELECT theme_storedb, theme_path, theme_name, theme_data
1152              FROM ' . STYLES_THEME_TABLE . "
1153              WHERE theme_id = $theme_id";
1154          $result = $db->sql_query($sql);
1155  
1156          if (!($theme_info = $db->sql_fetchrow($result)))
1157          {
1158              trigger_error($user->lang['NO_THEME'] . adm_back_link($this->u_action), E_USER_WARNING);
1159          }
1160          $db->sql_freeresult($result);
1161  
1162          // save changes to the theme if the user submitted any
1163          if ($save_changes)
1164          {
1165              // Get the filesystem location of the current file
1166              $file = "{$phpbb_root_path}styles/{$theme_info['theme_path']}/theme/$theme_file";
1167              $additional = '';
1168              $message = $user->lang['THEME_UPDATED'];
1169  
1170              // If the theme is stored on the filesystem try to write the file else store it in the database
1171              if (!$safe_mode && !$theme_info['theme_storedb'] && file_exists($file) && phpbb_is_writable($file))
1172              {
1173                  if (!($fp = @fopen($file, 'wb')))
1174                  {
1175                      trigger_error($user->lang['NO_THEME'] . adm_back_link($this->u_action), E_USER_WARNING);
1176                  }
1177                  fwrite($fp, $theme_data);
1178                  fclose($fp);
1179              }
1180              else
1181              {
1182                  // Write stylesheet to db
1183                  $sql_ary = array(
1184                      'theme_mtime'        => time(),
1185                      'theme_storedb'        => 1,
1186                      'theme_data'        => $this->db_theme_data($theme_info, $theme_data),
1187                  );
1188                  $sql = 'UPDATE ' . STYLES_THEME_TABLE . '
1189                      SET ' . $db->sql_build_array('UPDATE', $sql_ary) . '
1190                      WHERE theme_id = ' . $theme_id;
1191                  $db->sql_query($sql);
1192  
1193                  $cache->destroy('sql', STYLES_THEME_TABLE);
1194  
1195                  // notify the user if the theme was not stored in the db before his modification
1196                  if (!$theme_info['theme_storedb'])
1197                  {
1198                      add_log('admin', 'LOG_THEME_EDIT_DETAILS', $theme_info['theme_name']);
1199                      $message .= '<br />' . $user->lang['EDIT_THEME_STORED_DB'];
1200                  }
1201              }
1202              $cache->destroy('sql', STYLES_THEME_TABLE);
1203              add_log('admin', (!$theme_info['theme_storedb']) ? 'LOG_THEME_EDIT_FILE' : 'LOG_THEME_EDIT', $theme_info['theme_name'], (!$theme_info['theme_storedb']) ? $theme_file : '');
1204  
1205              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"));
1206          }
1207  
1208          // Generate a category array containing theme filenames
1209          if (!$theme_info['theme_storedb'])
1210          {
1211              $theme_path = "{$phpbb_root_path}styles/{$theme_info['theme_path']}/theme";
1212  
1213              $filelist = filelist($theme_path, '', 'css');
1214  
1215              if ($theme_file)
1216              {
1217                  if (!file_exists($theme_path . "/$theme_file") || !($theme_data = file_get_contents($theme_path . "/$theme_file")))
1218                  {
1219                      trigger_error($user->lang['NO_THEME'] . adm_back_link($this->u_action), E_USER_WARNING);
1220                  }
1221              }
1222          }
1223          else
1224          {
1225              $theme_data = &$theme_info['theme_data'];
1226          }
1227  
1228          // Now create the categories
1229          $filelist_cats[''] = array();
1230          foreach ($filelist as $pathfile => $file_ary)
1231          {
1232              // Use the directory name as category name
1233              if (!empty($pathfile))
1234              {
1235                  $filelist_cats[$pathfile] = array();
1236                  foreach ($file_ary as $file)
1237                  {
1238                      $filelist_cats[$pathfile][$pathfile . $file] = $file;
1239                  }
1240              }
1241              // or if it's in the main category use the word before the first underscore to group files
1242              else
1243              {
1244                  $cats = array();
1245                  foreach ($file_ary as $file)
1246                  {
1247                      $cats[] = substr($file, 0, strpos($file, '_'));
1248                      $filelist_cats[substr($file, 0, strpos($file, '_'))][$file] = $file;
1249                  }
1250  
1251                  $cats = array_values(array_unique($cats));
1252  
1253                  // we don't need any single element categories so put them into the misc '' category
1254                  for ($i = 0, $n = sizeof($cats); $i < $n; $i++)
1255                  {
1256                      if (sizeof($filelist_cats[$cats[$i]]) == 1 && $cats[$i] !== '')
1257                      {
1258                          $filelist_cats[''][key($filelist_cats[$cats[$i]])] = current($filelist_cats[$cats[$i]]);
1259                          unset($filelist_cats[$cats[$i]]);
1260                      }
1261                  }
1262                  unset($cats);
1263              }
1264          }
1265          unset($filelist);
1266  
1267          // Generate list of categorised theme files
1268          $tpl_options = '';
1269          ksort($filelist_cats);
1270          foreach ($filelist_cats as $category => $tpl_ary)
1271          {
1272              ksort($tpl_ary);
1273  
1274              if (!empty($category))
1275              {
1276                  $tpl_options .= '<option class="sep" value="">' . $category . '</option>';
1277              }
1278  
1279              foreach ($tpl_ary as $filename => $file)
1280              {
1281                  $selected = ($theme_file == $filename) ? ' selected="selected"' : '';
1282                  $tpl_options .= '<option value="' . $filename . '"' . $selected . '>' . $file . '</option>';
1283              }
1284          }
1285  
1286          $template->assign_vars(array(
1287              'S_EDIT_THEME'        => true,
1288              'S_HIDDEN_FIELDS'    => build_hidden_fields(array('template_file' => $theme_file)),
1289              'S_THEME_IN_DB'        => $theme_info['theme_storedb'],
1290              'S_TEMPLATES'        => $tpl_options,
1291  
1292              'U_ACTION'            => $this->u_action . "&amp;action=edit&amp;id=$theme_id&amp;text_rows=$text_rows",
1293              'U_BACK'            => $this->u_action,
1294  
1295              'L_EDIT'            => $user->lang['EDIT_THEME'],
1296              'L_EDIT_EXPLAIN'    => $user->lang['EDIT_THEME_EXPLAIN'],
1297              'L_EDITOR'            => $user->lang['THEME_EDITOR'],
1298              'L_EDITOR_HEIGHT'    => $user->lang['THEME_EDITOR_HEIGHT'],
1299              'L_FILE'            => $user->lang['THEME_FILE'],
1300              'L_SELECT'            => $user->lang['SELECT_THEME'],
1301              'L_SELECTED'        => $user->lang['SELECTED_THEME'],
1302              'L_SELECTED_FILE'    => $user->lang['SELECTED_THEME_FILE'],
1303  
1304              'SELECTED_TEMPLATE'    => $theme_info['theme_name'],
1305              'TEMPLATE_FILE'        => $theme_file,
1306              'TEMPLATE_DATA'        => utf8_htmlspecialchars($theme_data),
1307              'TEXT_ROWS'            => $text_rows)
1308          );
1309      }
1310  
1311      /**
1312      * Edit imagesets
1313      *
1314      * @param int $imageset_id specifies which imageset is being edited
1315      */
1316  	function edit_imageset($imageset_id)
1317      {
1318          global $db, $user, $phpbb_root_path, $cache, $template;
1319  
1320          $this->page_title = 'EDIT_IMAGESET';
1321  
1322          if (!$imageset_id)
1323          {
1324              trigger_error($user->lang['NO_IMAGESET'] . adm_back_link($this->u_action), E_USER_WARNING);
1325          }
1326  
1327          $update        = (isset($_POST['update'])) ? true : false;
1328  
1329          $imgname    = request_var('imgname', 'site_logo');
1330          $imgname    = preg_replace('#[^a-z0-9\-+_]#i', '', $imgname);
1331          $sql_extra = $imgnamelang = '';
1332  
1333          $sql = 'SELECT imageset_path, imageset_name
1334              FROM ' . STYLES_IMAGESET_TABLE . "
1335              WHERE imageset_id = $imageset_id";
1336          $result = $db->sql_query($sql);
1337          $imageset_row = $db->sql_fetchrow($result);
1338          $db->sql_freeresult($result);
1339  
1340          if (!$imageset_row)
1341          {
1342              trigger_error($user->lang['NO_IMAGESET'] . adm_back_link($this->u_action), E_USER_WARNING);
1343          }
1344  
1345          $imageset_path        = $imageset_row['imageset_path'];
1346          $imageset_name        = $imageset_row['imageset_name'];
1347  
1348          if (strpos($imgname, '-') !== false)
1349          {
1350              list($imgname, $imgnamelang) = explode('-', $imgname);
1351              $sql_extra = " AND image_lang IN ('" . $db->sql_escape($imgnamelang) . "', '')";
1352          }
1353  
1354          $sql = 'SELECT image_filename, image_width, image_height, image_lang, image_id
1355              FROM ' . STYLES_IMAGESET_DATA_TABLE . "
1356              WHERE imageset_id = $imageset_id
1357                  AND image_name = '" . $db->sql_escape($imgname) . "'$sql_extra";
1358          $result = $db->sql_query($sql);
1359          $imageset_data_row = $db->sql_fetchrow($result);
1360          $db->sql_freeresult($result);
1361  
1362          $image_filename    = $imageset_data_row['image_filename'];
1363          $image_width    = $imageset_data_row['image_width'];
1364          $image_height    = $imageset_data_row['image_height'];
1365          $image_lang        = $imageset_data_row['image_lang'];
1366          $image_id        = $imageset_data_row['image_id'];
1367          $imgsize        = ($imageset_data_row['image_width'] && $imageset_data_row['image_height']) ? 1 : 0;
1368  
1369          // Check to see whether the selected image exists in the table
1370          $valid_name = ($update) ? false : true;
1371  
1372          foreach ($this->imageset_keys as $category => $img_ary)
1373          {
1374              if (in_array($imgname, $img_ary))
1375              {
1376                  $valid_name = true;
1377                  break;
1378              }
1379          }
1380  
1381          if ($update && isset($_POST['imgpath']) && $valid_name)
1382          {
1383              // If imgwidth and imgheight are non-zero grab the actual size
1384              // from the image itself ... we ignore width settings for the poll center image
1385              $imgwidth    = request_var('imgwidth', 0);
1386              $imgheight    = request_var('imgheight', 0);
1387              $imgsize    = request_var('imgsize', 0);
1388              $imgpath    = request_var('imgpath', '');
1389              $imgpath    = str_replace('..', '.', $imgpath);
1390  
1391              // If no dimensions selected, we reset width and height to 0 ;)
1392              if (!$imgsize)
1393              {
1394                  $imgwidth = $imgheight = 0;
1395              }
1396  
1397              $imglang = '';
1398  
1399              if ($imgpath && !file_exists("{$phpbb_root_path}styles/$imageset_path/imageset/$imgpath"))
1400              {
1401                  trigger_error($user->lang['NO_IMAGE_ERROR'] . adm_back_link($this->u_action), E_USER_WARNING);
1402              }
1403  
1404              // Determine width/height. If dimensions included and no width/height given, we detect them automatically...
1405              if ($imgsize && $imgpath)
1406              {
1407                  if (!$imgwidth || !$imgheight)
1408                  {
1409                      list($imgwidth_file, $imgheight_file) = getimagesize("{$phpbb_root_path}styles/$imageset_path/imageset/$imgpath");
1410                      $imgwidth = ($imgwidth) ? $imgwidth : $imgwidth_file;
1411                      $imgheight = ($imgheight) ? $imgheight : $imgheight_file;
1412                  }
1413                  $imgwidth    = ($imgname != 'poll_center') ? (int) $imgwidth : 0;
1414                  $imgheight    = (int) $imgheight;
1415              }
1416  
1417              if (strpos($imgpath, '/') !== false)
1418              {
1419                  list($imglang, $imgfilename) = explode('/', $imgpath);
1420              }
1421              else
1422              {
1423                  $imgfilename = $imgpath;
1424              }
1425  
1426              $sql_ary = array(
1427                  'image_filename'    => (string) $imgfilename,
1428                  'image_width'        => (int) $imgwidth,
1429                  'image_height'        => (int) $imgheight,
1430                  'image_lang'        => (string) $imglang,
1431              );
1432  
1433              // already exists
1434              if ($imageset_data_row)
1435              {
1436                  $sql = 'UPDATE ' . STYLES_IMAGESET_DATA_TABLE . '
1437                      SET ' . $db->sql_build_array('UPDATE', $sql_ary) . "
1438                      WHERE image_id = $image_id";
1439                  $db->sql_query($sql);
1440              }
1441              // does not exist
1442              else if (!$imageset_data_row)
1443              {
1444                  $sql_ary['image_name']    = $imgname;
1445                  $sql_ary['imageset_id']    = (int) $imageset_id;
1446                  $db->sql_query('INSERT INTO ' . STYLES_IMAGESET_DATA_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary));
1447              }
1448  
1449              $cache->destroy('sql', STYLES_IMAGESET_DATA_TABLE);
1450  
1451              add_log('admin', 'LOG_IMAGESET_EDIT', $imageset_name);
1452  
1453              $template->assign_var('SUCCESS', true);
1454  
1455              $image_filename = $imgfilename;
1456              $image_width    = $imgwidth;
1457              $image_height    = $imgheight;
1458              $image_lang        = $imglang;
1459          }
1460  
1461          $imglang = '';
1462          $imagesetlist = array('nolang' => array(), 'lang' => array());
1463          $langs = array();
1464  
1465          $dir = "{$phpbb_root_path}styles/$imageset_path/imageset";
1466          $dp = @opendir($dir);
1467  
1468          if ($dp)
1469          {
1470              while (($file = readdir($dp)) !== false)
1471              {
1472                  if ($file[0] != '.' && strtoupper($file) != 'CVS' && !is_file($dir . '/' . $file) && !is_link($dir . '/' . $file))
1473                  {
1474                      $langs[] = $file;
1475                  }
1476                  else if (preg_match('#\.(?:gif|jpg|png)$#', $file))
1477                  {
1478                      $imagesetlist['nolang'][] = $file;
1479                  }
1480              }
1481  
1482              if ($sql_extra)
1483              {
1484                  $dp2 = @opendir("$dir/$imgnamelang");
1485  
1486                  if ($dp2)
1487                  {
1488                      while (($file2 = readdir($dp2)) !== false)
1489                      {
1490                          if (preg_match('#\.(?:gif|jpg|png)$#', $file2))
1491                          {
1492                              $imagesetlist['lang'][] = "$imgnamelang/$file2";
1493                          }
1494                      }
1495                      closedir($dp2);
1496                  }
1497              }
1498              closedir($dp);
1499          }
1500  
1501          // Generate list of image options
1502          $img_options = '';
1503          foreach ($this->imageset_keys as $category => $img_ary)
1504          {
1505              $template->assign_block_vars('category', array(
1506                  'NAME'            => $user->lang['IMG_CAT_' . strtoupper($category)]
1507              ));
1508  
1509              foreach ($img_ary as $img)
1510              {
1511                  if ($category == 'buttons')
1512                  {
1513                      foreach ($langs as $language)
1514                      {
1515                          $template->assign_block_vars('category.images', array(
1516                              'SELECTED'            => ($img == $imgname && $language == $imgnamelang),
1517                              'VALUE'                => $img . '-' . $language,
1518                              'TEXT'                => $user->lang['IMG_' . strtoupper($img)] . ' [ ' . $language . ' ]'
1519                          ));
1520                      }
1521                  }
1522                  else
1523                  {
1524                      $template->assign_block_vars('category.images', array(
1525                          'SELECTED'            => ($img == $imgname),
1526                          'VALUE'                => $img,
1527                          'TEXT'                => (($category == 'custom') ? $img : $user->lang['IMG_' . strtoupper($img)])
1528                      ));
1529                  }
1530              }
1531          }
1532  
1533          // Make sure the list of possible images is sorted alphabetically
1534          sort($imagesetlist['lang']);
1535          sort($imagesetlist['nolang']);
1536  
1537          $image_found = false;
1538          $img_val = '';
1539          foreach ($imagesetlist as $type => $img_ary)
1540          {
1541              if ($type !== 'lang' || $sql_extra)
1542              {
1543                  $template->assign_block_vars('imagesetlist', array(
1544                      'TYPE'    => ($type == 'lang')
1545                  ));
1546              }
1547  
1548              foreach ($img_ary as $img)
1549              {
1550                  $imgtext = preg_replace('/^([^\/]+\/)/', '', $img);
1551                  $selected = (!empty($imgname) && strpos($image_filename, $imgtext) !== false);
1552                  if ($selected)
1553                  {
1554                      $image_found = true;
1555                      $img_val = htmlspecialchars($img);
1556                  }
1557                  $template->assign_block_vars('imagesetlist.images', array(
1558                      'SELECTED'            => $selected,
1559                      'TEXT'                => $imgtext,
1560                      'VALUE'                => htmlspecialchars($img)
1561                  ));
1562              }
1563          }
1564  
1565          $imgsize_bool = (!empty($imgname) && $image_width && $image_height) ? true : false;
1566          $image_request = '../styles/' . $imageset_path . '/imageset/' . ($image_lang ? $imgnamelang . '/' : '') . $image_filename;
1567  
1568          $template->assign_vars(array(
1569              'S_EDIT_IMAGESET'    => true,
1570              'L_TITLE'            => $user->lang[$this->page_title],
1571              'L_EXPLAIN'            => $user->lang[$this->page_title . '_EXPLAIN'],
1572              'IMAGE_OPTIONS'        => $img_options,
1573              'IMAGE_SIZE'        => $image_width,
1574              'IMAGE_HEIGHT'        => $image_height,
1575              'IMAGE_REQUEST'        => (empty($image_filename)) ? 'images/no_image.png' : $image_request,
1576              'U_ACTION'            => $this->u_action . "&amp;action=edit&amp;id=$imageset_id",
1577              'U_BACK'            => $this->u_action,
1578              'NAME'                => $imageset_name,
1579              'A_NAME'            => addslashes($imageset_name),
1580              'PATH'                => $imageset_path,
1581              'A_PATH'            => addslashes($imageset_path),
1582              'ERROR'                => !$valid_name,
1583              'IMG_SRC'            => ($image_found) ? '../styles/' . $imageset_path . '/imageset/' . $img_val : 'images/no_image.png',
1584              'IMAGE_SELECT'        => $image_found
1585          ));
1586      }
1587  
1588      /**
1589      * Remove style/template/theme/imageset
1590      */
1591  	function remove($mode, $style_id)
1592      {
1593          global $db, $template, $user, $phpbb_root_path, $cache, $config;
1594  
1595          $new_id = request_var('new_id', 0);
1596          $update = (isset($_POST['update'])) ? true : false;
1597          $sql_where = '';
1598  
1599          switch ($mode)
1600          {
1601              case 'style':
1602                  $sql_from = STYLES_TABLE;
1603                  $sql_select = 'style_id, style_name, template_id, theme_id, imageset_id';
1604                  $sql_where = 'AND style_active = 1';
1605              break;
1606  
1607              case 'template':
1608                  $sql_from = STYLES_TEMPLATE_TABLE;
1609                  $sql_select = 'template_id, template_name, template_path, template_storedb';
1610              break;
1611  
1612              case 'theme':
1613                  $sql_from = STYLES_THEME_TABLE;
1614                  $sql_select = 'theme_id, theme_name, theme_path, theme_storedb';
1615              break;
1616  
1617              case 'imageset':
1618                  $sql_from = STYLES_IMAGESET_TABLE;
1619                  $sql_select = 'imageset_id, imageset_name, imageset_path';
1620              break;
1621          }
1622  
1623          if ($mode === 'template' && ($conflicts = $this->check_inheritance($mode, $style_id)))
1624          {
1625              $l_type = strtoupper($mode);
1626              $msg = $user->lang[$l_type . '_DELETE_DEPENDENT'];
1627              foreach ($conflicts as $id => $values)
1628              {
1629                  $msg .= '<br />' . $values['template_name'];
1630              }
1631  
1632              trigger_error($msg . adm_back_link($this->u_action), E_USER_WARNING);
1633          }
1634  
1635          $l_prefix = strtoupper($mode);
1636  
1637          $sql = "SELECT $sql_select
1638              FROM $sql_from
1639              WHERE {$mode}_id = $style_id";
1640          $result = $db->sql_query($sql);
1641          $style_row = $db->sql_fetchrow($result);
1642          $db->sql_freeresult($result);
1643  
1644          if (!$style_row)
1645          {
1646              trigger_error($user->lang['NO_' . $l_prefix] . adm_back_link($this->u_action), E_USER_WARNING);
1647          }
1648  
1649          $s_only_component = $this->display_component_options($mode, $style_row[$mode . '_id'], $style_row);
1650  
1651          if ($s_only_component)
1652          {
1653              trigger_error($user->lang['ONLY_' . $l_prefix] . adm_back_link($this->u_action), E_USER_WARNING);
1654          }
1655  
1656          if ($update)
1657          {
1658              if ($mode == 'style')
1659              {
1660                  $sql = "DELETE FROM $sql_from
1661                      WHERE {$mode}_id = $style_id";
1662                  $db->sql_query($sql);
1663  
1664                  $sql = 'UPDATE ' . USERS_TABLE . "
1665                      SET user_style = $new_id
1666                      WHERE user_style = $style_id";
1667                  $db->sql_query($sql);
1668  
1669                  $sql = 'UPDATE ' . FORUMS_TABLE . "
1670                      SET forum_style = $new_id
1671                      WHERE forum_style = $style_id";
1672                  $db->sql_query($sql);
1673  
1674                  if ($style_id == $config['default_style'])
1675                  {
1676                      set_config('default_style', $new_id);
1677                  }
1678  
1679                  // Remove the components
1680                  $components = array('template', 'theme', 'imageset');
1681                  foreach ($components as $component)
1682                  {
1683                      $new_id = request_var('new_' . $component . '_id', 0);
1684                      $component_id = $style_row[$component . '_id'];
1685                      $this->remove_component($component, $component_id, $new_id, $style_id);
1686                  }
1687              }
1688              else
1689              {
1690                  $this->remove_component($mode, $style_id, $new_id);
1691              }
1692  
1693              $cache->destroy('sql', STYLES_TABLE);
1694  
1695              add_log('admin', 'LOG_' . $l_prefix . '_DELETE', $style_row[$mode . '_name']);
1696              $message = ($mode != 'style') ? $l_prefix . '_DELETED_FS' : $l_prefix . '_DELETED';
1697              trigger_error($user->lang[$message] . adm_back_link($this->u_action));
1698          }
1699  
1700          $this->page_title = 'DELETE_' . $l_prefix;
1701  
1702          $template->assign_vars(array(
1703              'S_DELETE'            => true,
1704  
1705              'L_TITLE'            => $user->lang[$this->page_title],
1706              'L_EXPLAIN'            => $user->lang[$this->page_title . '_EXPLAIN'],
1707              'L_NAME'            => $user->lang[$l_prefix . '_NAME'],
1708              'L_REPLACE'            => $user->lang['REPLACE_' . $l_prefix],
1709              'L_REPLACE_EXPLAIN'    => $user->lang['REPLACE_' . $l_prefix . '_EXPLAIN'],
1710  
1711              'U_ACTION'        => $this->u_action . "&amp;action=delete&amp;id=$style_id",
1712              'U_BACK'        => $this->u_action,
1713  
1714              'NAME'            => $style_row[$mode . '_name'],
1715              )
1716          );
1717  
1718          if ($mode == 'style')
1719          {
1720              $template->assign_vars(array(
1721                  'S_DELETE_STYLE'        => true,
1722              ));
1723          }
1724      }
1725  
1726      /**
1727      * Remove template/theme/imageset entry from the database
1728      */
1729  	function remove_component($component, $component_id, $new_id, $style_id = false)
1730      {
1731          global $db;
1732  
1733          if (($new_id == 0) || ($component === 'template' && ($conflicts = $this->check_inheritance($component, $component_id))))
1734          {
1735              // We can not delete the template, as the user wants to keep the component or an other template is inheriting from this one.
1736              return;
1737          }
1738  
1739          $component_in_use = array();
1740          if ($component != 'style')
1741          {
1742              $component_in_use = $this->component_in_use($component, $component_id, $style_id);
1743          }
1744  
1745          if (($new_id == -1) && !empty($component_in_use))
1746          {
1747              // We can not delete the component, as it is still in use
1748              return;
1749          }
1750  
1751          if ($component == 'imageset')
1752          {
1753              $sql = 'DELETE FROM ' . STYLES_IMAGESET_DATA_TABLE . "
1754                  WHERE imageset_id = $component_id";
1755              $db->sql_query($sql);
1756          }
1757  
1758          switch ($component)
1759          {
1760              case 'template':
1761                  $sql_from = STYLES_TEMPLATE_TABLE;
1762              break;
1763  
1764              case 'theme':
1765                  $sql_from = STYLES_THEME_TABLE;
1766              break;
1767  
1768              case 'imageset':
1769                  $sql_from = STYLES_IMAGESET_TABLE;;
1770              break;
1771          }
1772  
1773          $sql = "DELETE FROM $sql_from
1774              WHERE {$component}_id = $component_id";
1775          $db->sql_query($sql);
1776  
1777          $sql = 'UPDATE ' . STYLES_TABLE . "
1778              SET {$component}_id = $new_id
1779              WHERE {$component}_id = $component_id";
1780          $db->sql_query($sql);
1781      }
1782  
1783      /**
1784      * Display the options which can be used to replace a style/template/theme/imageset
1785      *
1786      * @return boolean Returns true if the component is the only component and can not be deleted.
1787      */
1788  	function display_component_options($component, $component_id, $style_row = false, $style_id = false)
1789      {
1790          global $db, $template, $user;
1791  
1792          $is_only_component = true;
1793          $component_in_use = array();
1794          if ($component != 'style')
1795          {
1796              $component_in_use = $this->component_in_use($component, $component_id, $style_id);
1797          }
1798  
1799          $sql_where = '';
1800          switch ($component)
1801          {
1802              case 'style':
1803                  $sql_from = STYLES_TABLE;
1804                  $sql_where = 'WHERE style_active = 1';
1805              break;
1806  
1807              case 'template':
1808                  $sql_from = STYLES_TEMPLATE_TABLE;
1809                  $sql_where = 'WHERE template_inherits_id <> ' . $component_id;
1810              break;
1811  
1812              case 'theme':
1813                  $sql_from = STYLES_THEME_TABLE;
1814              break;
1815  
1816              case 'imageset':
1817                  $sql_from = STYLES_IMAGESET_TABLE;
1818              break;
1819          }
1820  
1821          $s_options = '';
1822          if (($component != 'style') && empty($component_in_use))
1823          {
1824              // If it is not in use, there must be another component
1825              $is_only_component = false;
1826  
1827              $sql = "SELECT {$component}_id, {$component}_name
1828                  FROM $sql_from
1829                  WHERE {$component}_id = {$component_id}";
1830              $result = $db->sql_query($sql);
1831              $row = $db->sql_fetchrow($result);
1832              $db->sql_freeresult($result);
1833  
1834              $s_options .= '<option value="-1" selected="selected">' . $user->lang['DELETE_' . strtoupper($component)] . '</option>';
1835              $s_options .= '<option value="0">' . sprintf($user->lang['KEEP_' . strtoupper($component)], $row[$component . '_name']) . '</option>';
1836          }
1837          else
1838          {
1839              $sql = "SELECT {$component}_id, {$component}_name
1840                  FROM $sql_from
1841                  $sql_where
1842                  ORDER BY {$component}_name ASC";
1843              $result = $db->sql_query($sql);
1844  
1845              $s_keep_option = $s_options = '';
1846              while ($row = $db->sql_fetchrow($result))
1847              {
1848                  if ($row[$component . '_id'] != $component_id)
1849                  {
1850                      $is_only_component = false;
1851                      $s_options .= '<option value="' . $row[$component . '_id'] . '">' . sprintf($user->lang['REPLACE_WITH_OPTION'], $row[$component . '_name']) . '</option>';
1852                  }
1853                  else if ($component != 'style')
1854                  {
1855                      $s_keep_option = '<option value="0" selected="selected">' . sprintf($user->lang['KEEP_' . strtoupper($component)], $row[$component . '_name']) . '</option>';
1856                  }
1857              }
1858              $db->sql_freeresult($result);
1859              $s_options = $s_keep_option . $s_options;
1860          }
1861  
1862          if (!$style_row)
1863          {
1864              $template->assign_var('S_REPLACE_' . strtoupper($component) . '_OPTIONS', $s_options);
1865          }
1866          else
1867          {
1868              $template->assign_var('S_REPLACE_OPTIONS', $s_options);
1869              if ($component == 'style')
1870              {
1871                  $components = array('template', 'theme', 'imageset');
1872                  foreach ($components as $component)
1873                  {
1874                      $this->display_component_options($component, $style_row[$component . '_id'], false, $component_id, true);
1875                  }
1876              }
1877          }
1878  
1879          return $is_only_component;
1880      }
1881  
1882      /**
1883      * Check whether the component is still used by another style or component
1884      */
1885  	function component_in_use($component, $component_id, $style_id = false)
1886      {
1887          global $db;
1888  
1889          $component_in_use = array();
1890  
1891          if ($style_id)
1892          {
1893              $sql = 'SELECT style_id, style_name
1894                  FROM ' . STYLES_TABLE . "
1895                  WHERE {$component}_id = {$component_id}
1896                      AND style_id <> {$style_id}
1897                  ORDER BY style_name ASC";
1898          }
1899          else
1900          {
1901              $sql = 'SELECT style_id, style_name
1902                  FROM ' . STYLES_TABLE . "
1903                  WHERE {$component}_id = {$component_id}
1904                  ORDER BY style_name ASC";
1905          }
1906          $result = $db->sql_query($sql);
1907          while ($row = $db->sql_fetchrow($result))
1908          {
1909              $component_in_use[] = $row['style_name'];
1910          }
1911          $db->sql_freeresult($result);
1912  
1913          if ($component === 'template' && ($conflicts = $this->check_inheritance($component, $component_id)))
1914          {
1915              foreach ($conflicts as $temp_id => $conflict_data)
1916              {
1917                  $component_in_use[] = $conflict_data['template_name'];
1918              }
1919          }
1920  
1921          return $component_in_use;
1922      }
1923  
1924      /**
1925      * Export style or style elements
1926      */
1927  	function export($mode, $style_id)
1928      {
1929          global $db, $template, $user, $phpbb_root_path, $cache, $phpEx, $config;
1930  
1931          $update = (isset($_POST['update'])) ? true : false;
1932  
1933          $inc_template = request_var('inc_template', 0);
1934          $inc_theme = request_var('inc_theme', 0);
1935          $inc_imageset = request_var('inc_imageset', 0);
1936          $store = request_var('store', 0);
1937          $format = request_var('format', '');
1938  
1939          $error = array();
1940          $methods = array('tar');
1941  
1942          $available_methods = array('tar.gz' => 'zlib', 'tar.bz2' => 'bz2', 'zip' => 'zlib');
1943          foreach ($available_methods as $type => $module)
1944          {
1945              if (!@extension_loaded($module))
1946              {
1947                  continue;
1948              }
1949  
1950              $methods[] = $type;
1951          }
1952  
1953          if (!in_array($format, $methods))
1954          {
1955              $format = 'tar';
1956          }
1957  
1958          switch ($mode)
1959          {
1960              case 'style':
1961                  if ($update && ($inc_template + $inc_theme + $inc_imageset) < 1)
1962                  {
1963                      $error[] = $user->lang['STYLE_ERR_MORE_ELEMENTS'];
1964                  }
1965  
1966                  $name = 'style_name';
1967  
1968                  $sql_select = 's.style_id, s.style_name, s.style_copyright';
1969                  $sql_select .= ($inc_template) ? ', t.*' : ', t.template_name';
1970                  $sql_select .= ($inc_theme) ? ', c.*' : ', c.theme_name';
1971                  $sql_select .= ($inc_imageset) ? ', i.*' : ', i.imageset_name';
1972                  $sql_from = STYLES_TABLE . ' s, ' . STYLES_TEMPLATE_TABLE . ' t, ' . STYLES_THEME_TABLE . ' c, ' . STYLES_IMAGESET_TABLE . ' i';
1973                  $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";
1974  
1975                  $l_prefix = 'STYLE';
1976              break;
1977  
1978              case 'template':
1979                  $name = 'template_name';
1980  
1981                  $sql_select = '*';
1982                  $sql_from = STYLES_TEMPLATE_TABLE;
1983                  $sql_where = "template_id = $style_id";
1984  
1985                  $l_prefix = 'TEMPLATE';
1986              break;
1987  
1988              case 'theme':
1989                  $name = 'theme_name';
1990  
1991                  $sql_select = '*';
1992                  $sql_from = STYLES_THEME_TABLE;
1993                  $sql_where = "theme_id = $style_id";
1994  
1995                  $l_prefix = 'THEME';
1996              break;
1997  
1998              case 'imageset':
1999                  $name = 'imageset_name';
2000  
2001                  $sql_select = '*';
2002                  $sql_from = STYLES_IMAGESET_TABLE;
2003                  $sql_where = "imageset_id = $style_id";
2004  
2005                  $l_prefix = 'IMAGESET';
2006              break;
2007          }
2008  
2009          if ($update && !sizeof($error))
2010          {
2011              $sql = "SELECT $sql_select
2012                  FROM $sql_from
2013                  WHERE $sql_where";
2014              $result = $db->sql_query($sql);
2015              $style_row = $db->sql_fetchrow($result);
2016              $db->sql_freeresult($result);
2017  
2018              if (!$style_row)
2019              {
2020                  trigger_error($user->lang['NO_' . $l_prefix] . adm_back_link($this->u_action), E_USER_WARNING);
2021              }
2022  
2023              $var_ary = array('style_id', 'style_name', 'style_copyright', 'template_id', 'template_name', 'template_path', 'template_copyright', 'template_storedb', 'template_inherits_id', 'bbcode_bitfield', 'theme_id', 'theme_name', 'theme_path', 'theme_copyright', 'theme_storedb', 'theme_mtime', 'theme_data', 'imageset_id', 'imageset_name', 'imageset_path', 'imageset_copyright');
2024  
2025              foreach ($var_ary as $var)
2026              {
2027                  if (!isset($style_row[$var]))
2028                  {
2029                      $style_row[$var] = '';
2030                  }
2031              }
2032  
2033              $files = $data = array();
2034  
2035              if ($mode == 'style')
2036              {
2037                  $style_cfg = str_replace(array('{MODE}', '{NAME}', '{COPYRIGHT}', '{VERSION}'), array($mode, $style_row['style_name'], $style_row['style_copyright'], $config['version']), $this->style_cfg);
2038  
2039                  $style_cfg .= (!$inc_template) ? "\nrequired_template = {$style_row['template_name']}" : '';
2040                  $style_cfg .= (!$inc_theme) ? "\nrequired_theme = {$style_row['theme_name']}" : '';
2041                  $style_cfg .= (!$inc_imageset) ? "\nrequired_imageset = {$style_row['imageset_name']}" : '';
2042  
2043                  $data[] = array(
2044                      'src'        => $style_cfg,
2045                      'prefix'    => 'style.cfg'
2046                  );
2047  
2048                  unset($style_cfg);
2049              }
2050  
2051              // Export template core code
2052              if ($mode == 'template' || $inc_template)
2053              {
2054                  $use_template_name = $style_row['template_name'];
2055  
2056                  // Add the inherit from variable, depending on it's use...
2057                  if ($style_row['template_inherits_id'])
2058                  {
2059                      // Get the template name
2060                      $sql = 'SELECT template_name
2061                          FROM ' . STYLES_TEMPLATE_TABLE . '
2062                          WHERE template_id = ' . (int) $style_row['template_inherits_id'];
2063                      $result = $db->sql_query($sql);
2064                      $use_template_name = (string) $db->sql_fetchfield('template_name');
2065                      $db->sql_freeresult($result);
2066                  }
2067  
2068                  $template_cfg = str_replace(array('{MODE}', '{NAME}', '{COPYRIGHT}', '{VERSION}', '{INHERIT_FROM}'), array($mode, $style_row['template_name'], $style_row['template_copyright'], $config['version'], $use_template_name), $this->template_cfg);
2069  
2070                  $template_cfg .= "\n\nbbcode_bitfield = {$style_row['bbcode_bitfield']}";
2071  
2072                  $data[] = array(
2073                      'src'        => $template_cfg,
2074                      'prefix'    => 'template/template.cfg'
2075                  );
2076  
2077                  // This is potentially nasty memory-wise ...
2078                  if (!$style_row['template_storedb'])
2079                  {
2080                      $files[] = array(
2081                          'src'        => "styles/{$style_row['template_path']}/template/",
2082                          'prefix-'    => "styles/{$style_row['template_path']}/",
2083                          'prefix+'    => false,
2084                          'exclude'    => 'template.cfg'
2085                      );
2086                  }
2087                  else
2088                  {
2089                      $sql = 'SELECT template_filename, template_data
2090                          FROM ' . STYLES_TEMPLATE_DATA_TABLE . "
2091                          WHERE template_id = {$style_row['template_id']}";
2092                      $result = $db->sql_query($sql);
2093  
2094                      while ($row = $db->sql_fetchrow($result))
2095                      {
2096                          $data[] = array(
2097                              'src' => $row['template_data'],
2098                              'prefix' => 'template/' . $row['template_filename']
2099                          );
2100                      }
2101                      $db->sql_freeresult($result);
2102                  }
2103                  unset($template_cfg);
2104              }
2105  
2106              // Export theme core code
2107              if ($mode == 'theme' || $inc_theme)
2108              {
2109                  $theme_cfg = str_replace(array('{MODE}', '{NAME}', '{COPYRIGHT}', '{VERSION}'), array($mode, $style_row['theme_name'], $style_row['theme_copyright'], $config['version']), $this->theme_cfg);
2110  
2111                  // Read old cfg file
2112                  $items = $cache->obtain_cfg_items($style_row);
2113                  $items = $items['theme'];
2114  
2115                  if (!isset($items['parse_css_file']))
2116                  {
2117                      $items['parse_css_file'] = 'off';
2118                  }
2119  
2120                  $theme_cfg = str_replace(array('{PARSE_CSS_FILE}'), array($items['parse_css_file']), $theme_cfg);
2121  
2122                  $files[] = array(
2123                      'src'        => "styles/{$style_row['theme_path']}/theme/",
2124                      'prefix-'    => "styles/{$style_row['theme_path']}/",
2125                      'prefix+'    => false,
2126                      'exclude'    => ($style_row['theme_storedb']) ? 'stylesheet.css,theme.cfg' : 'theme.cfg'
2127                  );
2128  
2129                  $data[] = array(
2130                      'src'        => $theme_cfg,
2131                      'prefix'    => 'theme/theme.cfg'
2132                  );
2133  
2134                  if ($style_row['theme_storedb'])
2135                  {
2136                      $data[] = array(
2137                          'src'        => $style_row['theme_data'],
2138                          'prefix'    => 'theme/stylesheet.css'
2139                      );
2140                  }
2141  
2142                  unset($items, $theme_cfg);
2143              }
2144  
2145              // Export imageset core code
2146              if ($mode == 'imageset' || $inc_imageset)
2147              {
2148                  $imageset_cfg = str_replace(array('{MODE}', '{NAME}', '{COPYRIGHT}', '{VERSION}'), array($mode, $style_row['imageset_name'], $style_row['imageset_copyright'], $config['version']), $this->imageset_cfg);
2149  
2150                  $imageset_main = array();
2151  
2152                  $sql = 'SELECT image_filename, image_name, image_height, image_width
2153                      FROM ' . STYLES_IMAGESET_DATA_TABLE . "
2154                      WHERE imageset_id = $style_id
2155                          AND image_lang = ''";
2156                  $result = $db->sql_query($sql);
2157                  while ($row = $db->sql_fetchrow($result))
2158                  {
2159                      $imageset_main[$row['image_name']] = $row['image_filename'] . ($row['image_height'] ? '*' . $row['image_height']: '') . ($row['image_width'] ? '*' . $row['image_width']: '');
2160                  }
2161                  $db->sql_freeresult($result);
2162  
2163                  foreach ($this->imageset_keys as $topic => $key_array)
2164                  {
2165                      foreach ($key_array as $key)
2166                      {
2167                          if (isset($imageset_main[$key]))
2168                          {
2169                              $imageset_cfg .= "\nimg_" . $key . ' = ' . str_replace("styles/{$style_row['imageset_path']}/imageset/", '{PATH}', $imageset_main[$key]);
2170                          }
2171                      }
2172                  }
2173  
2174                  $files[] = array(
2175                      'src'        => "styles/{$style_row['imageset_path']}/imageset/",
2176                      'prefix-'    => "styles/{$style_row['imageset_path']}/",
2177                      'prefix+'    => false,
2178                      'exclude'    => 'imageset.cfg'
2179                  );
2180  
2181                  $data[] = array(
2182                      'src'        => trim($imageset_cfg),
2183                      'prefix'    => 'imageset/imageset.cfg'
2184                  );
2185  
2186                  end($data);
2187  
2188                  $imageset_root = "{$phpbb_root_path}styles/{$style_row['imageset_path']}/imageset/";
2189  
2190                  if ($dh = @opendir($imageset_root))
2191                  {
2192                      while (($fname = readdir($dh)) !== false)
2193                      {
2194                          if ($fname[0] != '.' && $fname != 'CVS' && is_dir("$imageset_root$fname"))
2195                          {
2196                              $files[key($files)]['exclude'] .= ',' . $fname . '/imageset.cfg';
2197                          }
2198                      }
2199                      closedir($dh);
2200                  }
2201  
2202                  $imageset_lang = array();
2203  
2204                  $sql = 'SELECT image_filename, image_name, image_height, image_width, image_lang
2205                      FROM ' . STYLES_IMAGESET_DATA_TABLE . "
2206                      WHERE imageset_id = $style_id
2207                          AND image_lang <> ''";
2208                  $result = $db->sql_query($sql);
2209                  while ($row = $db->sql_fetchrow($result))
2210                  {
2211                      $imageset_lang[$row['image_lang']][$row['image_name']] = $row['image_filename'] . ($row['image_height'] ? '*' . $row['image_height']: '') . ($row['image_width'] ? '*' . $row['image_width']: '');
2212                  }
2213                  $db->sql_freeresult($result);
2214  
2215                  foreach ($imageset_lang as $lang => $imageset_localized)
2216                  {
2217                      $imageset_cfg = str_replace(array('{MODE}', '{NAME}', '{COPYRIGHT}', '{VERSION}'), array($mode, $style_row['imageset_name'], $style_row['imageset_copyright'], $config['version']), $this->imageset_cfg);
2218  
2219                      foreach ($this->imageset_keys as $topic => $key_array)
2220                      {
2221                          foreach ($key_array as $key)
2222                          {
2223                              if (isset($imageset_localized[$key]))
2224                              {
2225                                  $imageset_cfg .= "\nimg_" . $key . ' = ' . str_replace("styles/{$style_row['imageset_path']}/imageset/", '{PATH}', $imageset_localized[$key]);
2226                              }
2227                          }
2228                      }
2229  
2230                      $data[] = array(
2231                          'src'        => trim($imageset_cfg),
2232                          'prefix'    => 'imageset/' . $lang . '/imageset.cfg'
2233                      );
2234                  }
2235  
2236                  unset($imageset_cfg);
2237              }
2238  
2239              switch ($format)
2240              {
2241                  case 'tar':
2242                      $ext = '.tar';
2243                  break;
2244  
2245                  case 'zip':
2246                      $ext = '.zip';
2247                  break;
2248  
2249                  case 'tar.gz':
2250                      $ext = '.tar.gz';
2251                  break;
2252  
2253                  case 'tar.bz2':
2254                      $ext = '.tar.bz2';
2255                  break;
2256  
2257                  default:
2258                      $error[] = $user->lang[$l_prefix . '_ERR_ARCHIVE'];
2259              }
2260  
2261              if (!sizeof($error))
2262              {
2263                  include($phpbb_root_path . 'includes/functions_compress.' . $phpEx);
2264  
2265                  if ($mode == 'style')
2266                  {
2267                      $path = preg_replace('#[^\w-]+#', '_', $style_row['style_name']);
2268                  }
2269                  else
2270                  {
2271                      $path = $style_row[$mode . '_path'];
2272                  }
2273  
2274                  if ($format == 'zip')
2275                  {
2276                      $compress = new compress_zip('w', $phpbb_root_path . "store/$path$ext");
2277                  }
2278                  else
2279                  {
2280                      $compress = new compress_tar('w', $phpbb_root_path . "store/$path$ext", $ext);
2281                  }
2282  
2283                  if (sizeof($files))
2284                  {
2285                      foreach ($files as $file_ary)
2286                      {
2287                          $compress->add_file($file_ary['src'], $file_ary['prefix-'], $file_ary['prefix+'], $file_ary['exclude']);
2288                      }
2289                  }
2290  
2291                  if (sizeof($data))
2292                  {
2293                      foreach ($data as $data_ary)
2294                      {
2295                          $compress->add_data($data_ary['src'], $data_ary['prefix']);
2296                      }
2297                  }
2298  
2299                  $compress->close();
2300  
2301                  add_log('admin', 'LOG_' . $l_prefix . '_EXPORT', $style_row[$mode . '_name']);
2302  
2303                  if (!$store)
2304                  {
2305                      $compress->download($path);
2306                      @unlink("{$phpbb_root_path}store/$path$ext");
2307                      exit;
2308                  }
2309  
2310                  trigger_error(sprintf($user->lang[$l_prefix . '_EXPORTED'], "store/$path$ext") . adm_back_link($this->u_action));
2311              }
2312          }
2313  
2314          $sql = "SELECT {$mode}_id, {$mode}_name
2315              FROM " . (($mode == 'style') ? STYLES_TABLE : $sql_from) . "
2316              WHERE {$mode}_id = $style_id";
2317          $result = $db->sql_query($sql);
2318          $style_row = $db->sql_fetchrow($result);
2319          $db->sql_freeresult($result);
2320  
2321          if (!$style_row)
2322          {
2323              trigger_error($user->lang['NO_' . $l_prefix] . adm_back_link($this->u_action), E_USER_WARNING);
2324          }
2325  
2326          $this->page_title = $l_prefix . '_EXPORT';
2327  
2328          $format_buttons = '';
2329          foreach ($methods as $method)
2330          {
2331              $format_buttons .= '<label><input type="radio"' . ((!$format_buttons) ? ' id="format"' : '') . ' class="radio" value="' . $method . '" name="format"' . (($method == $format) ? ' checked="checked"' : '') . ' /> ' . $method . '</label>';
2332          }
2333  
2334          $template->assign_vars(array(
2335              'S_EXPORT'        => true,
2336              'S_ERROR_MSG'    => (sizeof($error)) ? true : false,
2337              'S_STYLE'        => ($mode == 'style') ? true : false,
2338  
2339              'L_TITLE'        => $user->lang[$this->page_title],
2340              'L_EXPLAIN'        => $user->lang[$this->page_title . '_EXPLAIN'],
2341              'L_NAME'        => $user->lang[$l_prefix . '_NAME'],
2342  
2343              'U_ACTION'        => $this->u_action . '&amp;action=export&amp;id=' . $style_id,
2344              'U_BACK'        => $this->u_action,
2345  
2346              'ERROR_MSG'            => (sizeof($error)) ? implode('<br />', $error) : '',
2347              'NAME'                => $style_row[$mode . '_name'],
2348              'FORMAT_BUTTONS'    => $format_buttons)
2349          );
2350      }
2351  
2352      /**
2353      * Display details
2354      */
2355  	function details($mode, $style_id)
2356      {
2357          global $template, $db, $config, $user, $safe_mode, $cache, $phpbb_root_path;
2358  
2359          $update = (isset($_POST['update'])) ? true : false;
2360          $l_type = strtoupper($mode);
2361  
2362          $error = array();
2363          $element_ary = array('template' => STYLES_TEMPLATE_TABLE, 'theme' => STYLES_THEME_TABLE, 'imageset' => STYLES_IMAGESET_TABLE);
2364  
2365          switch ($mode)
2366          {
2367              case 'style':
2368                  $sql_from = STYLES_TABLE;
2369              break;
2370  
2371              case 'template':
2372                  $sql_from = STYLES_TEMPLATE_TABLE;
2373              break;
2374  
2375              case 'theme':
2376                  $sql_from = STYLES_THEME_TABLE;
2377              break;
2378  
2379              case 'imageset':
2380                  $sql_from = STYLES_IMAGESET_TABLE;
2381              break;
2382          }
2383  
2384          $sql = "SELECT *
2385              FROM $sql_from
2386              WHERE {$mode}_id = $style_id";
2387          $result = $db->sql_query($sql);
2388          $style_row = $db->sql_fetchrow($result);
2389          $db->sql_freeresult($result);
2390  
2391          if (!$style_row)
2392          {
2393              trigger_error($user->lang['NO_' . $l_type] . adm_back_link($this->u_action), E_USER_WARNING);
2394          }
2395  
2396          $style_row['style_default'] = ($mode == 'style' && $config['default_style'] == $style_id) ? 1 : 0;
2397  
2398          if ($update)
2399          {
2400              $name = utf8_normalize_nfc(request_var('name', '', true));
2401              $copyright = utf8_normalize_nfc(request_var('copyright', '', true));
2402  
2403              $template_id = request_var('template_id', 0);
2404              $theme_id = request_var('theme_id', 0);
2405              $imageset_id = request_var('imageset_id', 0);
2406  
2407              $style_active = request_var('style_active', 0);
2408              $style_default = request_var('style_default', 0);
2409              $store_db = request_var('store_db', 0);
2410  
2411              // If the admin selected the style to be the default style, but forgot to activate it... we will do it for him
2412              if ($style_default)
2413              {
2414                  $style_active = 1;
2415              }
2416  
2417              $sql = "SELECT {$mode}_id, {$mode}_name
2418                  FROM $sql_from
2419                  WHERE {$mode}_id <> $style_id
2420                  AND LOWER({$mode}_name) = '" . $db->sql_escape(strtolower($name)) . "'";
2421              $result = $db->sql_query($sql);
2422              $conflict = $db->sql_fetchrow($result);
2423              $db->sql_freeresult($result);
2424  
2425              if ($mode == 'style' && (!$template_id || !$theme_id || !$imageset_id))
2426              {
2427                  $error[] = $user->lang['STYLE_ERR_NO_IDS'];
2428              }
2429  
2430              if ($mode == 'style' && $style_row['style_active'] && !$style_active && $config['default_style'] == $style_id)
2431              {
2432                  $error[] = $user->lang['DEACTIVATE_DEFAULT'];
2433              }
2434  
2435              if (!$name || $conflict)
2436              {
2437                  $error[] = $user->lang[$l_type . '_ERR_STYLE_NAME'];
2438              }
2439  
2440              if ($mode === 'theme' || $mode === 'template')
2441              {
2442                  // a rather elaborate check we have to do here once to avoid trouble later
2443                  $check = "{$phpbb_root_path}styles/" . $style_row["{$mode}_path"] . (($mode === 'theme') ? '/theme/stylesheet.css' : '/template');
2444                  if (($style_row["{$mode}_storedb"] != $store_db) && !$store_db && ($safe_mode || !phpbb_is_writable($check)))
2445                  {
2446                      $error[] = $user->lang['EDIT_' . strtoupper($mode) . '_STORED_DB'];
2447                      $store_db = 1;
2448                  }
2449  
2450                  // themes which have to be parsed have to go into db
2451                  if ($mode == 'theme')
2452                  {
2453                      $cfg = parse_cfg_file("{$phpbb_root_path}styles/" . $style_row["{$mode}_path"] . "/theme/theme.cfg");
2454  
2455                      if (isset($cfg['parse_css_file']) && $cfg['parse_css_file'] && !$store_db)
2456                      {
2457                          $error[] = $user->lang['EDIT_THEME_STORE_PARSED'];
2458                          $store_db = 1;
2459                      }
2460                  }
2461              }
2462  
2463              if (!sizeof($error))
2464              {
2465                  // Check length settings
2466                  if (utf8_strlen($name) > 30)
2467                  {
2468                      $error[] = $user->lang[$l_type . '_ERR_NAME_LONG'];
2469                  }
2470  
2471                  if (utf8_strlen($copyright) > 60)
2472                  {
2473                      $error[] = $user->lang[$l_type . '_ERR_COPY_LONG'];
2474                  }
2475              }
2476          }
2477  
2478          if ($update && sizeof($error))
2479          {
2480              $style_row = array_merge($style_row, array(
2481                  'template_id'            => $template_id,
2482                  'theme_id'                => $theme_id,
2483                  'imageset_id'            => $imageset_id,
2484                  'style_active'            => $style_active,
2485                  $mode . '_storedb'        => $store_db,
2486                  $mode . '_name'            => $name,
2487                  $mode . '_copyright'    => $copyright)
2488              );
2489          }
2490  
2491          // User has submitted form and no errors have occurred
2492          if ($update && !sizeof($error))
2493          {
2494              $sql_ary = array(
2495                  $mode . '_name'            => $name,
2496                  $mode . '_copyright'    => $copyright
2497              );
2498  
2499              switch ($mode)
2500              {
2501                  case 'style':
2502  
2503                      $sql_ary += array(
2504                          'template_id'        => (int) $template_id,
2505                          'theme_id'            => (int) $theme_id,
2506                          'imageset_id'        => (int) $imageset_id,
2507                          'style_active'        => (int) $style_active,
2508                      );
2509                  break;
2510  
2511                  case 'imageset':
2512                  break;
2513  
2514                  case 'theme':
2515  
2516                      if ($style_row['theme_storedb'] != $store_db)
2517                      {
2518                          $theme_data = '';
2519  
2520                          if (!$style_row['theme_storedb'])
2521                          {
2522                              $theme_data = $this->db_theme_data($style_row);
2523                          }
2524                          else if (!$store_db && !$safe_mode && phpbb_is_writable("{$phpbb_root_path}styles/{$style_row['theme_path']}/theme/stylesheet.css"))
2525                          {
2526                              $store_db = 1;
2527                              $theme_data = $style_row['theme_data'];
2528  
2529                              if ($fp = @fopen("{$phpbb_root_path}styles/{$style_row['theme_path']}/theme/stylesheet.css", 'wb'))
2530                              {
2531                                  $store_db = (@fwrite($fp, str_replace("styles/{$style_row['theme_path']}/theme/", './', $theme_data))) ? 0 : 1;
2532                              }
2533                              fclose($fp);
2534                          }
2535  
2536                          $sql_ary += array(
2537                              'theme_mtime'    => ($store_db) ? filemtime("{$phpbb_root_path}styles/{$style_row['theme_path']}/theme/stylesheet.css") : 0,
2538                              'theme_storedb'    => $store_db,
2539                              'theme_data'    => ($store_db) ? $theme_data : '',
2540                          );
2541                      }
2542                  break;
2543  
2544                  case 'template':
2545  
2546                      if ($style_row['template_storedb'] != $store_db)
2547                      {
2548                          if ($super = $this->get_super($mode, $style_row['template_id']))
2549                          {
2550                              $error[] = (sprintf($user->lang["{$l_type}_INHERITS"], $super['template_name']));
2551                              $sql_ary = array();
2552                          }
2553                          else
2554                          {
2555                              if (!$store_db && !$safe_mode && phpbb_is_writable("{$phpbb_root_path}styles/{$style_row['template_path']}/template"))
2556                              {
2557                                  $err = $this->store_in_fs('template', $style_row['template_id']);
2558                                  if ($err)
2559                                  {
2560                                      $error += $err;
2561                                  }
2562                              }
2563                              else if ($store_db)
2564                              {
2565                                  $this->store_in_db('template', $style_row['template_id']);
2566                              }
2567                              else
2568                              {
2569                                  // We no longer store within the db, but are also not able to update the file structure
2570                                  // Since the admin want to switch this, we adhere to his decision. But we also need to remove the cache
2571                                  $sql = 'DELETE FROM ' . STYLES_TEMPLATE_DATA_TABLE . "
2572                                      WHERE template_id = $style_id";
2573                                  $db->sql_query($sql);
2574                              }
2575  
2576                              $sql_ary += array(
2577                                  'template_storedb'    => $store_db,
2578                              );
2579                          }
2580                      }
2581                  break;
2582              }
2583  
2584              if (sizeof($sql_ary))
2585              {
2586                  $sql = "UPDATE $sql_from
2587                      SET " . $db->sql_build_array('UPDATE', $sql_ary) . "
2588                      WHERE {$mode}_id = $style_id";
2589                  $db->sql_query($sql);
2590  
2591                  // Making this the default style?
2592                  if ($mode == 'style' && $style_default)
2593                  {
2594                      set_config('default_style', $style_id);
2595                  }
2596              }
2597  
2598              $cache->destroy('sql', STYLES_TABLE);
2599  
2600              add_log('admin', 'LOG_' . $l_type . '_EDIT_DETAILS', $name);
2601              if (sizeof($error))
2602              {
2603                  trigger_error(implode('<br />', $error) . adm_back_link($this->u_action), E_USER_WARNING);
2604              }
2605              else
2606              {
2607                  trigger_error($user->lang[$l_type . '_DETAILS_UPDATED'] . adm_back_link($this->u_action));
2608              }
2609          }
2610  
2611          if ($mode == 'style')
2612          {
2613              foreach ($element_ary as $element => $table)
2614              {
2615                  $sql = "SELECT {$element}_id, {$element}_name
2616                      FROM $table
2617                      ORDER BY {$element}_id ASC";
2618                  $result = $db->sql_query($sql);
2619  
2620                  ${$element . '_options'} = '';
2621                  while ($row = $db->sql_fetchrow($result))
2622                  {
2623                      $selected = ($row[$element . '_id'] == $style_row[$element . '_id']) ? ' selected="selected"' : '';
2624                      ${$element . '_options'} .= '<option value="' . $row[$element . '_id'] . '"' . $selected . '>' . $row[$element . '_name'] . '</option>';
2625                  }
2626                  $db->sql_freeresult($result);
2627              }
2628          }
2629  
2630          if ($mode == 'template')
2631          {
2632              $super = array();
2633              if (isset($style_row[$mode . '_inherits_id']) && $style_row['template_inherits_id'])
2634              {
2635                  $super = $this->get_super($mode, $style_row['template_id']);
2636              }
2637          }
2638  
2639          $this->page_title = 'EDIT_DETAILS_' . $l_type;
2640  
2641          $template->assign_vars(array(
2642              'S_DETAILS'                => true,
2643              'S_ERROR_MSG'            => (sizeof($error)) ? true : false,
2644              'S_STYLE'                => ($mode == 'style') ? true : false,
2645              'S_TEMPLATE'            => ($mode == 'template') ? true : false,
2646              'S_THEME'                => ($mode == 'theme') ? true : false,
2647              'S_IMAGESET'            => ($mode == 'imageset') ? true : false,
2648              'S_STORE_DB'            => (isset($style_row[$mode . '_storedb'])) ? $style_row[$mode . '_storedb'] : 0,
2649              'S_STORE_DB_DISABLED'    => (isset($style_row[$mode . '_inherits_id'])) ? $style_row[$mode . '_inherits_id'] : 0,
2650              'S_STYLE_ACTIVE'        => (isset($style_row['style_active'])) ? $style_row['style_active'] : 0,
2651              'S_STYLE_DEFAULT'        => (isset($style_row['style_default'])) ? $style_row['style_default'] : 0,
2652              'S_SUPERTEMPLATE'        => (isset($style_row[$mode . '_inherits_id']) && $style_row[$mode . '_inherits_id']) ? $super['template_name'] : 0,
2653  
2654              'S_TEMPLATE_OPTIONS'    => ($mode == 'style') ? $template_options : '',
2655              'S_THEME_OPTIONS'        => ($mode == 'style') ? $theme_options : '',
2656              'S_IMAGESET_OPTIONS'    => ($mode == 'style') ? $imageset_options : '',
2657  
2658              'U_ACTION'        => $this->u_action . '&amp;action=details&amp;id=' . $style_id,
2659              'U_BACK'        => $this->u_action,
2660  
2661              'L_TITLE'                => $user->lang[$this->page_title],
2662              'L_EXPLAIN'                => $user->lang[$this->page_title . '_EXPLAIN'],
2663              'L_NAME'                => $user->lang[$l_type . '_NAME'],
2664              'L_LOCATION'            => ($mode == 'template' || $mode == 'theme') ? $user->lang[$l_type . '_LOCATION'] : '',
2665              'L_LOCATION_EXPLAIN'    => ($mode == 'template' || $mode == 'theme') ? $user->lang[$l_type . '_LOCATION_EXPLAIN'] : '',
2666  
2667              'ERROR_MSG'        => (sizeof($error)) ? implode('<br />', $error) : '',
2668              'NAME'            => $style_row[$mode . '_name'],
2669              'COPYRIGHT'        => $style_row[$mode . '_copyright'],
2670              )
2671          );
2672      }
2673  
2674      /**
2675      * Load css file contents
2676      */
2677  	function load_css_file($path, $filename)
2678      {
2679          global $phpbb_root_path;
2680  
2681          $file = "{$phpbb_root_path}styles/$path/theme/$filename";
2682  
2683          if (file_exists($file) && ($content = file_get_contents($file)))
2684          {
2685              $content = trim($content);
2686          }
2687          else
2688          {
2689              $content = '';
2690          }
2691          if (defined('DEBUG'))
2692          {
2693              $content = "/* BEGIN @include $filename */ \n $content \n /* END @include $filename */ \n";
2694          }
2695  
2696          return $content;
2697      }
2698  
2699      /**
2700      * Returns a string containing the value that should be used for the theme_data column in the theme database table.
2701      * Includes contents of files loaded via @import
2702      *
2703      * @param array $theme_row is an associative array containing the theme's current database entry
2704      * @param mixed $stylesheet can either be the new content for the stylesheet or false to load from the standard file
2705      * @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']}"
2706      *
2707      * @return string Stylesheet data for theme_data column in the theme table
2708      */
2709  	function db_theme_data($theme_row, $stylesheet = false, $root_path = '')
2710      {
2711          global $phpbb_root_path;
2712  
2713          if (!$root_path)
2714          {
2715              $root_path = $phpbb_root_path . 'styles/' . $theme_row['theme_path'];
2716          }
2717  
2718          if (!$stylesheet)
2719          {
2720              $stylesheet = '';
2721              if (file_exists($root_path . '/theme/stylesheet.css'))
2722              {
2723                  $stylesheet = file_get_contents($root_path . '/theme/stylesheet.css');
2724              }
2725          }
2726  
2727          // Match CSS imports
2728          $matches = array();
2729          preg_match_all('/@import url\((["\'])(.*)\1\);/i', $stylesheet, $matches);
2730  
2731          // remove commented stylesheets (very simple parser, allows only whitespace
2732          // around an @import statement)
2733          preg_match_all('#/\*\s*@import url\((["\'])(.*)\1\);\s\*/#i', $stylesheet, $commented);
2734          $matches[2] = array_diff($matches[2], $commented[2]);
2735  
2736          if (sizeof($matches))
2737          {
2738              foreach ($matches[0] as $idx => $match)
2739              {
2740                  if (isset($matches[2][$idx]))
2741                  {
2742                      $stylesheet = str_replace($match, acp_styles::load_css_file($theme_row['theme_path'], $matches[2][$idx]), $stylesheet);
2743                  }
2744              }
2745          }
2746  
2747          // adjust paths
2748          return str_replace('./', 'styles/' . $theme_row['theme_path'] . '/theme/', $stylesheet);
2749      }
2750  
2751      /**
2752      * Store template files into db
2753      */
2754  	function store_templates($mode, $style_id, $template_path, $filelist)
2755      {
2756          global $phpbb_root_path, $phpEx, $db;
2757  
2758          $template_path = $template_path . '/template/';
2759          $includes = array();
2760          foreach ($filelist as $pathfile => $file_ary)
2761          {
2762              foreach ($file_ary as $file)
2763              {
2764                  if (!($fp = @fopen("{$phpbb_root_path}styles/$template_path$pathfile$file", 'r')))
2765                  {
2766                      trigger_error("Could not open {$phpbb_root_path}styles/$template_path$pathfile$file", E_USER_ERROR);
2767                  }
2768  
2769                  $filesize = filesize("{$phpbb_root_path}styles/$template_path$pathfile$file");
2770  
2771                  if ($filesize)
2772                  {
2773                      $template_data = fread($fp, $filesize);
2774                  }
2775  
2776                  fclose($fp);
2777  
2778                  if (!$filesize)
2779                  {
2780                      // File is empty
2781                      continue;
2782                  }
2783  
2784                  if (preg_match_all('#<!-- INCLUDE (.*?\.html) -->#is', $template_data, $matches))
2785                  {
2786                      foreach ($matches[1] as $match)
2787                      {
2788                          $includes[trim($match)][] = $file;
2789                      }
2790                  }
2791              }
2792          }
2793  
2794          foreach ($filelist as $pathfile => $file_ary)
2795          {
2796              foreach ($file_ary as $file)
2797              {
2798                  // Skip index.
2799                  if (strpos($file, 'index.') === 0)
2800                  {
2801                      continue;
2802                  }
2803  
2804                  // We could do this using extended inserts ... but that could be one
2805                  // heck of a lot of data ...
2806                  $sql_ary = array(
2807                      'template_id'            => (int) $style_id,
2808                      'template_filename'        => "$pathfile$file",
2809                      'template_included'        => (isset($includes[$file])) ? implode(':', $includes[$file]) . ':' : '',
2810                      'template_mtime'        => (int) filemtime("{$phpbb_root_path}styles/$template_path$pathfile$file"),
2811                      'template_data'            => (string) file_get_contents("{$phpbb_root_path}styles/$template_path$pathfile$file"),
2812                  );
2813  
2814                  if ($mode == 'insert')
2815                  {
2816                      $sql = 'INSERT INTO ' . STYLES_TEMPLATE_DATA_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary);
2817                  }
2818                  else
2819                  {
2820                      $sql = 'UPDATE ' . STYLES_TEMPLATE_DATA_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $sql_ary) . "
2821                          WHERE template_id = $style_id
2822                              AND template_filename = '" . $db->sql_escape("$pathfile$file") . "'";
2823                  }
2824                  $db->sql_query($sql);
2825              }
2826          }
2827      }
2828  
2829      /**
2830      * Returns an array containing all template filenames for one template that are currently cached.
2831      *
2832      * @param string $template_path contains the name of the template's folder in /styles/
2833      *
2834      * @return array of filenames that exist in /styles/$template_path/template/ (without extension!)
2835      */
2836  	function template_cache_filelist($template_path)
2837      {
2838          global $phpbb_root_path, $phpEx, $user;
2839  
2840          $cache_prefix = 'tpl_' . str_replace('_', '-', $template_path);
2841  
2842          if (!($dp = @opendir("{$phpbb_root_path}cache")))
2843          {
2844              trigger_error($user->lang['TEMPLATE_ERR_CACHE_READ'] . adm_back_link($this->u_action), E_USER_WARNING);
2845          }
2846  
2847          $file_ary = array();
2848          while ($file = readdir($dp))
2849          {
2850              if ($file[0] == '.')
2851              {
2852                  continue;
2853              }
2854  
2855              if (is_file($phpbb_root_path . 'cache/' . $file) && (strpos($file, $cache_prefix) === 0))
2856              {
2857                  $file_ary[] = str_replace('.', '/', preg_replace('#^' . preg_quote($cache_prefix, '#') . '_(.*?)\.html\.' . $phpEx . '$#i', '\1', $file));
2858              }
2859          }
2860          closedir($dp);
2861  
2862          return $file_ary;
2863      }
2864  
2865      /**
2866      * Destroys cached versions of template files
2867      *
2868      * @param array $template_row contains the template's row in the STYLES_TEMPLATE_TABLE database table
2869      * @param mixed $file_ary is optional and may contain an array of template file names which should be refreshed in the cache.
2870      *    The file names should be the original template file names and not the cache file names.
2871      */
2872  	function clear_template_cache($template_row, $file_ary = false)
2873      {
2874          global $phpbb_root_path, $phpEx, $user;
2875  
2876          $cache_prefix = 'tpl_' . str_replace('_', '-', $template_row['template_path']);
2877  
2878          if (!$file_ary || !is_array($file_ary))
2879          {
2880              $file_ary = $this->template_cache_filelist($template_row['template_path']);
2881              $log_file_list = $user->lang['ALL_FILES'];
2882          }
2883          else
2884          {
2885              $log_file_list = implode(', ', $file_ary);
2886          }
2887  
2888          foreach ($file_ary as $file)
2889          {
2890              $file = str_replace('/', '.', $file);
2891  
2892              $file = "{$phpbb_root_path}cache/{$cache_prefix}_$file.html.$phpEx";
2893              if (file_exists($file) && is_file($file))
2894              {
2895                  @unlink($file);
2896              }
2897          }
2898          unset($file_ary);
2899  
2900          add_log('admin', 'LOG_TEMPLATE_CACHE_CLEARED', $template_row['template_name'], $log_file_list);
2901      }
2902  
2903      /**
2904      * Install Style/Template/Theme/Imageset
2905      */
2906  	function install($mode)
2907      {
2908          global $phpbb_root_path, $phpEx, $config, $db, $cache, $user, $template;
2909  
2910          $l_type = strtoupper($mode);
2911  
2912          $error = $installcfg = $style_row = array();
2913          $root_path = $cfg_file = '';
2914          $element_ary = array('template' => STYLES_TEMPLATE_TABLE, 'theme' => STYLES_THEME_TABLE, 'imageset' => STYLES_IMAGESET_TABLE);
2915  
2916          $install_path = request_var('path', '');
2917          $update = (isset($_POST['update'])) ? true : false;
2918  
2919          // Installing, obtain cfg file contents
2920          if ($install_path)
2921          {
2922              $root_path = $phpbb_root_path . 'styles/' . $install_path . '/';
2923              $cfg_file = ($mode == 'style') ? "$root_path$mode.cfg" : "$root_path$mode/$mode.cfg";
2924  
2925              if (!file_exists($cfg_file))
2926              {
2927                  $error[] = $user->lang[$l_type . '_ERR_NOT_' . $l_type];
2928              }
2929              else
2930              {
2931                  $installcfg = parse_cfg_file($cfg_file);
2932              }
2933          }
2934  
2935          // Installing
2936          if (sizeof($installcfg))
2937          {
2938              $name        = $installcfg['name'];
2939              $copyright    = $installcfg['copyright'];
2940              $version    = $installcfg['version'];
2941  
2942              $style_row = array(
2943                  $mode . '_id'            => 0,
2944                  $mode . '_name'            => '',
2945                  $mode . '_copyright'    => ''
2946              );
2947  
2948              switch ($mode)
2949              {
2950                  case 'style':
2951  
2952                      $style_row = array(
2953                          'style_id'            => 0,
2954                          'style_name'        => $installcfg['name'],
2955                          'style_copyright'    => $installcfg['copyright']
2956                      );
2957  
2958                      $reqd_template = (isset($installcfg['required_template'])) ? $installcfg['required_template'] : false;
2959                      $reqd_theme = (isset($installcfg['required_theme'])) ? $installcfg['required_theme'] : false;
2960                      $reqd_imageset = (isset($installcfg['required_imageset'])) ? $installcfg['required_imageset'] : false;
2961  
2962                      // Check to see if each element is already installed, if it is grab the id
2963                      foreach ($element_ary as $element => $table)
2964                      {
2965                          $style_row = array_merge($style_row, array(
2966                              $element . '_id'            => 0,
2967                              $element . '_name'            => '',
2968                              $element . '_copyright'        => '')
2969                          );
2970  
2971                           $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']);
2972  
2973                          if (!$style_row[$element . '_name'])
2974                          {
2975                              $style_row[$element . '_name'] = $reqd_template;
2976                          }
2977  
2978                          // Merge other information to installcfg... if present
2979                          $cfg_file = $phpbb_root_path . 'styles/' . $install_path . '/' . $element . '/' . $element . '.cfg';
2980  
2981                          if (file_exists($cfg_file))
2982                          {
2983                              $cfg_contents = parse_cfg_file($cfg_file);
2984  
2985                              // Merge only specific things. We may need them later.
2986                              foreach (array('inherit_from', 'parse_css_file') as $key)
2987                              {
2988                                  if (!empty($cfg_contents[$key]) && !isset($installcfg[$key]))
2989                                  {
2990                                      $installcfg[$key] = $cfg_contents[$key];
2991                                  }
2992                              }
2993                          }
2994                      }
2995  
2996                  break;
2997  
2998                  case 'template':
2999                      $this->test_installed('template', $error, $root_path, false, $style_row['template_id'], $style_row['template_name'], $style_row['template_copyright']);
3000                  break;
3001  
3002                  case 'theme':
3003                      $this->test_installed('theme', $error, $root_path, false, $style_row['theme_id'], $style_row['theme_name'], $style_row['theme_copyright']);
3004                  break;
3005  
3006                  case 'imageset':
3007                      $this->test_installed('imageset', $error, $root_path, false, $style_row['imageset_id'], $style_row['imageset_name'], $style_row['imageset_copyright']);
3008                  break;
3009              }
3010          }
3011          else
3012          {
3013              trigger_error($user->lang['NO_' . $l_type] . adm_back_link($this->u_action), E_USER_WARNING);
3014          }
3015  
3016          $style_row['store_db'] = request_var('store_db', 0);
3017          $style_row['style_active'] = request_var('style_active', 1);
3018          $style_row['style_default'] = request_var('style_default', 0);
3019  
3020          // User has submitted form and no errors have occurred
3021          if ($update && !sizeof($error))
3022          {
3023              if ($mode == 'style')
3024              {
3025                  foreach ($element_ary as $element => $table)
3026                  {
3027                      ${$element . '_root_path'} = (${'reqd_' . $element}) ? $phpbb_root_path . 'styles/' . ${'reqd_' . $element} . '/' : false;
3028                      ${$element . '_path'} = (${'reqd_' . $element}) ? ${'reqd_' . $element} : false;
3029                  }
3030                  $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);
3031              }
3032              else
3033              {
3034                  $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']);
3035              }
3036  
3037              if (!sizeof($error))
3038              {
3039                  $cache->destroy('sql', STYLES_TABLE);
3040  
3041                  $message = ($style_row['store_db']) ? '_ADDED_DB' : '_ADDED';
3042                  trigger_error($user->lang[$l_type . $message] . adm_back_link($this->u_action));
3043              }
3044          }
3045  
3046          $this->page_title = 'INSTALL_' . $l_type;
3047  
3048          $template->assign_vars(array(
3049              'S_DETAILS'            => true,
3050              'S_INSTALL'            => true,
3051              'S_ERROR_MSG'        => (sizeof($error)) ? true : false,
3052              'S_LOCATION'        => (isset($installcfg['inherit_from']) && $installcfg['inherit_from']) ? false : true,
3053              'S_STYLE'            => ($mode == 'style') ? true : false,
3054              'S_TEMPLATE'        => ($mode == 'template') ? true : false,
3055              'S_SUPERTEMPLATE'    => (isset($installcfg['inherit_from'])) ? $installcfg['inherit_from'] : '',
3056              'S_THEME'            => ($mode == 'theme') ? true : false,
3057  
3058              'S_STORE_DB'            => (isset($style_row[$mode . '_storedb'])) ? $style_row[$mode . '_storedb'] : 0,
3059              'S_STYLE_ACTIVE'        => (isset($style_row['style_active'])) ? $style_row['style_active'] : 0,
3060              'S_STYLE_DEFAULT'        => (isset($style_row['style_default'])) ? $style_row['style_default'] : 0,
3061  
3062              'U_ACTION'            => $this->u_action . "&amp;action=install&amp;path=" . urlencode($install_path),
3063              'U_BACK'            => $this->u_action,
3064  
3065              'L_TITLE'                => $user->lang[$this->page_title],
3066              'L_EXPLAIN'                => $user->lang[$this->page_title . '_EXPLAIN'],
3067              'L_NAME'                => $user->lang[$l_type . '_NAME'],
3068              'L_LOCATION'            => ($mode == 'template' || $mode == 'theme') ? $user->lang[$l_type . '_LOCATION'] : '',
3069              'L_LOCATION_EXPLAIN'    => ($mode == 'template' || $mode == 'theme') ? $user->lang[$l_type . '_LOCATION_EXPLAIN'] : '',
3070  
3071              'ERROR_MSG'            => (sizeof($error)) ? implode('<br />', $error) : '',
3072              'NAME'                => $style_row[$mode . '_name'],
3073              'COPYRIGHT'            => $style_row[$mode . '_copyright'],
3074              'TEMPLATE_NAME'        => ($mode == 'style') ? $style_row['template_name'] : '',
3075              'THEME_NAME'        => ($mode == 'style') ? $style_row['theme_name'] : '',
3076              'IMAGESET_NAME'        => ($mode == 'style') ? $style_row['imageset_name'] : '')
3077          );
3078      }
3079  
3080      /**
3081      * Add new style
3082      */
3083  	function add($mode)
3084      {
3085          global $phpbb_root_path, $phpEx, $config, $db, $cache, $user, $template;
3086  
3087          $l_type = strtoupper($mode);
3088          $element_ary = array('template' => STYLES_TEMPLATE_TABLE, 'theme' => STYLES_THEME_TABLE, 'imageset' => STYLES_IMAGESET_TABLE);
3089          $error = array();
3090  
3091          $style_row = array(
3092              $mode . '_name'            => utf8_normalize_nfc(request_var('name', '', true)),
3093              $mode . '_copyright'    => utf8_normalize_nfc(request_var('copyright', '', true)),
3094              'template_id'            => 0,
3095              'theme_id'                => 0,
3096              'imageset_id'            => 0,
3097              'store_db'                => request_var('store_db', 0),
3098              'style_active'            => request_var('style_active', 1),
3099              'style_default'            => request_var('style_default', 0),
3100          );
3101  
3102          $basis = request_var('basis', 0);
3103          $update = (isset($_POST['update'])) ? true : false;
3104  
3105          if ($basis)
3106          {
3107              switch ($mode)
3108              {
3109                  case 'style':
3110                      $sql_select = 'template_id, theme_id, imageset_id';
3111                      $sql_from = STYLES_TABLE;
3112                  break;
3113  
3114                  case 'template':
3115                      $sql_select = 'template_id';
3116                      $sql_from = STYLES_TEMPLATE_TABLE;
3117                  break;
3118  
3119                  case 'theme':
3120                      $sql_select = 'theme_id';
3121                      $sql_from = STYLES_THEME_TABLE;
3122                  break;
3123  
3124                  case 'imageset':
3125                      $sql_select = 'imageset_id';
3126                      $sql_from = STYLES_IMAGESET_TABLE;
3127                  break;
3128              }
3129  
3130              $sql = "SELECT $sql_select
3131                  FROM $sql_from
3132                  WHERE {$mode}_id = $basis";
3133              $result = $db->sql_query($sql);
3134              $row = $db->sql_fetchrow($result);
3135              $db->sql_freeresult($result);
3136  
3137              if (!$row)
3138              {
3139                  $error[] = $user->lang['NO_' . $l_type];
3140              }
3141  
3142              if (!sizeof($error))
3143              {
3144                  $style_row['template_id']    = (isset($row['template_id'])) ? $row['template_id'] : $style_row['template_id'];
3145                  $style_row['theme_id']        = (isset($row['theme_id'])) ? $row['theme_id'] : $style_row['theme_id'];
3146                  $style_row['imageset_id']    = (isset($row['imageset_id'])) ? $row['imageset_id'] : $style_row['imageset_id'];
3147              }
3148          }
3149  
3150          if ($update)
3151          {
3152              $style_row['template_id'] = request_var('template_id', $style_row['template_id']);
3153              $style_row['theme_id'] = request_var('theme_id', $style_row['theme_id']);
3154              $style_row['imageset_id'] = request_var('imageset_id', $style_row['imageset_id']);
3155  
3156              if ($mode == 'style' && (!$style_row['template_id'] || !$style_row['theme_id'] || !$style_row['imageset_id']))
3157              {
3158                  $error[] = $user->lang['STYLE_ERR_NO_IDS'];
3159              }
3160          }
3161  
3162          // User has submitted form and no errors have occurred
3163          if ($update && !sizeof($error))
3164          {
3165              if ($mode == 'style')
3166              {
3167                  $style_row['style_id'] = 0;
3168  
3169                  $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);
3170              }
3171  
3172              if (!sizeof($error))
3173              {
3174                  $cache->destroy('sql', STYLES_TABLE);
3175  
3176                  $message = ($style_row['store_db']) ? '_ADDED_DB' : '_ADDED';
3177                  trigger_error($user->lang[$l_type . $message] . adm_back_link($this->u_action));
3178              }
3179          }
3180  
3181          if ($mode == 'style')
3182          {
3183              foreach ($element_ary as $element => $table)
3184              {
3185                  $sql = "SELECT {$element}_id, {$element}_name
3186                      FROM $table
3187                      ORDER BY {$element}_id ASC";
3188                  $result = $db->sql_query($sql);
3189  
3190                  ${$element . '_options'} = '';
3191                  while ($row = $db->sql_fetchrow($result))
3192                  {
3193                      $selected = ($row[$element . '_id'] == $style_row[$element . '_id']) ? ' selected="selected"' : '';
3194                      ${$element . '_options'} .= '<option value="' . $row[$element . '_id'] . '"' . $selected . '>' . $row[$element . '_name'] . '</option>';
3195                  }
3196                  $db->sql_freeresult($result);
3197              }
3198          }
3199  
3200          $this->page_title = 'ADD_' . $l_type;
3201  
3202          $template->assign_vars(array(
3203              'S_DETAILS'            => true,
3204              'S_ADD'                => true,
3205              'S_ERROR_MSG'        => (sizeof($error)) ? true : false,
3206              'S_STYLE'            => ($mode == 'style') ? true : false,
3207              'S_TEMPLATE'        => ($mode == 'template') ? true : false,
3208              'S_THEME'            => ($mode == 'theme') ? true : false,
3209              'S_BASIS'            => ($basis) ? true : false,
3210  
3211              'S_STORE_DB'            => (isset($style_row['storedb'])) ? $style_row['storedb'] : 0,
3212              'S_STYLE_ACTIVE'        => (isset($style_row['style_active'])) ? $style_row['style_active'] : 0,
3213              'S_STYLE_DEFAULT'        => (isset($style_row['style_default'])) ? $style_row['style_default'] : 0,
3214              'S_TEMPLATE_OPTIONS'    => ($mode == 'style') ? $template_options : '',
3215              'S_THEME_OPTIONS'        => ($mode == 'style') ? $theme_options : '',
3216              'S_IMAGESET_OPTIONS'    => ($mode == 'style') ? $imageset_options : '',
3217  
3218              'U_ACTION'            => $this->u_action . '&amp;action=add&amp;basis=' . $basis,
3219              'U_BACK'            => $this->u_action,
3220  
3221              'L_TITLE'                => $user->lang[$this->page_title],
3222              'L_EXPLAIN'                => $user->lang[$this->page_title . '_EXPLAIN'],
3223              'L_NAME'                => $user->lang[$l_type . '_NAME'],
3224              'L_LOCATION'            => ($mode == 'template' || $mode == 'theme') ? $user->lang[$l_type . '_LOCATION'] : '',
3225              'L_LOCATION_EXPLAIN'    => ($mode == 'template' || $mode == 'theme') ? $user->lang[$l_type . '_LOCATION_EXPLAIN'] : '',
3226  
3227              'ERROR_MSG'            => (sizeof($error)) ? implode('<br />', $error) : '',
3228              'NAME'                => $style_row[$mode . '_name'],
3229              'COPYRIGHT'            => $style_row[$mode . '_copyright'])
3230          );
3231  
3232      }
3233  
3234      /**
3235  
3236                      $reqd_template = (isset($installcfg['required_template'])) ? $installcfg['required_template'] : false;
3237                      $reqd_theme = (isset($installcfg['required_theme'])) ? $installcfg['required_theme'] : false;
3238                      $reqd_imageset = (isset($installcfg['required_imageset'])) ? $installcfg['required_imageset'] : false;
3239  
3240                      // Check to see if each element is already installed, if it is grab the id
3241                      foreach ($element_ary as $element => $table)
3242                      {
3243                          $style_row = array_merge($style_row, array(
3244                              $element . '_id'            => 0,
3245                              $element . '_name'            => '',
3246                              $element . '_copyright'        => '')
3247                          );
3248  
3249                           $this->test_installed($element, $error, $root_path, ${'reqd_' . $element}, $style_row[$element . '_id'], $style_row[$element . '_name'], $style_row[$element . '_copyright']);
3250      * Is this element installed? If not, grab its cfg details
3251      */
3252  	function test_installed($element, &$error, $root_path, $reqd_name, &$id, &$name, &$copyright)
3253      {
3254          global $db, $user;
3255  
3256          switch ($element)
3257          {
3258              case 'template':
3259                  $sql_from = STYLES_TEMPLATE_TABLE;
3260              break;
3261  
3262              case 'theme':
3263                  $sql_from = STYLES_THEME_TABLE;
3264              break;
3265  
3266              case 'imageset':
3267                  $sql_from = STYLES_IMAGESET_TABLE;
3268              break;
3269          }
3270  
3271          $l_element = strtoupper($element);
3272  
3273          $chk_name = ($reqd_name !== false) ? $reqd_name : $name;
3274  
3275          $sql = "SELECT {$element}_id, {$element}_name
3276              FROM $sql_from
3277              WHERE {$element}_name = '" . $db->sql_escape($chk_name) . "'";
3278          $result = $db->sql_query($sql);
3279  
3280          if ($row = $db->sql_fetchrow($result))
3281          {
3282              $name = $row[$element . '_name'];
3283              $id = $row[$element . '_id'];
3284          }
3285          else
3286          {
3287              if (!($cfg = @file("$root_path$element/$element.cfg")))
3288              {
3289                  $error[] = sprintf($user->lang['REQUIRES_' . $l_element], $reqd_name);
3290                  return false;
3291              }
3292  
3293              $cfg = parse_cfg_file("$root_path$element/$element.cfg", $cfg);
3294  
3295              $name = $cfg['name'];
3296              $copyright = $cfg['copyright'];
3297              $id = 0;
3298  
3299              unset($cfg);
3300          }
3301          $db->sql_freeresult($result);
3302      }
3303  
3304      /**
3305      * Install/Add style
3306      */
3307  	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)
3308      {
3309          global $config, $db, $user;
3310  
3311          $element_ary = array('template', 'theme', 'imageset');
3312  
3313          if (!$name)
3314          {
3315              $error[] = $user->lang['STYLE_ERR_STYLE_NAME'];
3316          }
3317  
3318          // Check length settings
3319          if (utf8_strlen($name) > 30)
3320          {
3321              $error[] = $user->lang['STYLE_ERR_NAME_LONG'];
3322          }
3323  
3324          if (utf8_strlen($copyright) > 60)
3325          {
3326              $error[] = $user->lang['STYLE_ERR_COPY_LONG'];
3327          }
3328  
3329          // Check if the name already exist
3330          $sql = 'SELECT style_id
3331              FROM ' . STYLES_TABLE . "
3332              WHERE style_name = '" . $db->sql_escape($name) . "'";
3333          $result = $db->sql_query($sql);
3334          $row = $db->sql_fetchrow($result);
3335          $db->sql_freeresult($result);
3336  
3337          if ($row)
3338          {
3339              $error[] = $user->lang['STYLE_ERR_NAME_EXIST'];
3340          }
3341  
3342          if (sizeof($error))
3343          {
3344              return false;
3345          }
3346  
3347          foreach ($element_ary as $element)
3348          {
3349              // Zero id value ... need to install element ... run usual checks
3350              // and do the install if necessary
3351              if (!$style_row[$element . '_id'])
3352              {
3353                  $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']);
3354              }
3355          }
3356  
3357          if (!$style_row['template_id'] || !$style_row['theme_id'] || !$style_row['imageset_id'])
3358          {
3359              $error[] = $user->lang['STYLE_ERR_NO_IDS'];
3360          }
3361  
3362          if (sizeof($error))
3363          {
3364              return false;
3365          }
3366  
3367          $db->sql_transaction('begin');
3368  
3369          $sql_ary = array(
3370              'style_name'        => $name,
3371              'style_copyright'    => $copyright,
3372              'style_active'        => (int) $active,
3373              'template_id'        => (int) $style_row['template_id'],
3374              'theme_id'            => (int) $style_row['theme_id'],
3375              'imageset_id'        => (int) $style_row['imageset_id'],
3376          );
3377  
3378          $sql = 'INSERT INTO ' . STYLES_TABLE . '
3379              ' . $db->sql_build_array('INSERT', $sql_ary);
3380          $db->sql_query($sql);
3381  
3382          $id = $db->sql_nextid();
3383  
3384          if ($default)
3385          {
3386              $sql = 'UPDATE ' . USERS_TABLE . "
3387                  SET user_style = $id
3388                  WHERE user_style = " . $config['default_style'];
3389              $db->sql_query($sql);
3390  
3391              set_config('default_style', $id);
3392          }
3393  
3394          $db->sql_transaction('commit');
3395  
3396          add_log('admin', 'LOG_STYLE_ADD', $name);
3397      }
3398  
3399      /**
3400      * Install/add an element, doing various checks as we go
3401      */
3402  	function install_element($mode, &$error, $action, $root_path, &$id, $name, $path, $copyright, $store_db = 0)
3403      {
3404          global $phpbb_root_path, $db, $user;
3405  
3406          // we parse the cfg here (again)
3407          $cfg_data = parse_cfg_file("$root_path$mode/$mode.cfg");
3408  
3409          switch ($mode)
3410          {
3411              case 'template':
3412                  $sql_from = STYLES_TEMPLATE_TABLE;
3413              break;
3414  
3415              case 'theme':
3416                  $sql_from = STYLES_THEME_TABLE;
3417              break;
3418  
3419              case 'imageset':
3420                  $sql_from = STYLES_IMAGESET_TABLE;
3421              break;
3422          }
3423  
3424          $l_type = strtoupper($mode);
3425  
3426          if (!$name)
3427          {
3428              $error[] = $user->lang[$l_type . '_ERR_STYLE_NAME'];
3429          }
3430  
3431          // Check length settings
3432          if (utf8_strlen($name) > 30)
3433          {
3434              $error[] = $user->lang[$l_type . '_ERR_NAME_LONG'];
3435          }
3436  
3437          if (utf8_strlen($copyright) > 60)
3438          {
3439              $error[] = $user->lang[$l_type . '_ERR_COPY_LONG'];
3440          }
3441  
3442          // Check if the name already exist
3443          $sql = "SELECT {$mode}_id
3444              FROM $sql_from
3445              WHERE {$mode}_name = '" . $db->sql_escape($name) . "'";
3446          $result = $db->sql_query($sql);
3447          $row = $db->sql_fetchrow($result);
3448          $db->sql_freeresult($result);
3449  
3450          if ($row)
3451          {
3452              // If it exist, we just use the style on installation
3453              if ($action == 'install')
3454              {
3455                  $id = $row[$mode . '_id'];
3456                  return false;
3457              }
3458  
3459              $error[] = $user->lang[$l_type . '_ERR_NAME_EXIST'];
3460          }
3461  
3462          if (isset($cfg_data['inherit_from']) && $cfg_data['inherit_from'])
3463          {
3464              if ($mode === 'template')
3465              {
3466                  $select_bf = ', bbcode_bitfield';
3467              }
3468              else
3469              {
3470                  $select_bf = '';
3471              }
3472  
3473              $sql = "SELECT {$mode}_id, {$mode}_name, {$mode}_path, {$mode}_storedb $select_bf
3474                  FROM $sql_from
3475                  WHERE {$mode}_name = '" . $db->sql_escape($cfg_data['inherit_from']) . "'
3476                      AND {$mode}_inherits_id = 0";
3477              $result = $db->sql_query($sql);
3478              $row = $db->sql_fetchrow($result);
3479              $db->sql_freeresult($result);
3480              if (!$row)
3481              {
3482                  $error[] = sprintf($user->lang[$l_type . '_ERR_REQUIRED_OR_INCOMPLETE'], $cfg_data['inherit_from']);
3483              }
3484              else
3485              {
3486                  $inherit_id = $row["{$mode}_id"];
3487                  $inherit_path = $row["{$mode}_path"];
3488                  $inherit_bf = ($mode === 'template') ? $row["bbcode_bitfield"] : false;
3489                  $cfg_data['store_db'] = $row["{$mode}_storedb"];
3490                  $store_db = $row["{$mode}_storedb"];
3491              }
3492          }
3493          else
3494          {
3495              $inherit_id = 0;
3496              $inherit_path = '';
3497              $inherit_bf = false;
3498          }
3499  
3500          if (sizeof($error))
3501          {
3502              return false;
3503          }
3504  
3505          $sql_ary = array(
3506              $mode . '_name'            => $name,
3507              $mode . '_copyright'    => $copyright,
3508              $mode . '_path'            => $path,
3509          );
3510  
3511          switch ($mode)
3512          {
3513              case 'template':
3514                  // We check if the template author defined a different bitfield
3515                  if (!empty($cfg_data['template_bitfield']))
3516                  {
3517                      $sql_ary['bbcode_bitfield'] = $cfg_data['template_bitfield'];
3518                  }
3519                  else if ($inherit_bf)
3520                  {
3521                      $sql_ary['bbcode_bitfield'] = $inherit_bf;
3522                  }
3523                  else
3524                  {
3525                      $sql_ary['bbcode_bitfield'] = TEMPLATE_BITFIELD;
3526                  }
3527  
3528                  // We set a pre-defined bitfield here which we may use further in 3.2
3529                  $sql_ary += array(
3530                      'template_storedb'        => $store_db,
3531                  );
3532                  if (isset($cfg_data['inherit_from']) && $cfg_data['inherit_from'])
3533                  {
3534                      $sql_ary += array(
3535                          'template_inherits_id'    => $inherit_id,
3536                          'template_inherit_path' => $inherit_path,
3537                      );
3538                  }
3539              break;
3540  
3541              case 'theme':
3542                  // We are only interested in the theme configuration for now
3543  
3544                  if (isset($cfg_data['parse_css_file']) && $cfg_data['parse_css_file'])
3545                  {
3546                      $store_db = 1;
3547                  }
3548  
3549                  $sql_ary += array(
3550                      'theme_storedb'    => $store_db,
3551                      'theme_data'    => ($store_db) ? $this->db_theme_data($sql_ary, false, $root_path) : '',
3552                      'theme_mtime'    => (int) filemtime("{$phpbb_root_path}styles/$path/theme/stylesheet.css")
3553                  );
3554              break;
3555  
3556              // all the heavy lifting is done later
3557              case 'imageset':
3558              break;
3559          }
3560  
3561          $db->sql_transaction('begin');
3562  
3563          $sql = "INSERT INTO $sql_from
3564              " . $db->sql_build_array('INSERT', $sql_ary);
3565          $db->sql_query($sql);
3566  
3567          $id = $db->sql_nextid();
3568  
3569          if ($mode == 'template' && $store_db)
3570          {
3571              $filelist = filelist("{$root_path}template", '', 'html');
3572              $this->store_templates('insert', $id, $path, $filelist);
3573          }
3574          else if ($mode == 'imageset')
3575          {
3576              $cfg_data = parse_cfg_file("$root_path$mode/imageset.cfg");
3577  
3578              $imageset_definitions = array();
3579              foreach ($this->imageset_keys as $topic => $key_array)
3580              {
3581                  $imageset_definitions = array_merge($imageset_definitions, $key_array);
3582              }
3583  
3584              foreach ($cfg_data as $key => $value)
3585              {
3586                  if (strpos($value, '*') !== false)
3587                  {
3588                      if (substr($value, -1, 1) === '*')
3589                      {
3590                          list($image_filename, $image_height) = explode('*', $value);
3591                          $image_width = 0;
3592                      }
3593                      else
3594                      {
3595                          list($image_filename, $image_height, $image_width) = explode('*', $value);
3596                      }
3597                  }
3598                  else
3599                  {
3600                      $image_filename = $value;
3601                      $image_height = $image_width = 0;
3602                  }
3603  
3604                  if (strpos($key, 'img_') === 0 && $image_filename)
3605                  {
3606                      $key = substr($key, 4);
3607                      if (in_array($key, $imageset_definitions))
3608                      {
3609                          $sql_ary = array(
3610                              'image_name'        => $key,
3611                              'image_filename'    => str_replace('{PATH}', "styles/$path/imageset/", trim($image_filename)),
3612                              'image_height'        => (int) $image_height,
3613                              'image_width'        => (int) $image_width,
3614                              'imageset_id'        => (int) $id,
3615                              'image_lang'        => '',
3616                          );
3617                          $db->sql_query('INSERT INTO ' . STYLES_IMAGESET_DATA_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary));
3618                      }
3619                  }
3620              }
3621              unset($cfg_data);
3622  
3623              $sql = 'SELECT lang_dir
3624                  FROM ' . LANG_TABLE;
3625              $result = $db->sql_query($sql);
3626  
3627              while ($row = $db->sql_fetchrow($result))
3628              {
3629                  if (@file_exists("$root_path$mode/{$row['lang_dir']}/imageset.cfg"))
3630                  {
3631                      $cfg_data_imageset_data = parse_cfg_file("$root_path$mode/{$row['lang_dir']}/imageset.cfg");
3632                      foreach ($cfg_data_imageset_data as $image_name => $value)
3633                      {
3634                          if (strpos($value, '*') !== false)
3635                          {
3636                              if (substr($value, -1, 1) === '*')
3637                              {
3638                                  list($image_filename, $image_height) = explode('*', $value);
3639                                  $image_width = 0;
3640                              }
3641                              else
3642                              {
3643                                  list($image_filename, $image_height, $image_width) = explode('*', $value);
3644                              }
3645                          }
3646                          else
3647                          {
3648                              $image_filename = $value;
3649                              $image_height = $image_width = 0;
3650                          }
3651  
3652                          if (strpos($image_name, 'img_') === 0 && $image_filename)
3653                          {
3654                              $image_name = substr($image_name, 4);
3655                              if (in_array($image_name, $imageset_definitions))
3656                              {
3657                                  $sql_ary = array(
3658                                      'image_name'        => $image_name,
3659                                      'image_filename'    => $image_filename,
3660                                      'image_height'        => (int) $image_height,
3661                                      'image_width'        => (int) $image_width,
3662                                      'imageset_id'        => (int) $id,
3663                                      'image_lang'        => $row['lang_dir'],
3664                                  );
3665                                  $db->sql_query('INSERT INTO ' . STYLES_IMAGESET_DATA_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary));
3666                              }
3667                          }
3668                      }
3669                      unset($cfg_data_imageset_data);
3670                  }
3671              }
3672              $db->sql_freeresult($result);
3673          }
3674  
3675          $db->sql_transaction('commit');
3676  
3677          $log = ($store_db) ? 'LOG_' . $l_type . '_ADD_DB' : 'LOG_' . $l_type . '_ADD_FS';
3678          add_log('admin', $log, $name);
3679  
3680          // Return store_db in case it had to be altered
3681          return $store_db;
3682      }
3683  
3684      /**
3685      * Checks downwards dependencies
3686      *
3687      * @access public
3688      * @param string $mode The element type to check - only template is supported
3689      * @param int $id The template id
3690      * @returns false if no component inherits, array with name, path and id for each subtemplate otherwise
3691      */
3692  	function check_inheritance($mode, $id)
3693      {
3694          global $db;
3695  
3696          $l_type = strtoupper($mode);
3697  
3698          switch ($mode)
3699          {
3700              case 'template':
3701                  $sql_from = STYLES_TEMPLATE_TABLE;
3702              break;
3703  
3704              case 'theme':
3705                  $sql_from = STYLES_THEME_TABLE;
3706              break;
3707  
3708              case 'imageset':
3709                  $sql_from = STYLES_IMAGESET_TABLE;
3710              break;
3711          }
3712  
3713          $sql = "SELECT {$mode}_id, {$mode}_name, {$mode}_path
3714              FROM $sql_from
3715              WHERE {$mode}_inherits_id = " . (int) $id;
3716          $result = $db->sql_query($sql);
3717  
3718          $names = array();
3719          while ($row = $db->sql_fetchrow($result))
3720          {
3721  
3722              $names[$row["{$mode}_id"]] = array(
3723                  "{$mode}_id" => $row["{$mode}_id"],
3724                  "{$mode}_name" => $row["{$mode}_name"],
3725                  "{$mode}_path" => $row["{$mode}_path"],
3726              );
3727          }
3728          $db->sql_freeresult($result);
3729  
3730          if (sizeof($names))
3731          {
3732              return $names;
3733          }
3734          else
3735          {
3736              return false;
3737          }
3738      }
3739  
3740      /**
3741      * Checks upwards dependencies
3742      *
3743      * @access public
3744      * @param string $mode The element type to check - only template is supported
3745      * @param int $id The template id
3746      * @returns false if the component does not inherit, array with name, path and id otherwise
3747      */
3748  	function get_super($mode, $id)
3749      {
3750          global $db;
3751  
3752          $l_type = strtoupper($mode);
3753  
3754          switch ($mode)
3755          {
3756              case 'template':
3757                  $sql_from = STYLES_TEMPLATE_TABLE;
3758              break;
3759  
3760              case 'theme':
3761                  $sql_from = STYLES_THEME_TABLE;
3762              break;
3763  
3764              case 'imageset':
3765                  $sql_from = STYLES_IMAGESET_TABLE;
3766              break;
3767          }
3768  
3769          $sql = "SELECT {$mode}_inherits_id
3770              FROM $sql_from
3771              WHERE {$mode}_id = " . (int) $id;
3772          $result = $db->sql_query_limit($sql, 1);
3773  
3774          if ($row = $db->sql_fetchrow($result))
3775          {
3776              $db->sql_freeresult($result);
3777          }
3778          else
3779          {
3780              return false;
3781          }
3782  
3783          $super_id = $row["{$mode}_inherits_id"];
3784  
3785          $sql = "SELECT {$mode}_id, {$mode}_name, {$mode}_path
3786              FROM $sql_from
3787              WHERE {$mode}_id = " . (int) $super_id;
3788  
3789          $result = $db->sql_query_limit($sql, 1);
3790          if ($row = $db->sql_fetchrow($result))
3791          {
3792              $db->sql_freeresult($result);
3793              return $row;
3794          }
3795  
3796          return false;
3797      }
3798  
3799      /**
3800      * Moves a template set and its subtemplates to the database
3801      *
3802      * @access public
3803      * @param string $mode The component to move - only template is supported
3804      * @param int $id The template id
3805      */
3806  	function store_in_db($mode, $id)
3807      {
3808          global $db, $user;
3809  
3810          $error = array();
3811          $l_type = strtoupper($mode);
3812          if ($super = $this->get_super($mode, $id))
3813          {
3814              $error[] = (sprintf($user->lang["{$l_type}_INHERITS"], $super['template_name']));
3815              return $error;
3816          }
3817  
3818          $sql = "SELECT {$mode}_id, {$mode}_name, {$mode}_path
3819              FROM " . STYLES_TEMPLATE_TABLE . '
3820              WHERE template_id = ' . (int) $id;
3821  
3822          $result = $db->sql_query_limit($sql, 1);
3823          if ($row = $db->sql_fetchrow($result))
3824          {
3825              $db->sql_freeresult($result);
3826              $subs = $this->check_inheritance($mode, $id);
3827  
3828              $this->_store_in_db($mode, $id, $row["{$mode}_path"]);
3829              if ($subs && sizeof($subs))
3830              {
3831                  foreach ($subs as $sub_id => $sub)
3832                  {
3833                      if ($err = $this->_store_in_db($mode, $sub["{$mode}_id"], $sub["{$mode}_path"]))
3834                      {
3835                          $error[] = $err;
3836                      }
3837                  }
3838              }
3839          }
3840          if (sizeof($error))
3841          {
3842              return $error;
3843          }
3844  
3845          return false;
3846      }
3847  
3848      /**
3849      * Moves a template set to the database
3850      *
3851      * @access private
3852      * @param string $mode The component to move - only template is supported
3853      * @param int $id The template id
3854      * @param string $path TThe path to the template files
3855      */
3856  	function _store_in_db($mode, $id, $path)
3857      {
3858          global $phpbb_root_path, $db;
3859  
3860          $filelist = filelist("{$phpbb_root_path}styles/{$path}/template", '', 'html');
3861          $this->store_templates('insert', $id, $path, $filelist);
3862  
3863          // Okay, we do the query here -shouldn't be triggered often.
3864          $sql = 'UPDATE ' . STYLES_TEMPLATE_TABLE . '
3865                          SET template_storedb = 1
3866                          WHERE template_id = ' . $id;
3867          $db->sql_query($sql);
3868      }
3869  
3870      /**
3871      * Moves a template set and its subtemplates to the filesystem
3872      *
3873      * @access public
3874      * @param string $mode The component to move - only template is supported
3875      * @param int $id The template id
3876      */
3877  	function store_in_fs($mode, $id)
3878      {
3879          global $db, $user;
3880  
3881          $error = array();
3882          $l_type = strtoupper($mode);
3883          if ($super = $this->get_super($mode, $id))
3884          {
3885              $error[] = (sprintf($user->lang["{$l_type}_INHERITS"], $super['template_name']));
3886              return($error);
3887          }
3888  
3889          $sql = "SELECT {$mode}_id, {$mode}_name, {$mode}_path
3890              FROM " . STYLES_TEMPLATE_TABLE . '
3891              WHERE template_id = ' . (int) $id;
3892  
3893          $result = $db->sql_query_limit($sql, 1);
3894          if ($row = $db->sql_fetchrow($result))
3895          {
3896              $db->sql_freeresult($result);
3897              if (!sizeof($error))
3898              {
3899                  $subs = $this->check_inheritance($mode, $id);
3900  
3901                  $this->_store_in_fs($mode, $id, $row["{$mode}_path"]);
3902  
3903                  if ($subs && sizeof($subs))
3904                  {
3905                      foreach ($subs as $sub_id => $sub)
3906                      {
3907                          $this->_store_in_fs($mode, $sub["{$mode}_id"], $sub["{$mode}_path"]);
3908                      }
3909                  }
3910              }
3911              if (sizeof($error))
3912              {
3913                  $this->store_in_db($id, $mode);
3914                  return $error;
3915              }
3916          }
3917          return false;
3918      }
3919  
3920      /**
3921      * Moves a template set to the filesystem
3922      *
3923      * @access private
3924      * @param string $mode The component to move - only template is supported
3925      * @param int $id The template id
3926      * @param string $path The path to the template
3927      */
3928  	function _store_in_fs($mode, $id, $path)
3929      {
3930          global $phpbb_root_path, $db, $user, $safe_mode;
3931  
3932          $store_db = 0;
3933          $error = array();
3934          if (!$safe_mode && phpbb_is_writable("{$phpbb_root_path}styles/{$path}/template"))
3935          {
3936              $sql = 'SELECT *
3937                      FROM ' . STYLES_TEMPLATE_DATA_TABLE . "
3938                      WHERE template_id = $id";
3939              $result = $db->sql_query($sql);
3940  
3941              while ($row = $db->sql_fetchrow($result))
3942              {
3943                  if (!($fp = @fopen("{$phpbb_root_path}styles/{$path}/template/" . $row['template_filename'], 'wb')))
3944                  {
3945                      $store_db = 1;
3946                      $error[] = $user->lang['EDIT_TEMPLATE_STORED_DB'];
3947                      break;
3948                  }
3949  
3950                  fwrite($fp, $row['template_data']);
3951                  fclose($fp);
3952              }
3953              $db->sql_freeresult($result);
3954  
3955              if (!$store_db)
3956              {
3957                  $sql = 'DELETE FROM ' . STYLES_TEMPLATE_DATA_TABLE . "
3958                          WHERE template_id = $id";
3959                  $db->sql_query($sql);
3960              }
3961          }
3962          if (sizeof($error))
3963          {
3964              return $error;
3965          }
3966          $sql = 'UPDATE ' . STYLES_TEMPLATE_TABLE . '
3967                  SET template_storedb = 0
3968                  WHERE template_id = ' . $id;
3969          $db->sql_query($sql);
3970  
3971          return false;
3972      }
3973  
3974  }
3975  
3976  ?>


Generated: Wed Oct 2 15:03:47 2013 Cross-referenced by PHPXref 0.7.1