[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
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 . "&action=$option&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 . "&action=$option&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 . '&action=' . (($mode == 'style') ? 'details' : 'edit') . '&id=' . $row[$mode . '_id'], 631 'U_STYLE_ACT_DEACT' => $this->u_action . '&action=' . $stylevis . '&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 . '&action=install&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 . "&action=edit&id=$template_id&text_rows=$text_rows&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 . "&action=edit&id=$template_id&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 . "&action=cache&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>', '', '', '[', ']', '.', ':'); 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('#([^ ;]) ([^ &])#', '$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 . "&action=cache&id=$template_id&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 . "&action=cache&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 . "&action=edit&id=$theme_id&template_file=$theme_file&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 . "&action=edit&id=$theme_id&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 . "&action=edit&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 . "&action=delete&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 . '&action=export&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 . '&action=details&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 . "&action=install&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 . '&action=add&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 ?>
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Oct 2 15:03:47 2013 | Cross-referenced by PHPXref 0.7.1 |