3 /***************************************************************************
\r
6 * copyright : (C) 2003 - 2005 CyberAlien
\r
7 * support : http://www.phpbbstyles.com
\r
11 * file revision : 77
\r
12 * project revision : 78
\r
13 * last modified : 05 Dec 2005 13:54:54
\r
15 ***************************************************************************/
\r
17 /***************************************************************************
\r
19 * This program is free software; you can redistribute it and/or modify
\r
20 * it under the terms of the GNU General Public License as published by
\r
21 * the Free Software Foundation; either version 2 of the License, or
\r
22 * (at your option) any later version.
\r
24 ***************************************************************************/
\r
26 if (!defined('IN_PHPBB') || !defined('IN_XS'))
\r
28 die('Hacking attempt');
\r
31 if(defined('XS_INCLUDED'))
\r
35 define('XS_INCLUDED', true);
\r
39 // include language file
\r
42 if(!defined('XS_LANG_INCLUDED'))
\r
44 global $phpbb_root_path, $board_config, $phpEx, $lang;
\r
45 $xs_lang_file = $phpbb_root_path . 'language/lang_' . $board_config['default_lang'] . '/lang_xs.'.$phpEx;
\r
46 if( !@file_exists($xs_lang_file) )
\r
47 { // load english version if there is no translation to current language
\r
48 $xs_lang_file = $phpbb_root_path . 'language/lang_english/lang_xs.'.$phpEx;
\r
50 include($xs_lang_file);
\r
51 define('XS_LANG_INCLUDED', true);
\r
55 define('XS_SHOWNAV_CONFIG', 0);
\r
56 define('XS_SHOWNAV_INSTALL', 1);
\r
57 define('XS_SHOWNAV_UNINSTALL', 2);
\r
58 define('XS_SHOWNAV_DEFAULT', 3);
\r
59 define('XS_SHOWNAV_CACHE', 4);
\r
60 define('XS_SHOWNAV_IMPORT', 5);
\r
61 define('XS_SHOWNAV_EXPORT', 6);
\r
62 define('XS_SHOWNAV_CLONE', 7);
\r
63 define('XS_SHOWNAV_DOWNLOAD', 8);
\r
64 define('XS_SHOWNAV_EDITTPL', 9);
\r
65 define('XS_SHOWNAV_EDITDB', 10);
\r
66 define('XS_SHOWNAV_EXPORTDB', 11);
\r
67 define('XS_SHOWNAV_UPDATES', 12);
\r
68 define('XS_SHOWNAV_MAX', 13);
\r
70 global $xs_shownav_action;
\r
71 $xs_shownav_action = array(
\r
88 // override styles management in admin navigation
\r
89 function xs_admin_override($modded = false)
\r
91 if(defined('XS_ADMIN_OVERRIDE_FINISHED'))
\r
95 define('XS_ADMIN_OVERRIDE_FINISHED', true);
\r
96 global $module, $phpEx, $xs_shownav_action, $board_config, $lang;
\r
97 // remove default phpBB styles management
\r
98 if(isset($module['Styles']))
\r
100 $unset = array('Add_new', 'Create_new', 'Manage', 'Export');
\r
101 for($i=0; $i<count($unset); $i++)
\r
103 if(isset($module['Styles'][$unset[$i]]))
\r
105 unset($module['Styles'][$unset[$i]]);
\r
108 $module['Styles']['Menu'] = 'xs_frameset.'.$phpEx.'?action=menu&showwarning=1';
\r
111 $module_name = 'Extreme_Styles';
\r
112 $module[$module_name]['Styles_Management'] = 'xs_frameset.'.$phpEx.'?action=menu';
\r
113 for($i=0; $i<XS_SHOWNAV_MAX; $i++)
\r
116 if($i != XS_SHOWNAV_DOWNLOAD && ($board_config['xs_shownav'] & $num) > 0)
\r
118 $module[$module_name][$lang['xs_config_shownav'][$i]] = 'xs_frameset.'.$phpEx.'?action=' . $xs_shownav_action[$i];
\r
121 // add menu for style configuration
\r
122 foreach($board_config as $var => $value)
\r
124 if(substr($var, 0, 9) === 'xs_style_')
\r
126 $str = substr($var, 9);
\r
127 $module['Template_Config'][$str] = 'xs_frameset.'.$phpEx.'?action=style_config&tpl='.urlencode($str);
\r
133 if(!empty($setmodules))
\r
135 if(@function_exists('jr_admin_get_module_list'))
\r
137 $tmp_mod = $module;
\r
139 $module = $tmp_mod;
\r
140 xs_admin_override(true);
\r
146 // Global defines for eXtreme Styles mod administration panel
\r
148 define('STYLE_HEADER_START', 'xs_style_01<xs>');
\r
149 define('STYLE_HEADER_END', '</xs>');
\r
150 define('STYLE_HEADER_VERSION', '1');
\r
151 define('STYLE_EXTENSION', '.style');
\r
152 define('TAR_HEADER_PACK', 'a100A8A8A8A12A12A8A1A100A6A2A32A32A8A8a155a12');
\r
153 define('TAR_HEADER_UNPACK', 'a100filename/a8mode/a8uid/a8gid/a12size/a12mtime/a8checksum/a1typeflag/a100link/a6magic/a2version/a32uname/a32gname/a8devmajor/a8devminor/a155prefix/a12extra');
\r
154 define('XS_MAX_ITEMS_PER_STYLE', 32);
\r
155 define('XS_TEMP_DIR', '../cache/');
\r
156 define('XS_FTP_LOCAL', 'no_ftp');
\r
157 define('XS_UPDATE_STYLE', 1);
\r
158 define('XS_UPDATE_MOD', 2);
\r
159 define('XS_UPDATE_PHPBB', 3);
\r
160 define('XS_TPL_PATH', '../../xs_mod/tpl/');
\r
161 define('XS_BACKUP_PREFIX', 'backup.');
\r
162 define('XS_BACKUP_EXT', '.backup');
\r
163 define('XS_MAX_TIMEOUT', 600); // maximum timeout for downloads/import/installation
\r
165 $xs_row_class = array('row1', 'row2');
\r
167 $template_dir = 'templates/';
\r
169 $template->assign_vars(array(
\r
170 'XS_PATH' => '../xs_mod/',
\r
171 'XS_UL' => '<table width="100%" cellspacing="0" cellpadding="2" border="0">',
\r
172 'XS_UL2' => '</table>',
\r
173 'XS_LI' => '<tr><td width="20" align="center" valign="middle"><img src="../xs_mod/images/dot.gif" border="0" alt="" /></td><td align="left" valign="middle" width="100%"><span class="gen">',
\r
174 'XS_LI2' => '</span></td></tr>',
\r
175 'S_HIDDEN_FIELDS' => '<input type="hidden" name="sid" value="' . $userdata['session_id'] . '" />',
\r
178 if(!defined('NO_XS_HEADER'))
\r
180 $template->set_filenames(array(
\r
181 'xs_header' => XS_TPL_PATH . 'xs_header.tpl',
\r
182 'xs_footer' => XS_TPL_PATH . 'xs_footer.tpl',
\r
184 $template->preparse = 'xs_header';
\r
185 $template->postparse = 'xs_footer';
\r
186 $template->assign_block_vars('nav_left',array('ITEM' => '<a href="' . append_sid('xs_index.'.$phpEx) . '">' . $lang['xs_menu'] . '</a>'));
\r
190 header('Expires: ' . gmdate('D, d M Y H:i:s') . ' GMT');
\r
191 header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
\r
194 // Check compatibility with mods
\r
196 if(isset($config->data) && $config->data === $board_config && isset($config->data['mod_cat_hierarchy']))
\r
198 define('XS_MODS_CATEGORY_HIERARCHY210', true);
\r
200 elseif(defined('CACHE_THEMES') && @function_exists('cache_themes'))
\r
202 define('XS_MODS_CATEGORY_HIERARCHY', true);
\r
204 if(isset($theme['theme_public']))
\r
206 define('XS_MODS_ADMIN_TEMPLATES', true);
\r
211 // Get FTP configuration
\r
213 function get_ftp_config($action, $post = array(), $allow_local = false, $show_error = '')
\r
215 global $template, $board_config, $db, $lang, $HTTP_POST_VARS, $HTTP_SERVER_VARS;
\r
216 $board_config['xs_ftp_local'] = false;
\r
217 // check if ftp can be used
\r
218 if(!@function_exists('ftp_connect'))
\r
220 if($allow_local && xs_dir_writable('../templates/'))
\r
222 $board_config['xs_ftp_local'] = true;
\r
225 xs_error($lang['xs_ftp_error_fatal']);
\r
227 // check if we have configuration
\r
228 if(!empty($HTTP_POST_VARS['get_ftp_config']))
\r
230 $vars = array('xs_ftp_host', 'xs_ftp_login', 'xs_ftp_path');
\r
231 for($i=0; $i<count($vars); $i++)
\r
234 if($board_config[$var] !== $HTTP_POST_VARS[$var])
\r
236 $board_config[$var] = stripslashes($HTTP_POST_VARS[$var]);
\r
237 $sql = "UPDATE " . CONFIG_TABLE . " SET config_value = '" . xs_sql($board_config[$var]) . "' WHERE config_name = '{$var}'";
\r
238 $db->sql_query($sql);
\r
241 $board_config['xs_ftp_pass'] = stripslashes($HTTP_POST_VARS['xs_ftp_pass']);
\r
242 $board_config['xs_ftp_local'] = empty($HTTP_POST_VARS['xs_ftp_local']) ? false : true;
\r
243 // recache config table
\r
244 if(defined('XS_MODS_CATEGORY_HIERARCHY210'))
\r
247 if ( !empty($config) )
\r
249 $config->read(true);
\r
254 // check ftp configuration
\r
255 $xs_ftp_host = $board_config['xs_ftp_host'];
\r
256 if(empty($xs_ftp_host))
\r
258 $str = $HTTP_SERVER_VARS['HTTP_HOST'];
\r
259 $template->assign_vars(array(
\r
260 'HOST_GUESS' => str_replace(array('{HOST}', '{CLICK}'), array($str, 'document.ftp.xs_ftp_host.value=\''.$str.'\''), $lang['xs_ftp_host_guess'])
\r
264 $xs_ftp_login = $board_config['xs_ftp_login'];
\r
265 if(empty($xs_ftp_login))
\r
267 if(substr($dir, 0, 6) === '/home/')
\r
269 $str = substr($dir, 6);
\r
270 $pos = strpos($str, '/');
\r
273 $str = substr($str, 0, $pos);
\r
274 $template->assign_vars(array(
\r
275 'LOGIN_GUESS' => str_replace(array('{LOGIN}', '{CLICK}'), array($str, 'document.ftp.xs_ftp_login.value=\''.$str.'\''), $lang['xs_ftp_login_guess'])
\r
280 $xs_ftp_path = $board_config['xs_ftp_path'];
\r
281 if(empty($xs_ftp_path))
\r
283 if(substr($dir, 0, 6) === '/home/');
\r
284 $str = substr($dir, 6);
\r
285 $pos = strpos($str, '/');
\r
288 $str = substr($str, $pos + 1);
\r
289 $pos = strrpos($str, 'admin');
\r
292 $str = substr($str, 0, $pos-1);
\r
293 $template->assign_vars(array(
\r
294 'PATH_GUESS' => str_replace(array('{PATH}', '{CLICK}'), array($str, 'document.ftp.xs_ftp_path.value=\''.$str.'\''), $lang['xs_ftp_path_guess'])
\r
299 if($allow_local && xs_dir_writable('../templates/'))
\r
301 $template->assign_block_vars('xs_ftp_local', array());
\r
305 $template->assign_block_vars('xs_ftp_nolocal', array());
\r
307 $str = '<input type="hidden" name="get_ftp_config" value="1" />';
\r
308 foreach($post as $var => $value)
\r
310 $str .= '<input type="hidden" name="' . htmlspecialchars($var) . '" value="' . htmlspecialchars($value) . '" />';
\r
312 $template->assign_vars(array(
\r
313 'FORM_ACTION' => $action,
\r
314 'S_EXTRA_FIELDS' => $str,
\r
315 'XS_FTP_HOST' => $xs_ftp_host,
\r
316 'XS_FTP_LOGIN' => $xs_ftp_login,
\r
317 'XS_FTP_PATH' => $xs_ftp_path,
\r
321 $template->assign_block_vars('error', array('MSG' => $show_error));
\r
323 $template->set_filenames(array('config' => XS_TPL_PATH . 'ftp.tpl'));
\r
324 $template->pparse('config');
\r
329 function xs_ftp_connect($action, $post = array(), $allow_local = false)
\r
331 global $ftp, $board_config, $HTTP_POST_VARS, $phpEx, $lang, $template;
\r
332 $HTTP_POST_VARS['get_ftp_config'] = '';
\r
333 if($allow_local && !empty($board_config['xs_ftp_local']))
\r
335 $ftp = XS_FTP_LOCAL;
\r
338 $ftp = @ftp_connect($board_config['xs_ftp_host']);
\r
341 get_ftp_config($action, $post, $allow_local, str_replace('{HOST}', $board_config['xs_ftp_host'], $lang['xs_ftp_error_connect']));
\r
343 $res = @ftp_login($ftp, $board_config['xs_ftp_login'], $board_config['xs_ftp_pass']);
\r
346 get_ftp_config($action, $post, $allow_local, $lang['xs_ftp_error_login']);
\r
348 $res = @ftp_chdir($ftp, $board_config['xs_ftp_path']);
\r
351 get_ftp_config($action, $post, $allow_local, str_replace('{DIR}', $board_config['xs_ftp_path'], $lang['xs_ftp_error_chdir']));
\r
353 // check current directory
\r
354 $current_dir = @ftp_pwd($ftp);
\r
355 $list = @ftp_nlist($ftp, $current_dir);
\r
356 for($i=0; $i<count($list); $i++)
\r
358 $list[$i] = strtolower(basename($list[$i]));
\r
361 $check = array('extension.inc', 'templates', 'xs_mod');
\r
362 $found = array(false, false, false);
\r
363 for($i=0; $i<count($list); $i++)
\r
365 for($j=0; $j<count($check); $j++)
\r
367 if($list[$i] === $check[$j])
\r
374 for($i=0; $i<count($check); $i++)
\r
383 get_ftp_config($action, $post, $allow_local, $lang['xs_ftp_error_nonphpbbdir']);
\r
385 $HTTP_POST_VARS['get_ftp_config'] = '1';
\r
388 // get .style file header
\r
389 function xs_get_style_header($filename, $str = '')
\r
392 header format (v0.01):
\r
394 - header size (4 bytes)
\r
395 - file size (4 bytes)
\r
396 - number of entries (1 byte)
\r
397 - entries sizes (number_of_entries bytes)
\r
400 - gzcompressed tar of style (no crc check in tar)
\r
407 global $xs_header_error, $lang;
\r
408 $xs_header_error = '';
\r
411 $f = @fopen($filename, 'rb');
\r
414 $xs_header_error = $lang['xs_style_header_error_file'];
\r
417 $str = fread($f, 10240);
\r
420 if(substr($str, 0, strlen(STYLE_HEADER_START)) !== STYLE_HEADER_START)
\r
422 if(substr($str, 0, 7) === 'error: ')
\r
424 $xs_header_error = '<br /><br />' . $lang['xs_style_header_error_server'] . substr($str, 7);
\r
428 $xs_header_error = $lang['xs_style_header_error_invalid'];
\r
432 $start = strlen(STYLE_HEADER_START);
\r
433 $str1 = substr($str, $start, 8);
\r
434 $data = unpack('Nvar1/Nvar2', $str1);
\r
436 $header_size = $data['var1'];
\r
437 $filesize = $data['var2'];
\r
438 $total = ord($str{$start});
\r
442 $xs_header_error = $lang['xs_style_header_error_invalid'];
\r
445 $items_len = array();
\r
446 for($i=0; $i<$total; $i++)
\r
448 $items_len[$i] = ord($str{$i+$start});
\r
453 for($i=0; $i<$total; $i++)
\r
455 $str1 = substr($str, $start, $items_len[$i]);
\r
456 if($i == 0) $tpl = $str1;
\r
457 elseif($i == 1) $comment = $str1;
\r
458 else $items[] = $str1;
\r
459 $start += $items_len[$i];
\r
461 if(substr($str, $start, strlen(STYLE_HEADER_END)) !== STYLE_HEADER_END)
\r
463 $xs_header_error = $lang['xs_style_header_error_invalid'];
\r
467 'template' => $tpl,
\r
468 'styles' => $items,
\r
469 'date' => @filemtime($filename),
\r
470 'comment' => $comment,
\r
471 'offset' => $header_size,
\r
472 'filename' => $filename,
\r
473 'filesize' => $filesize,
\r
478 // check if cache is writable
\r
479 function xs_check_cache($filename)
\r
481 // check if filename is valid
\r
482 global $str, $template, $lang;
\r
483 if(substr($filename, 0, strlen($template->cachedir)) !== $template->cachedir)
\r
485 $str .= $lang['xs_check_filename'] . "<br />\n";
\r
490 // try to open file
\r
491 $file = @fopen($filename, 'w');
\r
494 $str .= sprintf($lang['xs_check_openfile1'], $filename) . "<br />\n";
\r
495 // try to create directories
\r
496 $dir = substr($filename, strlen($template->cachedir), strlen($filename));
\r
497 $dirs = explode('/', $dir);
\r
498 $path = $template->cachedir;
\r
500 if(!@is_dir($path))
\r
502 $str .= sprintf($lang['xs_check_nodir'], $path) . "<br />\n";
\r
505 $str .= sprintf($lang['xs_check_nodir2'], $path) . "<br />\n";
\r
510 $str .= sprintf($lang['xs_check_createddir'], $path) . "<br />\n";
\r
511 @chmod($path, 0777);
\r
516 $str .= sprintf($lang['xs_check_dir'] , $path) . "<br />\n";
\r
518 if(count($dirs) > 0)
\r
519 for($i=0; $i<count($dirs)-1; $i++)
\r
525 $path .= $dirs[$i];
\r
526 if(!@is_dir($path))
\r
528 $str .= sprintf($lang['xs_check_nodir'], $path) . "<br />\n";
\r
531 $str .= sprintf($lang['xs_check_nodir2'], $path) . "<br />\n";
\r
536 $str .= sprintf($lang['xs_check_createddir'], $path) . "<br />\n";
\r
537 @chmod($path, 0777);
\r
542 $str .= sprintf($lang['xs_check_dir'] , $path) . "<br />\n";
\r
545 // try to open file again after directories were created
\r
546 $file = @fopen($filename, 'w');
\r
550 $str .= sprintf($lang['xs_check_openfile2'], $filename) . "<br />\n";
\r
553 $str .= sprintf($lang['xs_check_ok'], $filename) . "<br />\n";
\r
554 fputs($file, ' ');
\r
556 @chmod($filename, 0777);
\r
561 // run ftp commands
\r
562 function ftp_myexec($list)
\r
564 global $ftp, $ftp_error, $ftp_log, $ftp_host, $ftp_login, $ftp_pass, $lang;
\r
566 $ftp_log = array();
\r
569 // checking ftp extensions
\r
570 if(!@function_exists('ftp_connect'))
\r
572 $ftp_log[] = $ftp_error = $lang['xs_ftp_log_disabled'];
\r
575 // connect to server
\r
576 $ftp_log[] = str_replace('{HOST}', "{$ftp_login}:*@{$ftp_host}", $lang['xs_ftp_log_connecting']);
\r
577 $ftp = @ftp_connect($ftp_host);
\r
580 $ftp_log[] = $ftp_error = str_replace('{HOST}', $ftp_host, $lang['xs_ftp_log_noconnect']);
\r
583 $ftp_log[] = $lang['xs_ftp_log_connected'];
\r
585 $logged_in = @ftp_login($ftp, $ftp_login, $ftp_pass);
\r
588 $ftp_log[] = $ftp_error = str_replace('{USER}', $ftp_login, $lang['xs_ftp_log_nologin']);
\r
592 $ftp_log[] = $lang['xs_ftp_log_loggedin'];
\r
594 if(!ftp_myexec2($ftp, $list))
\r
600 $ftp_log[] = $lang['xs_ftp_log_end'];
\r
604 // remove all files via ftp
\r
605 function ftp_remove_all($ftp)
\r
607 // get current directory
\r
608 $root_dir = @ftp_pwd($ftp);
\r
609 // get list of files
\r
610 $files = @ftp_nlist($ftp, $root_dir);
\r
611 // remove files/directories
\r
612 for($i=0; $i<count($files); $i++)
\r
614 $res = @ftp_chdir($ftp, $files[$i]);
\r
617 ftp_remove_all($ftp);
\r
618 @ftp_chdir($ftp, $root_dir);
\r
619 @ftp_rmdir($ftp, $files[$i]);
\r
623 if(!@ftp_delete($ftp, $files[$i]))
\r
625 @ftp_rmdir($ftp, $files[$i]);
\r
629 // change directory back
\r
630 @ftp_chdir($ftp, $root_dir);
\r
633 // execute ftp command. recursive.
\r
634 function ftp_myexec2($ftp, $list)
\r
636 global $ftp_log, $ftp_error, $lang;
\r
637 // getting current directory
\r
638 $root_dir = @ftp_pwd($ftp);
\r
639 if($root_dir === false)
\r
641 $ftp_log[] = $ftp_error = $lang['xs_ftp_log_nopwd'];
\r
644 $current_dir = strlen($root_dir) ? $root_dir . '/' : '';
\r
646 for($i=0; $i<count($list); $i++)
\r
649 if($item['command'] == 'mkdir')
\r
651 // create new directory
\r
652 $res = @ftp_mkdir($ftp, $item['dir']);
\r
655 $ftp_log[] = $ftp_error = str_replace('{DIR}', $item['dir'], $lang['xs_ftp_log_nomkdir']);
\r
656 if(empty($item['ignore']))
\r
663 $ftp_log[] = str_replace('{DIR}', $item['dir'], $lang['xs_ftp_log_mkdir']);
\r
666 elseif($item['command'] == 'chdir')
\r
668 // change current directory
\r
669 $res = @ftp_chdir($ftp, $item['dir']);
\r
672 $ftp_log[] = $ftp_error = str_replace('{DIR}', $item['dir'], $lang['xs_ftp_log_nochdir']);
\r
673 if(empty($item['ignore']))
\r
680 $ftp_log[] = str_replace('{DIR}', $item['dir'], $lang['xs_ftp_log_chdir']);
\r
683 elseif($item['command'] == 'cdup')
\r
685 // change current directory
\r
686 $res = @ftp_cdup($ftp);
\r
689 $ftp_log[] = $ftp_error = str_replace('{DIR}', '..', $lang['xs_ftp_log_nochdir']);
\r
690 if(empty($item['ignore']))
\r
697 $ftp_log[] = str_replace('{DIR}', '..', $lang['xs_ftp_log_chdir']);
\r
700 elseif($item['command'] == 'rmdir')
\r
702 // remove directory
\r
703 $res = @ftp_rmdir($ftp, $item['dir']);
\r
706 $ftp_log[] = $ftp_error = str_replace('{DIR}', $item['dir'], $lang['xs_ftp_log_normdir']);
\r
707 if(empty($item['ignore']))
\r
714 $ftp_log[] = str_replace('{DIR}', $item['dir'], $lang['xs_ftp_log_rmdir']);
\r
717 elseif($item['command'] == 'upload')
\r
720 $res = @ftp_put($ftp, $current_dir . $item['remote'], $item['local'], FTP_BINARY);
\r
723 $ftp_log[] = $ftp_error = str_replace('{FILE}', $item['remote'], $lang['xs_ftp_log_noupload']);
\r
724 if(empty($item['ignore']))
\r
731 $ftp_log[] = str_replace('{FILE}', $item['remote'], $lang['xs_ftp_log_upload']);
\r
734 elseif($item['command'] == 'chmod')
\r
737 $res = @ftp_chmod($ftp, $item['mode'], $current_dir . $item['file']);
\r
740 $ftp_log[] = str_replace('{FILE}', $item['file'], $lang['xs_ftp_log_nochmod']);
\r
741 if(empty($item['ignore']))
\r
748 $ftp_log[] = str_replace(array('{FILE}', '{MODE}'), array($item['file'], $item['mode']), $lang['xs_ftp_log_chmod']);
\r
751 elseif($item['command'] == 'exec')
\r
753 $res = ftp_myexec2($ftp, $item['list']);
\r
759 elseif($item['command'] == 'removeall')
\r
761 ftp_remove_all($ftp);
\r
765 $ftp_log[] = str_replace('{COMMAND}', $item['command'], $lang['xs_ftp_log_invalidcommand']);
\r
766 if(empty($item['ignore']))
\r
772 // changing current directory back
\r
773 $ftp_log[] = str_replace('{DIR}', $root_dir, $lang['xs_ftp_log_chdir2']);
\r
774 if(!@ftp_chdir($ftp, $root_dir))
\r
776 $ftp_log[] = $ftp_error = str_replace('{DIR}', $root_dir, $lang['xs_ftp_log_nochdir2']);
\r
782 // return data from theme_info.cfg
\r
783 function xs_get_themeinfo($tpl)
\r
785 // Get contents of theme_info.cfg
\r
786 // Run inside function to avoid theme_info.cfg accessing global variables
\r
787 $tpl = str_replace(array('/', '\\'), array('', ''), $tpl);
\r
788 include('../templates/' . $tpl . '/theme_info.cfg');
\r
789 return isset($$tpl) ? $$tpl : array();
\r
793 function xs_install_style($tpl, $num)
\r
796 $data = xs_get_themeinfo($tpl);
\r
797 if(empty($data[$num]))
\r
801 $data = $data[$num];
\r
802 if(empty($data['style_name']))
\r
806 $sql = "SELECT themes_id FROM " . THEMES_TABLE . " WHERE style_name='" . xs_sql($data['style_name']) . "'";
\r
807 if(!$result = $db->sql_query($sql))
\r
811 $row = $db->sql_fetchrow($result);
\r
812 if(!empty($row['themes_id']))
\r
818 foreach($data as $var => $value)
\r
820 $vars[] = xs_sql($var);
\r
821 $values[] = xs_sql(stripslashes($value));
\r
823 $sql = "INSERT INTO " . THEMES_TABLE . " (" . implode(', ', $vars) . ") VALUES ('" . implode("', '", $values) . "')";
\r
824 if(!$result = $db->sql_query($sql))
\r
828 // recache themes table
\r
829 if(defined('XS_MODS_CATEGORY_HIERARCHY210'))
\r
832 if ( empty($themes) )
\r
834 $themes = new themes();
\r
836 if ( !empty($themes) )
\r
838 $themes->read(true);
\r
841 // add configuration
\r
843 if($template->add_config($tpl))
\r
845 define('REFRESH_NAVBAR', true);
\r
850 // generate theme_info.cfg for template
\r
851 function xs_generate_themeinfo($theme_rowset, $export, $exportas, $total)
\r
853 global $HTTP_POST_VARS;
\r
854 $vars = array('template_name', 'style_name', 'head_stylesheet', 'body_background', 'body_bgcolor', 'body_text', 'body_link', 'body_vlink', 'body_alink', 'body_hlink', 'tr_color1', 'tr_color2', 'tr_color3', 'tr_class1', 'tr_class2', 'tr_class3', 'th_color1', 'th_color2', 'th_color3', 'th_class1', 'th_class2', 'th_class3', 'td_color1', 'td_color2', 'td_color3', 'td_class1', 'td_class2', 'td_class3', 'fontface1', 'fontface2', 'fontface3', 'fontsize1', 'fontsize2', 'fontsize3', 'fontcolor1', 'fontcolor2', 'fontcolor3', 'span_class1', 'span_class2', 'span_class3', 'img_size_poll', 'img_size_privmsg');
\r
855 $theme_data = '<?php'."\n\n";
\r
856 $theme_data .= "//\n// eXtreme Styles mod (compatible with phpBB 2.0.x) auto-generated theme config file for $exportas\n// Do not change anything in this file unless you know exactly what you are doing!\n//\n\n";
\r
857 for($i = 0; $i < count($theme_rowset); $i++)
\r
859 $id = $theme_rowset[$i]['themes_id'];
\r
860 $theme_name = $theme_rowset[$i]['style_name'];
\r
861 for($j=0; $j<$total; $j++)
\r
863 if(!empty($HTTP_POST_VARS['export_style_name_'.$j]) && $HTTP_POST_VARS['export_style_id_'.$j] == $id)
\r
865 $theme_name = stripslashes($HTTP_POST_VARS['export_style_name_'.$j]);
\r
866 $theme_rowset[$i]['style_name'] = $theme_name;
\r
869 for($j=0; $j<count($vars); $j++)
\r
872 $val = $theme_rowset[$i][$key];
\r
873 if($key === 'style_name')
\r
875 $theme_data .= '${\'' . $exportas . "'}[$i]['$key'] = \"" . str_replace(array("'", '"'), array("\'", "\\\""), $theme_name) . "\";\n";
\r
877 elseif($key === 'template_name')
\r
879 $theme_data .= '${\'' . $exportas . "'}[$i]['$key'] = \"" . str_replace(array("'", '"'), array("\'", "\\\""), $exportas) . "\";\n";
\r
883 $theme_data .= '${\'' . $exportas . "'}[$i]['$key'] = \"" . str_replace(array("'", '"'), array("\'", "\\\""), str_replace($export, $exportas, $val)) . "\";\n";
\r
886 $theme_data .= "\n";
\r
888 $theme_data .= '?' . '>'; // Done this to prevent highlighting editors getting confused!
\r
889 return $theme_data;
\r
892 // Checks if directory is writable
\r
893 function xs_dir_writable($dir)
\r
895 $filename = 'tmp_' . time();
\r
896 $f = @fopen($dir . $filename, 'wb');
\r
900 @unlink($dir . $filename);
\r
906 // Write to file. Create directory if necessary
\r
907 function xs_write_file($filename, $data)
\r
909 $f = @fopen($filename, 'wb');
\r
912 // try to create directories
\r
913 $pos = strrpos($filename, '/');
\r
918 $dir = substr($filename, 0, $pos);
\r
919 xs_create_dir($dir);
\r
920 $f = @fopen($filename, 'wb');
\r
928 @chmod($filename, 0777);
\r
932 // Create local directory
\r
933 function xs_create_dir($dir)
\r
939 // remove trailing /
\r
940 if(substr($dir, strlen($dir) - 1) === '/')
\r
942 $dir = substr($dir, 0, strlen($dir) - 1);
\r
948 if($dir === '.' || $dir === '..')
\r
952 $res = @mkdir($dir, 0777);
\r
957 // try to create previous directory
\r
958 $pos = strrpos($dir, '/');
\r
963 $dir1 = substr($dir, 0, $pos);
\r
964 $dir2 = substr($dir, $pos+1);
\r
965 if($dir2 === '.' || $dir2 === '..')
\r
969 if(!xs_create_dir($dir1))
\r
973 $res = @mkdir($dir2, 0777);
\r
974 return $res ? true : false;
\r
977 // replacement for in_array() (because of compatibility problems)
\r
978 function xs_in_array($needle, $haystack)
\r
980 for($i=0; $i<sizeof($haystack); $i++)
\r
982 if($haystack[$i] == $needle)
\r
990 // show error and exit
\r
991 function xs_error($error, $line = 0, $file = '')
\r
993 global $template, $lang;
\r
996 $error = basename($file) . '(' . $line . '): ' . $error;
\r
998 $template->set_filenames(array('errormsg' => XS_TPL_PATH . 'message.tpl'));
\r
999 $template->assign_vars(array(
\r
1000 'MESSAGE_TITLE' => $lang['Error'],
\r
1001 'MESSAGE_TEXT' => $error
\r
1003 $template->pparse('errormsg');
\r
1007 // show message and exit
\r
1008 function xs_message($title, $message)
\r
1011 $template->set_filenames(array('msg' => XS_TPL_PATH . 'message.tpl'));
\r
1012 $template->assign_vars(array(
\r
1013 'MESSAGE_TITLE' => $title,
\r
1014 'MESSAGE_TEXT' => $message
\r
1016 $template->pparse('msg');
\r
1020 // pack style to .style
\r
1021 function pack_style($name, $newname, $themes, $comment)
\r
1024 header format (v0.01):
\r
1026 - header size (4 bytes)
\r
1027 - file size (4 bytes)
\r
1028 - number of entries (1 byte)
\r
1029 - entries sizes (number_of_entries bytes)
\r
1032 - gzcompressed tar of style (no crc check in tar)
\r
1039 global $phpbb_root_path, $template_dir;
\r
1040 $data = gzcompress(pack_dir($phpbb_root_path . $template_dir . $name, '', $name, $newname));
\r
1041 $items_data = chr(strlen($newname)) . chr(strlen($comment));
\r
1042 $items_str = $newname . $comment;
\r
1043 for($i=0; $i<count($themes); $i++)
\r
1045 $str = $themes[$i]['style_name'];
\r
1046 $items_data .= chr(strlen($str));
\r
1047 $items_str .= $str;
\r
1049 $header_size = strlen(STYLE_HEADER_START) + 8 + 1 + strlen($items_data) + strlen($items_str) + strlen(STYLE_HEADER_END);
\r
1050 $filesize = $header_size + strlen($data);
\r
1051 $header = STYLE_HEADER_START . pack('NN', $header_size, $filesize) . chr(strlen($items_data)) . $items_data . $items_str . STYLE_HEADER_END;
\r
1052 return $header . $data;
\r
1056 function pack_dir($dir1, $dir2, $search, $replace)
\r
1058 global $pack_error, $pack_list, $pack_replace, $lang;
\r
1059 // replacements in content
\r
1060 $search2 = array('templates/'.$search.'/'.$search, 'templates/'.$search);
\r
1061 $replace2 = array('templates/'.$replace.'/'.$replace, 'templates/'.$replace);
\r
1062 // replacements in filename
\r
1063 $search3 = './'.$search;
\r
1064 $replace3 = './'.$replace;
\r
1069 $dir = $dir1 . '/' . $dir2;
\r
1070 $res = @opendir($dir);
\r
1074 $pack_error = str_replace('{DIR}', $lang['xs_export_no_open_dir'], $dir);
\r
1077 // get list of files/directories
\r
1079 $subdir = array();
\r
1080 while(($file = readdir($res)) !== false)
\r
1082 if($file !== '.' && $file !== '..')
\r
1084 if(@is_dir($dir . '/' . $file))
\r
1086 $subdir[] = $file;
\r
1088 elseif(@is_file($dir . '/' . $file))
\r
1095 // add current directory
\r
1096 $base_dir = ($dir2 ? $dir2 : '.') . '/';
\r
1098 'filename' => $base_dir,
\r
1099 'mode' => '40777',
\r
1102 'size' => decoct(0),
\r
1103 'mtime' => decoct(@filemtime($dir)),
\r
1104 'checksum' => '0', // ignore checksum
\r
1105 'typeflag' => '5',
\r
1107 'magic' => "ustar",
\r
1109 'uname' => 'user',
\r
1110 'gname' => 'group',
\r
1116 $header_str = pack(TAR_HEADER_PACK, $header['filename'], $header['mode'], $header['uid'], $header['gid'], $header['size'], $header['mtime'], $header['checksum'], $header['typeflag'], $header['linkname'], $header['magic'], $header['version'], $header['uname'], $header['gname'], $header['devmajor'], $header['devminor'], $header['prefix'], $header['extra']);
\r
1119 $str .= $header_str . $file_str . $extra_str;
\r
1121 for($i=0; $i<count($files); $i++)
\r
1123 $file = $files[$i];
\r
1124 $header['filename'] = $base_dir . $file;
\r
1125 $pack_list[] = $header['filename'];
\r
1126 if(isset($pack_replace[$header['filename']]))
\r
1128 $file_str = $pack_replace[$header['filename']];
\r
1129 $file_size = strlen($file_str);
\r
1133 $f = @fopen($dir . '/' . $file, 'rb');
\r
1136 $pack_error = str_replace('{FILE}', $dir . '/' . $file, $lang['xs_export_no_open_file']);
\r
1139 $file_size = @filesize($dir . '/' . $file);
\r
1142 $file_str = fread($f, $file_size);
\r
1148 if(strlen($file_str) != $file_size)
\r
1150 $pack_error = str_replace('{FILE}', $dir . '/' . $file, $lang['xs_export_no_read_file']);
\r
1154 if($search !== $replace)
\r
1156 $file_str = str_replace($search2, $replace2, $file_str);
\r
1159 if($search !== $replace && substr($header['filename'], strlen($header['filename']) - 4) !== '.tpl')
\r
1161 if(substr($header['filename'], 0, strlen($search)) === $search)
\r
1163 $header['filename'] = $replace . substr($header['filename'], strlen($search));
\r
1165 elseif(substr($header['filename'], 0, strlen($search3)) === $search3)
\r
1167 $header['filename'] = $replace3 . substr($header['filename'], strlen($search3));
\r
1170 /* echo 'filename: ', $header['filename'], '<br />';
\r
1171 if($header['filename'] === './overall_header.tpl')
\r
1173 echo 'overall_header.tpl:<br /><hr />', nl2br(htmlspecialchars($file_str)), '<br /><hr /><br />';
\r
1175 $size = strlen($file_str);
\r
1176 $header['size'] = decoct($size);
\r
1177 $header['typeflag'] = '0';
\r
1178 $header['mode'] = '100666';
\r
1179 $full_size = floor(($size + 511) / 512) * 512;
\r
1180 $extra_str = $full_size > $size ? str_repeat("\0", $full_size - $size) : '';
\r
1181 $header_str = pack(TAR_HEADER_PACK, $header['filename'], $header['mode'], $header['uid'], $header['gid'], $header['size'], $header['mtime'], $header['checksum'], $header['typeflag'], $header['linkname'], $header['magic'], $header['version'], $header['uname'], $header['gname'], $header['devmajor'], $header['devminor'], $header['prefix'], $header['extra']);
\r
1182 $str .= $header_str . $file_str . $extra_str;
\r
1184 // add all directories
\r
1185 for($i=0; $i<count($subdir); $i++)
\r
1187 $str .= pack_dir($dir1, $dir2 ? $dir2 . '/' . $subdir[$i] : $subdir[$i], $search, $replace);
\r
1191 $str .= str_repeat("\0", 1024);
\r
1196 // save export configuration
\r
1197 function set_export_method($method, $data)
\r
1199 global $db, $board_config;
\r
1200 $data['method'] = $method;
\r
1201 $str = xs_sql(serialize($data));
\r
1202 $sql = isset($board_config['xs_export_data']) ? "UPDATE " . CONFIG_TABLE . " SET config_value='{$str}' WHERE config_name='xs_export_data'" : "INSERT INTO " . CONFIG_TABLE . " (config_name, config_value) VALUES ('xs_export_data', '{$str}')";
\r
1203 $db->sql_query($sql);
\r
1207 function xs_download_file($filename, $content, $content_type = '')
\r
1209 if(empty($content_type))
\r
1211 $content_type = 'application/unknown';
\r
1213 header('Content-Type: ' . $content_type);
\r
1214 header('Content-Length: ' . strlen($content));
\r
1215 header('Expires: ' . gmdate('D, d M Y H:i:s') . ' GMT');
\r
1218 header('Content-Disposition: inline; filename="' . $filename . '"');
\r
1220 header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
\r
1221 header('Pragma: public');
\r
1225 // strip slashes for sql
\r
1226 function xs_sql($sql, $strip = false)
\r
1230 $sql = stripslashes($sql);
\r
1232 return str_replace('\\\'', '\'\'', addslashes($sql));
\r
1235 // clean template name
\r
1236 function xs_tpl_name($name)
\r
1238 return str_replace(array('\\', '/', "'", '"'), array('','','',''), $name);
\r
1241 // close database and maybe do some other stuff
\r
1242 function xs_exit()
\r
1252 // check directory name/filename
\r
1253 function xs_fix_dir($dir)
\r
1255 $dir = str_replace('\\', '/', $dir);
\r
1256 $dir = str_replace('../', './', $dir);
\r
1257 while(strlen($dir > 1) && substr($dir, strlen($dir) - 2) === '..')
\r
1259 $dir = substr($dir, 0, strlen($dir) - 1);
\r