/** * This function lists and allows updating of multiple attachments paths. */ public function action_attachpaths() { global $modSettings, $scripturl, $context, $txt; require_once SUBSDIR . '/Attachments.subs.php'; require_once SUBSDIR . '/ManageAttachments.subs.php'; // Since this needs to be done eventually. if (!is_array($modSettings['attachmentUploadDir'])) { $modSettings['attachmentUploadDir'] = unserialize($modSettings['attachmentUploadDir']); } if (!isset($modSettings['attachment_basedirectories'])) { $modSettings['attachment_basedirectories'] = array(); } elseif (!is_array($modSettings['attachment_basedirectories'])) { $modSettings['attachment_basedirectories'] = unserialize($modSettings['attachment_basedirectories']); } $errors = array(); // Saving? if (isset($_REQUEST['save'])) { checkSession(); $_POST['current_dir'] = isset($_POST['current_dir']) ? (int) $_POST['current_dir'] : 0; $new_dirs = array(); require_once SUBSDIR . '/Themes.subs.php'; $themes = installedThemes(); $reserved_dirs = array(BOARDDIR, SOURCEDIR, SUBSDIR, CONTROLLERDIR, CACHEDIR, EXTDIR, LANGUAGEDIR, ADMINDIR); foreach ($themes as $theme) { $reserved_dirs[] = $theme['theme_dir']; } foreach ($_POST['dirs'] as $id => $path) { $error = ''; $id = (int) $id; if ($id < 1) { continue; } $real_path = rtrim(trim($path), DIRECTORY_SEPARATOR); // If it doesn't look like a directory, probably is not a directory if (preg_match('~[/\\\\]~', $real_path) !== 1) { $real_path = realpath(BOARDDIR . DIRECTORY_SEPARATOR . ltrim($real_path, DIRECTORY_SEPARATOR)); } // Hmm, a new path maybe? if (!array_key_exists($id, $modSettings['attachmentUploadDir'])) { // or is it? if (in_array($path, $modSettings['attachmentUploadDir']) || in_array(BOARDDIR . DIRECTORY_SEPARATOR . $path, $modSettings['attachmentUploadDir'])) { $errors[] = $path . ': ' . $txt['attach_dir_duplicate_msg']; continue; } // or is it a system dir? if (in_array($real_path, $reserved_dirs)) { $errors[] = $real_path . ': ' . $txt['attach_dir_reserved']; continue; } // OK, so let's try to create it then. if (automanage_attachments_create_directory($path)) { $_POST['current_dir'] = $modSettings['currentAttachmentUploadDir']; } else { $errors[] = $path . ': ' . $txt[$context['dir_creation_error']]; } } // Changing a directory name? if (!empty($modSettings['attachmentUploadDir'][$id]) && !empty($path) && $real_path != $modSettings['attachmentUploadDir'][$id]) { if ($real_path != $modSettings['attachmentUploadDir'][$id] && !is_dir($real_path)) { if (!@rename($modSettings['attachmentUploadDir'][$id], $real_path)) { $errors[] = $real_path . ': ' . $txt['attach_dir_no_rename']; $real_path = $modSettings['attachmentUploadDir'][$id]; } } else { $errors[] = $real_path . ': ' . $txt['attach_dir_exists_msg']; $real_path = $modSettings['attachmentUploadDir'][$id]; } // Update the base directory path if (!empty($modSettings['attachment_basedirectories']) && array_key_exists($id, $modSettings['attachment_basedirectories'])) { $base = $modSettings['basedirectory_for_attachments'] == $modSettings['attachmentUploadDir'][$id] ? $real_path : $modSettings['basedirectory_for_attachments']; $modSettings['attachment_basedirectories'][$id] = $real_path; updateSettings(array('attachment_basedirectories' => serialize($modSettings['attachment_basedirectories']), 'basedirectory_for_attachments' => $base)); $modSettings['attachment_basedirectories'] = unserialize($modSettings['attachment_basedirectories']); } } if (empty($path)) { $real_path = $modSettings['attachmentUploadDir'][$id]; // It's not a good idea to delete the current directory. if ($id == (!empty($_POST['current_dir']) ? $_POST['current_dir'] : $modSettings['currentAttachmentUploadDir'])) { $errors[] = $real_path . ': ' . $txt['attach_dir_is_current']; } elseif (!empty($modSettings['basedirectory_for_attachments']) && $modSettings['basedirectory_for_attachments'] == $modSettings['attachmentUploadDir'][$id]) { $errors[] = $real_path . ': ' . $txt['attach_dir_is_current_bd']; } else { // Let's not try to delete a path with files in it. $num_attach = countAttachmentsInFolders($id); // A check to see if it's a used base dir. if (!empty($modSettings['attachment_basedirectories'])) { // Count any sub-folders. foreach ($modSettings['attachmentUploadDir'] as $sub) { if (strpos($sub, $real_path . DIRECTORY_SEPARATOR) !== false) { $num_attach++; } } } // It's safe to delete. So try to delete the folder also if ($num_attach == 0) { if (is_dir($real_path)) { $doit = true; } elseif (is_dir(BOARDDIR . DIRECTORY_SEPARATOR . $real_path)) { $doit = true; $real_path = BOARDDIR . DIRECTORY_SEPARATOR . $real_path; } if (isset($doit)) { unlink($real_path . '/.htaccess'); unlink($real_path . '/index.php'); if (!@rmdir($real_path)) { $error = $real_path . ': ' . $txt['attach_dir_no_delete']; } } // Remove it from the base directory list. if (empty($error) && !empty($modSettings['attachment_basedirectories'])) { unset($modSettings['attachment_basedirectories'][$id]); updateSettings(array('attachment_basedirectories' => serialize($modSettings['attachment_basedirectories']))); $modSettings['attachment_basedirectories'] = unserialize($modSettings['attachment_basedirectories']); } } else { $error = $real_path . ': ' . $txt['attach_dir_no_remove']; } if (empty($error)) { continue; } else { $errors[] = $error; } } } $new_dirs[$id] = $real_path; } // We need to make sure the current directory is right. if (empty($_POST['current_dir']) && !empty($modSettings['currentAttachmentUploadDir'])) { $_POST['current_dir'] = $modSettings['currentAttachmentUploadDir']; } // Find the current directory if there's no value carried, if (empty($_POST['current_dir']) || empty($new_dirs[$_POST['current_dir']])) { if (array_key_exists($modSettings['currentAttachmentUploadDir'], $modSettings['attachmentUploadDir'])) { $_POST['current_dir'] = $modSettings['currentAttachmentUploadDir']; } else { $_POST['current_dir'] = max(array_keys($modSettings['attachmentUploadDir'])); } } // If the user wishes to go back, update the last_dir array if ($_POST['current_dir'] != $modSettings['currentAttachmentUploadDir'] && !empty($modSettings['last_attachments_directory']) && (isset($modSettings['last_attachments_directory'][$_POST['current_dir']]) || isset($modSettings['last_attachments_directory'][0]))) { if (!is_array($modSettings['last_attachments_directory'])) { $modSettings['last_attachments_directory'] = unserialize($modSettings['last_attachments_directory']); } $num = substr(strrchr($modSettings['attachmentUploadDir'][$_POST['current_dir']], '_'), 1); if (is_numeric($num)) { // Need to find the base folder. $bid = -1; $use_subdirectories_for_attachments = 0; if (!empty($modSettings['attachment_basedirectories'])) { foreach ($modSettings['attachment_basedirectories'] as $bid => $base) { if (strpos($modSettings['attachmentUploadDir'][$_POST['current_dir']], $base . DIRECTORY_SEPARATOR) !== false) { $use_subdirectories_for_attachments = 1; break; } } } if ($use_subdirectories_for_attachments == 0 && strpos($modSettings['attachmentUploadDir'][$_POST['current_dir']], BOARDDIR . DIRECTORY_SEPARATOR) !== false) { $bid = 0; } $modSettings['last_attachments_directory'][$bid] = (int) $num; $modSettings['basedirectory_for_attachments'] = !empty($modSettings['basedirectory_for_attachments']) ? $modSettings['basedirectory_for_attachments'] : ''; $modSettings['use_subdirectories_for_attachments'] = !empty($modSettings['use_subdirectories_for_attachments']) ? $modSettings['use_subdirectories_for_attachments'] : 0; updateSettings(array('last_attachments_directory' => serialize($modSettings['last_attachments_directory']), 'basedirectory_for_attachments' => $bid == 0 ? $modSettings['basedirectory_for_attachments'] : $modSettings['attachment_basedirectories'][$bid], 'use_subdirectories_for_attachments' => $use_subdirectories_for_attachments)); } } // Going back to just one path? if (count($new_dirs) == 1) { // We might need to reset the paths. This loop will just loop through once. foreach ($new_dirs as $id => $dir) { if ($id != 1) { updateAttachmentIdFolder($id, 1); } $update = array('currentAttachmentUploadDir' => 1, 'attachmentUploadDir' => serialize(array(1 => $dir))); } } else { // Save it to the database. $update = array('currentAttachmentUploadDir' => $_POST['current_dir'], 'attachmentUploadDir' => serialize($new_dirs)); } if (!empty($update)) { updateSettings($update); } if (!empty($errors)) { $_SESSION['errors']['dir'] = $errors; } redirectexit('action=admin;area=manageattachments;sa=attachpaths;' . $context['session_var'] . '=' . $context['session_id']); } // Saving a base directory? if (isset($_REQUEST['save2'])) { checkSession(); // Changing the current base directory? $_POST['current_base_dir'] = (int) $_POST['current_base_dir']; if (empty($_POST['new_base_dir']) && !empty($_POST['current_base_dir'])) { if ($modSettings['basedirectory_for_attachments'] != $modSettings['attachmentUploadDir'][$_POST['current_base_dir']]) { $update = array('basedirectory_for_attachments' => $modSettings['attachmentUploadDir'][$_POST['current_base_dir']]); } //$modSettings['attachmentUploadDir'] = serialize($modSettings['attachmentUploadDir']); } if (isset($_POST['base_dir'])) { foreach ($_POST['base_dir'] as $id => $dir) { if (!empty($dir) && $dir != $modSettings['attachmentUploadDir'][$id]) { if (@rename($modSettings['attachmentUploadDir'][$id], $dir)) { $modSettings['attachmentUploadDir'][$id] = $dir; $modSettings['attachment_basedirectories'][$id] = $dir; $update = array('attachmentUploadDir' => serialize($modSettings['attachmentUploadDir']), 'attachment_basedirectories' => serialize($modSettings['attachment_basedirectories']), 'basedirectory_for_attachments' => $modSettings['attachmentUploadDir'][$_POST['current_base_dir']]); } } if (empty($dir)) { if ($id == $_POST['current_base_dir']) { $errors[] = $modSettings['attachmentUploadDir'][$id] . ': ' . $txt['attach_dir_is_current']; continue; } unset($modSettings['attachment_basedirectories'][$id]); $update = array('attachment_basedirectories' => serialize($modSettings['attachment_basedirectories']), 'basedirectory_for_attachments' => $modSettings['attachmentUploadDir'][$_POST['current_base_dir']]); } } } // Or adding a new one? if (!empty($_POST['new_base_dir'])) { require_once SUBSDIR . '/Attachments.subs.php'; $_POST['new_base_dir'] = htmlspecialchars($_POST['new_base_dir'], ENT_QUOTES, 'UTF-8'); $current_dir = $modSettings['currentAttachmentUploadDir']; if (!in_array($_POST['new_base_dir'], $modSettings['attachmentUploadDir'])) { if (!automanage_attachments_create_directory($_POST['new_base_dir'])) { $errors[] = $_POST['new_base_dir'] . ': ' . $txt['attach_dir_base_no_create']; } } $modSettings['currentAttachmentUploadDir'] = array_search($_POST['new_base_dir'], $modSettings['attachmentUploadDir']); if (!in_array($_POST['new_base_dir'], $modSettings['attachment_basedirectories'])) { $modSettings['attachment_basedirectories'][$modSettings['currentAttachmentUploadDir']] = $_POST['new_base_dir']; } ksort($modSettings['attachment_basedirectories']); $update = array('attachment_basedirectories' => serialize($modSettings['attachment_basedirectories']), 'basedirectory_for_attachments' => $_POST['new_base_dir'], 'currentAttachmentUploadDir' => $current_dir); } if (!empty($errors)) { $_SESSION['errors']['base'] = $errors; } if (!empty($update)) { updateSettings($update); } redirectexit('action=admin;area=manageattachments;sa=attachpaths;' . $context['session_var'] . '=' . $context['session_id']); } if (isset($_SESSION['errors'])) { if (is_array($_SESSION['errors'])) { $errors = array(); if (!empty($_SESSION['errors']['dir'])) { foreach ($_SESSION['errors']['dir'] as $error) { $errors['dir'][] = Util::htmlspecialchars($error, ENT_QUOTES); } } if (!empty($_SESSION['errors']['base'])) { foreach ($_SESSION['errors']['base'] as $error) { $errors['base'][] = Util::htmlspecialchars($error, ENT_QUOTES); } } } unset($_SESSION['errors']); } $listOptions = array('id' => 'attach_paths', 'base_href' => $scripturl . '?action=admin;area=manageattachments;sa=attachpaths;' . $context['session_var'] . '=' . $context['session_id'], 'title' => $txt['attach_paths'], 'get_items' => array('function' => 'list_getAttachDirs'), 'columns' => array('current_dir' => array('header' => array('value' => $txt['attach_current'], 'class' => 'centertext'), 'data' => array('function' => create_function('$rowData', ' return \'<input type="radio" name="current_dir" value="\' . $rowData[\'id\'] . \'" \' . ($rowData[\'current\'] ? \' checked="checked"\' : \'\') . (!empty($rowData[\'disable_current\']) ? \' disabled="disabled"\' : \'\') . \' class="input_radio" />\'; '), 'style' => 'width: 10%;', 'class' => 'centertext')), 'path' => array('header' => array('value' => $txt['attach_path']), 'data' => array('function' => create_function('$rowData', ' return \'<input type="hidden" name="dirs[\' . $rowData[\'id\'] . \']" value="\' . $rowData[\'path\'] . \'" /><input type="text" size="40" name="dirs[\' . $rowData[\'id\'] . \']" value="\' . $rowData[\'path\'] . \'"\' . (!empty($rowData[\'disable_base_dir\']) ? \' disabled="disabled"\' : \'\') . \' class="input_text"/>\'; '), 'style' => 'width: 40%;')), 'current_size' => array('header' => array('value' => $txt['attach_current_size']), 'data' => array('db' => 'current_size', 'style' => 'width: 15%;')), 'num_files' => array('header' => array('value' => $txt['attach_num_files']), 'data' => array('db' => 'num_files', 'style' => 'width: 15%;')), 'status' => array('header' => array('value' => $txt['attach_dir_status']), 'data' => array('db' => 'status', 'style' => 'width: 25%;'))), 'form' => array('href' => $scripturl . '?action=admin;area=manageattachments;sa=attachpaths;' . $context['session_var'] . '=' . $context['session_id']), 'additional_rows' => array(array('class' => 'submitbutton', 'position' => 'below_table_data', 'value' => ' <input type="hidden" name="' . $context['session_var'] . '" value="' . $context['session_id'] . '" /> <input type="submit" name="save" value="' . $txt['save'] . '" class="right_submit" /> <input type="submit" name="new_path" value="' . $txt['attach_add_path'] . '" class="right_submit" />'), empty($errors['dir']) ? array('position' => 'top_of_list', 'value' => $txt['attach_dir_desc'], 'style' => 'padding: 5px 10px;', 'class' => 'windowbg2 smalltext') : array('position' => 'top_of_list', 'value' => $txt['attach_dir_save_problem'] . '<br />' . implode('<br />', $errors['dir']), 'style' => 'padding-left: 35px;', 'class' => 'warningbox'))); require_once SUBSDIR . '/GenericList.class.php'; createList($listOptions); if (!empty($modSettings['attachment_basedirectories'])) { $listOptions2 = array('id' => 'base_paths', 'base_href' => $scripturl . '?action=admin;area=manageattachments;sa=attachpaths;' . $context['session_var'] . '=' . $context['session_id'], 'title' => $txt['attach_base_paths'], 'get_items' => array('function' => 'list_getBaseDirs'), 'columns' => array('current_dir' => array('header' => array('value' => $txt['attach_current'], 'class' => 'centertext'), 'data' => array('function' => create_function('$rowData', ' return \'<input type="radio" name="current_base_dir" value="\' . $rowData[\'id\'] . \'" \' . ($rowData[\'current\'] ? \' checked="checked"\' : \'\') . \' class="input_radio" />\'; '), 'style' => 'width: 10%;', 'class' => 'centertext')), 'path' => array('header' => array('value' => $txt['attach_path']), 'data' => array('db' => 'path', 'style' => 'width: 45%;')), 'num_dirs' => array('header' => array('value' => $txt['attach_num_dirs']), 'data' => array('db' => 'num_dirs', 'style' => 'width: 15%;')), 'status' => array('header' => array('value' => $txt['attach_dir_status']), 'data' => array('db' => 'status', 'style' => 'width: 15%;'))), 'form' => array('href' => $scripturl . '?action=admin;area=manageattachments;sa=attachpaths;' . $context['session_var'] . '=' . $context['session_id']), 'additional_rows' => array(array('class' => 'submitbutton', 'position' => 'below_table_data', 'value' => '<input type="hidden" name="' . $context['session_var'] . '" value="' . $context['session_id'] . '" /> <input type="submit" name="save2" value="' . $txt['save'] . '" class="right_submit" /> <input type="submit" name="new_base_path" value="' . $txt['attach_add_path'] . '" class="right_submit" />'), empty($errors['base']) ? array('position' => 'top_of_list', 'value' => $txt['attach_dir_base_desc'], 'style' => 'padding: 5px 10px;', 'class' => 'windowbg2 smalltext') : array('position' => 'top_of_list', 'value' => $txt['attach_dir_save_problem'] . '<br />' . implode('<br />', $errors['base']), 'style' => 'padding-left: 35px', 'class' => 'warningbox'))); createList($listOptions2); } // Fix up our template. $context[$context['admin_menu_name']]['current_subsection'] = 'attachpaths'; $context['page_title'] = $txt['attach_path_manage']; }
/** * Theme Selection Block, Displays themes available for user selection * * @param mixed[] $parameters not used in this block * @param int $id - not used in this block * @param boolean $return_parameters if true returns the configuration options for the block */ function sp_theme_select($parameters, $id, $return_parameters = false) { global $modSettings, $user_info, $settings, $language, $txt; $block_parameters = array(); if ($return_parameters) { return $block_parameters; } loadLanguage('Profile'); loadLanguage('ManageThemes'); require_once SUBSDIR . '/Themes.subs.php'; if (!empty($_SESSION['id_theme']) && (!empty($modSettings['theme_allow']) || allowedTo('admin_forum'))) { $current_theme = (int) $_SESSION['id_theme']; } else { $current_theme = $user_info['theme']; } // Load in all the themes in the system $current_theme = empty($current_theme) ? -1 : $current_theme; $available_themes = installedThemes(); // Set the guest theme if (!isset($available_themes[$modSettings['theme_guests']])) { $available_themes[0] = array('num_users' => 0); $guest_theme = 0; } else { $guest_theme = $modSettings['theme_guests']; } $current_images_url = $settings['images_url']; foreach ($available_themes as $id_theme => $theme_data) { if ($id_theme == 0) { continue; } $settings['images_url'] =& $theme_data['images_url']; // Set the description in their language if available if (file_exists($theme_data['theme_dir'] . '/languages/Settings.' . $user_info['language'] . '.php')) { include $theme_data['theme_dir'] . '/languages/Settings.' . $user_info['language'] . '.php'; } elseif (file_exists($theme_data['theme_dir'] . '/languages/Settings.' . $language . '.php')) { include $theme_data['theme_dir'] . '/languages/Settings.' . $language . '.php'; } else { $txt['theme_thumbnail_href'] = $theme_data['images_url'] . '/thumbnail.png'; $txt['theme_description'] = ''; } $available_themes[$id_theme]['thumbnail_href'] = $txt['theme_thumbnail_href']; $available_themes[$id_theme]['description'] = $txt['theme_description']; // Set the name, keep it short so it does not break our list $available_themes[$id_theme]['name'] = preg_replace('~\\stheme$~i', '', $theme_data['name']); if (Util::strlen($available_themes[$id_theme]['name']) > 18) { $available_themes[$id_theme]['name'] = Util::substr($available_themes[$id_theme]['name'], 0, 18) . '…'; } } $settings['images_url'] = $current_images_url; if ($guest_theme != 0) { $available_themes[-1] = $available_themes[$guest_theme]; } $available_themes[-1]['id'] = -1; $available_themes[-1]['name'] = $txt['theme_forum_default']; $available_themes[-1]['selected'] = $current_theme == 0; $available_themes[-1]['description'] = $txt['theme_global_description']; ksort($available_themes); // Validate the selected theme id. if (!array_key_exists($current_theme, $available_themes)) { $current_theme = -1; $available_themes[-1]['selected'] = true; } if (!empty($_POST['sp_ts_submit']) && !empty($_POST['sp_ts_permanent']) && !empty($_POST['theme']) && isset($available_themes[$_POST['theme']]) && (!empty($modSettings['theme_allow']) || allowedTo('admin_forum'))) { updateMemberData($user_info['id'], array('id_theme' => $_POST['theme'] == -1 ? 0 : (int) $_POST['theme'])); } echo ' <form method="post" action="?" accept-charset="UTF-8"> <div class="centertext"> <select name="theme" onchange="sp_theme_select(this)">'; foreach ($available_themes as $theme) { echo ' <option value="', $theme['id'], '"', $theme['id'] == $current_theme ? ' selected="selected"' : '', '>', $theme['name'], '</option>'; } echo ' </select> <br /><br /> <img src="', $available_themes[$current_theme]['thumbnail_href'], '" alt="', $available_themes[$current_theme]['name'], '" id="sp_ts_thumb" /> <br /><br /> <input type="checkbox" class="input_check" name="sp_ts_permanent" value="1" /> ', $txt['sp-theme_permanent'], ' <br /> <input type="submit" name="sp_ts_submit" value="', $txt['sp-theme_change'], '" class="button_submit" /> </div> </form>'; $javascript = ' var sp_ts_thumbs = [];'; foreach ($available_themes as $id => $theme_data) { $javascript .= ' sp_ts_thumbs[' . $id . '] = "' . $theme_data['thumbnail_href'] . '";'; } addInlineJavascript($javascript, true); }
/** * List installed themes. * The listing will allow editing if the files are writable. */ public function action_themelist() { global $context; loadTemplate('ManageThemes'); // We'll work hard with them themes! require_once SUBSDIR . '/Themes.subs.php'; $context['themes'] = installedThemes(); foreach ($context['themes'] as $key => $theme) { // There has to be a Settings template! if (!file_exists($theme['theme_dir'] . '/index.template.php') && !file_exists($theme['theme_dir'] . '/css/index.css')) { unset($context['themes'][$key]); } else { if (!isset($theme['theme_templates'])) { $templates = array('index'); } else { $templates = explode(',', $theme['theme_templates']); } foreach ($templates as $template) { if (file_exists($theme['theme_dir'] . '/' . $template . '.template.php')) { // Fetch the header... a good 256 bytes should be more than enough. $fp = fopen($theme['theme_dir'] . '/' . $template . '.template.php', 'rb'); $header = fread($fp, 256); fclose($fp); // Can we find a version comment, at all? if (preg_match('~\\*\\s@version\\s+(.+)[\\s]{2}~i', $header, $match) == 1) { $ver = $match[1]; if (!isset($context['themes'][$key]['version']) || $context['themes'][$key]['version'] > $ver) { $context['themes'][$key]['version'] = $ver; } } } } $context['themes'][$key]['can_edit_style'] = file_exists($theme['theme_dir'] . '/css/index.css'); } } $context['sub_template'] = 'themelist'; }