phpBB.com/mods/umil', E_USER_ERROR); } include($phpbb_root_path . 'umil/umil.' . $phpEx); } /** * UMIL - Unified MOD Installation File class Front End */ class umil_frontend extends umil { // The title of the mod var $title = ''; // Were there any errors so far (used when displaying results)? var $errors = false; // Was anything done at all (used when displaying results)? var $results = false; // The file we will record any errors in var $error_file = ''; // Force displaying of the results? var $force_display_results = false; /** * Constructor * * @param string $title The title to display * @param bool $auto_display_results Automatically display results or not? * @param bool $force_display_results Allows you to force this to automatically display all results * @param object|bool $db Allows you to use your own $db object instead of the global $db */ function umil_frontend($title = '', $auto_display_results = false, $force_display_results = false, $db = false) { global $phpbb_root_path, $phpEx, $template, $user; $this->title = $title; // we must call the main constructor $this->umil(false, $db); $this->auto_display_results = $auto_display_results; $this->force_display_results = $force_display_results; $user->add_lang('install'); // Setup the template $template->set_custom_template($phpbb_root_path . 'umil/style', 'umil'); // The UMIL template is never stored in the database $user->theme['template_storedb'] = false; $template->set_filenames(array( 'body' => 'index_body.html', )); $title_explain = (isset($user->lang[$title . '_EXPLAIN'])) ? $user->lang[$title . '_EXPLAIN'] : ''; $title = (isset($user->lang[$title])) ? $user->lang[$title] : $title; page_header($title, false); $template->assign_vars(array( 'SQL_LAYER' => $this->db->sql_layer, 'UMIL_ROOT_PATH' => $phpbb_root_path . 'umil/', 'U_ADM_INDEX' => append_sid("{$phpbb_root_path}adm/index.$phpEx", false, true, $user->session_id), 'U_INDEX' => append_sid("{$phpbb_root_path}index.$phpEx"), 'PAGE_TITLE' => $title, 'L_TITLE' => $title, 'L_TITLE_EXPLAIN' => $title_explain, )); } /** * Display Stages * * Outputs the stage list * * @param array $stages The list of stages. * Either send the array like: array('CONFIGURE', 'INSTALL') or you can send it like array('CONFIGURE' => array('url' => $url), 'INSTALL' => array('url' => $url)) or you can use a mixture of the two. * @param int $selected The current stage */ function display_stages($stages, $selected = 1) { global $template, $user; $i = 1; foreach ($stages as $stage => $data) { if (!is_array($data)) { $stage = $data; $data = array(); } $template->assign_block_vars('l_block', array( 'L_TITLE' => (isset($user->lang[$stage])) ? $user->lang[$stage] : $stage, 'U_TITLE' => (isset($data['url'])) ? $data['url'] : false, 'S_COMPLETE' => ($i < $selected) ? true : false, 'S_SELECTED' => ($i == $selected) ? true : false, )); $i++; } } /** * Confirm Box * * Displays an inline confirm box (makes it possible to have a nicer looking confirm box shown if you want to use stages) * * @param boolean $check True for checking if confirmed (without any additional parameters) and false for displaying the confirm box * @param string $title Title/Message used for confirm box. * message text is _CONFIRM appended to title. * If title cannot be found in user->lang a default one is displayed * If title_CONFIRM cannot be found in user->lang the text given is used. * @param string $hidden Hidden variables */ function confirm_box($check, $title = '', $hidden = '', $html_body = 'index_body.html') { if (!$check) { global $template; $template->assign_var('S_CONFIRM', true); } if (is_array($hidden)) { $hidden = build_hidden_fields($hidden); } return confirm_box($check, $title, $hidden, $html_body); } /** * Display Options * * Display a set of options from an inputted array. * * @param array $options This is the array of options. Format it like you would if you were using the setup in acp_board except only enter what would go in the 'vars' array. */ function display_options($options) { global $phpbb_root_path, $phpEx, $template, $user; foreach ($options as $name => $vars) { if (!is_array($vars) && strpos($name, 'legend') === false) { continue; } if (strpos($name, 'legend') !== false) { $template->assign_block_vars('options', array( 'S_LEGEND' => true, 'LEGEND' => (isset($user->lang[$vars])) ? $user->lang[$vars] : $vars) ); continue; } $type = explode(':', $vars['type']); $l_explain = ''; if (isset($vars['explain']) && $vars['explain'] && isset($vars['lang_explain'])) { $l_explain = (isset($user->lang[$vars['lang_explain']])) ? $user->lang[$vars['lang_explain']] : $vars['lang_explain']; } else if (isset($vars['explain']) && $vars['explain']) { $l_explain = (isset($user->lang[$vars['lang'] . '_EXPLAIN'])) ? $user->lang[$vars['lang'] . '_EXPLAIN'] : ''; } $content = $this->build_cfg_template($type, $name, $vars); if (!sizeof($content)) { continue; } $template->assign_block_vars('options', array( 'KEY' => $name, 'TITLE' => (isset($user->lang[$vars['lang']])) ? $user->lang[$vars['lang']] : $vars['lang'], 'S_EXPLAIN' => (isset($vars['explain'])) ? $vars['explain'] : false, 'TITLE_EXPLAIN' => $l_explain, 'CONTENT' => $content['tpl'], // Find user link 'S_FIND_USER' => (isset($content['find_user'])) ? true : false, 'U_FIND_USER' => (isset($content['find_user'])) ? append_sid("{$phpbb_root_path}memberlist.$phpEx", array('mode' => 'searchuser', 'form' => 'select_user', 'field' => 'username', 'select_single' => 'true', 'form' => 'umil', 'field' => $content['find_user_field'])) : '', )); } } /** * Display results * * Display the results from the previous command, or you may enter your own command/result if you would like. * * @param string $command The command you would like shown (leave blank to use the last command saved in $this->command) * @param string $result The result you would like shown (leave blank to use the last result saved in $this->result) */ function display_results($command = '', $result = '') { global $config, $template, $user, $phpbb_root_path; $command = ($command) ? $command : $this->command; $command = (isset($user->lang[$command])) ? $user->lang[$command] : $command; $result = ($result) ? $result : $this->result; $result = (isset($user->lang[$result])) ? $user->lang[$result] : $result; $this->results = true; if ($result != $user->lang['SUCCESS']) { // Check if the umil/error_files/ is writable if (!is_writable("{$phpbb_root_path}umil/error_files/")) { phpbb_chmod("{$phpbb_root_path}umil/error_files/", CHMOD_ALL); } // Hopefully it is writable now. If not there is nothing we can do. if (is_writable("{$phpbb_root_path}umil/error_files/")) { if ($this->errors == false) { $this->errors = true; // Setting up an error recording file $append = 0; $this->error_file = "{$phpbb_root_path}umil/error_files/" . strtolower($this->title) . '.txt'; while (file_exists($this->error_file)) { $this->error_file = "{$phpbb_root_path}umil/error_files/" . strtolower($this->title) . $append . '.txt'; $append++; } } if (file_exists($this->error_file) && filesize($this->error_file)) { $fp = fopen($this->error_file, 'rb'); $contents = fread($fp, filesize($this->error_file)); fclose($fp); phpbb_chmod($this->error_file, CHMOD_ALL); } else { $contents = ((isset($user->lang[$this->title])) ? $user->lang[$this->title] : $this->title) . "\n"; $contents .= 'PHP Version: ' . phpversion() . "\n"; $contents .= 'DBMS: ' . $this->db->sql_server_info() . "\n"; $contents .= 'phpBB3 Version: ' . $config['version'] . "\n\n"; } $contents .= "{$command}\n{$result}\n\n"; $fp = fopen($this->error_file, 'wb'); fwrite($fp, $contents); fclose($fp); phpbb_chmod($this->error_file, CHMOD_ALL); } else { $this->errors = true; } } if ($result != $user->lang['SUCCESS'] || $this->force_display_results == true)// || defined('DEBUG')) { $template->assign_block_vars('results', array( 'COMMAND' => $command, 'RESULT' => $result, 'S_SUCCESS' => ($result == $user->lang['SUCCESS']) ? true : false, )); } } /** * Done * * This should be called when everything is done for this page. */ function done() { global $phpbb_root_path, $phpEx, $template, $user; $download_file = ($this->error_file) ? append_sid("{$phpbb_root_path}umil/file.$phpEx", 'file=' . basename($this->error_file, '.txt')) : ''; $filename = ($this->error_file) ? 'umil/error_files/' . basename($this->error_file) : ''; $template->assign_vars(array( 'U_ERROR_FILE' => $this->error_file, 'L_RESULTS' => ($this->errors) ? $user->lang['FAIL'] : $user->lang['SUCCESS'], 'L_ERROR_NOTICE' => ($this->errors) ? (($this->error_file) ? sprintf($user->lang['ERROR_NOTICE'], $download_file, $filename) : $user->lang['ERROR_NOTICE_NO_FILE']) : '', 'S_RESULTS' => $this->results, 'S_SUCCESS' => ($this->errors) ? false : true, 'S_PERMISSIONS' => $this->permissions_added, )); page_footer(); } /** * Build configuration template for acp configuration pages * * Slightly modified from adm/index.php */ function build_cfg_template($tpl_type, $name, $vars) { global $user; $tpl = array(); $default = (isset($vars['default'])) ? request_var($name, $vars['default']) : request_var($name, ''); switch ($tpl_type[0]) { case 'text': // If requested set some vars so that we later can display the link correct if (isset($vars['select_user']) && $vars['select_user'] === true) { $tpl['find_user'] = true; $tpl['find_user_field'] = $name; } case 'password': $size = (int) $tpl_type[1]; $maxlength = (int) $tpl_type[2]; $tpl['tpl'] = ''; break; case 'textarea': $rows = (int) $tpl_type[1]; $cols = (int) $tpl_type[2]; $tpl['tpl'] = ''; break; case 'radio': $name_yes = ($default) ? ' checked="checked"' : ''; $name_no = (!$default) ? ' checked="checked"' : ''; $tpl_type_cond = explode('_', $tpl_type[1]); $type_no = ($tpl_type_cond[0] == 'disabled' || $tpl_type_cond[0] == 'enabled') ? false : true; $tpl_no = ''; $tpl_yes = ''; $tpl['tpl'] = ($tpl_type_cond[0] == 'yes' || $tpl_type_cond[0] == 'enabled') ? $tpl_yes . $tpl_no : $tpl_no . $tpl_yes; break; case 'checkbox': $checked = ($default) ? ' checked="checked"' : ''; $tpl['tpl'] = ''; break; case 'select': case 'select_multiple': case 'custom': $return = ''; if (isset($vars['function'])) { $call = $vars['function']; } else { break; } if (isset($vars['params'])) { $args = array(); foreach ($vars['params'] as $value) { switch ($value) { case '{CONFIG_VALUE}': $value = $default; break; case '{KEY}': $value = $name; break; } $args[] = $value; } } else { if ($tpl_type[0] == 'select_multiple') { $new[$config_key] = @unserialize(trim($new[$config_key])); } $args = array($default, $name); } $return = call_user_func_array($call, $args); if ($tpl_type[0] == 'select_multiple') { $tpl = ''; } else if ($tpl_type[0] == 'select') { $multiple = ((isset($vars['multiple']) && $vars['multiple']) ? ' multiple="multiple"' : ''); $tpl['tpl'] = ''; } else { $tpl['tpl'] = $return; } break; default: break; } if (isset($vars['append'])) { $tpl['tpl'] .= $vars['append']; } return $tpl; } } // Compatibility if (!function_exists('phpbb_chmod')) { // They shouldn't be defined...but just in case... if (!defined('CHMOD_ALL')) { @define('CHMOD_ALL', 7); @define('CHMOD_READ', 4); @define('CHMOD_WRITE', 2); @define('CHMOD_EXECUTE', 1); } /** * Global function for chmodding directories and files for internal use * This function determines owner and group whom the file belongs to and user and group of PHP and then set safest possible file permissions. * The function determines owner and group from common.php file and sets the same to the provided file. Permissions are mapped to the group, user always has rw(x) permission. * The function uses bit fields to build the permissions. * The function sets the appropiate execute bit on directories. * * Supported constants representing bit fields are: * * CHMOD_ALL - all permissions (7) * CHMOD_READ - read permission (4) * CHMOD_WRITE - write permission (2) * CHMOD_EXECUTE - execute permission (1) * * NOTE: The function uses POSIX extension and fileowner()/filegroup() functions. If any of them is disabled, this function tries to build proper permissions, by calling is_readable() and is_writable() functions. * * @param $filename The file/directory to be chmodded * @param $perms Permissions to set * @return true on success, otherwise false * * @author faw, phpBB Group */ function phpbb_chmod($filename, $perms = CHMOD_READ) { // Return if the file no longer exists. if (!file_exists($filename)) { return false; } if (!function_exists('fileowner') || !function_exists('filegroup')) { $file_uid = $file_gid = false; $common_php_owner = $common_php_group = false; } else { global $phpbb_root_path, $phpEx; // Determine owner/group of common.php file and the filename we want to change here $common_php_owner = fileowner($phpbb_root_path . 'common.' . $phpEx); $common_php_group = filegroup($phpbb_root_path . 'common.' . $phpEx); $file_uid = fileowner($filename); $file_gid = filegroup($filename); // Try to set the owner to the same common.php has if ($common_php_owner !== $file_uid && $common_php_owner !== false && $file_uid !== false) { // Will most likely not work if (@chown($filename, $common_php_owner)); { clearstatcache(); $file_uid = fileowner($filename); } } // Try to set the group to the same common.php has if ($common_php_group !== $file_gid && $common_php_group !== false && $file_gid !== false) { if (@chgrp($filename, $common_php_group)); { clearstatcache(); $file_gid = filegroup($filename); } } } // And the owner and the groups PHP is running under. $php_uid = (function_exists('posix_getuid')) ? @posix_getuid() : false; $php_gids = (function_exists('posix_getgroups')) ? @posix_getgroups() : false; // Who is PHP? if ($file_uid === false || $file_gid === false || $php_uid === false || $php_gids === false) { $php = NULL; } else if ($file_uid == $php_uid /* && $common_php_owner !== false && $common_php_owner === $file_uid*/) { $php = 'owner'; } else if (in_array($file_gid, $php_gids)) { $php = 'group'; } else { $php = 'other'; } // Owner always has read/write permission $owner = CHMOD_READ | CHMOD_WRITE; if (is_dir($filename)) { $owner |= CHMOD_EXECUTE; // Only add execute bit to the permission if the dir needs to be readable if ($perms & CHMOD_READ) { $perms |= CHMOD_EXECUTE; } } switch ($php) { case null: case 'owner': /* ATTENTION: if php is owner or NULL we set it to group here. This is the most failsafe combination for the vast majority of server setups. $result = @chmod($filename, ($owner << 6) + (0 << 3) + (0 << 0)); clearstatcache(); if (!is_null($php) || (is_readable($filename) && is_writable($filename))) { break; } */ case 'group': $result = @chmod($filename, ($owner << 6) + ($perms << 3) + (0 << 0)); clearstatcache(); if (!is_null($php) || ((!($perms & CHMOD_READ) || is_readable($filename)) && (!($perms & CHMOD_WRITE) || is_writable($filename)))) { break; } case 'other': $result = @chmod($filename, ($owner << 6) + ($perms << 3) + ($perms << 0)); clearstatcache(); if (!is_null($php) || ((!($perms & CHMOD_READ) || is_readable($filename)) && (!($perms & CHMOD_WRITE) || is_writable($filename)))) { break; } default: return false; break; } return $result; } } ?>