function activateAccount($memID) { global $sourcedir, $context, $user_profile, $modSettings; isAllowedTo('moderate_forum'); if (isset($_REQUEST['save']) && isset($user_profile[$memID]['is_activated']) && $user_profile[$memID]['is_activated'] != 1) { // If we are approving the deletion of an account, we do something special ;) if ($user_profile[$memID]['is_activated'] == 4) { require_once $sourcedir . '/lib/Subs-Members.php'; deleteMembers($context['id_member']); redirectexit(); } // Let the integrations know of the activation. HookAPI::callHook('integrate_activate', array($user_profile[$memID]['member_name'])); // Actually update this member now, as it guarantees the unapproved count can't get corrupted. updateMemberData($context['id_member'], array('is_activated' => $user_profile[$memID]['is_activated'] >= 10 ? 11 : 1, 'validation_code' => '')); // If we are doing approval, update the stats for the member just in case. if (in_array($user_profile[$memID]['is_activated'], array(3, 4, 13, 14))) { updateSettings(array('unapprovedMembers' => $modSettings['unapprovedMembers'] > 1 ? $modSettings['unapprovedMembers'] - 1 : 0)); } // Make sure we update the stats too. updateStats('member', false); } // Leave it be... redirectexit('action=profile;u=' . $memID . ';area=summary'); }
function AdminMain() { global $txt, $context, $scripturl, $modSettings, $settings, $sourcedir, $options, $boarddir, $backend_subdir; // Load the language and templates.... loadLanguage('Admin'); loadAdminTemplate('Admin'); $context['robot_no_index'] = true; require_once $sourcedir . '/lib/Subs-Menu.php'; // Some preferences. $context['admin_preferences'] = !empty($options['admin_preferences']) ? unserialize($options['admin_preferences']) : array(); // Define all the menu structure - see Subs-Menu.php for details! $admin_areas = array('forum' => array('title' => $txt['admin_main'], 'permission' => array('admin_forum', 'manage_permissions', 'moderate_forum', 'manage_membergroups', 'manage_bans', 'send_mail', 'edit_news', 'manage_boards', 'manage_smileys', 'manage_attachments'), 'areas' => array('index' => array('label' => $txt['admin_center'], 'function' => 'AdminHome', 'icon' => 'administration.gif'), 'credits' => array('label' => $txt['support_credits_title'], 'function' => 'AdminHome', 'icon' => 'support.gif'), 'news' => array('label' => $txt['news_title'], 'file' => $backend_subdir . '/ManageNews.php', 'function' => 'ManageNews', 'icon' => 'news.gif', 'permission' => array('edit_news', 'send_mail', 'admin_forum'), 'subsections' => array('editnews' => array($txt['admin_edit_news'], 'edit_news'), 'mailingmembers' => array($txt['admin_newsletters'], 'send_mail'), 'settings' => array($txt['settings'], 'admin_forum'))), 'packages' => array('label' => $txt['package'], 'file' => $backend_subdir . '/Packages.php', 'function' => 'Packages', 'permission' => array('admin_forum'), 'icon' => 'packages.gif', 'subsections' => array('browse' => array($txt['browse_packages']), 'packageget' => array($txt['download_packages'], 'url' => $scripturl . '?action=admin;area=packages;sa=packageget;get'), 'installed' => array($txt['installed_packages']), 'perms' => array($txt['package_file_perms']), 'options' => array($txt['package_settings']))), 'plugins' => array('label' => $txt['plugins_title'], 'file' => $backend_subdir . '/Plugins.php', 'function' => 'PluginsMain', 'permission' => array('admin_forum'), 'icon' => 'packages.gif', 'subsections' => array('browse' => array($txt['browse_plugins']), 'hooks' => array($txt['browse_hooks']))), 'search' => array('function' => 'AdminSearch', 'permission' => array('admin_forum'), 'select' => 'index'))), 'config' => array('title' => $txt['admin_config'], 'permission' => array('admin_forum'), 'areas' => array('corefeatures' => array('label' => $txt['core_settings_title'], 'file' => $backend_subdir . '/ManageSettings.php', 'function' => 'ModifyCoreFeatures', 'icon' => 'corefeatures.gif'), 'featuresettings' => array('label' => $txt['modSettings_title'], 'file' => $backend_subdir . '/ManageSettings.php', 'function' => 'ModifyFeatureSettings', 'icon' => 'features.gif', 'subsections' => array('basic' => array($txt['mods_cat_features']), 'layout' => array($txt['mods_cat_layout']), 'sig' => array($txt['signature_settings_short']), 'profile' => array($txt['custom_profile_shorttitle'], 'enabled' => in_array('cp', $context['admin_features'])))), 'securitysettings' => array('label' => $txt['admin_security_moderation'], 'file' => $backend_subdir . '/ManageSettings.php', 'function' => 'ModifySecuritySettings', 'icon' => 'security.gif', 'subsections' => array('general' => array($txt['mods_cat_security_general']), 'spam' => array($txt['antispam_title']), 'moderation' => array($txt['moderation_settings_short'], 'enabled' => substr($modSettings['warning_settings'], 0, 1) == 1))), 'languages' => array('label' => $txt['language_configuration'], 'file' => $backend_subdir . '/ManageServer.php', 'function' => 'ManageLanguages', 'icon' => 'languages.gif', 'subsections' => array('edit' => array($txt['language_edit']), 'add' => array($txt['language_add']), 'settings' => array($txt['language_settings']))), 'serversettings' => array('label' => $txt['admin_server_settings'], 'file' => $backend_subdir . '/ManageServer.php', 'function' => 'ModifySettings', 'icon' => 'server.gif', 'subsections' => array('general' => array($txt['general_settings']), 'database' => array($txt['database_paths_settings']), 'cookie' => array($txt['cookies_sessions_settings']), 'cache' => array($txt['caching_settings']), 'loads' => array($txt['load_balancing_settings']))), 'relatedtopics' => array('label' => $txt['admin_related_topic'], 'file' => $backend_subdir . '/RelatedTopics.php', 'function' => 'RelatedTopicsAdmin', 'subsections' => array('settings' => array($txt['admin_related_topics_settings']), 'methods' => array($txt['admin_related_topics_methods']))), 'current_theme' => array('label' => $txt['theme_current_settings'], 'file' => $backend_subdir . '/Themes.php', 'function' => 'ThemesMain', 'custom_url' => $scripturl . '?action=admin;area=theme;sa=settings;th=' . $settings['theme_id'], 'icon' => 'current_theme.gif'), 'theme' => array('label' => $txt['theme_admin'], 'file' => $backend_subdir . '/Themes.php', 'function' => 'ThemesMain', 'custom_url' => $scripturl . '?action=admin;area=theme;sa=admin', 'icon' => 'themes.gif', 'subsections' => array('admin' => array($txt['themeadmin_admin_title']), 'list' => array($txt['themeadmin_list_title']), 'reset' => array($txt['themeadmin_reset_title']), 'edit' => array($txt['themeadmin_edit_title']))), 'modsettings' => array('label' => $txt['admin_modifications'], 'file' => $backend_subdir . '/ManageSettings.php', 'function' => 'ModifyModSettings', 'icon' => 'modifications.gif', 'related' => array($txt['admin_related_topic']), 'subsections' => array('general' => array($txt['mods_cat_modifications_misc']))), 'socialsettings' => array('label' => $txt['admin_social'], 'file' => $backend_subdir . '/ManageSettings.php', 'function' => 'ModifySocialSettings', 'subsections' => array('general' => array($txt['socialsettings_general']), 'astream' => array($txt['socialsettings_astream']))))), 'layout' => array('title' => $txt['layout_controls'], 'permission' => array('manage_boards', 'admin_forum', 'manage_smileys', 'manage_attachments', 'moderate_forum'), 'areas' => array('manageboards' => array('label' => $txt['admin_boards'], 'file' => $backend_subdir . '/ManageBoards.php', 'function' => 'ManageBoards', 'icon' => 'boards.gif', 'permission' => array('manage_boards'), 'subsections' => array('main' => array($txt['boardsEdit']), 'newcat' => array($txt['mboards_new_cat']), 'settings' => array($txt['settings'], 'admin_forum'))), 'postsettings' => array('label' => $txt['manageposts'], 'file' => $backend_subdir . '/ManagePosts.php', 'function' => 'ManagePostSettings', 'permission' => array('admin_forum'), 'icon' => 'posts.gif', 'subsections' => array('posts' => array($txt['manageposts_settings']), 'bbc' => array($txt['manageposts_bbc_settings']), 'censor' => array($txt['admin_censored_words']), 'topics' => array($txt['manageposts_topic_settings']), 'prefixes' => array($txt['manageposts_prefix_settings']), 'tags' => array($txt['manageposts_tag_settings']), 'ratings' => array($txt['karma']))), 'managecalendar' => array('label' => $txt['manage_calendar'], 'file' => $backend_subdir . '/ManageCalendar.php', 'function' => 'ManageCalendar', 'icon' => 'calendar.gif', 'permission' => array('admin_forum'), 'enabled' => in_array('cd', $context['admin_features']), 'subsections' => array('holidays' => array($txt['manage_holidays'], 'admin_forum', 'enabled' => !empty($modSettings['cal_enabled'])), 'settings' => array($txt['calendar_settings'], 'admin_forum'))), 'managesearch' => array('label' => $txt['manage_search'], 'file' => $backend_subdir . '/ManageSearch.php', 'function' => 'ManageSearch', 'icon' => 'search.gif', 'permission' => array('admin_forum'), 'subsections' => array('weights' => array($txt['search_weights']), 'method' => array($txt['search_method']), 'settings' => array($txt['settings']), 'managesphinx' => array($txt['search_managesphinx']))), 'smileys' => array('label' => $txt['smileys_manage'], 'file' => $backend_subdir . '/ManageSmileys.php', 'function' => 'ManageSmileys', 'icon' => 'smiley.gif', 'permission' => array('manage_smileys'), 'subsections' => array('editsets' => array($txt['smiley_sets']), 'addsmiley' => array($txt['smileys_add'], 'enabled' => !empty($modSettings['smiley_enable'])), 'editsmileys' => array($txt['smileys_edit'], 'enabled' => !empty($modSettings['smiley_enable'])), 'setorder' => array($txt['smileys_set_order'], 'enabled' => !empty($modSettings['smiley_enable'])), 'editicons' => array($txt['icons_edit_message_icons'], 'enabled' => !empty($modSettings['messageIcons_enable'])), 'settings' => array($txt['settings']))), 'manageattachments' => array('label' => $txt['attachments_avatars'], 'file' => $backend_subdir . '/ManageAttachments.php', 'function' => 'ManageAttachments', 'icon' => 'attachment.gif', 'permission' => array('manage_attachments'), 'subsections' => array('browse' => array($txt['attachment_manager_browse']), 'attachments' => array($txt['attachment_manager_settings']), 'avatars' => array($txt['attachment_manager_avatar_settings']), 'maintenance' => array($txt['attachment_manager_maintenance']))))), 'members' => array('title' => $txt['admin_manage_members'], 'permission' => array('moderate_forum', 'manage_membergroups', 'manage_bans', 'manage_permissions', 'admin_forum'), 'areas' => array('viewmembers' => array('label' => $txt['admin_users'], 'file' => $backend_subdir . '/ManageMembers.php', 'function' => 'ViewMembers', 'icon' => 'members.gif', 'permission' => array('moderate_forum'), 'subsections' => array('all' => array($txt['view_all_members']), 'search' => array($txt['mlist_search']))), 'membergroups' => array('label' => $txt['admin_groups'], 'file' => $backend_subdir . '/ManageMembergroups.php', 'function' => 'ModifyMembergroups', 'icon' => 'membergroups.gif', 'permission' => array('manage_membergroups'), 'subsections' => array('index' => array($txt['membergroups_edit_groups'], 'manage_membergroups'), 'add' => array($txt['membergroups_new_group'], 'manage_membergroups'), 'settings' => array($txt['settings'], 'admin_forum'))), 'permissions' => array('label' => $txt['edit_permissions'], 'file' => $backend_subdir . '/ManagePermissions.php', 'function' => 'ModifyPermissions', 'icon' => 'permissions.gif', 'permission' => array('manage_permissions'), 'subsections' => array('index' => array($txt['permissions_groups'], 'manage_permissions'), 'board' => array($txt['permissions_boards'], 'manage_permissions'), 'profiles' => array($txt['permissions_profiles'], 'manage_permissions'), 'postmod' => array($txt['permissions_post_moderation'], 'manage_permissions', 'enabled' => $modSettings['postmod_active']), 'settings' => array($txt['settings'], 'admin_forum'))), 'regcenter' => array('label' => $txt['registration_center'], 'file' => $backend_subdir . '/ManageRegistration.php', 'function' => 'RegCenter', 'icon' => 'regcenter.gif', 'permission' => array('admin_forum', 'moderate_forum'), 'subsections' => array('register' => array($txt['admin_browse_register_new'], 'moderate_forum'), 'agreement' => array($txt['registration_agreement'], 'admin_forum'), 'reservednames' => array($txt['admin_reserved_set'], 'admin_forum'), 'settings' => array($txt['settings'], 'admin_forum'))), 'ban' => array('label' => $txt['ban_title'], 'file' => $backend_subdir . '/ManageBans.php', 'function' => 'Ban', 'icon' => 'ban.gif', 'permission' => 'manage_bans', 'subsections' => array('list' => array($txt['ban_edit_list']), 'add' => array($txt['ban_add_new']), 'browse' => array($txt['ban_trigger_browse']), 'log' => array($txt['ban_log']))), 'paidsubscribe' => array('label' => $txt['paid_subscriptions'], 'enabled' => in_array('ps', $context['admin_features']), 'file' => $backend_subdir . '/ManagePaid.php', 'icon' => 'paid.gif', 'function' => 'ManagePaidSubscriptions', 'permission' => 'admin_forum', 'subsections' => array('view' => array($txt['paid_subs_view']), 'settings' => array($txt['settings']))), 'sengines' => array('label' => $txt['search_engines'], 'enabled' => in_array('sp', $context['admin_features']), 'file' => $backend_subdir . '/ManageSearchEngines.php', 'icon' => 'engines.gif', 'function' => 'SearchEngines', 'permission' => 'admin_forum', 'subsections' => array('stats' => array($txt['spider_stats']), 'logs' => array($txt['spider_logs']), 'spiders' => array($txt['spiders']), 'settings' => array($txt['settings']))))), 'maintenance' => array('title' => $txt['admin_maintenance'], 'permission' => array('admin_forum'), 'areas' => array('maintain' => array('label' => $txt['maintain_title'], 'file' => $backend_subdir . '/ManageMaintenance.php', 'icon' => 'maintain.gif', 'function' => 'ManageMaintenance', 'subsections' => array('routine' => array($txt['maintain_sub_routine'], 'admin_forum'), 'database' => array($txt['maintain_sub_database'], 'admin_forum'), 'members' => array($txt['maintain_sub_members'], 'admin_forum'), 'topics' => array($txt['maintain_sub_topics'], 'admin_forum'))), 'scheduledtasks' => array('label' => $txt['maintain_tasks'], 'file' => $backend_subdir . '/ManageScheduledTasks.php', 'icon' => 'scheduled.gif', 'function' => 'ManageScheduledTasks', 'subsections' => array('tasks' => array($txt['maintain_tasks'], 'admin_forum'), 'tasklog' => array($txt['scheduled_log'], 'admin_forum'))), 'mailqueue' => array('label' => $txt['mailqueue_title'], 'file' => $backend_subdir . '/ManageMail.php', 'function' => 'ManageMail', 'icon' => 'mail.gif', 'subsections' => array('browse' => array($txt['mailqueue_browse'], 'admin_forum'), 'settings' => array($txt['mailqueue_settings'], 'admin_forum'))), 'reports' => array('enabled' => in_array('rg', $context['admin_features']), 'label' => $txt['generate_reports'], 'file' => 'Reports.php', 'function' => 'ReportsMain', 'icon' => 'reports.gif'), 'logs' => array('label' => $txt['logs'], 'function' => 'AdminLogs', 'icon' => 'logs.gif', 'subsections' => array('errorlog' => array($txt['errlog'], 'admin_forum', 'enabled' => !empty($modSettings['enableErrorLogging']), 'url' => $scripturl . '?action=admin;area=logs;sa=errorlog;desc'), 'adminlog' => array($txt['admin_log'], 'admin_forum', 'enabled' => in_array('ml', $context['admin_features'])), 'modlog' => array($txt['moderation_log'], 'admin_forum', 'enabled' => in_array('ml', $context['admin_features'])), 'banlog' => array($txt['ban_log'], 'manage_bans'), 'spiderlog' => array($txt['spider_logs'], 'admin_forum', 'enabled' => in_array('sp', $context['admin_features'])), 'tasklog' => array($txt['scheduled_log'], 'admin_forum'), 'pruning' => array($txt['pruning_title'], 'admin_forum'))), 'repairboards' => array('label' => $txt['admin_repair'], 'file' => $backend_subdir . '/RepairBoards.php', 'function' => 'RepairBoards', 'select' => 'maintain', 'hidden' => true)))); if (!$modSettings['tags_active']) { unset($admin_areas['layout']['areas']['postsettings']['subsections']['tags']); } if (empty($modSettings['karmaMode'])) { unset($admin_areas['layout']['areas']['postsettings']['subsections']['ratings']); } // Any files to include for administration? if (!empty($modSettings['integrate_admin_include'])) { $admin_includes = explode(',', $modSettings['integrate_admin_include']); foreach ($admin_includes as $include) { $include = strtr(trim($include), array('$boarddir' => $boarddir, '$sourcedir' => $sourcedir, '$themedir' => $settings['theme_dir'])); if (file_exists($include)) { require_once $include; } } } // Let them modify admin areas easily. HookAPI::callHook('integrate_admin_areas', array(&$admin_areas)); SimpleSEF::adminAreas($admin_areas); // Make sure the administrator has a valid session... validateSession(); // Actually create the menu! $admin_include_data = createMenu($admin_areas); unset($admin_areas); // Nothing valid? if ($admin_include_data == false) { fatal_lang_error('no_access', false); } // Build the link tree. $context['linktree'][] = array('url' => $scripturl . '?action=admin', 'name' => $txt['admin_center']); if (isset($admin_include_data['current_area']) && $admin_include_data['current_area'] != 'index') { $context['linktree'][] = array('url' => $scripturl . '?action=admin;area=' . $admin_include_data['current_area'] . ';' . $context['session_var'] . '=' . $context['session_id'], 'name' => $admin_include_data['label']); } if (!empty($admin_include_data['current_subsection']) && $admin_include_data['subsections'][$admin_include_data['current_subsection']][0] != $admin_include_data['label']) { $context['linktree'][] = array('url' => $scripturl . '?action=admin;area=' . $admin_include_data['current_area'] . ';sa=' . $admin_include_data['current_subsection'] . ';' . $context['session_var'] . '=' . $context['session_id'], 'name' => $admin_include_data['subsections'][$admin_include_data['current_subsection']][0]); } // Make a note of the Unique ID for this menu. $context['admin_menu_id'] = $context['max_menu_id']; $context['admin_menu_name'] = 'menu_data_' . $context['admin_menu_id']; // Why on the admin are we? $context['admin_area'] = $admin_include_data['current_area']; // Now - finally - call the right place! if (isset($admin_include_data['file'])) { require_once $sourcedir . '/' . $admin_include_data['file']; } $admin_include_data['function'](); }
/** * Ban center. The main entrance point for all ban center functions. * It is accesssed by ?action=admin;area=ban. * It choses a function based on the 'sa' parameter, like many others. * The default sub-action is BanList(). * It requires the ban_members permission. * It initializes the admin tabs. * * @uses ManageBans template. */ function Ban() { global $context, $txt, $scripturl; isAllowedTo('manage_bans'); loadAdminTemplate('ManageBans'); $subActions = array('add' => 'BanEdit', 'browse' => 'BanBrowseTriggers', 'edittrigger' => 'BanEditTrigger', 'edit' => 'BanEdit', 'list' => 'BanList', 'log' => 'BanLog'); HookAPI::callHook('manage_bans', array(&$subActions)); // Default the sub-action to 'view ban list'. $_REQUEST['sa'] = isset($_REQUEST['sa']) && isset($subActions[$_REQUEST['sa']]) ? $_REQUEST['sa'] : 'list'; $context['page_title'] = $txt['ban_title']; $context['sub_action'] = $_REQUEST['sa']; // Tabs for browsing the different ban functions. $context[$context['admin_menu_name']]['tab_data'] = array('title' => $txt['ban_title'], 'help' => 'ban_members', 'description' => $txt['ban_description'], 'tabs' => array('list' => array('description' => $txt['ban_description'], 'href' => $scripturl . '?action=admin;area=ban;sa=list', 'is_selected' => $_REQUEST['sa'] == 'list' || $_REQUEST['sa'] == 'edit' || $_REQUEST['sa'] == 'edittrigger'), 'add' => array('description' => $txt['ban_description'], 'href' => $scripturl . '?action=admin;area=ban;sa=add', 'is_selected' => $_REQUEST['sa'] == 'add'), 'browse' => array('description' => $txt['ban_trigger_browse_description'], 'href' => $scripturl . '?action=admin;area=ban;sa=browse', 'is_selected' => $_REQUEST['sa'] == 'browse'), 'log' => array('description' => $txt['ban_log_description'], 'href' => $scripturl . '?action=admin;area=ban;sa=log', 'is_selected' => $_REQUEST['sa'] == 'log', 'is_last' => true))); // Call the right function for this sub-acton. $subActions[$_REQUEST['sa']](); }
/** * get the notifications for the current user. * * $_REQUEST['view'] tells us what to get: * a) 'recent' (default) - the most recent and unread notifications * b) 'unread' - all unread notifications * c) 'all' - everything (this is for the profile page mainly). * * since notifications are basically references into the activity stream, they are pruned * together with actitvities. default activity expiration is 30 days. */ function aStreamGetNotifications() { global $user_info, $context, $scripturl; if ($user_info['is_guest']) { // guests don't get anything, they can't have notifications fatal_lang_error('no_access'); } $xml = isset($_REQUEST['xml']) ? true : false; $view = isset($_REQUEST['view']) ? $_REQUEST['view'] : 'recent'; //loadTemplate('Activities'); loadLanguage('Activities'); $start = isset($_REQUEST['start']) ? $_REQUEST['start'] : 0; $context['get_notifications'] = true; $context['rich_output'] = true; // todo: this indicates whether we want simple or rich activity bits (rich = with avatar and possibly other member data) $where = 'WHERE n.id_member = {int:id_member} AND ' . (!empty($user_info['ignoreusers']) ? 'a.id_member NOT IN({array_int:ignoredusers}) AND ' : '') . ' ({query_wanna_see_board} OR a.id_board = 0) '; if ($view != 'all') { $where .= ' AND n.unread = 1 '; $context['view_all'] = false; } else { $context['view_all'] = true; } $result = smf_db_query('SELECT n.id_act, n.unread, a.id_member, a.updated, a.id_type, a.params, a.is_private, a.id_board, a.id_topic, a.id_content, a.id_owner, t.*, b.name AS board_name FROM {db_prefix}log_notifications AS n LEFT JOIN {db_prefix}log_activities AS a ON (a.id_act = n.id_act) LEFT JOIN {db_prefix}activity_types AS t ON (t.id_type = a.id_type) LEFT JOIN {db_prefix}boards AS b ON(b.id_board = a.id_board) ' . $where . 'ORDER BY n.id_act DESC LIMIT {int:start}, 20', array('id_member' => $user_info['id'], 'start' => $start, 'ignoredusers' => $user_info['ignoreusers'])); aStreamOutput($result, true); Eos_Smarty::loadTemplate($xml ? 'astream/notification_popup' : 'astream/notification_full'); $context['unread_pm'] = $user_info['unread_messages']; $context['pmlink'] = URL::parse($scripturl . '?action=pm'); $context['modlink'] = URL::parse($scripturl . '?action=moderate;area=reports'); /* * this hook allows plugins to extend the notification popup */ HookAPI::callHook('astream_notification_popup'); }
function BoardIndex() { global $txt, $user_info, $sourcedir, $modSettings, $context, $settings, $scripturl, $boardurl, $boarddir; EoS_Smarty::loadTemplate('boardindex'); $context['is_board_index'] = true; $context['sidebar_template'] = 'sidebars/sidebar_on_index.tpl'; $context['show_sidebar'] = true; $context['sidebar_class'] = 'index'; GetSidebarVisibility('index'); // Set a canonical URL for this page. $context['canonical_url'] = $scripturl; $context['share_url'] = $boardurl; // Do not let search engines index anything if there is a random thing in $_GET. if (!empty($_GET)) { $context['robot_no_index'] = true; } // Retrieve the categories and boards. require_once $sourcedir . '/lib/Subs-BoardIndex.php'; $boardIndexOptions = array('include_categories' => true, 'base_level' => 0, 'parent_id' => 0, 'set_latest_post' => true, 'countChildPosts' => !empty($modSettings['countChildPosts'])); $context['categories'] = getBoardIndex($boardIndexOptions); // Get the user online list. require_once $sourcedir . '/lib/Subs-MembersOnline.php'; $membersOnlineOptions = array('show_hidden' => allowedTo('moderate_forum'), 'sort' => 'log_time', 'reverse_sort' => true); $context += getMembersOnlineStats($membersOnlineOptions); $context['show_buddies'] = !empty($user_info['buddies']); // Are we showing all membergroups on the board index? if (!empty($settings['show_group_key'])) { $context['membergroups'] = cache_quick_get('membergroup_list', 'lib/Subs-Membergroups.php', 'cache_getMembergroupList', array()); } // Track most online statistics? (Subs-MembersOnline.php) if (!empty($modSettings['trackStats'])) { trackStatsUsersOnline($context['num_guests'] + $context['num_spiders'] + $context['num_users_online']); } // Retrieve the latest posts if the theme settings require it. if (isset($settings['number_recent_posts']) && $settings['number_recent_posts'] > 1) { $latestPostOptions = array('number_posts' => $settings['number_recent_posts']); $context['latest_posts'] = cache_quick_get('boardindex-latest_posts:' . md5($user_info['query_wanna_see_board'] . $user_info['language']), 'lib/Subs-Recent.php', 'cache_getLastPosts', array($latestPostOptions)); } $settings['display_recent_bar'] = !empty($settings['number_recent_posts']) ? $settings['number_recent_posts'] : 0; $settings['show_member_bar'] &= allowedTo('view_mlist'); $context['show_stats'] = allowedTo('view_stats') && !empty($modSettings['trackStats']); $context['show_member_list'] = allowedTo('view_mlist'); $context['show_who'] = allowedTo('who_view') && !empty($modSettings['who_enabled']); // Load the calendar? if (!empty($modSettings['cal_enabled']) && allowedTo('calendar_view')) { // Retrieve the calendar data (events, birthdays, holidays). $eventOptions = array('include_holidays' => $modSettings['cal_showholidays'] > 1, 'include_birthdays' => $modSettings['cal_showbdays'] > 1, 'include_events' => $modSettings['cal_showevents'] > 1, 'num_days_shown' => empty($modSettings['cal_days_for_index']) || $modSettings['cal_days_for_index'] < 1 ? 1 : $modSettings['cal_days_for_index']); $context += cache_quick_get('calendar_index_offset_' . ($user_info['time_offset'] + $modSettings['time_offset']), 'lib/Subs-Calendar.php', 'cache_getRecentEvents', array($eventOptions)); // Whether one or multiple days are shown on the board index. $context['calendar_only_today'] = $modSettings['cal_days_for_index'] == 1; // This is used to show the "how-do-I-edit" help. $context['calendar_can_edit'] = allowedTo('calendar_edit_any'); } else { $context['show_calendar'] = false; } $context['page_title'] = sprintf($txt['forum_index'], $context['forum_name']); $context['template_hooks']['boardindex'] = array('above_boardlisting' => '', 'below_boardlisting' => ''); if (isset($context['show_who'])) { $bracketList = array(); if ($context['show_buddies']) { $bracketList[] = comma_format($context['num_buddies']) . ' ' . ($context['num_buddies'] == 1 ? $txt['buddy'] : $txt['buddies']); } if (!empty($context['num_spiders'])) { $bracketList[] = comma_format($context['num_spiders']) . ' ' . ($context['num_spiders'] == 1 ? $txt['spider'] : $txt['spiders']); } if (!empty($context['num_users_hidden'])) { $bracketList[] = comma_format($context['num_users_hidden']) . ' ' . $txt['hidden']; } if (!empty($bracketList)) { $context['show_who_formatted'] = ' (' . implode(', ', $bracketList) . ')'; } } $context['mark_read_button'] = array('markread' => array('text' => 'mark_as_read', 'image' => 'markread.gif', 'lang' => true, 'url' => $scripturl . '?action=markasread;sa=all;' . $context['session_var'] . '=' . $context['session_id'])); HookAPI::callHook('boardindex', array()); fetchNewsItems(0, 0); }
function template_single_post_xml() { global $context, $settings, $options, $txt, $scripturl, $topic; echo '<', '?xml version="1.0" encoding="UTF-8" ?', '> <document> <response open="default_overlay" width="70%" /> <content> <![CDATA['; // Build the normal button array. $normal_buttons = array('reply' => array('test' => 'can_reply', 'text' => 'reply', 'image' => 'reply.gif', 'lang' => true, 'url' => $scripturl . '?action=post;topic=' . $context['current_topic'] . '.' . $context['start'] . ';last_msg=' . $context['topic_last_message'], 'active' => true), 'add_poll' => array('test' => 'can_add_poll', 'text' => 'add_poll', 'image' => 'add_poll.gif', 'lang' => true, 'url' => $scripturl . '?action=editpoll;add;topic=' . $context['current_topic'] . '.' . $context['start']), 'notify' => array('test' => 'can_mark_notify', 'text' => $context['is_marked_notify'] ? 'unnotify' : 'notify', 'image' => ($context['is_marked_notify'] ? 'un' : '') . 'notify.gif', 'lang' => true, 'custom' => 'onclick="return Eos_Confirm(\'\', \'' . ($context['is_marked_notify'] ? $txt['notification_disable_topic'] : $txt['notification_enable_topic']) . '\', $(this).attr(\'href\'));"', 'url' => $scripturl . '?action=notify;sa=' . ($context['is_marked_notify'] ? 'off' : 'on') . ';topic=' . $context['current_topic'] . '.' . $context['start'] . ';' . $context['session_var'] . '=' . $context['session_id']), 'mark_unread' => array('test' => 'can_mark_unread', 'text' => 'mark_unread', 'image' => 'markunread.gif', 'lang' => true, 'url' => $scripturl . '?action=markasread;sa=topic;t=' . $context['mark_unread_time'] . ';topic=' . $context['current_topic'] . '.' . $context['start'] . ';' . $context['session_var'] . '=' . $context['session_id']), 'send' => array('test' => 'can_send_topic', 'text' => 'send_topic', 'image' => 'sendtopic.gif', 'lang' => true, 'url' => $scripturl . '?action=emailuser;sa=sendtopic;topic=' . $context['current_topic'] . '.0'), 'print' => array('text' => 'print', 'image' => 'print.gif', 'lang' => true, 'custom' => 'rel="nofollow"', 'url' => $scripturl . '?action=printpage;topic=' . $context['current_topic'] . '.0')); // Allow adding new buttons easily. HookAPI::callHook('integrate_display_buttons', array(&$normal_buttons)); // Show the topic information - icon, subject, etc. echo ' <div id="mcard_content">'; echo ' <div class="clear"></div> <form data-alt="', $scripturl, '?action=post;msg=%id_msg%;topic=', $context['current_topic'], '.', $context['start'], '" action="', $scripturl, '?action=quickmod2;topic=', $context['current_topic'], '.', $context['start'], '" method="post" accept-charset="UTF-8" name="quickModForm" id="quickModForm" style="margin: 0;" onsubmit="return oQuickModify.bInEditMode ? oQuickModify.modifySave(\'' . $context['session_id'] . '\', \'' . $context['session_var'] . '\') : false"> <div class="posts_container framed_region">'; $ignoredMsgs = array(); $removableMessageIDs = array(); // Get all the messages... while ($message = $context['get_message']()) { if ($message['can_remove']) { $removableMessageIDs[] = $message['id']; } template_postbit_normal($message); } echo ' <input type="hidden" name="goadvanced" value="1" /> </div> </form> </div> <a id="lastPost"></a>'; $context['inline_footer_script'] .= ' var smf_likelabel = \'' . $txt['like_label'] . '\'; var smf_unlikelabel = \'' . $txt['unlike_label'] . '\' '; // Restore topic. eh? No monkey business. if ($context['can_restore_topic']) { $mod_buttons[] = array('text' => 'restore_topic', 'image' => '', 'lang' => true, 'url' => $scripturl . '?action=restoretopic;topics=' . $context['current_topic'] . ';' . $context['session_var'] . '=' . $context['session_id']); } if (!empty($options['display_quick_mod']) && $context['can_remove_post']) { $context['inline_footer_script'] .= ' var oInTopicModeration = new InTopicModeration({ sSelf: \'oInTopicModeration\', sCheckboxContainerMask: \'in_topic_mod_check_\', aMessageIds: [\'' . implode('\', \'', $removableMessageIDs) . '\'], sSessionId: \'' . $context['session_id'] . '\', sSessionVar: \'' . $context['session_var'] . '\', sButtonStrip: \'moderationbuttons\', sButtonStripDisplay: \'moderationbuttons_strip\', bUseImageButton: false, bCanRemove: ' . ($context['can_remove_post'] ? 'true' : 'false') . ', sRemoveButtonLabel: \'' . $txt['quickmod_delete_selected'] . '\', sRemoveButtonImage: \'delete_selected.gif\', sRemoveButtonConfirm: \'' . $txt['quickmod_confirm'] . '\', bCanRestore: ' . ($context['can_restore_msg'] ? 'true' : 'false') . ', sRestoreButtonLabel: \'' . $txt['quick_mod_restore'] . '\', sRestoreButtonImage: \'restore_selected.gif\', sRestoreButtonConfirm: \'' . $txt['quickmod_confirm'] . '\', sFormId: \'quickModForm\' }); '; } $context['inline_footer_script'] .= ' if (\'XMLHttpRequest\' in window) { var oQuickModify = new QuickModify({ sScriptUrl: smf_scripturl, bShowModify: ' . ($settings['show_modify'] ? 'true' : 'false') . ', iTopicId: ' . $context['current_topic'] . ', sTemplateBodyEdit: ' . JavaScriptEscape(' <div id="quick_edit_body_container"> <div id="error_box" style="padding: 4px;" class="error"></div> <textarea class="editor" name="message" rows="20" style="' . ($context['browser']['is_ie8'] ? 'width: 635px; max-width: 100%; min-width: 100%' : 'width: 100%') . '; margin-bottom: 10px;" tabindex="' . $context['tabindex']++ . '">%body%</textarea><br /> <input type="hidden" name="' . $context['session_var'] . '" value="' . $context['session_id'] . '" /> <input type="hidden" name="topic" value="' . $context['current_topic'] . '" /> <input type="hidden" name="msg" value="%msg_id%" /> <input type="hidden" style="width: 50%;" name="subject" value="%subject%" size="50" maxlength="80" tabindex="' . $context['tabindex']++ . '" class="input_text" /> <div class="righttext"> <span class="button floatright" onclick="return oQuickModify.goAdvanced(\'' . $context['session_id'] . '\', \'' . $context['session_var'] . '\');" />Go Advanced</a></span> <span class="button floatright" onclick="return oQuickModify.modifyCancel();" >' . $txt['modify_cancel'] . '</span> <span class="button floatright" onclick="return oQuickModify.modifySave(\'' . $context['session_id'] . '\', \'' . $context['session_var'] . '\');" accesskey="s">' . $txt['save'] . '</span> </div> </div>') . ', sTemplateSubjectEdit: ' . JavaScriptEscape('<input type="text" style="width: 50%;" name="subject_edit" value="%subject%" size="50" maxlength="80" tabindex="' . $context['tabindex']++ . '" class="input_text" />') . ', sTemplateBodyNormal: ' . JavaScriptEscape('%body%') . ', sTemplateSubjectNormal: ' . JavaScriptEscape('<a href="' . $scripturl . '?topic=' . $context['current_topic'] . '.msg%msg_id%#msg%msg_id%" rel="nofollow">%subject%</a>') . ', sTemplateTopSubject: ' . JavaScriptEscape($txt['topic'] . ': %subject% (' . $txt['read'] . ' ' . $context['num_views'] . ' ' . $txt['times'] . ')') . ', sErrorBorderStyle: ' . JavaScriptEscape('1px solid red') . ' }); aJumpTo[aJumpTo.length] = new JumpTo({ sContainerId: "display_jump_to", sJumpToTemplate: "<label class=\\"smalltext\\" for=\\"%select_id%\\">' . $context['jump_to']['label'] . ':<" + "/label> %dropdown_list%", iCurBoardId: ' . $context['current_board'] . ', iCurBoardChildLevel: ' . $context['jump_to']['child_level'] . ', sCurBoardName: "' . $context['jump_to']['board_name'] . '", sBoardChildLevelIndicator: "==", sBoardPrefix: "=> ", sCatSeparator: "-----------------------------", sCatPrefix: "", sGoButtonLabel: "' . $txt['go'] . '" }); } '; if (!empty($ignoredMsgs)) { $context['inline_footer_script'] .= ''; } if ($context['can_reply']) { $context['inline_footer_script'] .= ' function mquote(msg_id,remove) { if (!window.XMLHttpRequest) return true; var elementButton = "mquote_" + msg_id; var elementButtonDelete = "mquote_remove_" + msg_id; var exdate = new Date(); (remove == "remove") ? exdate.setDate(exdate.getDate() - 1) : exdate.setDate(exdate.getDate() + 1); document.getElementById(elementButton).style.display = (remove == "remove") ? "inline" : "none"; document.getElementById(elementButtonDelete).style.display = (remove == "remove") ? "none" : "inline"; document.cookie = "mquote" + msg_id + "=; expires="+exdate.toGMTString()+"; path=/"; } '; } $context['inline_footer_script'] .= ' function getIntralink(e, mid) { var tid = ' . $context['current_topic'] . '; var _sid = "#subject_" + mid; var el = $("#interpostlink_helper"); el.css("position", "fixed"); var _content = "[ilink topic=" + tid + " post=" + mid + "]" + $(_sid).html().trim() + "[/ilink]"; $("#interpostlink_helper_content").val(_content); $("#interpostlink_helper_content_full").val(e.attr("href")); centerElement(el, -200); el.css("z-index", 9999); setDimmed(1); el.show(); $("#interpostlink_helper_content").focus(); $("#interpostlink_helper_content").select(); } $(document).keydown(function(e) { if(e.keyCode == 27 && $("#interpostlink_helper").css("display") != "none") { $("#interpostlink_helper").css("position", "static"); $("#interpostlink_helper").hide(); setDimmed(0); } }); var topic_id = ' . $context['current_topic'] . '; '; echo ' ]]> </content> </document>'; }
function ViewQuery() { global $scripturl, $user_info, $settings, $context, $db_connection, $modSettings, $boarddir, $smcFunc, $txt, $db_show_debug; // We should have debug mode enabled, as well as something to display! if (!isset($db_show_debug) || $db_show_debug !== true || !isset($_SESSION['debug'])) { fatal_lang_error('no_access', false); } // Don't allow except for administrators. isAllowedTo('admin_forum'); // If we're just hiding/showing, do it now. if (isset($_REQUEST['sa']) && $_REQUEST['sa'] == 'hide') { $_SESSION['view_queries'] = $_SESSION['view_queries'] == 1 ? 0 : 1; if (strpos($_SESSION['old_url'], 'action=viewquery') !== false) { redirectexit(); } else { redirectexit($_SESSION['old_url']); } } HookAPI::callHook('integrate_egg_nog'); $query_id = isset($_REQUEST['qq']) ? (int) $_REQUEST['qq'] - 1 : -1; echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"', $context['right_to_left'] ? ' dir="rtl"' : '', '> <head> <title>', $context['forum_name_html_safe'], '</title> <link rel="stylesheet" type="text/css" href="', $settings['theme_url'], '/css/index.css" /> <style type="text/css"> body { margin: 1ex; } body, td, th, .normaltext { font-size: x-small; } .smalltext { font-size: xx-small; } </style> </head> <body id="help_popup"> <div class="tborder windowbg description">'; foreach ($_SESSION['debug'] as $q => $query_data) { // Fix the indentation.... $query_data['q'] = ltrim(str_replace("\r", '', $query_data['q']), "\n"); $query = explode("\n", $query_data['q']); $min_indent = 0; foreach ($query as $line) { preg_match('/^(\\t*)/', $line, $temp); if (strlen($temp[0]) < $min_indent || $min_indent == 0) { $min_indent = strlen($temp[0]); } } foreach ($query as $l => $dummy) { $query[$l] = substr($dummy, $min_indent); } $query_data['q'] = implode("\n", $query); // Make the filenames look a bit better. if (isset($query_data['f'])) { $query_data['f'] = preg_replace('~^' . preg_quote($boarddir, '~') . '~', '...', $query_data['f']); } $is_select_query = substr(trim($query_data['q']), 0, 6) == 'SELECT'; if ($is_select_query) { $select = $query_data['q']; } elseif (preg_match('~^INSERT(?: IGNORE)? INTO \\w+(?:\\s+\\([^)]+\\))?\\s+(SELECT .+)$~s', trim($query_data['q']), $matches) != 0) { $is_select_query = true; $select = $matches[1]; } elseif (preg_match('~^CREATE TEMPORARY TABLE .+?(SELECT .+)$~s', trim($query_data['q']), $matches) != 0) { $is_select_query = true; $select = $matches[1]; } // Temporary tables created in earlier queries are not explainable. if ($is_select_query) { foreach (array('log_topics_unread', 'topics_posted_in', 'tmp_log_search_topics', 'tmp_log_search_messages') as $tmp) { if (strpos($select, $tmp) !== false) { $is_select_query = false; break; } } } echo ' <div id="qq', $q, '" style="margin-bottom: 2ex;"> <a', $is_select_query ? ' href="' . $scripturl . '?action=viewquery;qq=' . ($q + 1) . '#qq' . $q . '"' : '', ' style="font-weight: bold; text-decoration: none;"> ', nl2br(str_replace("\t", ' ', htmlspecialchars($query_data['q']))), ' </a><br />'; if (!empty($query_data['f']) && !empty($query_data['l'])) { echo sprintf($txt['debug_query_in_line'], $query_data['f'], $query_data['l']); } if (isset($query_data['s'], $query_data['t']) && isset($txt['debug_query_which_took_at'])) { echo sprintf($txt['debug_query_which_took_at'], round($query_data['t'], 8), round($query_data['s'], 8)); } else { echo sprintf($txt['debug_query_which_took'], round($query_data['t'], 8)); } echo ' </div>'; // Explain the query. if ($query_id == $q && $is_select_query) { $result = smf_db_query(' EXPLAIN ' . $select, array()); if ($result === false) { echo ' <table border="1" cellpadding="4" cellspacing="0" style="empty-cells: show; font-family: serif; margin-bottom: 2ex;"> <tr><td>', mysql_error($db_connection), '</td></tr> </table>'; continue; } echo ' <table border="1" rules="all" cellpadding="4" cellspacing="0" style="empty-cells: show; font-family: serif; margin-bottom: 2ex;">'; $row = mysql_fetch_assoc($result); echo ' <tr> <th>' . implode('</th> <th>', array_keys($row)) . '</th> </tr>'; mysql_data_seek($result, 0); while ($row = mysql_fetch_assoc($result)) { echo ' <tr> <td>' . implode('</td> <td>', $row) . '</td> </tr>'; } mysql_free_result($result); echo ' </table>'; } } echo ' </div> </body> </html>'; obExit(false); }
function loadTheme($id_theme = 0, $initialize = true) { global $user_info, $user_settings, $board_info, $boarddir, $db_show_debug; global $txt, $boardurl, $scripturl, $mbname, $modSettings; global $context, $settings, $options, $sourcedir, $ssi_theme; // The theme was specified by parameter. if (!empty($id_theme)) { $id_theme = (int) $id_theme; } elseif (!empty($_REQUEST['theme']) && (!empty($modSettings['theme_allow']) || allowedTo('admin_forum'))) { $id_theme = (int) $_REQUEST['theme']; $_SESSION['id_theme'] = $id_theme; } elseif (!empty($_SESSION['id_theme']) && (!empty($modSettings['theme_allow']) || allowedTo('admin_forum'))) { $id_theme = (int) $_SESSION['id_theme']; } elseif (!empty($user_info['theme']) && !isset($_REQUEST['theme']) && (!empty($modSettings['theme_allow']) || allowedTo('admin_forum'))) { $id_theme = $user_info['theme']; } elseif (!empty($board_info['theme'])) { $id_theme = $board_info['theme']; } else { $id_theme = $modSettings['theme_guests']; } // Verify the id_theme... no foul play. // Always allow the board specific theme, if they are overriding. if (!empty($board_info['theme']) && $board_info['override_theme']) { $id_theme = $board_info['theme']; } elseif (!empty($ssi_theme) && $id_theme == $ssi_theme) { $id_theme = (int) $id_theme; } elseif (!empty($modSettings['knownThemes']) && !allowedTo('admin_forum')) { $themes = explode(',', $modSettings['knownThemes']); if (!in_array($id_theme, $themes)) { $id_theme = $modSettings['theme_guests']; } else { $id_theme = (int) $id_theme; } } else { $id_theme = (int) $id_theme; } $member = empty($user_info['id']) ? -1 : $user_info['id']; if (!empty($modSettings['cache_enable']) && $modSettings['cache_enable'] >= 2 && ($temp = CacheAPI::getCache('theme_settings-' . $id_theme . ':' . $member, 60)) != null && time() - 60 > $modSettings['settings_updated']) { $themeData = $temp; $flag = true; } elseif (($temp = CacheAPI::getCache('theme_settings-' . $id_theme, 90)) != null && time() - 60 > $modSettings['settings_updated']) { $themeData = $temp + array($member => array()); } else { $themeData = array(-1 => array(), 0 => array(), $member => array()); } if (empty($flag)) { // Load variables from the current or default theme, global or this user's. $result = smf_db_query(' SELECT variable, value, id_member, id_theme FROM {db_prefix}themes WHERE id_member' . (empty($themeData[0]) ? ' IN (-1, 0, {int:id_member})' : ' = {int:id_member}') . ' AND id_theme' . ($id_theme == 1 ? ' = {int:id_theme}' : ' IN ({int:id_theme}, 1)'), array('id_theme' => $id_theme, 'id_member' => $member)); // Pick between $settings and $options depending on whose data it is. while ($row = mysql_fetch_assoc($result)) { // There are just things we shouldn't be able to change as members. if ($row['id_member'] != 0 && in_array($row['variable'], array('actual_theme_url', 'actual_images_url', 'base_theme_dir', 'base_theme_url', 'default_images_url', 'default_theme_dir', 'default_theme_url', 'default_template', 'images_url', 'number_recent_posts', 'smiley_sets_default', 'theme_dir', 'theme_id', 'theme_layers', 'theme_templates', 'theme_url'))) { continue; } // If this is the theme_dir of the default theme, store it. if (in_array($row['variable'], array('theme_dir', 'theme_url', 'images_url')) && $row['id_theme'] == '1' && empty($row['id_member'])) { $themeData[0]['default_' . $row['variable']] = $row['value']; } // If this isn't set yet, is a theme option, or is not the default theme.. if (!isset($themeData[$row['id_member']][$row['variable']]) || $row['id_theme'] != '1') { $themeData[$row['id_member']][$row['variable']] = substr($row['variable'], 0, 5) == 'show_' ? $row['value'] == '1' : $row['value']; } } mysql_free_result($result); if (!empty($themeData[-1])) { foreach ($themeData[-1] as $k => $v) { if (!isset($themeData[$member][$k])) { $themeData[$member][$k] = $v; } } } if (!empty($modSettings['cache_enable']) && $modSettings['cache_enable'] >= 2) { CacheAPI::putCache('theme_settings-' . $id_theme . ':' . $member, $themeData, 60); } elseif (!isset($temp)) { CacheAPI::putCache('theme_settings-' . $id_theme, array(-1 => $themeData[-1], 0 => $themeData[0]), 90); } } $settings = $themeData[0]; $options = $themeData[$member]; $member_tracking_optin = $user_info['is_guest'] || (empty($options['disable_analytics']) ? 1 : !$options['disable_analytics']); if (isset($modSettings['embed_GA']) && $modSettings['embed_GA'] && !empty($modSettings['GA_tracker_id']) && !empty($modSettings['GA_domain_name']) && $member_tracking_optin) { $context['want_GA_embedded'] = true; } if (isset($modSettings['embed_piwik']) && $modSettings['embed_piwik'] && !empty($modSettings['piwik_uri']) && !empty($modSettings['piwik_tracker_id']) && $member_tracking_optin) { $context['want_piwik_embedded'] = true; $modSettings['piwik_uri'] = rtrim($modSettings['piwik_uri'], '/\\ '); } $settings['theme_id'] = $id_theme; $settings['actual_theme_url'] = $settings['theme_url']; $settings['actual_images_url'] = $settings['images_url']; $settings['actual_theme_dir'] = $settings['theme_dir']; $settings['posticons_url'] = $settings['images_url'] . '/post/'; $settings['template_dirs'] = array(); // This theme first. $settings['template_dirs'][] = $settings['theme_dir']; // Based on theme (if there is one). if (!empty($settings['base_theme_dir'])) { $settings['template_dirs'][] = $settings['base_theme_dir']; } // Lastly the default theme. if ($settings['theme_dir'] != $settings['default_theme_dir']) { $settings['template_dirs'][] = $settings['default_theme_dir']; } if (!$initialize) { return; } // Check to see if they're accessing it from the wrong place. if (isset($_SERVER['HTTP_HOST']) || isset($_SERVER['SERVER_NAME'])) { $detected_url = isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) == 'on' ? 'https://' : 'http://'; $detected_url .= empty($_SERVER['HTTP_HOST']) ? $_SERVER['SERVER_NAME'] . (empty($_SERVER['SERVER_PORT']) || $_SERVER['SERVER_PORT'] == '80' ? '' : ':' . $_SERVER['SERVER_PORT']) : $_SERVER['HTTP_HOST']; $temp = preg_replace('~/' . basename($scripturl) . '(/.+)?$~', '', strtr(dirname($_SERVER['PHP_SELF']), '\\', '/')); if ($temp != '/') { $detected_url .= $temp; } } if (isset($detected_url) && $detected_url != $boardurl) { // Try #1 - check if it's in a list of alias addresses. if (!empty($modSettings['forum_alias_urls'])) { $aliases = explode(',', $modSettings['forum_alias_urls']); foreach ($aliases as $alias) { // Rip off all the boring parts, spaces, etc. if ($detected_url == trim($alias) || strtr($detected_url, array('http://' => '', 'https://' => '')) == trim($alias)) { $do_fix = true; } } } // Hmm... check #2 - is it just different by a www? Send them to the correct place!! if (empty($do_fix) && strtr($detected_url, array('://' => '://www.')) == $boardurl && (empty($_GET) || count($_GET) == 1) && SMF != 'SSI') { // Okay, this seems weird, but we don't want an endless loop - this will make $_GET not empty ;). if (empty($_GET)) { redirectexit('wwwRedirect'); } else { list($k, $v) = each($_GET); if ($k != 'wwwRedirect') { redirectexit('wwwRedirect;' . $k . '=' . $v); } } } // #3 is just a check for SSL... if (strtr($detected_url, array('https://' => 'http://')) == $boardurl) { $do_fix = true; } // Okay, #4 - perhaps it's an IP address? We're gonna want to use that one, then. (assuming it's the IP or something...) if (!empty($do_fix) || preg_match('~^http[s]?://(?:[\\d\\.:]+|\\[[\\d:]+\\](?::\\d+)?)(?:$|/)~', $detected_url) == 1) { // Caching is good ;). $oldurl = $boardurl; // Fix $boardurl and $scripturl. $boardurl = $detected_url; $scripturl = strtr($scripturl, array($oldurl => $boardurl)); $_SERVER['REQUEST_URL'] = strtr($_SERVER['REQUEST_URL'], array($oldurl => $boardurl)); // Fix the theme urls... $settings['theme_url'] = strtr($settings['theme_url'], array($oldurl => $boardurl)); $settings['default_theme_url'] = strtr($settings['default_theme_url'], array($oldurl => $boardurl)); $settings['actual_theme_url'] = strtr($settings['actual_theme_url'], array($oldurl => $boardurl)); $settings['images_url'] = strtr($settings['images_url'], array($oldurl => $boardurl)); $settings['default_images_url'] = strtr($settings['default_images_url'], array($oldurl => $boardurl)); $settings['actual_images_url'] = strtr($settings['actual_images_url'], array($oldurl => $boardurl)); // And just a few mod settings :). $modSettings['smileys_url'] = strtr($modSettings['smileys_url'], array($oldurl => $boardurl)); $modSettings['avatar_url'] = strtr($modSettings['avatar_url'], array($oldurl => $boardurl)); // Clean up after loadBoard(). if (isset($board_info['moderators'])) { foreach ($board_info['moderators'] as $k => $dummy) { $board_info['moderators'][$k]['href'] = strtr($dummy['href'], array($oldurl => $boardurl)); $board_info['moderators'][$k]['link'] = strtr($dummy['link'], array('"' . $oldurl => '"' . $boardurl)); } } foreach ($context['linktree'] as $k => $dummy) { $context['linktree'][$k]['url'] = strtr($dummy['url'], array($oldurl => $boardurl)); } } } // Set up the contextual user array. $context['user'] = array('id' => $user_info['id'], 'is_logged' => !$user_info['is_guest'], 'is_guest' => &$user_info['is_guest'], 'is_admin' => &$user_info['is_admin'], 'is_mod' => &$user_info['is_mod'], 'can_mod' => allowedTo('access_mod_center') || !$user_info['is_guest'] && ($user_info['mod_cache']['gq'] != '0=1' || $user_info['mod_cache']['bq'] != '0=1' || $modSettings['postmod_active'] && !empty($user_info['mod_cache']['ap'])), 'username' => $user_info['username'], 'language' => $user_info['language'], 'email' => $user_info['email'], 'ignoreusers' => $user_info['ignoreusers']); if (!$context['user']['is_guest']) { $context['user']['name'] = $user_info['name']; } elseif ($context['user']['is_guest'] && !empty($txt['guest_title'])) { $context['user']['name'] = $txt['guest_title']; } // Determine the current smiley set and map it to a numeric id (parsed post cache needs this, because // we don't want to left join with string matching $smiley_sets = explode(',', $modSettings['smiley_sets_known']); $user_info['smiley_set'] = !in_array($user_info['smiley_set'], $smiley_sets) && $user_info['smiley_set'] != 'none' || empty($modSettings['smiley_sets_enable']) ? !empty($settings['smiley_sets_default']) ? $settings['smiley_sets_default'] : $modSettings['smiley_sets_default'] : $user_info['smiley_set']; if ($user_info['smiley_set'] == 'none') { $user_info['smiley_set_id'] = 0; } else { $user_info['smiley_set_id'] = array_search($user_info['smiley_set'], $smiley_sets) + 1; } $context['user']['smiley_set'] = $user_info['smiley_set']; // Some basic information... if (!isset($context['html_headers'])) { $context['html_headers'] = ''; } $context['menu_separator'] = !empty($settings['use_image_buttons']) ? ' ' : ' | '; $context['session_var'] = $_SESSION['session_var']; $context['session_id'] = $_SESSION['session_value']; $context['forum_name'] = $mbname; $context['forum_name_html_safe'] = commonAPI::htmlspecialchars($context['forum_name']); $context['header_logo_url_html_safe'] = empty($settings['header_logo_url']) ? '' : commonAPI::htmlspecialchars($settings['header_logo_url']); $context['current_action'] = isset($_REQUEST['action']) ? $_REQUEST['action'] : null; $context['current_subaction'] = isset($_REQUEST['sa']) ? $_REQUEST['sa'] : null; if (isset($modSettings['load_average'])) { $context['load_average'] = $modSettings['load_average']; } // Set some permission related settings. $context['show_login_bar'] = $user_info['is_guest'] && !empty($modSettings['enableVBStyleLogin']); // This determines the server... not used in many places, except for login fixing. $context['server'] = array('is_iis' => isset($_SERVER['SERVER_SOFTWARE']) && strpos($_SERVER['SERVER_SOFTWARE'], 'Microsoft-IIS') !== false, 'is_apache' => isset($_SERVER['SERVER_SOFTWARE']) && (strpos($_SERVER['SERVER_SOFTWARE'], 'Apache') !== false || strpos($_SERVER['SERVER_SOFTWARE'], 'LiteSpeed') !== false), 'is_lighttpd' => isset($_SERVER['SERVER_SOFTWARE']) && strpos($_SERVER['SERVER_SOFTWARE'], 'lighttpd') !== false, 'is_nginx' => isset($_SERVER['SERVER_SOFTWARE']) && strpos($_SERVER['SERVER_SOFTWARE'], 'nginx') !== false, 'is_cgi' => isset($_SERVER['SERVER_SOFTWARE']) && strpos(php_sapi_name(), 'cgi') !== false, 'is_windows' => strpos(PHP_OS, 'WIN') === 0, 'iso_case_folding' => ord(strtolower(chr(138))) === 154, 'complex_preg_chars' => 1); // A bug in some versions of IIS under CGI (older ones) makes cookie setting not work with Location: headers. $context['server']['needs_login_fix'] = $context['server']['is_cgi'] && $context['server']['is_iis']; // Detect the browser. This is separated out because it's also used in attachment downloads detectBrowser(); // Set the top level linktree up. /* array_unshift($context['linktree'], array( 'url' => URL::home(), 'name' => $context['forum_name_html_safe'] )); */ // This allows sticking some HTML on the page output - useful for controls. if (!isset($txt)) { $txt = array(); } $simpleActions = array('findmember', 'helpadmin', 'printpage', 'quotefast'); if (isset($_REQUEST['xml'])) { loadLanguage('index+Modifications'); loadTemplate('Xml'); $context['template_layers'] = array(); } elseif (!empty($_REQUEST['action']) && in_array($_REQUEST['action'], $simpleActions)) { loadLanguage('index+Modifications'); $context['template_layers'] = array(); } else { loadLanguage('index+Modifications'); // Custom templates to load, or just default? $is_admin = isset($_REQUEST['action']) && $_REQUEST['action'] === 'admin'; $templates = array('index'); // Load each template... foreach ($templates as $template) { if (!$is_admin) { loadTemplate($template); } else { loadAdminTemplate($template); } } $context['template_layers'] = array('html', 'body'); } if (isset($db_show_debug) && !empty($db_show_debug)) { loadLanguage('Debug'); } if (file_exists($settings['theme_dir'] . '/theme_support.php')) { @(require_once $settings['theme_dir'] . '/theme_support.php'); } else { @(require_once $settings['default_theme_dir'] . '/theme_support.php'); } // Guests may still need a name. if ($context['user']['is_guest'] && empty($context['user']['name'])) { $context['user']['name'] = $txt['guest_title']; } // Any theme-related strings that need to be loaded? if (!empty($settings['require_theme_strings'])) { loadLanguage('ThemeStrings', '', false); } // We allow theme variants, because we're cool. $context['theme_variant'] = ''; $context['theme_variant_url'] = ''; if (empty($settings['theme_variants'])) { $settings['theme_variants'] = array('default'); } // Overriding - for previews and that ilk. if (!empty($_REQUEST['variant'])) { $_SESSION['id_variant'] = $_REQUEST['variant']; } // User selection? if (empty($settings['disable_user_variant']) || allowedTo('admin_forum')) { $context['theme_variant'] = !empty($_SESSION['id_variant']) ? $_SESSION['id_variant'] : (!empty($options['theme_variant']) ? $options['theme_variant'] : ''); } // If not a user variant, select the default. if ($context['theme_variant'] == '' || !in_array($context['theme_variant'], $settings['theme_variants'])) { $context['theme_variant'] = !empty($settings['default_variant']) && in_array($settings['default_variant'], $settings['theme_variants']) ? $settings['default_variant'] : $settings['theme_variants'][0]; } if (!in_array($context['theme_variant'], $settings['theme_variants'])) { $context['theme_variant'] = 'default'; } // Do this to keep things easier in the templates. $context['theme_variant'] = '_' . $context['theme_variant']; $context['theme_variant_url'] = $context['theme_variant'] . '/'; /* if(!empty($context['theme_variant']) && $context['theme_variant'] != '_default') { if(!empty($settings['base_theme_dir'])) $settings['template_dirs'][] = $settings['base_theme_dir'] . '/variants/' . $context['theme_variant']; else $settings['template_dirs'][] = $settings['default_theme_dir'] . '/variants/' . $context['theme_variant']; } */ // Allow overriding the board wide time/number formats. if (empty($user_settings['time_format']) && !empty($txt['time_format'])) { $user_info['time_format'] = $txt['time_format']; } $txt['number_format'] = empty($txt['number_format']) ? empty($modSettings['number_format']) ? '' : $modSettings['number_format'] : $txt['number_format']; if (isset($settings['use_default_images']) && $settings['use_default_images'] == 'always') { $settings['theme_url'] = $settings['default_theme_url']; $settings['images_url'] = $settings['default_images_url']; $settings['theme_dir'] = $settings['default_theme_dir']; } // Make a special URL for the language. $settings['lang_images_url'] = $settings['images_url'] . '/' . (!empty($txt['image_lang']) ? $txt['image_lang'] : $user_info['language']); // Set the character set from the template. $context['character_set'] = 'UTF-8'; $context['utf8'] = true; $context['right_to_left'] = !empty($txt['lang_rtl']); $context['tabindex'] = 1; // Compatibility. if (!isset($settings['theme_version'])) { $modSettings['memberCount'] = $modSettings['totalMembers']; } // This allows us to change the way things look for the admin. $context['admin_features'] = isset($modSettings['admin_features']) ? explode(',', $modSettings['admin_features']) : array('cd,cp,k,w,rg,ml,pm'); // If we think we have mail to send, let's offer up some possibilities... robots get pain (Now with scheduled task support!) if (!empty($modSettings['mail_next_send']) && $modSettings['mail_next_send'] < time() && empty($modSettings['mail_queue_use_cron']) || empty($modSettings['next_task_time']) || $modSettings['next_task_time'] < time()) { if ($context['browser']['possibly_robot']) { //!!! Maybe move this somewhere better?! require_once $sourcedir . '/ScheduledTasks.php'; // What to do, what to do?! if (empty($modSettings['next_task_time']) || $modSettings['next_task_time'] < time()) { AutoTask(); } else { ReduceMailQueue(); } } else { $type = empty($modSettings['next_task_time']) || $modSettings['next_task_time'] < time() ? 'task' : 'mailq'; $ts = $type == 'mailq' ? $modSettings['mail_next_send'] : $modSettings['next_task_time']; $context['html_headers'] .= ' <script type="text/javascript"> function smfAutoTask() { var tempImage = new Image(); tempImage.src = "' . $scripturl . '?scheduled=' . $type . ';ts=' . $ts . '"; } window.setTimeout("smfAutoTask();", 1); </script>'; } } // Any files to include at this point? if (!empty($modSettings['integrate_theme_include'])) { $theme_includes = explode(',', $modSettings['integrate_theme_include']); foreach ($theme_includes as $include) { $include = strtr(trim($include), array('$boarddir' => $boarddir, '$sourcedir' => $sourcedir, '$themedir' => $settings['theme_dir'])); if (file_exists($include)) { require_once $include; } } } $settings['primary_css'] = $settings['theme_url'] . MOBILE_SUBDIR . '/css/' . CSS_PRIMARY_BASE . $context['theme_variant']; $context['theme_scripts'] = array(); $context['inline_footer_script'] = ''; $context['news_item_count'] = 0; $context['hot_topic_message'] = sprintf($txt['hot_topics'], $modSettings['hotTopicPosts']); $context['very_hot_topic_message'] = sprintf($txt['very_hot_topics'], $modSettings['hotTopicVeryPosts']); $context['old_topic_message'] = sprintf($txt['old_topic_message'], $modSettings['oldTopicDays']); // Call load theme integration functions. HookAPI::callHook('integrate_load_theme'); // We are ready to go. $context['theme_loaded'] = true; }
function loadAllPermissions($loadType = 'classic') { global $context, $txt, $modSettings; // List of all the groups dependant on the currently selected view - for the order so it looks pretty, yea? // Note to Mod authors - you don't need to stick your permission group here if you don't mind SMF sticking it the last group of the page. $permissionGroups = array('membergroup' => array('simple' => array('view_basic_info', 'use_pm_system', 'post_calendar', 'edit_profile', 'delete_account', 'use_avatar', 'moderate_general', 'administrate'), 'classic' => array('general', 'pm', 'calendar', 'maintenance', 'member_admin', 'profile')), 'board' => array('simple' => array('make_posts', 'make_unapproved_posts', 'post_polls', 'participate', 'modify', 'notification', 'attach', 'moderate'), 'classic' => array('general_board', 'topic', 'post', 'poll', 'notification', 'attachment'))); /* The format of this list is as follows: 'membergroup' => array( 'permissions_inside' => array(has_multiple_options, classic_view_group, simple_view_group(_own)*, simple_view_group_any*), ), 'board' => array( 'permissions_inside' => array(has_multiple_options, classic_view_group, simple_view_group(_own)*, simple_view_group_any*), ); */ $permissionList = array('membergroup' => array('view_stats' => array(false, 'general', 'view_basic_info'), 'view_mlist' => array(false, 'general', 'view_basic_info'), 'who_view' => array(false, 'general', 'view_basic_info'), 'search_posts' => array(false, 'general', 'view_basic_info'), 'karma_edit' => array(false, 'general', 'moderate_general'), 'pm_read' => array(false, 'pm', 'use_pm_system'), 'pm_send' => array(false, 'pm', 'use_pm_system'), 'calendar_view' => array(false, 'calendar', 'view_basic_info'), 'calendar_post' => array(false, 'calendar', 'post_calendar'), 'calendar_edit' => array(true, 'calendar', 'post_calendar', 'moderate_general'), 'admin_forum' => array(false, 'maintenance', 'administrate'), 'manage_boards' => array(false, 'maintenance', 'administrate'), 'manage_attachments' => array(false, 'maintenance', 'administrate'), 'manage_smileys' => array(false, 'maintenance', 'administrate'), 'edit_news' => array(false, 'maintenance', 'administrate'), 'access_mod_center' => array(false, 'maintenance', 'moderate_general'), 'moderate_forum' => array(false, 'member_admin', 'moderate_general'), 'manage_membergroups' => array(false, 'member_admin', 'administrate'), 'manage_permissions' => array(false, 'member_admin', 'administrate'), 'manage_bans' => array(false, 'member_admin', 'administrate'), 'send_mail' => array(false, 'member_admin', 'administrate'), 'issue_warning' => array(false, 'member_admin', 'moderate_general'), 'profile_view' => array(true, 'profile', 'view_basic_info', 'view_basic_info'), 'profile_identity' => array(true, 'profile', 'edit_profile', 'moderate_general'), 'profile_extra' => array(true, 'profile', 'edit_profile', 'moderate_general'), 'profile_title' => array(true, 'profile', 'edit_profile', 'moderate_general'), 'profile_remove' => array(true, 'profile', 'delete_account', 'moderate_general'), 'profile_server_avatar' => array(false, 'profile', 'use_avatar'), 'profile_upload_avatar' => array(false, 'profile', 'use_avatar'), 'profile_remote_avatar' => array(false, 'profile', 'use_avatar'), 'profile_signature' => array(false, 'profile', 'edit_profile'), 'smftags_add' => array(false, 'smftags', 'smftags'), 'smftags_del' => array(false, 'smftags', 'smftags'), 'smftags_manage' => array(false, 'smftags', 'smftags'), 'drafts_allow' => array(false, 'drafts', 'drafts'), 'drafts_autosave_allow' => array(false, 'drafts', 'drafts'), 'post_links' => array(false, 'general', 'general'), 'can_dismiss_news' => array(false, 'general', 'general'), 'can_view_ratings' => array(false, 'general', 'general')), 'board' => array('moderate_board' => array(false, 'general_board', 'moderate'), 'approve_posts' => array(false, 'general_board', 'moderate'), 'post_new' => array(false, 'topic', 'make_posts'), 'post_unapproved_topics' => array(false, 'topic', 'make_unapproved_posts'), 'post_unapproved_replies' => array(true, 'topic', 'make_unapproved_posts', 'make_unapproved_posts'), 'post_reply' => array(true, 'topic', 'make_posts', 'make_posts'), 'post_sticky' => array(false, 'topic', 'make_posts'), 'merge_any' => array(false, 'topic', 'moderate'), 'split_any' => array(false, 'topic', 'moderate'), 'send_topic' => array(false, 'topic', 'moderate'), 'make_sticky' => array(false, 'topic', 'moderate'), 'move' => array(true, 'topic', 'moderate', 'moderate'), 'lock' => array(true, 'topic', 'moderate', 'moderate'), 'remove' => array(true, 'topic', 'modify', 'moderate'), 'modify_replies' => array(false, 'topic', 'moderate'), 'delete_replies' => array(false, 'topic', 'moderate'), 'announce_topic' => array(false, 'topic', 'moderate'), 'delete' => array(true, 'post', 'modify', 'moderate'), 'modify' => array(true, 'post', 'modify', 'moderate'), 'report_any' => array(false, 'post', 'participate'), 'tag_users' => array(false, 'post', 'participate'), 'post_links' => array(false, 'post', 'participate'), 'poll_view' => array(false, 'poll', 'participate'), 'poll_vote' => array(false, 'poll', 'participate'), 'poll_post' => array(false, 'poll', 'post_polls'), 'poll_add' => array(true, 'poll', 'post_polls', 'moderate'), 'poll_edit' => array(true, 'poll', 'modify', 'moderate'), 'poll_lock' => array(true, 'poll', 'moderate', 'moderate'), 'poll_remove' => array(true, 'poll', 'modify', 'moderate'), 'mark_any_notify' => array(false, 'notification', 'notification'), 'mark_notify' => array(false, 'notification', 'notification'), 'view_attachments' => array(false, 'attachment', 'participate'), 'post_unapproved_attachments' => array(false, 'attachment', 'make_unapproved_posts'), 'post_attachment' => array(false, 'attachment', 'attach'), 'like_see' => array(false, 'like', 'like'), 'like_give' => array(false, 'like', 'like'), 'use_share' => array(false, 'share', 'share'), 'see_hidden1' => array(false, 'hide', 'hide'), 'see_hidden2' => array(false, 'hide', 'hide'), 'see_hidden3' => array(false, 'hide', 'hide'))); // All permission groups that will be shown in the left column on classic view. $leftPermissionGroups = array('general', 'calendar', 'maintenance', 'member_admin', 'topic', 'post'); // We need to know what permissions we can't give to guests. loadIllegalGuestPermissions(); // Some permissions are hidden if features are off. $hiddenPermissions = array(); $relabelPermissions = array(); // Permissions to apply a different label to. $relabelGroups = array(); // As above but for groups. if (!in_array('cd', $context['admin_features'])) { $hiddenPermissions[] = 'calendar_view'; $hiddenPermissions[] = 'calendar_post'; $hiddenPermissions[] = 'calendar_edit'; } if (!in_array('w', $context['admin_features'])) { $hiddenPermissions[] = 'issue_warning'; } // Post moderation? if (!$modSettings['postmod_active']) { $hiddenPermissions[] = 'approve_posts'; $hiddenPermissions[] = 'post_unapproved_topics'; $hiddenPermissions[] = 'post_unapproved_replies'; $hiddenPermissions[] = 'post_unapproved_attachments'; } else { // Relabel the topics permissions $relabelPermissions['post_new'] = 'auto_approve_topics'; // Relabel the reply permissions $relabelPermissions['post_reply'] = 'auto_approve_replies'; // Relabel the attachment permissions $relabelPermissions['post_attachment'] = 'auto_approve_attachments'; } // Provide a practical way to modify permissions. HookAPI::callHook('integrate_load_permissions', array(&$permissionGroups, &$permissionList, &$leftPermissionGroups, &$hiddenPermissions, &$relabelPermissions)); $context['permissions'] = array(); $context['hidden_permissions'] = array(); foreach ($permissionList as $permissionType => $permissionList) { $context['permissions'][$permissionType] = array('id' => $permissionType, 'view' => $loadType, 'columns' => array()); foreach ($permissionList as $permission => $permissionArray) { // If this is a guest permission we don't do it if it's the guest group. if (isset($context['group']['id']) && $context['group']['id'] == -1 && in_array($permission, $context['non_guest_permissions'])) { continue; } // What groups will this permission be in? $own_group = $permissionArray[$loadType == 'classic' ? 1 : 2]; $any_group = $loadType == 'simple' && !empty($permissionArray[3]) ? $permissionArray[3] : ($loadType == 'simple' && $permissionArray[0] ? $permissionArray[2] : ''); // First, Do these groups actually exist - if not add them. if (!isset($permissionGroups[$permissionType][$loadType][$own_group])) { $permissionGroups[$permissionType][$loadType][$own_group] = true; } if (!empty($any_group) && !isset($permissionGroups[$permissionType][$loadType][$any_group])) { $permissionGroups[$permissionType][$loadType][$any_group] = true; } // What column should this be located into? $position = $loadType == 'classic' && !in_array($own_group, $leftPermissionGroups) ? 1 : 0; // If the groups have not yet been created be sure to create them. $bothGroups = array('own' => $own_group); $bothGroups = array(); // For guests, just reset the array. if (!isset($context['group']['id']) || !($context['group']['id'] == -1 && $any_group)) { $bothGroups['own'] = $own_group; } if ($any_group) { $bothGroups['any'] = $any_group; } foreach ($bothGroups as $group) { if (!isset($context['permissions'][$permissionType]['columns'][$position][$group])) { $context['permissions'][$permissionType]['columns'][$position][$group] = array('type' => $permissionType, 'id' => $group, 'name' => $loadType == 'simple' ? isset($txt['permissiongroup_simple_' . $group]) ? $txt['permissiongroup_simple_' . $group] : '' : $txt['permissiongroup_' . $group], 'icon' => isset($txt['permissionicon_' . $group]) ? $txt['permissionicon_' . $group] : $txt['permissionicon'], 'help' => isset($txt['permissionhelp_' . $group]) ? $txt['permissionhelp_' . $group] : '', 'hidden' => false, 'permissions' => array()); } } // This is where we set up the permission dependant on the view. if ($loadType == 'classic') { $context['permissions'][$permissionType]['columns'][$position][$own_group]['permissions'][$permission] = array('id' => $permission, 'name' => !isset($relabelPermissions[$permission]) ? $txt['permissionname_' . $permission] : $txt[$relabelPermissions[$permission]], 'show_help' => isset($txt['permissionhelp_' . $permission]), 'note' => isset($txt['permissionnote_' . $permission]) ? $txt['permissionnote_' . $permission] : '', 'has_own_any' => $permissionArray[0], 'own' => array('id' => $permission . '_own', 'name' => $permissionArray[0] ? $txt['permissionname_' . $permission . '_own'] : ''), 'any' => array('id' => $permission . '_any', 'name' => $permissionArray[0] ? $txt['permissionname_' . $permission . '_any'] : ''), 'hidden' => in_array($permission, $hiddenPermissions)); } else { foreach ($bothGroups as $group_type => $group) { $context['permissions'][$permissionType]['columns'][$position][$group]['permissions'][$permission . ($permissionArray[0] ? '_' . $group_type : '')] = array('id' => $permission . ($permissionArray[0] ? '_' . $group_type : ''), 'name' => isset($txt['permissionname_simple_' . $permission . ($permissionArray[0] ? '_' . $group_type : '')]) ? $txt['permissionname_simple_' . $permission . ($permissionArray[0] ? '_' . $group_type : '')] : $txt['permissionname_' . $permission], 'help_index' => isset($txt['permissionhelp_' . $permission]) ? 'permissionhelp_' . $permission : '', 'hidden' => in_array($permission, $hiddenPermissions)); } } if (in_array($permission, $hiddenPermissions)) { if ($permissionArray[0]) { $context['hidden_permissions'][] = $permission . '_own'; $context['hidden_permissions'][] = $permission . '_any'; } else { $context['hidden_permissions'][] = $permission; } } } ksort($context['permissions'][$permissionType]['columns']); } // Check we don't leave any empty groups - and mark hidden ones as such. foreach ($context['permissions'][$permissionType]['columns'] as $column => $groups) { foreach ($groups as $id => $group) { if (empty($group['permissions'])) { unset($context['permissions'][$permissionType]['columns'][$column][$id]); } else { $foundNonHidden = false; foreach ($group['permissions'] as $permission) { if (empty($permission['hidden'])) { $foundNonHidden = true; } } if (!$foundNonHidden) { $context['permissions'][$permissionType]['columns'][$column][$id]['hidden'] = true; } } } } }
function fix_possible_url($val) { global $modSettings, $context, $scripturl; if (substr($val, 0, strlen($scripturl)) != $scripturl) { return $val; } HookAPI::callHook('integrate_fix_url', array(&$val)); return $val; }
function ModifyGeneralModSettings($return_config = false) { global $txt, $scripturl, $context, $settings, $sc, $modSettings; $config_vars = array(); // Make it even easier to add new settings. HookAPI::callHook('integrate_general_mod_settings', array(&$config_vars)); if ($return_config) { return $config_vars; } $context['post_url'] = $scripturl . '?action=admin;area=modsettings;save;sa=general'; $context['settings_title'] = $txt['mods_cat_modifications_misc']; // No removing this line you, dirty unwashed mod authors. :p if (empty($config_vars)) { $context['settings_save_dont_show'] = true; $context['settings_message'] = '<div class="centertext">' . $txt['modification_no_misc_settings'] . '</div>'; return prepareDBSettingContext($config_vars); } // Saving? if (isset($_GET['save'])) { checkSession(); $save_vars = $config_vars; // This line is to help mod authors do a search/add after if you want to add something here. Keyword: FOOT TAPPING SUCKS! saveDBSettings($save_vars); // This line is to help mod authors do a search/add after if you want to add something here. Keyword: I LOVE TEA! redirectexit('action=admin;area=modsettings;sa=general'); } // This line is to help mod authors do a search/add after if you want to add something here. Keyword: RED INK IS FOR TEACHERS AND THOSE WHO LIKE PAIN! prepareDBSettingContext($config_vars); }
function authentication($memID, $saving = false) { global $context, $cur_profile, $sourcedir, $post_errors, $modSettings; loadLanguage('Login'); // We are saving? if ($saving) { // Moving to password passed authentication? if ($_POST['authenticate'] == 'passwd') { // Didn't enter anything? if ($_POST['passwrd1'] == '') { $post_errors[] = 'no_password'; } elseif (!isset($_POST['passwrd2']) || $_POST['passwrd1'] != $_POST['passwrd2']) { $post_errors[] = 'bad_new_password'; } else { require_once $sourcedir . '/lib/Subs-Auth.php'; $passwordErrors = validatePassword($_POST['passwrd1'], $cur_profile['member_name'], array($cur_profile['real_name'], $cur_profile['email_address'])); // Were there errors? if ($passwordErrors != null) { $post_errors[] = 'password_' . $passwordErrors; } } if (empty($post_errors)) { // Integration? HookAPI::callHook('integrate_reset_pass', array($cur_profile['member_name'], $cur_profile['member_name'], $_POST['passwrd1'])); // Go then. $passwd = sha1(strtolower($cur_profile['member_name']) . un_htmlspecialchars($_POST['passwrd1'])); // Do the important bits. updateMemberData($memID, array('openid_uri' => '', 'passwd' => $passwd)); if ($context['user']['is_owner']) { setLoginCookie(60 * $modSettings['cookieTime'], $memID, sha1(sha1(strtolower($cur_profile['member_name']) . un_htmlspecialchars($_POST['passwrd2'])) . $cur_profile['password_salt'])); } redirectexit('action=profile;u=' . $memID); } return true; } elseif ($_POST['authenticate'] == 'openid' && !empty($_POST['openid_identifier'])) { require_once $sourcedir . '/lib/Subs-OpenID.php'; $_POST['openid_identifier'] = smf_openID_canonize($_POST['openid_identifier']); if (smf_openid_member_exists($_POST['openid_identifier'])) { $post_errors[] = 'openid_in_use'; } elseif (empty($post_errors)) { // Authenticate using the new OpenID URI first to make sure they didn't make a mistake. if ($context['user']['is_owner']) { $_SESSION['new_openid_uri'] = $_POST['openid_identifier']; smf_openID_validate($_POST['openid_identifier'], false, null, 'change_uri'); } else { updateMemberData($memID, array('openid_uri' => $_POST['openid_identifier'])); } } } } // Some stuff. $context['member']['openid_uri'] = $cur_profile['openid_uri']; $context['auth_method'] = empty($cur_profile['openid_uri']) ? 'password' : 'openid'; $context['sub_template'] = 'authentication_method'; }
function validateSession() { global $modSettings, $sourcedir, $user_info, $sc, $user_settings; // We don't care if the option is off, because Guests should NEVER get past here. is_not_guest(); // If we're using XML give an additional ten minutes grace as an admin can't log on in XML mode. $refreshTime = isset($_GET['xml']) ? 4200 : 3600; // Is the security option off? Or are they already logged in? if (!empty($_SESSION['admin_time']) && $_SESSION['admin_time'] + $refreshTime >= time()) { return; } require_once $sourcedir . '/lib/Subs-Auth.php'; // Hashed password, ahoy! if (isset($_POST['admin_hash_pass']) && strlen($_POST['admin_hash_pass']) == 40) { checkSession(); $good_password = in_array(true, HookAPI::callHook('integrate_verify_password', array($user_info['username'], $_POST['admin_hash_pass'], true)), true); if ($good_password || $_POST['admin_hash_pass'] == sha1($user_info['passwd'] . $sc)) { $_SESSION['admin_time'] = time(); return; } } // Posting the password... check it. if (isset($_POST['admin_pass'])) { checkSession(); $good_password = in_array(true, HookAPI::callHook('integrate_verify_password', array($user_info['username'], $_POST['admin_pass'], false)), true); // Password correct? if ($good_password || sha1(strtolower($user_info['username']) . $_POST['admin_pass']) == $user_info['passwd']) { $_SESSION['admin_time'] = time(); return; } } // OpenID? if (!empty($user_settings['openid_uri'])) { require_once $sourcedir . '/lib/Subs-OpenID.php'; smf_openID_revalidate(); $_SESSION['admin_time'] = time(); return; } // Need to type in a password for that, man. adminLogin(); }
function smf_main() { global $context, $modSettings, $settings, $user_info, $board, $topic, $board_info, $maintenance, $sourcedir, $backend_subdir, $db_show_debug; // Special case: session keep-alive, output a transparent pixel. if (isset($_GET['action']) && $_GET['action'] == 'keepalive') { header('Content-Type: image/gif'); die("GIF89a€!ù,D;"); } // Load the user's cookie (or set as guest) and load their settings. loadUserSettings(); // Load the current board's information. loadBoard(); // Load the current user's permissions. loadPermissions(); $context['can_search'] = allowedTo('search_posts'); $context['additional_admin_errors'] .= CacheAPI::verifyFileCache(); // Attachments don't require the entire theme to be loaded. if (isset($_REQUEST['action']) && $_REQUEST['action'] == 'dlattach' && (!empty($modSettings['allow_guestAccess']) && $user_info['is_guest'])) { detectBrowser(); $context['forum_name_html_safe'] = ''; } else { loadTheme(); EoS_Smarty::init($db_show_debug); } $user_info['notify_count'] += !empty($context['open_mod_reports']) ? 1 : 0; URL::setSID(); array_unshift($context['linktree'], array('url' => URL::home(), 'name' => $context['forum_name_html_safe'])); // Check if the user should be disallowed access. is_not_banned(); $context['can_see_hidden_level1'] = allowedTo('see_hidden1'); $context['can_see_hidden_level2'] = allowedTo('see_hidden2'); $context['can_see_hidden_level2'] = allowedTo('see_hidden2'); // If we are in a topic and don't have permission to approve it then duck out now. if (!empty($topic) && empty($board_info['cur_topic_approved']) && !allowedTo('approve_posts') && ($user_info['id'] != $board_info['cur_topic_starter'] || $user_info['is_guest'])) { fatal_lang_error('not_a_topic', false); } // Do some logging, unless this is an attachment, avatar, toggle of editor buttons, theme option, XML feed etc. if (empty($_REQUEST['action']) || !in_array($_REQUEST['action'], array('dlattach', 'findmember', 'jseditor', 'jsoption', 'requestmembers', 'smstats', '.xml', 'xmlhttp', 'verificationcode', 'viewquery', 'viewsmfile'))) { // Log this user as online. writeLog(); // Track forum statistics and hits...? if (!empty($modSettings['hitStats'])) { trackStats(array('hits' => '+')); } } // Is the forum in maintenance mode? (doesn't apply to administrators.) if (!empty($maintenance) && !allowedTo('admin_forum')) { // You can only login.... otherwise, you're getting the "maintenance mode" display. if (isset($_REQUEST['action']) && ($_REQUEST['action'] == 'login2' || $_REQUEST['action'] == 'logout')) { require_once $sourcedir . '/LogInOut.php'; return $_REQUEST['action'] == 'login2' ? 'Login2' : 'Logout'; } else { require_once $sourcedir . '/lib/Subs-Auth.php'; return 'InMaintenance'; } } elseif (empty($modSettings['allow_guestAccess']) && $user_info['is_guest'] && (!isset($_REQUEST['action']) || !in_array($_REQUEST['action'], array('coppa', 'login', 'login2', 'register', 'register2', 'reminder', 'activate', 'help', 'smstats', 'mailq', 'verificationcode', 'openidreturn')))) { require_once $sourcedir . '/lib/Subs-Auth.php'; return 'KickGuest'; } elseif (empty($_REQUEST['action'])) { // Action and board are both empty... BoardIndex! if (empty($board) && empty($topic)) { require_once $sourcedir . '/BoardIndex.php'; return 'BoardIndex'; } elseif (empty($topic)) { require_once $sourcedir . '/MessageIndex.php'; return 'MessageIndex'; } else { require_once $sourcedir . '/Display.php'; return 'Display'; } } // Here's the monstrous $_REQUEST['action'] array - $_REQUEST['action'] => array($file, $function). $actionArray = array('activate' => array('Register.php', 'Activate'), 'admin' => array($backend_subdir . '/Admin.php', 'AdminMain'), 'announce' => array('Post.php', 'AnnounceTopic'), 'attachapprove' => array('lib/Subs-ManageAttachments.php', 'ApproveAttach'), 'buddy' => array('lib/Subs-Members.php', 'BuddyListToggle'), 'calendar' => array('Calendar.php', 'CalendarMain'), 'clock' => array('Calendar.php', 'clock'), 'collapse' => array('BoardIndex.php', 'CollapseCategory'), 'coppa' => array('Register.php', 'CoppaForm'), 'credits' => array('Who.php', 'Credits'), 'deletemsg' => array('RemoveTopic.php', 'DeleteMessage'), 'display' => array('Display.php', 'Display'), 'dlattach' => array('Display.php', 'Download'), 'editpoll' => array('Poll.php', 'EditPoll'), 'editpoll2' => array('Poll.php', 'EditPoll2'), 'emailuser' => array('SendTopic.php', 'EmailUser'), 'findmember' => array('lib/Subs-Auth.php', 'JSMembers'), 'groups' => array('Groups.php', 'Groups'), 'help' => array('Help.php', 'ShowHelp'), 'helpadmin' => array('Help.php', 'ShowAdminHelp'), 'im' => array('PersonalMessage.php', 'MessageMain'), 'jseditor' => array('lib/Subs-Editor.php', 'EditorMain'), 'jsmodify' => array('Post.php', 'JavaScriptModify'), 'jsoption' => array($backend_subdir . '/Themes.php', 'SetJavaScript'), 'lock' => array('LockTopic.php', 'LockTopic'), 'lockvoting' => array('Poll.php', 'LockVoting'), 'login' => array('LogInOut.php', 'Login'), 'login2' => array('LogInOut.php', 'Login2'), 'logout' => array('LogInOut.php', 'Logout'), 'markasread' => array('lib/Subs-Boards.php', 'MarkRead'), 'mergetopics' => array('SplitTopics.php', 'MergeTopics'), 'mlist' => array('Memberlist.php', 'Memberlist'), 'moderate' => array('ModerationCenter.php', 'ModerationMain'), 'modifycat' => array('ManageBoards.php', 'ModifyCat'), 'movetopic' => array('MoveTopic.php', 'MoveTopic'), 'movetopic2' => array('MoveTopic.php', 'MoveTopic2'), 'notify' => array('Notify.php', 'Notify'), 'notifyboard' => array('Notify.php', 'BoardNotify'), 'openidreturn' => array('lib/Subs-OpenID.php', 'smf_openID_return'), 'pm' => array('PersonalMessage.php', 'MessageMain'), 'post' => array('Post.php', 'Post'), 'post2' => array('Post.php', 'Post2'), 'printpage' => array('Printpage.php', 'PrintTopic'), 'profile' => array('Profile.php', 'ModifyProfile'), 'quotefast' => array('Post.php', 'QuoteFast'), 'quickmod' => array('MessageIndex.php', 'QuickModeration'), 'quickmod2' => array('Display.php', 'QuickInTopicModeration'), 'recent' => array('Recent.php', 'RecentPosts'), 'register' => array('Register.php', 'Register'), 'register2' => array('Register.php', 'Register2'), 'reminder' => array('Reminder.php', 'RemindMe'), 'removepoll' => array('Poll.php', 'RemovePoll'), 'removetopic2' => array('RemoveTopic.php', 'RemoveTopic2'), 'reporttm' => array('SendTopic.php', 'ReportToModerator'), 'requestmembers' => array('lib/Subs-Auth.php', 'RequestMembers'), 'restoretopic' => array('RemoveTopic.php', 'RestoreTopic'), 'search' => array('Search.php', 'PlushSearch1'), 'search2' => array('Search.php', 'PlushSearch2'), 'sendtopic' => array('SendTopic.php', 'EmailUser'), 'smstats' => array('Stats.php', 'SMStats'), 'suggest' => array('lib/Subs-Editor.php', 'AutoSuggestHandler'), 'splittopics' => array('SplitTopics.php', 'SplitTopics'), 'stats' => array('Stats.php', 'DisplayStats'), 'sticky' => array('LockTopic.php', 'Sticky'), 'theme' => array($backend_subdir . '/Themes.php', 'ThemesMain'), 'trackip' => array('Profile-View.php', 'trackIP'), 'about:unknown' => array('Karma.php', 'BookOfUnknown'), 'unread' => array('Recent.php', 'UnreadTopics'), 'unreadreplies' => array('Recent.php', 'UnreadTopics'), 'verificationcode' => array('Register.php', 'VerificationCode'), 'viewprofile' => array('Profile.php', 'ModifyProfile'), 'vote' => array('Poll.php', 'Vote'), 'viewquery' => array('ViewQuery.php', 'ViewQuery'), 'who' => array('Who.php', 'Who'), '.xml' => array('News.php', 'ShowXmlFeed'), 'xmlhttp' => array('Xml.php', 'XMLhttpMain'), 'like' => array('Ratings.php', 'LikeDispatch'), 'tags' => array('Tagging.php', 'TagsMain'), 'astream' => array('Activities.php', 'aStreamDispatch'), 'dismissnews' => array('Profile-Actions.php', 'DismissNews'), 'whatsnew' => array('Recent.php', 'WhatsNew')); // Allow modifying $actionArray easily. HookAPI::callHook('integrate_actions', array(&$actionArray)); // Get the function and file to include - if it's not there, do the board index. if (!isset($_REQUEST['action']) || !isset($actionArray[$_REQUEST['action']])) { // Catch the action with the theme? if (!empty($settings['catch_action'])) { require_once $sourcedir . '/' . $backend_subdir . '/Themes.php'; return 'WrapAction'; } // Fall through to the board index then... require_once $sourcedir . '/BoardIndex.php'; return 'BoardIndex'; } // Otherwise, it was set - so let's go to that action. require_once $sourcedir . '/' . $actionArray[$_REQUEST['action']][0]; return $actionArray[$_REQUEST['action']][1]; }
function SecretAnswer2() { global $txt, $context, $modSettings, $smcFunc, $sourcedir; checkSession(); // Hacker? How did you get this far without an email or username? if (empty($_REQUEST['uid'])) { fatal_lang_error('username_no_exist', false); } loadLanguage('Login'); // Get the information from the database. $request = smf_db_query(' SELECT id_member, real_name, member_name, secret_answer, secret_question, openid_uri, email_address FROM {db_prefix}members WHERE id_member = {int:id_member} LIMIT 1', array('id_member' => $_REQUEST['uid'])); if (mysql_num_rows($request) == 0) { fatal_lang_error('username_no_exist', false); } $row = mysql_fetch_assoc($request); mysql_free_result($request); // Check if the secret answer is correct. if ($row['secret_question'] == '' || $row['secret_answer'] == '' || md5($_POST['secret_answer']) != $row['secret_answer']) { log_error(sprintf($txt['reminder_error'], $row['member_name']), 'user'); fatal_lang_error('incorrect_answer', false); } // If it's OpenID this is where the music ends. if (!empty($row['openid_uri'])) { $context['sub_template'] = 'sent'; $context['description'] = sprintf($txt['reminder_openid_is'], $row['openid_uri']); return; } // You can't use a blank one! if (strlen(trim($_POST['passwrd1'])) === 0) { fatal_lang_error('no_password', false); } // They have to be the same too. if ($_POST['passwrd1'] != $_POST['passwrd2']) { fatal_lang_error('passwords_dont_match', false); } // Make sure they have a strong enough password. require_once $sourcedir . '/lib/Subs-Auth.php'; $passwordError = validatePassword($_POST['passwrd1'], $row['member_name'], array($row['email_address'])); // Invalid? if ($passwordError != null) { fatal_lang_error('profile_error_password_' . $passwordError, false); } // Alright, so long as 'yer sure. updateMemberData($row['id_member'], array('passwd' => sha1(strtolower($row['member_name']) . $_POST['passwrd1']))); HookAPI::callHook('integrate_reset_pass', array($row['member_name'], $row['member_name'], $_POST['passwrd1'])); // Tell them it went fine. EoS_Smarty::loadTemplate('generic_skeleton'); EoS_Smarty::getConfigInstance()->registerHookTemplate('generic_content_area', 'loginout/login'); $context += array('page_title' => $txt['reminder_password_set'], 'default_username' => $row['member_name'], 'default_password' => $_POST['passwrd1'], 'never_expire' => false, 'description' => $txt['reminder_password_set']); }
/** * @name EosAlpha BBS * @copyright 2011 Alex Vie silvercircle(AT)gmail(DOT)com * * This software is a derived product, based on: * * Simple Machines Forum (SMF) * copyright: 2011 Simple Machines (http://www.simplemachines.org) * license: BSD, See included LICENSE.TXT for terms and conditions. * * @version 1.0pre */ function template_main() { global $context, $settings, $options, $scripturl, $modSettings, $txt; echo ' <a id="top"></a> <h1 class="bigheader">', $context['name'], '</h1>'; if (!empty($options['show_board_desc']) && $context['description'] != '') { echo ' <div class="smalltext">', $context['description'], '</div>'; } if (count($context['boards']) && (!empty($options['show_children']) || $context['start'] == 0)) { $collapser = array('id' => $context['current_board'] . '_childboards', 'title' => $txt['parent_boards'], 'bodyclass' => 'generic_container'); echo '<br>'; template_create_collapsible_container($collapser); echo '<div class="framed_region smallpadding"><ol id="board_', $context['current_board'], '_children" class="commonlist category">'; $context['alternate'] = 1; foreach ($context['boards'] as &$board) { if (!$board['ignored']) { template_boardbit($board); } } echo ' </ol> </div> </div> '; } if ($context['hidden_boards']['hidden_count']) { echo ' <br> <div id="show_hidden_boards" class="orange_container norounded gradient_darken_down tinytext"><span class="floatright">', $context['hidden_boards']['setup_notice'], '</span><strong>', sprintf($context['hidden_boards']['notice'], $context['hidden_boards']['hidden_count'], '<a onclick="$(\'div#hidden_boards\').fadeIn();return(false);" href="!#">'), '</strong></div> <div class="category" id="hidden_boards" style="display:none;"> <div class="framed_region cleantop root_cat" id="category_0"> <ol class="commonlist category">'; foreach ($context['hidden_boards']['boards'] as &$board) { if ($board['ignored']) { template_boardbit($board); } } echo ' </ol> </div> </div> <div class="cContainer_end"></div>'; } if (!$context['act_as_cat']) { $normal_buttons = array('new_topic' => array('test' => 'can_post_new', 'text' => 'new_topic', 'image' => 'new_topic.gif', 'lang' => true, 'url' => $scripturl . '?action=post;board=' . $context['current_board'] . '.0', 'active' => true), 'post_poll' => array('test' => 'can_post_poll', 'text' => 'new_poll', 'image' => 'new_poll.gif', 'lang' => true, 'url' => $scripturl . '?action=post;board=' . $context['current_board'] . '.0;poll'), 'notify' => array('test' => 'can_mark_notify', 'text' => $context['is_marked_notify'] ? 'unnotify' : 'notify', 'image' => ($context['is_marked_notify'] ? 'un' : '') . 'notify.gif', 'lang' => true, 'custom' => 'onclick="return confirm(\'' . ($context['is_marked_notify'] ? $txt['notification_disable_board'] : $txt['notification_enable_board']) . '\');"', 'url' => $scripturl . '?action=notifyboard;sa=' . ($context['is_marked_notify'] ? 'off' : 'on') . ';board=' . $context['current_board'] . '.' . $context['start'] . ';' . $context['session_var'] . '=' . $context['session_id']), 'markread' => array('text' => 'mark_read_short', 'image' => 'markread.gif', 'lang' => true, 'url' => $scripturl . '?action=markasread;sa=board;board=' . $context['current_board'] . '.0;' . $context['session_var'] . '=' . $context['session_id'])); // They can only mark read if they are logged in and it's enabled! if (!$context['user']['is_logged'] || !$settings['show_mark_read']) { unset($normal_buttons['markread']); } // Allow adding new buttons easily. HookAPI::callHook('integrate_messageindex_buttons', array(&$normal_buttons)); if (!$context['no_topic_listing']) { echo ' <div class="pagesection top smallpadding"> <div class="pagelinks floatleft">', $context['page_index'], ' <a class="navPages" href="#bot">' . $txt['go_down'] . '</a></div> ', template_button_strip($normal_buttons, 'right'), ' </div>'; // If Quick Moderation is enabled start the form. if (!empty($context['can_quick_mod']) && $options['display_quick_mod'] > 0 && !empty($context['topics'])) { echo ' <form action="', $scripturl, '?action=quickmod;board=', $context['current_board'], '.', $context['start'], '" method="post" accept-charset="UTF-8" class="clear" name="quickModForm" id="quickModForm">'; } echo ' <div class="framed_region"> <table class="topic_table">'; // Are there actually any topics to show? if (!empty($context['topics'])) { echo ' <thead> <tr class="mediumpadding"> <th scope="col" colspan="2" class="first_th glass cleantop" style="width:8%;"> </th> <th scope="col" class="lefttext nowrap glass cleantop"><a rel="nofollow" href="', $scripturl, '?board=', $context['current_board'], '.', $context['start'], ';sort=subject', $context['sort_by'] == 'subject' && $context['sort_direction'] == 'up' ? ';desc' : '', '">', $txt['subject'], $context['sort_by'] == 'subject' ? ' <img src="' . $settings['images_url'] . '/sort_' . $context['sort_direction'] . '.gif" alt="" />' : '', '</a> / <a rel="nofollow" href="', $scripturl, '?board=', $context['current_board'], '.', $context['start'], ';sort=starter', $context['sort_by'] == 'starter' && $context['sort_direction'] == 'up' ? ';desc' : '', '">', $txt['started_by'], $context['sort_by'] == 'starter' ? ' <img src="' . $settings['images_url'] . '/sort_' . $context['sort_direction'] . '.gif" alt="" />' : '', '</a></th> <th scope="col" class="nowrap glass cleantop"><a rel="nofollow" href="', $scripturl, '?board=', $context['current_board'], '.', $context['start'], ';sort=replies', $context['sort_by'] == 'replies' && $context['sort_direction'] == 'up' ? ';desc' : '', '">', $txt['replies'], $context['sort_by'] == 'replies' ? ' <img src="' . $settings['images_url'] . '/sort_' . $context['sort_direction'] . '.gif" alt="" />' : '', '</a> / <a href="', $scripturl, '?board=', $context['current_board'], '.', $context['start'], ';sort=views', $context['sort_by'] == 'views' && $context['sort_direction'] == 'up' ? ';desc' : '', '">', $txt['views'], $context['sort_by'] == 'views' ? ' <img src="' . $settings['images_url'] . '/sort_' . $context['sort_direction'] . '.gif" alt="" />' : '', '</a></th> <th scope="col" class="centertext nowrap glass cleantop"><a rel="nofollow" href="', $scripturl, '?board=', $context['current_board'], '.', $context['start'], ';sort=last_post', $context['sort_by'] == 'last_post' && $context['sort_direction'] == 'up' ? ';desc' : '', '">', $txt['last_post'], $context['sort_by'] == 'last_post' ? ' <img src="' . $settings['images_url'] . '/sort_' . $context['sort_direction'] . '.gif" alt="" />' : '', '</a></th>'; // Show a "select all" box for quick moderation? if (!empty($context['can_quick_mod'])) { echo ' <th scope="col" class="glass cleantop last_th" style="width:24px;"><input type="checkbox" class="input_check cb_invertall" /></th>'; } } else { echo ' <thead> <tr> <th class="red_container"><strong>', $txt['msg_alert_none'], '</strong></th>'; } echo ' </tr> </thead>'; if (!empty($settings['display_who_viewing'])) { echo ' <tr class="whos_viewing mediumpadding"> <td colspan="', !empty($context['can_quick_mod']) ? '6' : '5', '" class="smalltext">'; if ($settings['display_who_viewing'] == 1) { echo count($context['view_members']), ' ', count($context['view_members']) === 1 ? $txt['who_member'] : $txt['members']; } else { echo empty($context['view_members_list']) ? '0 ' . $txt['members'] : implode(', ', $context['view_members_list']) . ((empty($context['view_num_hidden']) or $context['can_moderate_forum']) ? '' : ' (+ ' . $context['view_num_hidden'] . ' ' . $txt['hidden'] . ')'); } echo $txt['who_and'], $context['view_num_guests'], ' ', $context['view_num_guests'] == 1 ? $txt['guest'] : $txt['guests'], $txt['who_viewing_board'], ' </td> </tr>'; } // If this person can approve items and we have some awaiting approval tell them. if (!empty($context['unapproved_posts_message'])) { echo ' <tr class="windowbg2"> <td colspan="', !empty($context['can_quick_mod']) ? '6' : '5', '"> <span class="alert">!</span> ', $context['unapproved_posts_message'], ' </td> </tr>'; } foreach ($context['topics'] as &$topic) { template_topicbit($topic); } if (!empty($context['can_quick_mod']) && $options['display_quick_mod'] && !empty($context['topics'])) { echo ' <tr> <td colspan="6" class="righttext"> <select class="qaction" name="qaction"', $context['can_move'] ? ' onchange="this.form.moveItTo.disabled = (this.options[this.selectedIndex].value != \'move\');"' : '', '> <option value="">--------</option>', $context['can_remove'] ? ' <option value="remove">' . $txt['quick_mod_remove'] . '</option>' : '', $context['can_lock'] ? ' <option value="lock">' . $txt['quick_mod_lock'] . '</option>' : '', $context['can_sticky'] ? ' <option value="sticky">' . $txt['quick_mod_sticky'] . '</option>' : '', $context['can_move'] ? ' <option value="move">' . $txt['quick_mod_move'] . ': </option>' : '', $context['can_merge'] ? ' <option value="merge">' . $txt['quick_mod_merge'] . '</option>' : '', $context['can_restore'] ? ' <option value="restore">' . $txt['quick_mod_restore'] . '</option>' : '', $context['can_approve'] ? ' <option value="approve">' . $txt['quick_mod_approve'] . '</option>' : '', $context['user']['is_logged'] ? ' <option value="markread">' . $txt['quick_mod_markread'] . '</option>' : '', ' </select>'; // Show a list of boards they can move the topic to. if ($context['can_move']) { echo ' <select class="qaction" id="moveItTo" name="move_to" disabled="disabled">'; foreach ($context['move_to_boards'] as $category) { echo ' <optgroup label="', $category['name'], '">'; foreach ($category['boards'] as $board) { echo ' <option value="', $board['id'], '"', $board['selected'] ? ' selected="selected"' : '', '>', $board['child_level'] > 0 ? str_repeat('==', $board['child_level'] - 1) . '=>' : '', ' ', $board['name'], '</option>'; } echo ' </optgroup>'; } echo ' </select>'; } echo ' <input type="submit" value="', $txt['quick_mod_go'], '" onclick="return document.forms.quickModForm.qaction.value != \'\' && confirm(\'', $txt['quickmod_confirm'], '\');" class="button_submit qaction" /> </td> </tr>'; } echo ' </tbody> </table> </div>'; } echo ' <a id="bot"></a>'; // Finish off the form - again. if (!empty($context['can_quick_mod']) && $options['display_quick_mod'] > 0 && !empty($context['topics'])) { echo ' <input type="hidden" name="' . $context['session_var'] . '" value="' . $context['session_id'] . '" /> </form>'; } echo ' <div class="pagesection bottom smallpadding"> ', template_button_strip($normal_buttons, 'right'), ' <div class="pagelinks floatleft">', $context['page_index'], ' <a class="navPages" href="#top">' . $txt['go_up'] . '</a></div> </div>'; } theme_linktree(); echo ' <div class="tborder" id="topic_icons"> <div class="description"> <p class="floatright" id="message_index_jump_to"> </p>'; $context['inline_footer_script'] .= ' if (typeof(window.XMLHttpRequest) != "undefined") aJumpTo[aJumpTo.length] = new JumpTo({ sContainerId: "message_index_jump_to", sJumpToTemplate: "<label class=\\"smalltext\\" for=\\"%select_id%\\">' . $context['jump_to']['label'] . ':<" + "/label> %dropdown_list%", iCurBoardId: ' . $context['current_board'] . ', iCurBoardChildLevel: ' . $context['jump_to']['child_level'] . ', sCurBoardName: "' . $context['jump_to']['board_name'] . '", sBoardChildLevelIndicator: "==", sBoardPrefix: "=> ", sCatSeparator: "-----------------------------", sCatPrefix: "", sGoButtonLabel: "' . $txt['quick_mod_go'] . '" }); '; echo ' <br class="clear" /> </div> </div>'; // Javascript for inline editing. $context['inline_footer_script'] .= ' // Hide certain bits during topic edit. hide_prefixes.push("lockicon", "stickyicon", "pages", "newicon"); // Use it to detect when we\'ve stopped editing. document.onclick = modify_topic_click; var mouse_on_div; function modify_topic_click() { if (in_edit_mode == 1 && mouse_on_div == 0) modify_topic_save("' . $context['session_id'] . '", "' . $context['session_var'] . '"); } function modify_topic_keypress(oEvent) { if (typeof(oEvent.keyCode) != "undefined" && oEvent.keyCode == 13) { modify_topic_save("' . $context['session_id'] . '", "' . $context['session_var'] . '"); if (typeof(oEvent.preventDefault) == "undefined") oEvent.returnValue = false; else oEvent.preventDefault(); } } // For templating, shown when an inline edit is made. function modify_topic_show_edit(subject) { // Just template the subject. setInnerHTML(cur_subject_div, \'<input type="text" name="subject" value="\' + subject + \'" size="60" style="width: 95%;" maxlength="80" onkeypress="modify_topic_keypress(event)" class="input_text" /><input type="hidden" name="topic" value="\' + cur_topic_id + \'" /><input type="hidden" name="msg" value="\' + cur_msg_id.substr(4) + \'" />\'); } // And the reverse for hiding it. function modify_topic_hide_edit(subject) { // Re-template the subject! setInnerHTML(cur_subject_div, \'<a href="' . $scripturl . '?topic=\' + cur_topic_id + \'.0">\' + subject + \'<\' +\'/a>\'); } '; }
function resetPassword($memID, $username = null) { global $scripturl, $context, $txt, $sourcedir, $modSettings, $smcFunc, $language; // Language... and a required file. loadLanguage('Login'); require_once $sourcedir . '/lib/Subs-Post.php'; // Get some important details. $request = smf_db_query(' SELECT member_name, email_address, lngfile FROM {db_prefix}members WHERE id_member = {int:id_member}', array('id_member' => $memID)); list($user, $email, $lngfile) = mysql_fetch_row($request); mysql_free_result($request); if ($username !== null) { $old_user = $user; $user = trim($username); } // Generate a random password. $newPassword = substr(preg_replace('/\\W/', '', md5(mt_rand())), 0, 10); $newPassword_sha1 = sha1(strtolower($user) . $newPassword); // Do some checks on the username if needed. if ($username !== null) { validateUsername($memID, $user); // Update the database... updateMemberData($memID, array('member_name' => $user, 'passwd' => $newPassword_sha1)); } else { updateMemberData($memID, array('passwd' => $newPassword_sha1)); } HookAPI::callHook('integrate_reset_pass', array($old_user, $user, $newPassword)); $replacements = array('USERNAME' => $user, 'PASSWORD' => $newPassword); $emaildata = loadEmailTemplate('change_password', $replacements, empty($lngfile) || empty($modSettings['userLanguage']) ? $language : $lngfile); // Send them the email informing them of the change - then we're done! sendmail($email, $emaildata['subject'], $emaildata['body'], null, null, false, 0); }
function Activate() { global $context, $txt, $modSettings, $scripturl, $sourcedir, $language; loadLanguage('Login'); //loadTemplate('Login'); if (empty($_REQUEST['u']) && empty($_POST['user'])) { if (empty($modSettings['registration_method']) || $modSettings['registration_method'] == 3) { fatal_lang_error('no_access', false); } $context['member_id'] = 0; EoS_Smarty::loadTemplate('generic_skeleton'); EoS_Smarty::getConfigInstance()->registerHookTemplate('generic_content_area', 'loginout/resend'); $context['page_title'] = $txt['invalid_activation_resend']; $context['can_activate'] = empty($modSettings['registration_method']) || $modSettings['registration_method'] == 1; $context['default_username'] = isset($_GET['user']) ? $_GET['user'] : ''; return; } // Get the code from the database... $request = smf_db_query(' SELECT id_member, validation_code, member_name, real_name, email_address, is_activated, passwd, lngfile FROM {db_prefix}members' . (empty($_REQUEST['u']) ? ' WHERE member_name = {string:email_address} OR email_address = {string:email_address}' : ' WHERE id_member = {int:id_member}') . ' LIMIT 1', array('id_member' => isset($_REQUEST['u']) ? (int) $_REQUEST['u'] : 0, 'email_address' => isset($_POST['user']) ? $_POST['user'] : '')); // Does this user exist at all? if (mysql_num_rows($request) == 0) { EoS_Smarty::loadTemplate('generic_skeleton'); EoS_Smarty::getConfigInstance()->registerHookTemplate('generic_content_area', 'loginout/retry_activate'); $context['page_title'] = $txt['invalid_userid']; $context['member_id'] = 0; return; } $row = mysql_fetch_assoc($request); mysql_free_result($request); // Change their email address? (they probably tried a fake one first :P.) if (isset($_POST['new_email'], $_REQUEST['passwd']) && sha1(strtolower($row['member_name']) . $_REQUEST['passwd']) == $row['passwd']) { if (empty($modSettings['registration_method']) || $modSettings['registration_method'] == 3) { fatal_lang_error('no_access', false); } // !!! Separate the sprintf? if (preg_match('~^[0-9A-Za-z=_+\\-/][0-9A-Za-z=_\'+\\-/\\.]*@[\\w\\-]+(\\.[\\w\\-]+)*(\\.[\\w]{2,6})$~', $_POST['new_email']) == 0) { fatal_error(sprintf($txt['valid_email_needed'], htmlspecialchars($_POST['new_email'])), false); } // Make sure their email isn't banned. isBannedEmail($_POST['new_email'], 'cannot_register', $txt['ban_register_prohibited']); // Ummm... don't even dare try to take someone else's email!! $request = smf_db_query(' SELECT id_member FROM {db_prefix}members WHERE email_address = {string:email_address} LIMIT 1', array('email_address' => $_POST['new_email'])); // !!! Separate the sprintf? if (mysql_num_rows($request) != 0) { fatal_lang_error('email_in_use', false, array(htmlspecialchars($_POST['new_email']))); } mysql_free_result($request); updateMemberData($row['id_member'], array('email_address' => $_POST['new_email'])); $row['email_address'] = $_POST['new_email']; $email_change = true; } // Resend the password, but only if the account wasn't activated yet. if (!empty($_REQUEST['sa']) && $_REQUEST['sa'] == 'resend' && ($row['is_activated'] == 0 || $row['is_activated'] == 2) && (!isset($_REQUEST['code']) || $_REQUEST['code'] == '')) { require_once $sourcedir . '/lib/Subs-Post.php'; $replacements = array('REALNAME' => $row['real_name'], 'USERNAME' => $row['member_name'], 'ACTIVATIONLINK' => $scripturl . '?action=activate;u=' . $row['id_member'] . ';code=' . $row['validation_code'], 'ACTIVATIONLINKWITHOUTCODE' => $scripturl . '?action=activate;u=' . $row['id_member'], 'ACTIVATIONCODE' => $row['validation_code'], 'FORGOTPASSWORDLINK' => $scripturl . '?action=reminder'); $emaildata = loadEmailTemplate('resend_activate_message', $replacements, empty($row['lngfile']) || empty($modSettings['userLanguage']) ? $language : $row['lngfile']); sendmail($row['email_address'], $emaildata['subject'], $emaildata['body'], null, null, false, 0); $context['page_title'] = $txt['invalid_activation_resend']; // This will ensure we don't actually get an error message if it works! $context['error_title'] = ''; fatal_lang_error(!empty($email_change) ? 'change_email_success' : 'resend_email_success', false); } // Quit if this code is not right. if (empty($_REQUEST['code']) || $row['validation_code'] != $_REQUEST['code']) { if (!empty($row['is_activated'])) { fatal_lang_error('already_activated', false); } elseif ($row['validation_code'] == '') { loadLanguage('Profile'); fatal_error($txt['registration_not_approved'] . ' <a href="' . $scripturl . '?action=activate;user='******'member_name'] . '">' . $txt['here'] . '</a>.', false); } EoS_Smarty::loadTemplate('generic_skeleton'); EoS_Smarty::getConfigInstance()->registerHookTemplate('generic_content_area', 'loginout/retry_activate'); $context['page_title'] = $txt['invalid_activation_code']; $context['member_id'] = $row['id_member']; return; } // Let the integration know that they've been activated! HookAPI::callHook('integrate_activate', array($row['member_name'])); // Validation complete - update the database! updateMemberData($row['id_member'], array('is_activated' => 1, 'validation_code' => '')); // Also do a proper member stat re-evaluation. updateStats('member', false); if (!isset($_POST['new_email'])) { $actid = 0; require_once $sourcedir . '/lib/Subs-Post.php'; // add to the activity stream if ($modSettings['astream_active']) { require_once $sourcedir . '/lib/Subs-Activities.php'; $actid = aStreamAdd($row['id_member'], ACT_NEWMEMBER, array('member_name' => $row['member_name']), 0, 0, 0, $row['id_member']); } adminNotify('activation', $row['id_member'], $row['member_name'], $actid, ACT_NEWMEMBER); } EoS_Smarty::loadTemplate('generic_skeleton'); EoS_Smarty::getConfigInstance()->registerHookTemplate('generic_content_area', 'loginout/login'); $context += array('page_title' => $txt['registration_successful'], 'sub_template' => 'login', 'default_username' => $row['member_name'], 'default_password' => '', 'never_expire' => false, 'description' => $txt['activate_success']); }
function Logout($internal = false, $redirect = true) { global $sourcedir, $user_info, $user_settings, $context, $modSettings, $smcFunc; // Make sure they aren't being auto-logged out. if (!$internal) { checkSession('get'); } require_once $sourcedir . '/lib/Subs-Auth.php'; if (isset($_SESSION['pack_ftp'])) { $_SESSION['pack_ftp'] = null; } // They cannot be open ID verified any longer. if (isset($_SESSION['openid'])) { unset($_SESSION['openid']); } // It won't be first login anymore. unset($_SESSION['first_login']); // Just ensure they aren't a guest! if (!$user_info['is_guest']) { // Pass the logout information to integrations. HookAPI::callHook('integrate_logout', array($user_settings['member_name'])); // If you log out, you aren't online anymore :P. smf_db_query(' DELETE FROM {db_prefix}log_online WHERE id_member = {int:current_member}', array('current_member' => $user_info['id'])); } $_SESSION['log_time'] = 0; // Empty the cookie! (set it in the past, and for id_member = 0) setLoginCookie(-3600, 0); CacheAPI::putCache('_team_members_online', null, 0); // Off to the merry board index we go! if ($redirect) { if (empty($_SESSION['logout_url'])) { redirectexit('', $context['server']['needs_login_fix']); } else { $temp = $_SESSION['logout_url']; unset($_SESSION['logout_url']); redirectexit($temp, $context['server']['needs_login_fix']); } } }
function createPost(&$msgOptions, &$topicOptions, &$posterOptions) { global $user_info, $txt, $modSettings, $context, $sourcedir; // Set optional parameters to the default value. $msgOptions['icon'] = empty($msgOptions['icon']) ? 'xx' : $msgOptions['icon']; $msgOptions['smileys_enabled'] = !empty($msgOptions['smileys_enabled']); $msgOptions['attachments'] = empty($msgOptions['attachments']) ? array() : $msgOptions['attachments']; $msgOptions['approved'] = isset($msgOptions['approved']) ? (int) $msgOptions['approved'] : 1; $msgOptions['locked'] = 0; $topicOptions['id'] = empty($topicOptions['id']) ? 0 : (int) $topicOptions['id']; $topicOptions['poll'] = isset($topicOptions['poll']) ? (int) $topicOptions['poll'] : null; $topicOptions['lock_mode'] = isset($topicOptions['lock_mode']) ? $topicOptions['lock_mode'] : null; $topicOptions['sticky_mode'] = isset($topicOptions['sticky_mode']) ? $topicOptions['sticky_mode'] : null; $posterOptions['id'] = empty($posterOptions['id']) ? 0 : (int) $posterOptions['id']; $posterOptions['ip'] = empty($posterOptions['ip']) ? $user_info['ip'] : $posterOptions['ip']; $context['can_tag_users'] = allowedTo('tag_users'); $tagged_users = handleUserTags($msgOptions['body']); // We need to know if the topic is approved. If we're told that's great - if not find out. if (!$modSettings['postmod_active']) { $topicOptions['is_approved'] = true; } elseif (!empty($topicOptions['id']) && !isset($topicOptions['is_approved'])) { $request = smf_db_query(' SELECT approved FROM {db_prefix}topics WHERE id_topic = {int:id_topic} LIMIT 1', array('id_topic' => $topicOptions['id'])); list($topicOptions['is_approved']) = mysql_fetch_row($request); mysql_free_result($request); } // If nothing was filled in as name/e-mail address, try the member table. if (!isset($posterOptions['name']) || $posterOptions['name'] == '' || empty($posterOptions['email']) && !empty($posterOptions['id'])) { if (empty($posterOptions['id'])) { $posterOptions['id'] = 0; $posterOptions['name'] = $txt['guest_title']; $posterOptions['email'] = ''; } elseif ($posterOptions['id'] != $user_info['id']) { $request = smf_db_query(' SELECT member_name, email_address, real_name FROM {db_prefix}members WHERE id_member = {int:id_member} LIMIT 1', array('id_member' => $posterOptions['id'])); // Couldn't find the current poster? if (mysql_num_rows($request) == 0) { trigger_error('createPost(): Invalid member id ' . $posterOptions['id'], E_USER_NOTICE); $posterOptions['id'] = 0; $posterOptions['name'] = $txt['guest_title']; $posterOptions['email'] = ''; } else { list($posterOptions['name'], $posterOptions['email'], $posterOptions['real_name']) = mysql_fetch_row($request); } mysql_free_result($request); } else { $posterOptions['name'] = $posterOptions['real_name'] = $user_info['name']; $posterOptions['email'] = $user_info['email']; } } else { $posterOptions['real_name'] = $user_info['name']; } // It's do or die time: forget any user aborts! $previous_ignore_user_abort = ignore_user_abort(true); $new_topic = empty($topicOptions['id']); // decide whether we should just update the last post or append a new one $automerge_posts = false; $want_automerge = isset($_REQUEST['want_automerge']) && $_REQUEST['want_automerge'] > 0 ? true : false; if (!$new_topic && ($topicOptions['automerge'] > 0 && $want_automerge) && $topicOptions['id_member_updated'] == $posterOptions['id'] && empty($topicOptions['poll'])) { $result = smf_db_query(' SELECT poster_time, modified_time, body FROM {db_prefix}messages WHERE id_msg = {int:last_id}', array('last_id' => $topicOptions['id_last_msg'])); list($ptime, $mtime, $oldbody) = mysql_fetch_row($result); if (smf_db_affected_rows() != 0) { if ($want_automerge || time() - max($ptime, $mtime) < $topicOptions['automerge'] * 60) { $automerge_posts = true; $msg_to_update = $topicOptions['id_last_msg']; } } mysql_free_result($result); } // Insert the post. if (false === $automerge_posts) { smf_db_insert('', '{db_prefix}messages', array('id_board' => 'int', 'id_topic' => 'int', 'id_member' => 'int', 'subject' => 'string-255', 'body' => !empty($modSettings['max_messageLength']) && $modSettings['max_messageLength'] > 65534 ? 'string-' . $modSettings['max_messageLength'] : 'string', 'poster_name' => 'string-255', 'poster_email' => 'string-255', 'poster_time' => 'int', 'poster_ip' => 'string-255', 'smileys_enabled' => 'int', 'modified_name' => 'string', 'icon' => 'string-16', 'approved' => 'int', 'locked' => 'int'), array($topicOptions['board'], $topicOptions['id'], $posterOptions['id'], $msgOptions['subject'], $msgOptions['body'], $posterOptions['name'], $posterOptions['email'], time(), $posterOptions['ip'], $msgOptions['smileys_enabled'] ? 1 : 0, '', $msgOptions['icon'], $msgOptions['approved'], $msgOptions['locked']), array('id_msg')); $msgOptions['id'] = smf_db_insert_id('{db_prefix}messages', 'id_msg'); if (count($tagged_users) > 0) { notifyTaggedUsers($tagged_users, array('id_topic' => $topicOptions['id'], 'id_message' => $msgOptions['id'])); } // Something went wrong creating the message... if (empty($msgOptions['id'])) { return false; } $msg_to_update = $msgOptions['id']; // needed for later tasks // Fix the attachments. if (!empty($msgOptions['attachments'])) { smf_db_query(' UPDATE {db_prefix}attachments SET id_msg = {int:id_msg} WHERE id_attach IN ({array_int:attachment_list})', array('attachment_list' => $msgOptions['attachments'], 'id_msg' => $msgOptions['id'])); } } else { if ($msg_to_update) { $newbody = $oldbody . "\n[hr][size=11px][color=red][b] Posted: [time]" . time() . "[/time][/b][/color][/size]\n" . $msgOptions['body']; // todo: make the separator customizable //todo: it should be possible to customize the separator smf_db_query(' UPDATE {db_prefix}messages SET body = {string:newbody}, modified_time = {int:now}, approved = {int:approved} WHERE id_msg = {int:id_msg}', array('newbody' => $newbody, 'now' => time(), 'id_msg' => $msg_to_update, 'approved' => $msgOptions['approved'])); smf_db_query('DELETE FROM {db_prefix}messages_cache WHERE id_msg = {int:id_msg}', array('id_msg' => $msg_to_update)); CacheAPI::clearCacheByPrefix('parse:' . trim($msg_to_update) . '-'); if (count($tagged_users) > 0) { notifyTaggedUsers($tagged_users, array('id_topic' => $topicOptions['id'], 'id_message' => $msgOptions['id'])); } if (empty($msgOptions['attachments'])) { $attachments[0] = -1; } else { $attachments = $msgOptions['attachments']; } // attachments must be fixed and "redirected" for the new post id... smf_db_query(' UPDATE {db_prefix}attachments SET id_msg = {int:id_msg} WHERE id_attach IN ({array_int:attachment_list})', array('attachment_list' => $attachments, 'id_msg' => $msg_to_update)); } else { return false; } // that should NOT happen... } // Insert a new topic (if the topicID was left empty.) if ($new_topic) { if (!isset($topicOptions['topic_prefix'])) { $topicOptions['topic_prefix'] = 0; } if (!isset($topicOptions['topic_layout'])) { $topicOptions['topic_layout'] = 0; } smf_db_insert('', '{db_prefix}topics', array('id_board' => 'int', 'id_member_started' => 'int', 'id_member_updated' => 'int', 'id_first_msg' => 'int', 'id_last_msg' => 'int', 'locked' => 'int', 'is_sticky' => 'int', 'num_views' => 'int', 'id_poll' => 'int', 'unapproved_posts' => 'int', 'approved' => 'int', 'id_prefix' => 'int', 'id_layout' => 'int'), array($topicOptions['board'], $posterOptions['id'], $posterOptions['id'], $msgOptions['id'], $msgOptions['id'], $topicOptions['lock_mode'] === null ? 0 : $topicOptions['lock_mode'], $topicOptions['sticky_mode'] === null ? 0 : $topicOptions['sticky_mode'], 0, $topicOptions['poll'] === null ? 0 : $topicOptions['poll'], $msgOptions['approved'] ? 0 : 1, $msgOptions['approved'], $topicOptions['topic_prefix'], $topicOptions['topic_layout']), array('id_topic')); $topicOptions['id'] = smf_db_insert_id('{db_prefix}topics', 'id_topic'); // The topic couldn't be created for some reason. if (empty($topicOptions['id'])) { // We should delete the post that did work, though... smf_db_query(' DELETE FROM {db_prefix}messages WHERE id_msg = {int:id_msg}', array('id_msg' => $msgOptions['id'])); return false; } // Fix the message with the topic. smf_db_query(' UPDATE {db_prefix}messages SET id_topic = {int:id_topic} WHERE id_msg = {int:id_msg}', array('id_topic' => $topicOptions['id'], 'id_msg' => $msgOptions['id'])); // There's been a new topic AND a new post today. trackStats(array('topics' => '+', 'posts' => '+')); updateStats('topic', true); updateStats('subject', $topicOptions['id'], $msgOptions['subject']); // todo supporting code for related topics mod (should go away - the mod is not included) if (isset($modSettings['have_related_topics']) && $modSettings['have_related_topics']) { require_once $sourcedir . '/lib/Subs-Related.php'; relatedUpdateTopics($topicOptions['id']); } // What if we want to export new topics out to a CMS? HookAPI::callHook('create_topic', array(&$msgOptions, &$topicOptions, &$posterOptions)); // record the activity if ($modSettings['astream_active'] && !$context['no_astream']) { require_once $sourcedir . '/lib/Subs-Activities.php'; aStreamAdd($posterOptions['id'], ACT_NEWTOPIC, array('member_name' => $posterOptions['real_name'], 'topic_title' => $msgOptions['subject']), $topicOptions['board'], $topicOptions['id'], $msgOptions['id'], $posterOptions['id']); } } else { if (false === $automerge_posts) { $countChange = $msgOptions['approved'] ? 'num_replies = num_replies + 1' : 'unapproved_posts = unapproved_posts + 1'; } else { // the # of replies and unapproved posts does not increase if we merge $countChange = $msgOptions['approved'] ? 'num_replies = num_replies' : 'unapproved_posts = unapproved_posts'; } // Update the number of replies and the lock/sticky status. smf_db_query(' UPDATE {db_prefix}topics SET ' . ($msgOptions['approved'] ? 'id_member_updated = {int:poster_id}, id_last_msg = {int:id_msg},' : '') . ' ' . $countChange . ($topicOptions['lock_mode'] === null ? '' : ', locked = {int:locked}') . ($topicOptions['sticky_mode'] === null ? '' : ', is_sticky = {int:is_sticky}') . ' WHERE id_topic = {int:id_topic}', array('poster_id' => $posterOptions['id'], 'id_msg' => $msg_to_update, 'locked' => $topicOptions['lock_mode'], 'is_sticky' => $topicOptions['sticky_mode'], 'id_topic' => $topicOptions['id'])); // One new post has been added today. if (false === $automerge_posts) { trackStats(array('posts' => '+')); } if ($modSettings['astream_active'] && !$context['no_astream']) { // add to activity stream, but do not notify when we reply to our own topic require_once $sourcedir . '/lib/Subs-Activities.php'; aStreamAdd($posterOptions['id'], ACT_REPLIED, array('member_name' => $posterOptions['real_name'], 'topic_title' => $msgOptions['subject']), $topicOptions['board'], $topicOptions['id'], $msg_to_update, $topicOptions['id_member_started'], 0, $posterOptions['id'] == $topicOptions['id_member_started'] ? true : false); } HookAPI::callHook('update_topic', array(&$msgOptions, &$topicOptions, &$posterOptions)); } // Creating is modifying...in a way. //!!! Why not set id_msg_modified on the insert? smf_db_query(' UPDATE {db_prefix}messages SET id_msg_modified = {int:id_msg} WHERE id_msg = {int:id_msg}', array('id_msg' => $automerge_posts ? $modSettings['maxMsgID'] : $msg_to_update)); // Increase the number of posts and topics on the board. if ($msgOptions['approved'] && false === $automerge_posts) { smf_db_query(' UPDATE {db_prefix}boards SET num_posts = num_posts + 1' . ($new_topic ? ', num_topics = num_topics + 1' : '') . ' WHERE id_board = {int:id_board}', array('id_board' => $topicOptions['board'])); } else { if (false === $automerge_posts) { smf_db_query(' UPDATE {db_prefix}boards SET unapproved_posts = unapproved_posts + 1' . ($new_topic ? ', unapproved_topics = unapproved_topics + 1' : '') . ' WHERE id_board = {int:id_board}', array('id_board' => $topicOptions['board'])); // Add to the approval queue too. smf_db_insert('', '{db_prefix}approval_queue', array('id_msg' => 'int'), array($msgOptions['id']), array()); } } // Mark inserted topic as read (only for the user calling this function). if (!empty($topicOptions['mark_as_read']) && !$user_info['is_guest']) { // Since it's likely they *read* it before replying, let's try an UPDATE first. if (!$new_topic) { smf_db_query(' UPDATE {db_prefix}log_topics SET id_msg = {int:id_msg} WHERE id_member = {int:current_member} AND id_topic = {int:id_topic}', array('current_member' => $posterOptions['id'], 'id_msg' => $msg_to_update, 'id_topic' => $topicOptions['id'])); $flag = smf_db_affected_rows() != 0; } if (empty($flag)) { smf_db_insert('ignore', '{db_prefix}log_topics', array('id_topic' => 'int', 'id_member' => 'int', 'id_msg' => 'int'), array($topicOptions['id'], $posterOptions['id'], $msg_to_update), array('id_topic', 'id_member')); } } // If there's a custom search index, it needs updating... if (!empty($modSettings['search_custom_index_config'])) { $customIndexSettings = unserialize($modSettings['search_custom_index_config']); if ($automerge_posts) { $text = $newbody; } else { $text = $msgOptions['body']; } $inserts = array(); foreach (text2words($text, $customIndexSettings['bytes_per_word'], true) as $word) { $inserts[] = array($word, $msg_to_update); } if (!empty($inserts)) { smf_db_insert('ignore', '{db_prefix}log_search_words', array('id_word' => 'int', 'id_msg' => 'int'), $inserts, array('id_word', 'id_msg')); } } // Increase the post counter for the user that created the post. if (!empty($posterOptions['update_post_count']) && !empty($posterOptions['id']) && $msgOptions['approved'] && false === $automerge_posts) { // Are you the one that happened to create this post? if ($user_info['id'] == $posterOptions['id']) { $user_info['posts']++; } updateMemberData($posterOptions['id'], array('posts' => '+')); } // They've posted, so they can make the view count go up one if they really want. (this is to keep views >= replies...) $_SESSION['last_read_topic'] = 0; // Better safe than sorry. if (isset($_SESSION['topicseen_cache'][$topicOptions['board']])) { $_SESSION['topicseen_cache'][$topicOptions['board']]--; } // Update all the stats so everyone knows about this new topic and message. if (false === $automerge_posts) { updateStats('message', true, $msg_to_update); } // Update the last message on the board assuming it's approved AND the topic is. if ($msgOptions['approved']) { updateLastMessages($topicOptions['board'], $new_topic || !empty($topicOptions['is_approved']) ? $msg_to_update : 0); } // Clear recent posts cache CacheAPI::clearCacheByPrefix('boardindex-latest_posts'); // Alright, done now... we can abort now, I guess... at least this much is done. ignore_user_abort($previous_ignore_user_abort); // Success. return true; }
/** * add a stream activity * * @param int $id_member the member id who owns this activity (= who did it) * @param int $atype activity type (numeric) * @param $params array with parameters, mostly for formatting * @param int $id_board the board id where it happened (if applicable) * @param int $id_topic the topic id where it happened (if applicable) * @param int $id_content the content id. this can be a message id but could also be a user id * (e.g. when a member posts on the profile of another member). depends on the context * @param int $id_owner the content owner (id_member) * @param int $priv_level privacy level for is_private. * @param int $dont_notify do not send the owner a notification for the activity. * * @return unique id (positive integer) of the inserted activity type, 0 if something went wrong. */ function aStreamAdd($id_member, $atype, $params, $id_board = 0, $id_topic = 0, $id_content = 0, $id_owner = 0, $priv_level = 0, $dont_notify = false) { global $user_info; $act_must_notify = array(ACT_LIKE, ACT_REPLIED); // these activity types will trigger a *mandatory* if (0 == $id_member || 0 == $id_owner) { // notification for $id_owner unless $dont_notify indicates otherwise return 0; } if (0 == $atype) { $_s = sprintf('Warning: tried to add atype==0 with id_member=%d, params=%s, id_board=%d, id_topic=%d', $id_member, @serialize($params), $id_board, $id_topic); log_error($_s); return 0; } // respect opt out setting if (!empty($user_info['act_optout'])) { if (in_array($atype, explode(',', $user_info['act_optout'])) !== false) { return 0; } } smf_db_insert('', '{db_prefix}log_activities', array('id_member' => 'int', 'id_type' => 'int', 'updated' => 'int', 'params' => 'string', 'is_private' => 'int', 'id_board' => 'int', 'id_topic' => 'int', 'id_content' => 'int', 'id_owner' => 'int'), array((int) $id_member, (int) $atype, time(), serialize($params), $priv_level, (int) $id_board, (int) $id_topic, (int) $id_content, (int) $id_owner), array('id_act')); $id_act = smf_db_insert_id('{db_prefix}log_activities', 'id_act'); // if this activity triggers a notification for the id_owner, use the $id_act to link it // to the notifications table. if ($id_act && $id_owner && in_array($atype, $act_must_notify) && !$dont_notify) { aStreamAddNotification($id_owner, $id_act, $atype); } $data = array('id_member' => $id_member, 'type' => $atype, 'params' => $params, 'board' => $id_board, 'topic' => $id_topic, 'content_id' => $id_content, 'id_owner' => $id_owner, 'plevel' => $priv_level, 'event_id' => $id_act); HookAPI::callHook('astream_event_added', array(&$data)); return $id_act; }
/** * @name EosAlpha BBS * @copyright 2011 Alex Vie silvercircle(AT)gmail(DOT)com * * This software is a derived product, based on: * * Simple Machines Forum (SMF) * copyright: 2011 Simple Machines (http://www.simplemachines.org) * license: BSD, See included LICENSE.TXT for terms and conditions. * * @version 1.0pre */ function template_main() { global $context, $settings, $options, $txt, $scripturl, $modSettings, $topic; // Let them know, if their report was a success! if ($context['report_sent']) { echo ' <div class="windowbg" id="profile_success"> ', $txt['report_sent'], ' </div>'; } echo ' <div class="jqmWindow" style="display:none;" id="interpostlink_helper"> <div class="jqmWindow_container"> <div class="glass jsconfirm title">', $txt['quick_post_link_title'], ' </div> <div class="flat_container lefttext smalltext">', $txt['quick_post_link_text'], ' <dl class="common left" style="line-height:24px;"> <dt><strong>', $txt['quick_post_link_bbcode'], '</strong></dt><dd><input size="78" type="text" id="interpostlink_helper_content" value="" /></dd> <dt><strong>', $txt['quick_post_link_full'], '</strong></dt><dd><input size="78" type="text" id="interpostlink_helper_content_full" value="" /></dd> </dl> </div> <div class="centertext smalltext smallpadding"><span class="button default centered" onclick="$(\'#interpostlink_helper\').css(\'position\',\'static\');$(\'#interpostlink_helper\').hide();setDimmed(0);">', $txt['quick_post_link_dismiss'], '</span></div> </div> </div> <div id="share_bar" style="display:none;position:absolute;right:0;white-space:nowrap;width:auto;"> <div class="bmbar"> <span role="button" class="button icon share_this share_fb" data-href="http://www.facebook.com/sharer.php?u=%%uri%%">Share</span> <span role="button" class="button icon share_this share_tw" data-href="http://twitter.com/share?text=%%txt%%&url=%%uri%%">Tweet</span> <span role="button" class="button icon share_this share_digg" data-href="http://digg.com/submit?phase=2&title=%%txt%%&url=%%uri%%">Digg</span> <div class="clear"></div> </div> </div>'; // Show the anchor for the top and for the first message. If the first message is new, say so. echo ' <a id="top"></a> <a id="msg', $context['first_message'], '"></a>', $context['first_new_message'] ? '<a id="new"></a>' : ''; // Is this topic also a poll? if ($context['is_poll']) { echo ' <br> <div id="poll"> <div class="cat_bar"> <h3> <span class="ie6_header floatleft"><img src="', $settings['images_url'], '/topic/', $context['poll']['is_locked'] ? 'normal_poll_locked' : 'normal_poll', '.gif" alt="" class="icon" /> ', $txt['poll'], '</span> </h3> </div> <div class="blue_container"> <div class="content" id="poll_options"> <h4 id="pollquestion"> ', $context['poll']['question'], ' </h4>'; // Are they not allowed to vote but allowed to view the options? if ($context['poll']['show_results'] || !$context['allow_vote']) { echo ' <dl class="options">'; // Show each option with its corresponding percentage bar. foreach ($context['poll']['options'] as $option) { echo ' <dt class="smalltext', $option['voted_this'] ? ' voted' : '', '">', $option['option'], '</dt> <dd class="smalltext statsbar', $option['voted_this'] ? ' voted' : '', '">'; if ($context['allow_poll_view']) { echo ' ', $option['bar_ndt'], ' <span class="percentage">', $option['votes'], ' (', $option['percent'], '%)</span>'; } echo ' </dd>'; } echo ' </dl>'; if ($context['allow_poll_view']) { echo ' <p><strong>', $txt['poll_total_voters'], ':</strong> ', $context['poll']['total_votes'], '</p>'; } } else { echo ' <form action="', $scripturl, '?action=vote;topic=', $context['current_topic'], '.', $context['start'], ';poll=', $context['poll']['id'], '" method="post" accept-charset="UTF-8">'; // Show a warning if they are allowed more than one option. if ($context['poll']['allowed_warning']) { echo ' <p class="smallpadding">', $context['poll']['allowed_warning'], '</p>'; } echo ' <ul class="reset options">'; // Show each option with its button - a radio likely. foreach ($context['poll']['options'] as $option) { echo ' <li class="smalltext">', $option['vote_button'], ' <label for="', $option['id'], '">', $option['option'], '</label></li>'; } echo ' </ul> <div class="submitbutton"> <input type="submit" value="', $txt['poll_vote'], '" class="button_submit" /> <input type="hidden" name="', $context['session_var'], '" value="', $context['session_id'], '" /> </div> </form>'; } // Is the clock ticking? if (!empty($context['poll']['expire_time'])) { echo ' <p><strong>', $context['poll']['is_expired'] ? $txt['poll_expired_on'] : $txt['poll_expires_on'], ':</strong> ', $context['poll']['expire_time'], '</p>'; } echo ' </div> </div> </div> <div id="pollmoderation">'; // Build the poll moderation button array. $poll_buttons = array('vote' => array('test' => 'allow_return_vote', 'text' => 'poll_return_vote', 'image' => 'poll_options.gif', 'lang' => true, 'url' => $scripturl . '?topic=' . $context['current_topic'] . '.' . $context['start']), 'results' => array('test' => 'show_view_results_button', 'text' => 'poll_results', 'image' => 'poll_results.gif', 'lang' => true, 'url' => $scripturl . '?topic=' . $context['current_topic'] . '.' . $context['start'] . ';viewresults'), 'change_vote' => array('test' => 'allow_change_vote', 'text' => 'poll_change_vote', 'image' => 'poll_change_vote.gif', 'lang' => true, 'url' => $scripturl . '?action=vote;topic=' . $context['current_topic'] . '.' . $context['start'] . ';poll=' . $context['poll']['id'] . ';' . $context['session_var'] . '=' . $context['session_id']), 'lock' => array('test' => 'allow_lock_poll', 'text' => !$context['poll']['is_locked'] ? 'poll_lock' : 'poll_unlock', 'image' => 'poll_lock.gif', 'lang' => true, 'url' => $scripturl . '?action=lockvoting;topic=' . $context['current_topic'] . '.' . $context['start'] . ';' . $context['session_var'] . '=' . $context['session_id']), 'edit' => array('test' => 'allow_edit_poll', 'text' => 'poll_edit', 'image' => 'poll_edit.gif', 'lang' => true, 'url' => $scripturl . '?action=editpoll;topic=' . $context['current_topic'] . '.' . $context['start']), 'remove_poll' => array('test' => 'can_remove_poll', 'text' => 'poll_remove', 'image' => 'admin_remove_poll.gif', 'lang' => true, 'custom' => 'onclick="return Eos_Confirm(\'\', \'' . $txt['poll_remove_warn'] . '\', $(this).attr(\'href\'));"', 'url' => $scripturl . '?action=removepoll;topic=' . $context['current_topic'] . '.' . $context['start'] . ';' . $context['session_var'] . '=' . $context['session_id'])); template_button_strip($poll_buttons); echo ' </div>'; } // Does this topic have some events linked to it? if (!empty($context['linked_calendar_events'])) { echo ' <div class="orange_container"> <h3>', $txt['calendar_linked_events'], '</h3> <ul class="reset">'; foreach ($context['linked_calendar_events'] as $event) { echo ' <li> ', $event['can_edit'] ? '<a href="' . $event['modify_href'] . '"> <img src="' . $settings['images_url'] . '/icons/modify_small.gif" alt="" title="' . $txt['modify'] . '" class="edit_event" /></a> ' : '', '<strong>', $event['title'], '</strong>: ', $event['start_date'], $event['start_date'] != $event['end_date'] ? ' - ' . $event['end_date'] : '', ' </li>'; } echo ' </ul> </div>'; } // Build the normal button array. $normal_buttons = array('reply' => array('test' => 'can_reply', 'text' => 'reply', 'custom' => 'onclick="return oQuickReply.quote(0);" ', 'image' => 'reply.gif', 'lang' => true, 'url' => $scripturl . '?action=post;topic=' . $context['current_topic'] . '.' . $context['start'] . ';last_msg=' . $context['topic_last_message'], 'active' => true), 'add_poll' => array('test' => 'can_add_poll', 'text' => 'add_poll', 'image' => 'add_poll.gif', 'lang' => true, 'url' => $scripturl . '?action=editpoll;add;topic=' . $context['current_topic'] . '.' . $context['start']), 'notify' => array('test' => 'can_mark_notify', 'text' => $context['is_marked_notify'] ? 'unnotify' : 'notify', 'image' => ($context['is_marked_notify'] ? 'un' : '') . 'notify.gif', 'lang' => true, 'custom' => 'onclick="return Eos_Confirm(\'\', \'' . ($context['is_marked_notify'] ? $txt['notification_disable_topic'] : $txt['notification_enable_topic']) . '\', $(this).attr(\'href\'));"', 'url' => $scripturl . '?action=notify;sa=' . ($context['is_marked_notify'] ? 'off' : 'on') . ';topic=' . $context['current_topic'] . '.' . $context['start'] . ';' . $context['session_var'] . '=' . $context['session_id']), 'mark_unread' => array('test' => 'can_mark_unread', 'text' => 'mark_unread', 'image' => 'markunread.gif', 'lang' => true, 'url' => $scripturl . '?action=markasread;sa=topic;t=' . $context['mark_unread_time'] . ';topic=' . $context['current_topic'] . '.' . $context['start'] . ';' . $context['session_var'] . '=' . $context['session_id']), 'send' => array('test' => 'can_send_topic', 'text' => 'send_topic', 'image' => 'sendtopic.gif', 'lang' => true, 'url' => $scripturl . '?action=emailuser;sa=sendtopic;topic=' . $context['current_topic'] . '.0'), 'print' => array('text' => 'print', 'image' => 'print.gif', 'lang' => true, 'custom' => 'rel="nofollow"', 'url' => $scripturl . '?action=printpage;topic=' . $context['current_topic'] . '.0')); // Allow adding new buttons easily. HookAPI::callHook('integrate_display_buttons', array(&$normal_buttons)); echo ' <div id="forumposts"><form data-alt="', $scripturl, '?action=post;msg=%id_msg%;topic=', $context['current_topic'], '.', $context['start'], '" action="', $scripturl, '?action=quickmod2;topic=', $context['current_topic'], '.', $context['start'], '" method="post" accept-charset="UTF-8" name="quickModForm" id="quickModForm" style="margin: 0;" onsubmit="return oQuickModify.bInEditMode ? oQuickModify.modifySave(\'' . $context['session_id'] . '\', \'' . $context['session_var'] . '\') : false">'; $removableMessageIDs = array(); // Get all the messages... while ($message = $context['get_message']()) { if ($message['can_remove']) { $removableMessageIDs[] = $message['id']; } $message['postbit_callback']($message); if ($message['id'] == $context['first_message']) { if ($context['use_share'] && ($context['user']['is_guest'] || (empty($options['use_share_bar']) ? 1 : !$options['use_share_bar']))) { socialbar($scripturl . '?topic=' . $topic, urlencode($context['subject'])); } if ($context['tags_active']) { echo ' <div id="tagstrip"><span id="tags">'; foreach ($context['topic_tags'] as $i => $tag) { echo '<a href="' . $scripturl . '?action=tags;tagid=' . $tag['ID_TAG'] . '">' . $tag['tag'] . '</a>'; if ($context['can_delete_tags']) { echo '<a href="' . $scripturl . '?action=tags;sa=deletetag;tagid=' . $tag['ID'] . '"><span onclick="sendRequest(\'action=xmlhttp;sa=tags;deletetag=1;tagid=' . $tag['ID'] . '\', $(\'#tags\'));return(false);" class="xtag"> </span></a>'; } else { echo ' '; } } echo '</span>'; if ($context['can_add_tags']) { echo ' <a rel="nofollow" id="addtag" onclick="$(\'#tagform\').remove();sendRequest(\'action=xmlhttp;sa=tags;addtag=1;topic=', $topic, '\', $(\'#addtag\'));return(false);" data-id="', $topic, '" href="' . $scripturl . '?action=tags;sa=addtag;topic=', $topic, '">' . $txt['smftags_addtag'] . '</a>'; } else { echo ' '; } echo ' </div>'; } echo $context['num_replies'], ' Replies<div class="clear"></div> <div class="posts_container commentstyle" id="posts_container">'; } } echo ' </div> <input type="hidden" name="goadvanced" value="1" /> </form> </div> <a id="lastPost"></a>'; if (!empty($settings['display_who_viewing'])) { echo ' <p id="whoisviewing" class="smalltext">'; // Show just numbers...? if ($settings['display_who_viewing'] == 1) { echo count($context['view_members']), ' ', count($context['view_members']) == 1 ? $txt['who_member'] : $txt['members']; } else { echo empty($context['view_members_list']) ? '0 ' . $txt['members'] : implode(', ', $context['view_members_list']) . (empty($context['view_num_hidden']) || $context['can_moderate_forum'] ? '' : ' (+ ' . $context['view_num_hidden'] . ' ' . $txt['hidden'] . ')'); } // Now show how many guests are here too. echo $txt['who_and'], $context['view_num_guests'], ' ', $context['view_num_guests'] == 1 ? $txt['guest'] : $txt['guests'], $txt['who_viewing_topic'], ' </p>'; } if ($context['can_reply'] && !empty($options['display_quick_reply'])) { echo ' <a id="quickreply"></a> <div class="clear"></div> <div style="display:none;overflow:hidden;" id="quickreplybox">'; echo ' <div class="cat_bar"> <strong>', $txt['post_reply'], '</strong> <a href="', $scripturl, '?action=helpadmin;help=quickreply_help', '" onclick="return reqWin(this.href);" class="help tinytext">', $txt['post_reply_help'], '</a> </div> <div class="flat_container mediumpadding">'; //<form action="', $scripturl, '?board=', $context['current_board'], ';action=post2" method="post" accept-charset="UTF-8" name="postmodify" id="postmodify" style="margin: 0;"> echo ' <input type="hidden" name="_qr_board" value="', $context['current_board'], '" /> <input type="hidden" name="topic" value="', $context['current_topic'], '" /> <input type="hidden" name="subject" value="', $context['response_prefix'], $context['subject'], '" /> <input type="hidden" name="icon" value="xx" /> <input type="hidden" name="from_qr" value="1" /> <input type="hidden" name="notify" value="', $context['is_marked_notify'] || !empty($options['auto_notify']) ? '1' : '0', '" /> <input type="hidden" name="not_approved" value="', !$context['can_reply_approved'], '" /> <input type="hidden" name="goback" value="', empty($options['return_to_post']) ? '0' : '1', '" /> <input type="hidden" name="last_msg" value="', $context['topic_last_message'], '" /> <input type="hidden" name="', $context['session_var'], '" value="', $context['session_id'], '" /> <input type="hidden" name="seqnum" value="', $context['form_sequence_number'], '" />'; // Guests just need more. if ($context['user']['is_guest']) { echo ' <strong>', $txt['name'], ':</strong> <input type="text" name="guestname" value="', $context['name'], '" size="25" class="input_text" tabindex="', $context['tabindex']++, '" /> <strong>', $txt['email'], ':</strong> <input type="text" name="email" value="', $context['email'], '" size="25" class="input_text" tabindex="', $context['tabindex']++, '" /><br />'; } // Is visual verification enabled? if ($context['require_verification']) { echo ' <strong>', $txt['verification'], ':</strong>', template_control_verification($context['visual_verification_id'], 'quick_reply'), '<br />'; } if (isset($context['user']['avatar']['image']) && !empty($context['user']['avatar']['image'])) { echo ' <div class="floatleft blue_container smallpadding avatar">', $context['user']['avatar']['image'], ' </div>'; } echo ' <div class="quickReplyContent" style="margin-left:150px;">'; echo $context['is_locked'] ? '<div class="alert smalltext">' . $txt['quick_reply_warning'] . '</div>' : '', $context['oldTopicError'] ? '<div class="alert smalltext">' . sprintf($txt['error_old_topic'], $modSettings['oldTopicDays']) . '</div>' : '', ' ', $context['can_reply_approved'] ? '' : '<em>' . $txt['wait_for_approval'] . '</em>', ' ', !$context['can_reply_approved'] && $context['require_verification'] ? '<br />' : ''; echo ' <textarea id="quickReplyMessage" style="width:99%;" rows="18" name="message" tabindex="', $context['tabindex']++, '"></textarea> </div> <div class="righttext padding"> <input type="submit" name="post" value="', $txt['post'], '" onclick="return submitThisOnce(this);" accesskey="s" tabindex="', $context['tabindex']++, '" class="button_submit" /> <input type="submit" name="preview" value="', $txt['go_advanced'], '" onclick="return submitThisOnce(this);" accesskey="p" tabindex="', $context['tabindex']++, '" class="button_submit" /> <input type="submit" name="cancel" value="', 'Cancel', '" onclick="return(oQuickReply.cancel());" accesskey="p" tabindex="', $context['tabindex']++, '" class="button_submit" />'; /* if (!empty($context['can_save_draft'])) echo ' <input type="hidden" id="draft_id" name="draft_id" value="', empty($context['draft_id']) ? '0' : $context['draft_id'], '" /> <input type="submit" name="draft" value="', $txt['save_draft'], '" onclick="return submitThisOnce(this);" accesskey="d" tabindex="', $context['tabindex']++, '" class="button_submit" />'; if (!empty($context['can_autosave_draft'])) { echo ' <div id="draft_lastautosave" class="clear righttext"></div>'; $context['inline_footer_script'] .= ' var oAutoSave = new draftAutosave({ sSelf: \'oAutoSave\', sScriptUrl: smf_scripturl, sSessionId: \''. $context['session_id']. '\', sSessionVar: \''. $context['session_var']. '\', sLastNote: \'draft_lastautosave\', sType: \'quickreply\', iBoard: '. (empty($context['current_board']) ? 0 : $context['current_board']). ', iFreq: '. (empty($modSettings['enableAutoSaveDrafts']) ? 30000 : $modSettings['enableAutoSaveDrafts'] * 1000). ' }); '; }*/ echo ' </div> <!-- </form> --> <!-- </div> --> </div> <br> </div>'; } $context['inline_footer_script'] .= ' var smf_likelabel = \'' . $txt['like_label'] . '\'; var smf_unlikelabel = \'' . $txt['unlike_label'] . '\' '; // Show the page index... "Pages: [1]". echo ' <div class="pagesection bottom"> ', template_button_strip($normal_buttons, 'right'); if ($context['multiquote_posts_count'] > 0) { echo ' <div class="floatright clear_right tinytext mediummargin mq_remove_msg">', sprintf($txt['posts_marked_mq'], $context['multiquote_posts_count']), ', <a href="#" onclick="return oQuickReply.clearAllMultiquote(', $context['current_topic'], ');">', $txt['remove'], '</a></div>'; } echo ' <div class="pagelinks floatleft">', $txt['pages'], ': ', $context['page_index'], !empty($modSettings['topbottomEnable']) ? $context['menu_separator'] . ' <a href="#top"><strong>' . $txt['go_up'] . '</strong></a>' : '', '</div> <div class="nextlinks_bottom">', $context['previous_next'], '</div> </div>'; // Show the lower breadcrumbs. theme_linktree(); $mod_buttons = array('move' => array('test' => 'can_move', 'text' => 'move_topic', 'image' => 'admin_move.gif', 'lang' => true, 'url' => $scripturl . '?action=movetopic;topic=' . $context['current_topic'] . '.0'), 'delete' => array('test' => 'can_delete', 'text' => 'remove_topic', 'image' => 'admin_rem.gif', 'lang' => true, 'custom' => 'onclick="return confirm(\'' . $txt['are_sure_remove_topic'] . '\');"', 'url' => $scripturl . '?action=removetopic2;topic=' . $context['current_topic'] . '.0;' . $context['session_var'] . '=' . $context['session_id']), 'lock' => array('test' => 'can_lock', 'text' => empty($context['is_locked']) ? 'set_lock' : 'set_unlock', 'image' => 'admin_lock.gif', 'lang' => true, 'url' => $scripturl . '?action=lock;topic=' . $context['current_topic'] . '.' . $context['start'] . ';' . $context['session_var'] . '=' . $context['session_id']), 'sticky' => array('test' => 'can_sticky', 'text' => empty($context['is_sticky']) ? 'set_sticky' : 'set_nonsticky', 'image' => 'admin_sticky.gif', 'lang' => true, 'url' => $scripturl . '?action=sticky;topic=' . $context['current_topic'] . '.' . $context['start'] . ';' . $context['session_var'] . '=' . $context['session_id']), 'merge' => array('test' => 'can_merge', 'text' => 'merge', 'image' => 'merge.gif', 'lang' => true, 'url' => $scripturl . '?action=mergetopics;board=' . $context['current_board'] . '.0;from=' . $context['current_topic']), 'calendar' => array('test' => 'calendar_post', 'text' => 'calendar_link', 'image' => 'linktocal.gif', 'lang' => true, 'url' => $scripturl . '?action=post;calendar;msg=' . $context['topic_first_message'] . ';topic=' . $context['current_topic'] . '.0')); // Restore topic. eh? No monkey business. if ($context['can_restore_topic']) { $mod_buttons[] = array('text' => 'restore_topic', 'image' => '', 'lang' => true, 'url' => $scripturl . '?action=restoretopic;topics=' . $context['current_topic'] . ';' . $context['session_var'] . '=' . $context['session_id']); } // Allow adding new mod buttons easily. HookAPI::callHook('integrate_mod_buttons', array(&$mod_buttons)); echo ' <div id="moderationbuttons">', template_button_strip($mod_buttons, 'bottom', array('id' => 'moderationbuttons_strip')), '</div>'; // Show the jumpto box, or actually...let Javascript do it. echo ' <div class="plainbox" id="display_jump_to"> </div>'; $context['inline_footer_script'] .= ' var oQuickReply = new QuickReply({ bDefaultCollapsed: ' . (!empty($options['display_quick_reply']) && $options['display_quick_reply'] == 2 ? 'false' : 'true') . ', iTopicId: ' . $context['current_topic'] . ', iStart: ' . $context['start'] . ', sScriptUrl: smf_scripturl, sImagesUrl: "' . $settings['images_url'] . '", sContainerId: "quickReplyOptions", sImageId: "quickReplyExpand", sImageCollapsed: "collapse.gif", sImageExpanded: "expand.gif", iMarkedForMQ: ' . $context['multiquote_posts_count'] . ', sJumpAnchor: "quickreplybox", bEnabled: ' . (!empty($options['display_quick_reply']) ? 'true' : 'false') . ' }); '; if (!empty($options['display_quick_mod']) && $context['can_remove_post']) { $context['inline_footer_script'] .= ' var oInTopicModeration = new InTopicModeration({ sSelf: \'oInTopicModeration\', sCheckboxContainerMask: \'in_topic_mod_check_\', aMessageIds: [\'' . implode('\', \'', $removableMessageIDs) . '\'], sSessionId: \'' . $context['session_id'] . '\', sSessionVar: \'' . $context['session_var'] . '\', sButtonStrip: \'moderationbuttons\', sButtonStripDisplay: \'moderationbuttons_strip\', bUseImageButton: false, bCanRemove: ' . ($context['can_remove_post'] ? 'true' : 'false') . ', sRemoveButtonLabel: \'' . $txt['quickmod_delete_selected'] . '\', sRemoveButtonImage: \'delete_selected.gif\', sRemoveButtonConfirm: \'' . $txt['quickmod_confirm'] . '\', bCanRestore: ' . ($context['can_restore_msg'] ? 'true' : 'false') . ', sRestoreButtonLabel: \'' . $txt['quick_mod_restore'] . '\', sRestoreButtonImage: \'restore_selected.gif\', sRestoreButtonConfirm: \'' . $txt['quickmod_confirm'] . '\', sFormId: \'quickModForm\' }); '; } $context['inline_footer_script'] .= ' if (\'XMLHttpRequest\' in window) { var oQuickModify = new QuickModify({ sScriptUrl: smf_scripturl, bShowModify: ' . ($settings['show_modify'] ? 'true' : 'false') . ', iTopicId: ' . $context['current_topic'] . ', sTemplateBodyEdit: ' . JavaScriptEscape(' <div id="quick_edit_body_container"> <div id="error_box" style="padding: 4px;" class="error"></div> <textarea class="editor" name="message" rows="20" style="' . ($context['browser']['is_ie8'] ? 'width: 635px; max-width: 100%; min-width: 100%' : 'width: 100%') . '; margin-bottom: 10px;" tabindex="' . $context['tabindex']++ . '">%body%</textarea><br /> <input type="hidden" name="' . $context['session_var'] . '" value="' . $context['session_id'] . '" /> <input type="hidden" name="topic" value="' . $context['current_topic'] . '" /> <input type="hidden" name="msg" value="%msg_id%" /> <input type="hidden" style="width: 50%;" name="subject" value="%subject%" size="50" maxlength="80" tabindex="' . $context['tabindex']++ . '" class="input_text" /> <div class="righttext"> <span class="button floatright" onclick="return oQuickModify.goAdvanced(\'' . $context['session_id'] . '\', \'' . $context['session_var'] . '\');" />Go Advanced</a></span> <span class="button floatright" onclick="return oQuickModify.modifyCancel();" >' . $txt['modify_cancel'] . '</span> <span class="button floatright" onclick="return oQuickModify.modifySave(\'' . $context['session_id'] . '\', \'' . $context['session_var'] . '\');" accesskey="s">' . $txt['save'] . '</span> </div> </div>') . ', sTemplateSubjectEdit: ' . JavaScriptEscape('<input type="text" style="width: 50%;" name="subject_edit" value="%subject%" size="50" maxlength="80" tabindex="' . $context['tabindex']++ . '" class="input_text" />') . ', sTemplateBodyNormal: ' . JavaScriptEscape('%body%') . ', sTemplateSubjectNormal: ' . JavaScriptEscape('<a href="' . $scripturl . '?topic=' . $context['current_topic'] . '.msg%msg_id%#msg%msg_id%" rel="nofollow">%subject%</a>') . ', sTemplateTopSubject: ' . JavaScriptEscape($txt['topic'] . ': %subject% (' . $txt['read'] . ' ' . $context['num_views'] . ' ' . $txt['times'] . ')') . ', sErrorBorderStyle: ' . JavaScriptEscape('1px solid red') . ' }); aJumpTo[aJumpTo.length] = new JumpTo({ sContainerId: "display_jump_to", sJumpToTemplate: "<label class=\\"smalltext\\" for=\\"%select_id%\\">' . $context['jump_to']['label'] . ':<" + "/label> %dropdown_list%", iCurBoardId: ' . $context['current_board'] . ', iCurBoardChildLevel: ' . $context['jump_to']['child_level'] . ', sCurBoardName: "' . $context['jump_to']['board_name'] . '", sBoardChildLevelIndicator: "==", sBoardPrefix: "=> ", sCatSeparator: "-----------------------------", sCatPrefix: "", sGoButtonLabel: "' . $txt['go'] . '" }); } '; if (!empty($ignoredMsgs)) { $context['inline_footer_script'] .= ''; } $context['inline_footer_script'] .= ' function getIntralink(e, mid) { var tid = ' . $context['current_topic'] . '; var _sid = "#subject_" + mid; var el = $("#interpostlink_helper"); el.css("position", "fixed"); var _content = "[ilink topic=" + tid + " post=" + mid + "]" + $(_sid).html().trim() + "[/ilink]"; $("#interpostlink_helper_content").val(_content); $("#interpostlink_helper_content_full").val(e.attr("href")); centerElement(el, -200); el.css("z-index", 9999); setDimmed(1); el.show(); $("#interpostlink_helper_content").focus(); $("#interpostlink_helper_content").select(); } $(document).keydown(function(e) { if(e.keyCode == 27 && $("#interpostlink_helper").css("display") != "none") { $("#interpostlink_helper").css("position", "static"); $("#interpostlink_helper").hide(); setDimmed(0); } }); var topic_id = ' . $context['current_topic'] . '; '; }
function error_handler($error_level, $error_string, $file, $line) { global $settings, $modSettings, $db_show_debug; // Ignore errors if we're ignoring them or they are strict notices from PHP 5 (which cannot be solved without breaking PHP 4.) if (error_reporting() == 0 || defined('E_STRICT') && $error_level == E_STRICT && (empty($modSettings['enableErrorLogging']) || $modSettings['enableErrorLogging'] != 2)) { return; } if (strpos($file, 'eval()') !== false && !empty($settings['current_include_filename'])) { if (function_exists('debug_backtrace')) { $array = debug_backtrace(); for ($i = 0; $i < count($array); $i++) { if ($array[$i]['function'] != 'loadSubTemplate') { continue; } // This is a bug in PHP, with eval, it seems! if (empty($array[$i]['args'])) { $i++; } break; } if (isset($array[$i]) && !empty($array[$i]['args'])) { $file = realpath($settings['current_include_filename']) . ' (' . $array[$i]['args'][0] . ' sub template - eval?)'; } else { $file = realpath($settings['current_include_filename']) . ' (eval?)'; } } else { $file = realpath($settings['current_include_filename']) . ' (eval?)'; } } if (isset($db_show_debug) && $db_show_debug === true) { // Commonly, undefined indexes will occur inside attributes; try to show them anyway! if ($error_level % 255 != E_ERROR) { $temporary = ob_get_contents(); if (substr($temporary, -2) == '="') { echo '"'; } } // Debugging! This should look like a PHP error message. echo '<br /> <strong>', $error_level % 255 == E_ERROR ? 'Error' : ($error_level % 255 == E_WARNING ? 'Warning' : 'Notice'), '</strong>: ', $error_string, ' in <strong>', $file, '</strong> on line <strong>', $line, '</strong><br />'; } $error_type = strpos(strtolower($error_string), 'undefined') !== false ? 'undefined_vars' : 'general'; $message = log_error($error_level . ': ' . $error_string, $error_type, $file, $line); // Let's give integrations a chance to ouput a bit differently HookAPI::callHook('integrate_output_error', array($message, $error_type, $error_level, $file, $line)); // Dying on these errors only causes MORE problems (blank pages!) if ($file == 'Unknown') { return; } // If this is an E_ERROR or E_USER_ERROR.... die. Violently so. if ($error_level % 255 == E_ERROR) { obExit(false); } else { return; } // If this is an E_ERROR, E_USER_ERROR, E_WARNING, or E_USER_WARNING.... die. Violently so. if ($error_level % 255 == E_ERROR || $error_level % 255 == E_WARNING) { fatal_error(allowedTo('admin_forum') ? $message : $error_string, false); } // We should NEVER get to this point. Any fatal error MUST quit, or very bad things can happen. if ($error_level % 255 == E_ERROR) { die('Hacking attempt...'); } }
function AdminApprove() { global $txt, $context, $scripturl, $modSettings, $sourcedir, $language, $user_info, $smcFunc; // First, check our session. checkSession(); require_once $sourcedir . '/lib/Subs-Post.php'; // We also need to the login languages here - for emails. loadLanguage('Login'); // Sort out where we are going... $browse_type = isset($_REQUEST['type']) ? $_REQUEST['type'] : (!empty($modSettings['registration_method']) && $modSettings['registration_method'] == 1 ? 'activate' : 'approve'); $current_filter = (int) $_REQUEST['orig_filter']; // If we are applying a filter do just that - then redirect. if (isset($_REQUEST['filter']) && $_REQUEST['filter'] != $_REQUEST['orig_filter']) { redirectexit('action=admin;area=viewmembers;sa=browse;type=' . $_REQUEST['type'] . ';sort=' . $_REQUEST['sort'] . ';filter=' . $_REQUEST['filter'] . ';start=' . $_REQUEST['start']); } // Nothing to do? if (!isset($_POST['todoAction']) && !isset($_POST['time_passed'])) { redirectexit('action=admin;area=viewmembers;sa=browse;type=' . $_REQUEST['type'] . ';sort=' . $_REQUEST['sort'] . ';filter=' . $current_filter . ';start=' . $_REQUEST['start']); } // Are we dealing with members who have been waiting for > set amount of time? if (isset($_POST['time_passed'])) { $timeBefore = time() - 86400 * (int) $_POST['time_passed']; $condition = ' AND date_registered < {int:time_before}'; } else { $members = array(); foreach ($_POST['todoAction'] as $id) { $members[] = (int) $id; } $condition = ' AND id_member IN ({array_int:members})'; } // Get information on each of the members, things that are important to us, like email address... $request = smf_db_query(' SELECT id_member, member_name, real_name, email_address, validation_code, lngfile FROM {db_prefix}members WHERE is_activated = {int:activated_status}' . $condition . ' ORDER BY lngfile', array('activated_status' => $current_filter, 'time_before' => empty($timeBefore) ? 0 : $timeBefore, 'members' => empty($members) ? array() : $members)); $member_count = mysql_num_rows($request); // If no results then just return! if ($member_count == 0) { redirectexit('action=admin;area=viewmembers;sa=browse;type=' . $_REQUEST['type'] . ';sort=' . $_REQUEST['sort'] . ';filter=' . $current_filter . ';start=' . $_REQUEST['start']); } $member_info = array(); $members = array(); // Fill the info array. while ($row = mysql_fetch_assoc($request)) { $members[] = $row['id_member']; $member_info[] = array('id' => $row['id_member'], 'username' => $row['member_name'], 'name' => $row['real_name'], 'email' => $row['email_address'], 'language' => empty($row['lngfile']) || empty($modSettings['userLanguage']) ? $language : $row['lngfile'], 'code' => $row['validation_code']); } mysql_free_result($request); // Are we activating or approving the members? if ($_POST['todo'] == 'ok' || $_POST['todo'] == 'okemail') { // Approve/activate this member. smf_db_query(' UPDATE {db_prefix}members SET validation_code = {string:blank_string}, is_activated = {int:is_activated} WHERE is_activated = {int:activated_status}' . $condition, array('is_activated' => 1, 'time_before' => empty($timeBefore) ? 0 : $timeBefore, 'members' => empty($members) ? array() : $members, 'activated_status' => $current_filter, 'blank_string' => '')); // Do we have to let the integration code know about the activations? if (!empty($modSettings['integrate_activate'])) { foreach ($member_info as $member) { HookAPI::callHook('integrate_activate', array($member['username'])); } } // Check for email. if ($_POST['todo'] == 'okemail') { foreach ($member_info as $member) { $replacements = array('NAME' => $member['name'], 'USERNAME' => $member['username'], 'PROFILELINK' => $scripturl . '?action=profile;u=' . $member['id'], 'FORGOTPASSWORDLINK' => $scripturl . '?action=reminder'); $emaildata = loadEmailTemplate('admin_approve_accept', $replacements, $member['language']); sendmail($member['email'], $emaildata['subject'], $emaildata['body'], null, null, false, 0); } } } elseif ($_POST['todo'] == 'require_activation') { require_once $sourcedir . '/lib/Subs-Members.php'; // We have to do this for each member I'm afraid. foreach ($member_info as $member) { // Generate a random activation code. $validation_code = generateValidationCode(); // Set these members for activation - I know this includes two id_member checks but it's safer than bodging $condition ;). smf_db_query(' UPDATE {db_prefix}members SET validation_code = {string:validation_code}, is_activated = {int:not_activated} WHERE is_activated = {int:activated_status} ' . $condition . ' AND id_member = {int:selected_member}', array('not_activated' => 0, 'activated_status' => $current_filter, 'selected_member' => $member['id'], 'validation_code' => $validation_code, 'time_before' => empty($timeBefore) ? 0 : $timeBefore, 'members' => empty($members) ? array() : $members)); $replacements = array('USERNAME' => $member['name'], 'ACTIVATIONLINK' => $scripturl . '?action=activate;u=' . $member['id'] . ';code=' . $validation_code, 'ACTIVATIONLINKWITHOUTCODE' => $scripturl . '?action=activate;u=' . $member['id'], 'ACTIVATIONCODE' => $validation_code); $emaildata = loadEmailTemplate('admin_approve_activation', $replacements, $member['language']); sendmail($member['email'], $emaildata['subject'], $emaildata['body'], null, null, false, 0); } } elseif ($_POST['todo'] == 'reject' || $_POST['todo'] == 'rejectemail') { require_once $sourcedir . '/lib/Subs-Members.php'; deleteMembers($members); // Send email telling them they aren't welcome? if ($_POST['todo'] == 'rejectemail') { foreach ($member_info as $member) { $replacements = array('USERNAME' => $member['name']); $emaildata = loadEmailTemplate('admin_approve_reject', $replacements, $member['language']); sendmail($member['email'], $emaildata['subject'], $emaildata['body'], null, null, false, 1); } } } elseif ($_POST['todo'] == 'delete' || $_POST['todo'] == 'deleteemail') { require_once $sourcedir . '/lib/Subs-Members.php'; deleteMembers($members); // Send email telling them they aren't welcome? if ($_POST['todo'] == 'deleteemail') { foreach ($member_info as $member) { $replacements = array('USERNAME' => $member['name']); $emaildata = loadEmailTemplate('admin_approve_delete', $replacements, $member['language']); sendmail($member['email'], $emaildata['subject'], $emaildata['body'], null, null, false, 1); } } } elseif ($_POST['todo'] == 'remind') { foreach ($member_info as $member) { $replacements = array('USERNAME' => $member['name'], 'ACTIVATIONLINK' => $scripturl . '?action=activate;u=' . $member['id'] . ';code=' . $member['code'], 'ACTIVATIONLINKWITHOUTCODE' => $scripturl . '?action=activate;u=' . $member['id'], 'ACTIVATIONCODE' => $member['code']); $emaildata = loadEmailTemplate('admin_approve_remind', $replacements, $member['language']); sendmail($member['email'], $emaildata['subject'], $emaildata['body'], null, null, false, 1); } } // Back to the user's language! if (isset($current_language) && $current_language != $user_info['language']) { loadLanguage('index'); loadLanguage('ManageMembers'); } // Log what we did? if (!empty($modSettings['modlog_enabled']) && in_array($_POST['todo'], array('ok', 'okemail', 'require_activation', 'remind'))) { $log_action = $_POST['todo'] == 'remind' ? 'remind_member' : 'approve_member'; $log_inserts = array(); foreach ($member_info as $member) { $log_inserts[] = array(time(), 3, $user_info['id'], $user_info['ip'], $log_action, 0, 0, 0, serialize(array('member' => $member['id']))); } smf_db_insert('', '{db_prefix}log_actions', array('log_time' => 'int', 'id_log' => 'int', 'id_member' => 'int', 'ip' => 'string-16', 'action' => 'string', 'id_board' => 'int', 'id_topic' => 'int', 'id_msg' => 'int', 'extra' => 'string-65534'), $log_inserts, array('id_action')); } // Although updateStats *may* catch this, best to do it manually just in case (Doesn't always sort out unapprovedMembers). if (in_array($current_filter, array(3, 4))) { updateSettings(array('unapprovedMembers' => $modSettings['unapprovedMembers'] > $member_count ? $modSettings['unapprovedMembers'] - $member_count : 0)); } // Update the member's stats. (but, we know the member didn't change their name.) updateStats('member', false); // If they haven't been deleted, update the post group statistics on them... if (!in_array($_POST['todo'], array('delete', 'deleteemail', 'reject', 'rejectemail', 'remind'))) { updateStats('postgroups', $members); } redirectexit('action=admin;area=viewmembers;sa=browse;type=' . $_REQUEST['type'] . ';sort=' . $_REQUEST['sort'] . ';filter=' . $current_filter . ';start=' . $_REQUEST['start']); }
function registerMember(&$regOptions, $return_errors = false) { global $scripturl, $txt, $modSettings, $context, $sourcedir; global $user_info, $options, $settings, $smcFunc; loadLanguage('Login'); // We'll need some external functions. require_once $sourcedir . '/lib/Subs-Auth.php'; require_once $sourcedir . '/lib/Subs-Post.php'; // Put any errors in here. $reg_errors = array(); // Registration from the admin center, let them sweat a little more. if ($regOptions['interface'] == 'admin') { is_not_guest(); isAllowedTo('moderate_forum'); } elseif ($regOptions['interface'] == 'guest') { // You cannot register twice... if (empty($user_info['is_guest'])) { redirectexit(); } // Make sure they didn't just register with this session. if (!empty($_SESSION['just_registered']) && empty($modSettings['disableRegisterCheck'])) { fatal_lang_error('register_only_once', false); } } // What method of authorization are we going to use? if (empty($regOptions['auth_method']) || !in_array($regOptions['auth_method'], array('password', 'openid'))) { if (!empty($regOptions['openid'])) { $regOptions['auth_method'] = 'openid'; } else { $regOptions['auth_method'] = 'password'; } } // No name?! How can you register with no name? if (empty($regOptions['username'])) { $reg_errors[] = array('lang', 'need_username'); } // Spaces and other odd characters are evil... $regOptions['username'] = preg_replace('~[\\t\\n\\r\\x0B\\0' . ($context['server']['complex_preg_chars'] ? '\\x{A0}' : " ") . ']+~u', ' ', $regOptions['username']); // Don't use too long a name. if (commonAPI::strlen($regOptions['username']) > 25) { $reg_errors[] = array('lang', 'error_long_name'); } // Only these characters are permitted. if (preg_match('~[<>&"\'=\\\\]~', preg_replace('~&#(?:\\d{1,7}|x[0-9a-fA-F]{1,6});~', '', $regOptions['username'])) != 0 || $regOptions['username'] == '_' || $regOptions['username'] == '|' || strpos($regOptions['username'], '[code') !== false || strpos($regOptions['username'], '[/code') !== false) { $reg_errors[] = array('lang', 'error_invalid_characters_username'); } if (commonAPI::strtolower($regOptions['username']) === commonAPI::strtolower($txt['guest_title'])) { $reg_errors[] = array('lang', 'username_reserved', 'general', array($txt['guest_title'])); } // !!! Separate the sprintf? if (empty($regOptions['email']) || preg_match('~^[0-9A-Za-z=_+\\-/][0-9A-Za-z=_\'+\\-/\\.]*@[\\w\\-]+(\\.[\\w\\-]+)*(\\.[\\w]{2,6})$~', $regOptions['email']) === 0 || strlen($regOptions['email']) > 255) { $reg_errors[] = array('done', sprintf($txt['valid_email_needed'], commonAPI::htmlspecialchars($regOptions['username']))); } if (!empty($regOptions['check_reserved_name']) && isReservedName($regOptions['username'], 0, false)) { if ($regOptions['password'] == 'chocolate cake') { $reg_errors[] = array('done', 'Sorry, I don\'t take bribes... you\'ll need to come up with a different name.'); } $reg_errors[] = array('done', '(' . htmlspecialchars($regOptions['username']) . ') ' . $txt['name_in_use']); } // Generate a validation code if it's supposed to be emailed. $validation_code = ''; if ($regOptions['require'] == 'activation') { $validation_code = generateValidationCode(); } // If you haven't put in a password generate one. if ($regOptions['interface'] == 'admin' && $regOptions['password'] == '' && $regOptions['auth_method'] == 'password') { mt_srand(time() + 1277); $regOptions['password'] = generateValidationCode(); $regOptions['password_check'] = $regOptions['password']; } elseif ($regOptions['password'] != $regOptions['password_check'] && $regOptions['auth_method'] == 'password') { $reg_errors[] = array('lang', 'passwords_dont_match'); } // That's kind of easy to guess... if ($regOptions['password'] == '') { if ($regOptions['auth_method'] == 'password') { $reg_errors[] = array('lang', 'no_password'); } else { $regOptions['password'] = sha1(mt_rand()); } } // Now perform hard password validation as required. if (!empty($regOptions['check_password_strength'])) { $passwordError = validatePassword($regOptions['password'], $regOptions['username'], array($regOptions['email'])); // Password isn't legal? if ($passwordError != null) { $reg_errors[] = array('lang', 'profile_error_password_' . $passwordError); } } // If they are using an OpenID that hasn't been verified yet error out. // !!! Change this so they can register without having to attempt a login first if ($regOptions['auth_method'] == 'openid' && (empty($_SESSION['openid']['verified']) || $_SESSION['openid']['openid_uri'] != $regOptions['openid'])) { $reg_errors[] = array('lang', 'openid_not_verified'); } // You may not be allowed to register this email. if (!empty($regOptions['check_email_ban'])) { isBannedEmail($regOptions['email'], 'cannot_register', $txt['ban_register_prohibited']); } // Check if the email address is in use. $request = smf_db_query(' SELECT id_member FROM {db_prefix}members WHERE email_address = {string:email_address} OR email_address = {string:username} LIMIT 1', array('email_address' => $regOptions['email'], 'username' => $regOptions['username'])); // !!! Separate the sprintf? if (mysql_num_rows($request) != 0) { $reg_errors[] = array('lang', 'email_in_use', false, array(htmlspecialchars($regOptions['email']))); } mysql_free_result($request); // If we found any errors we need to do something about it right away! foreach ($reg_errors as $key => $error) { /* Note for each error: 0 = 'lang' if it's an index, 'done' if it's clear text. 1 = The text/index. 2 = Whether to log. 3 = sprintf data if necessary. */ if ($error[0] == 'lang') { loadLanguage('Errors'); } $message = $error[0] == 'lang' ? empty($error[3]) ? $txt[$error[1]] : vsprintf($txt[$error[1]], $error[3]) : $error[1]; // What to do, what to do, what to do. if ($return_errors) { if (!empty($error[2])) { log_error($message, $error[2]); } $reg_errors[$key] = $message; } else { fatal_error($message, empty($error[2]) ? false : $error[2]); } } // If there's any errors left return them at once! if (!empty($reg_errors)) { return $reg_errors; } $reservedVars = array('actual_theme_url', 'actual_images_url', 'base_theme_dir', 'base_theme_url', 'default_images_url', 'default_theme_dir', 'default_theme_url', 'default_template', 'images_url', 'number_recent_posts', 'smiley_sets_default', 'theme_dir', 'theme_id', 'theme_layers', 'theme_templates', 'theme_url'); // Can't change reserved vars. if (isset($regOptions['theme_vars']) && array_intersect($regOptions['theme_vars'], $reservedVars) != array()) { fatal_lang_error('no_theme'); } // Some of these might be overwritten. (the lower ones that are in the arrays below.) $regOptions['register_vars'] = array('member_name' => $regOptions['username'], 'email_address' => $regOptions['email'], 'passwd' => sha1(strtolower($regOptions['username']) . $regOptions['password']), 'password_salt' => substr(md5(mt_rand()), 0, 4), 'posts' => 0, 'date_registered' => time(), 'member_ip' => $regOptions['interface'] == 'admin' ? '127.0.0.1' : $user_info['ip'], 'member_ip2' => $regOptions['interface'] == 'admin' ? '127.0.0.1' : $_SERVER['BAN_CHECK_IP'], 'validation_code' => $validation_code, 'real_name' => $regOptions['username'], 'personal_text' => $modSettings['default_personal_text'], 'pm_email_notify' => 1, 'id_theme' => 0, 'id_post_group' => 4, 'lngfile' => '', 'buddy_list' => '', 'pm_ignore_list' => '', 'message_labels' => '', 'location' => '', 'time_format' => '', 'signature' => '', 'avatar' => '', 'usertitle' => '', 'secret_question' => '', 'secret_answer' => '', 'additional_groups' => '', 'ignore_boards' => '', 'smiley_set' => '', 'openid_uri' => !empty($regOptions['openid']) ? $regOptions['openid'] : ''); // Setup the activation status on this new account so it is correct - firstly is it an under age account? if ($regOptions['require'] == 'coppa') { $regOptions['register_vars']['is_activated'] = 5; // !!! This should be changed. To what should be it be changed?? $regOptions['register_vars']['validation_code'] = ''; } elseif ($regOptions['require'] == 'nothing') { $regOptions['register_vars']['is_activated'] = 1; } elseif ($regOptions['require'] == 'activation') { $regOptions['register_vars']['is_activated'] = 0; } else { $regOptions['register_vars']['is_activated'] = 3; } if (isset($regOptions['memberGroup'])) { // Make sure the id_group will be valid, if this is an administator. $regOptions['register_vars']['id_group'] = $regOptions['memberGroup'] == 1 && !allowedTo('admin_forum') ? 0 : $regOptions['memberGroup']; // Check if this group is assignable. $unassignableGroups = array(-1, 3); $request = smf_db_query(' SELECT id_group FROM {db_prefix}membergroups WHERE min_posts != {int:min_posts}' . (allowedTo('admin_forum') ? '' : ' OR group_type = {int:is_protected}'), array('min_posts' => -1, 'is_protected' => 1)); while ($row = mysql_fetch_assoc($request)) { $unassignableGroups[] = $row['id_group']; } mysql_free_result($request); if (in_array($regOptions['register_vars']['id_group'], $unassignableGroups)) { $regOptions['register_vars']['id_group'] = 0; } } // Integrate optional member settings to be set. if (!empty($regOptions['extra_register_vars'])) { foreach ($regOptions['extra_register_vars'] as $var => $value) { $regOptions['register_vars'][$var] = $value; } } // Integrate optional user theme options to be set. $theme_vars = array(); if (!empty($regOptions['theme_vars'])) { foreach ($regOptions['theme_vars'] as $var => $value) { $theme_vars[$var] = $value; } } // Call an optional function to validate the users' input. HookAPI::callHook('integrate_register', array(&$regOptions, &$theme_vars)); // Right, now let's prepare for insertion. $knownInts = array('date_registered', 'posts', 'id_group', 'last_login', 'instant_messages', 'unread_messages', 'new_pm', 'pm_prefs', 'gender', 'hide_email', 'show_online', 'pm_email_notify', 'karma_good', 'karma_bad', 'notify_announcements', 'notify_send_body', 'notify_regularity', 'notify_types', 'id_theme', 'is_activated', 'id_msg_last_visit', 'id_post_group', 'total_time_logged_in', 'warning'); $knownFloats = array('time_offset'); $column_names = array(); $values = array(); foreach ($regOptions['register_vars'] as $var => $val) { $type = 'string'; if (in_array($var, $knownInts)) { $type = 'int'; } elseif (in_array($var, $knownFloats)) { $type = 'float'; } elseif ($var == 'birthdate') { $type = 'date'; } $column_names[$var] = $type; $values[$var] = $val; } // Register them into the database. smf_db_insert('', '{db_prefix}members', $column_names, $values, array('id_member')); $memberID = smf_db_insert_id('{db_prefix}members', 'id_member'); // Update the number of members and latest member's info - and pass the name, but remove the 's. if ($regOptions['register_vars']['is_activated'] == 1) { updateStats('member', $memberID, $regOptions['register_vars']['real_name']); } else { updateStats('member'); } // Theme variables too? if (!empty($theme_vars)) { $inserts = array(); foreach ($theme_vars as $var => $val) { $inserts[] = array($memberID, $var, $val); } smf_db_insert('insert', '{db_prefix}themes', array('id_member' => 'int', 'variable' => 'string-255', 'value' => 'string-65534'), $inserts, array('id_member', 'variable')); } // If it's enabled, increase the registrations for today. trackStats(array('registers' => '+')); // Administrative registrations are a bit different... if ($regOptions['interface'] == 'admin') { if ($regOptions['require'] == 'activation') { $email_message = 'admin_register_activate'; } elseif (!empty($regOptions['send_welcome_email'])) { $email_message = 'admin_register_immediate'; } if (isset($email_message)) { $replacements = array('REALNAME' => $regOptions['register_vars']['real_name'], 'USERNAME' => $regOptions['username'], 'PASSWORD' => $regOptions['password'], 'FORGOTPASSWORDLINK' => $scripturl . '?action=reminder', 'ACTIVATIONLINK' => $scripturl . '?action=activate;u=' . $memberID . ';code=' . $validation_code, 'ACTIVATIONLINKWITHOUTCODE' => $scripturl . '?action=activate;u=' . $memberID, 'ACTIVATIONCODE' => $validation_code); $emaildata = loadEmailTemplate($email_message, $replacements); sendmail($regOptions['email'], $emaildata['subject'], $emaildata['body'], null, null, false, 0); } // All admins are finished here. return $memberID; } // Can post straight away - welcome them to your fantastic community... if ($regOptions['require'] == 'nothing') { if (!empty($regOptions['send_welcome_email'])) { $replacements = array('REALNAME' => $regOptions['register_vars']['real_name'], 'USERNAME' => $regOptions['username'], 'PASSWORD' => $regOptions['password'], 'FORGOTPASSWORDLINK' => $scripturl . '?action=reminder', 'OPENID' => !empty($regOptions['openid']) ? $regOptions['openid'] : ''); $emaildata = loadEmailTemplate('register_' . ($regOptions['auth_method'] == 'openid' ? 'openid_' : '') . 'immediate', $replacements); sendmail($regOptions['email'], $emaildata['subject'], $emaildata['body'], null, null, false, 0); } // Send admin their notification. adminNotify('standard', $memberID, $regOptions['username']); } elseif ($regOptions['require'] == 'activation' || $regOptions['require'] == 'coppa') { $replacements = array('REALNAME' => $regOptions['register_vars']['real_name'], 'USERNAME' => $regOptions['username'], 'PASSWORD' => $regOptions['password'], 'FORGOTPASSWORDLINK' => $scripturl . '?action=reminder', 'OPENID' => !empty($regOptions['openid']) ? $regOptions['openid'] : ''); if ($regOptions['require'] == 'activation') { $replacements += array('ACTIVATIONLINK' => $scripturl . '?action=activate;u=' . $memberID . ';code=' . $validation_code, 'ACTIVATIONLINKWITHOUTCODE' => $scripturl . '?action=activate;u=' . $memberID, 'ACTIVATIONCODE' => $validation_code); } else { $replacements += array('COPPALINK' => $scripturl . '?action=coppa;u=' . $memberID); } $emaildata = loadEmailTemplate('register_' . ($regOptions['auth_method'] == 'openid' ? 'openid_' : '') . ($regOptions['require'] == 'activation' ? 'activate' : 'coppa'), $replacements); sendmail($regOptions['email'], $emaildata['subject'], $emaildata['body'], null, null, false, 0); } else { $replacements = array('REALNAME' => $regOptions['register_vars']['real_name'], 'USERNAME' => $regOptions['username'], 'PASSWORD' => $regOptions['password'], 'FORGOTPASSWORDLINK' => $scripturl . '?action=reminder', 'OPENID' => !empty($regOptions['openid']) ? $regOptions['openid'] : ''); $emaildata = loadEmailTemplate('register_' . ($regOptions['auth_method'] == 'openid' ? 'openid_' : '') . 'pending', $replacements); sendmail($regOptions['email'], $emaildata['subject'], $emaildata['body'], null, null, false, 0); // Admin gets informed here... adminNotify('approval', $memberID, $regOptions['username']); } // Okay, they're for sure registered... make sure the session is aware of this for security. (Just married :P!) $_SESSION['just_registered'] = 1; return $memberID; }
public function setupContext() { global $context, $settings, $modSettings, $options, $txt; global $forum_copyright, $forum_version; $context['template_time_now'] = forum_time(false); $context['template_timezone'] = date_default_timezone_get(); $context['template_time_now_formatted'] = strftime($modSettings['time_format'], $context['template_time_now']); $context['template_allow_rss'] = !empty($modSettings['xmlnews_enable']) && (!empty($modSettings['allow_guestAccess']) || $context['user']['is_logged']); $context['template_copyright'] = sprintf($forum_copyright, $forum_version); $context['inline_footer_script'] .= $txt['jquery_timeago_loc']; $context['show_load_time'] = !empty($modSettings['timeLoadPageEnable']); $context['hidden_sid_input'] = '<input type="hidden" name="' . $context['session_var'] . '" value="' . $context['session_id'] . '" />'; if (isset($settings['use_default_images']) && $settings['use_default_images'] == 'defaults' && isset($settings['default_template'])) { $settings['theme_url'] = $settings['actual_theme_url']; $settings['images_url'] = $settings['actual_images_url']; $settings['theme_dir'] = $settings['actual_theme_dir']; } $this->assignGlobals(); $context['collapsed_containers'] = isset($_COOKIE['SF_collapsed']) ? explode(',', $_COOKIE['SF_collapsed']) : array(0); /* * hook to extend theme context initialization. */ HookAPI::callHook('smarty_init_context', array(&$this)); }
function scheduled_weekly_maintenance() { global $modSettings; // Delete some settings that needn't be set if they are otherwise empty. $emptySettings = array('warning_mute', 'warning_moderate', 'warning_watch', 'warning_show', 'disableCustomPerPage', 'spider_mode', 'spider_group', 'paid_currency_code', 'paid_currency_symbol', 'paid_email_to', 'paid_email', 'paid_enabled', 'paypal_email', 'search_enable_captcha', 'search_floodcontrol_time', 'show_spider_online'); smf_db_query(' DELETE FROM {db_prefix}settings WHERE variable IN ({array_string:setting_list}) AND (value = {string:zero_value} OR value = {string:blank_value})', array('zero_value' => '0', 'blank_value' => '', 'setting_list' => $emptySettings)); // Some settings we never want to keep - they are just there for temporary purposes. $deleteAnywaySettings = array('attachment_full_notified'); smf_db_query(' DELETE FROM {db_prefix}settings WHERE variable IN ({array_string:setting_list})', array('setting_list' => $deleteAnywaySettings)); // Ok should we prune the logs? if (!empty($modSettings['pruningOptions'])) { if (!empty($modSettings['pruningOptions']) && strpos($modSettings['pruningOptions'], ',') !== false) { list($modSettings['pruneErrorLog'], $modSettings['pruneModLog'], $modSettings['pruneBanLog'], $modSettings['pruneReportLog'], $modSettings['pruneScheduledTaskLog'], $modSettings['pruneSpiderHitLog'], $modSettings['pruneSpiderStats']) = explode(',', $modSettings['pruningOptions']); } if (!empty($modSettings['pruneErrorLog'])) { // Figure out when our cutoff time is. 1 day = 86400 seconds. $t = time() - $modSettings['pruneErrorLog'] * 86400; smf_db_query(' DELETE FROM {db_prefix}log_errors WHERE log_time < {int:log_time}', array('log_time' => $t)); } if (!empty($modSettings['pruneModLog'])) { // Figure out when our cutoff time is. 1 day = 86400 seconds. $t = time() - $modSettings['pruneModLog'] * 86400; smf_db_query(' DELETE FROM {db_prefix}log_actions WHERE log_time < {int:log_time} AND id_log = {int:moderation_log}', array('log_time' => $t, 'moderation_log' => 1)); } if (!empty($modSettings['pruneBanLog'])) { // Figure out when our cutoff time is. 1 day = 86400 seconds. $t = time() - $modSettings['pruneBanLog'] * 86400; smf_db_query(' DELETE FROM {db_prefix}log_banned WHERE log_time < {int:log_time}', array('log_time' => $t)); } if (!empty($modSettings['pruneReportLog'])) { // Figure out when our cutoff time is. 1 day = 86400 seconds. $t = time() - $modSettings['pruneReportLog'] * 86400; // This one is more complex then the other logs. First we need to figure out which reports are too old. $reports = array(); $result = smf_db_query(' SELECT id_report FROM {db_prefix}log_reported WHERE time_started < {int:time_started}', array('time_started' => $t)); while ($row = mysql_fetch_row($result)) { $reports[] = $row[0]; } mysql_free_result($result); if (!empty($reports)) { // Now delete the reports... smf_db_query(' DELETE FROM {db_prefix}log_reported WHERE id_report IN ({array_int:report_list})', array('report_list' => $reports)); // And delete the comments for those reports... smf_db_query(' DELETE FROM {db_prefix}log_reported_comments WHERE id_report IN ({array_int:report_list})', array('report_list' => $reports)); } } if (!empty($modSettings['pruneScheduledTaskLog'])) { // Figure out when our cutoff time is. 1 day = 86400 seconds. $t = time() - $modSettings['pruneScheduledTaskLog'] * 86400; smf_db_query(' DELETE FROM {db_prefix}log_scheduled_tasks WHERE time_run < {int:time_run}', array('time_run' => $t)); } if (!empty($modSettings['pruneSpiderHitLog'])) { // Figure out when our cutoff time is. 1 day = 86400 seconds. $t = time() - $modSettings['pruneSpiderHitLog'] * 86400; smf_db_query(' DELETE FROM {db_prefix}log_spider_hits WHERE log_time < {int:log_time}', array('log_time' => $t)); } if (!empty($modSettings['pruneSpiderStats'])) { $t = time() - $modSettings['pruneSpiderStats'] * 86400; smf_db_query(' DELETE FROM {db_prefix}log_spider_stats WHERE last_seen < {int:time_cutoff}', array('time_cutoff' => $t)); } } // Get rid of any paid subscriptions that were never actioned. smf_db_query(' DELETE FROM {db_prefix}log_subscribed WHERE end_time = {int:no_end_time} AND status = {int:not_active} AND start_time < {int:start_time} AND payments_pending < {int:payments_pending}', array('no_end_time' => 0, 'not_active' => 0, 'start_time' => time() - 60, 'payments_pending' => 1)); // Some OS's don't seem to clean out their sessions. smf_db_query(' DELETE FROM {db_prefix}sessions WHERE last_update < {int:last_update}', array('last_update' => time() - 86400)); // perform maintainance for activity stream if ($modSettings['astream_active']) { smf_db_query(' DELETE a.*, n.* FROM {db_prefix}log_activities AS a LEFT JOIN {db_prefix}log_notifications AS n ON(n.id_act = a.id_act) WHERE a.updated < {int:cutoff_time}', array('cutoff_time' => time() - 86400 * $modSettings['astream_expire_days'])); } HookAPI::callHook('sys_weekly_maint'); return true; }
function prepareDisplayContext($reset = false) { global $txt, $modSettings, $options, $user_info, $output; global $memberContext, $context, $messages_request; static $counter = null; static $seqnr = 0; // If the query returned false, bail. if ($messages_request == false) { return false; } // Remember which message this is. (ie. reply #83) if ($counter === null || $reset) { $counter = empty($options['view_newest_first']) ? $context['start'] : $context['total_visible_posts'] - $context['start']; } // Start from the beginning... if ($reset) { return @mysql_data_seek($messages_request, 0); } // Attempt to get the next message. $message = mysql_fetch_assoc($messages_request); if (!$message) { mysql_free_result($messages_request); return false; } // If you're a lazy bum, you probably didn't give a subject... $message['subject'] = $message['subject'] != '' ? $message['subject'] : $txt['no_subject']; // Are you allowed to remove at least a single reply? $context['can_remove_post'] |= $context['can_delete_own'] && (empty($modSettings['edit_disable_time']) || $message['poster_time'] + $modSettings['edit_disable_time'] * 60 >= time()) && $message['id_member'] == $user_info['id']; // If it couldn't load, or the user was a guest.... someday may be done with a guest table. if (!loadMemberContext($message['id_member'], true)) { // Notice this information isn't used anywhere else.... $memberContext[$message['id_member']]['name'] = $message['poster_name']; $memberContext[$message['id_member']]['id'] = 0; $memberContext[$message['id_member']]['group'] = $txt['guest_title']; $memberContext[$message['id_member']]['link'] = $message['poster_name']; $memberContext[$message['id_member']]['email'] = $message['poster_email']; $memberContext[$message['id_member']]['show_email'] = showEmailAddress(true, 0); $memberContext[$message['id_member']]['is_guest'] = true; $memberContext[$message['id_member']]['is_banned_from_topic'] = $memberContext[$message['id_member']]['can_see_warning'] = false; } else { $memberContext[$message['id_member']]['can_view_profile'] = $context['can_profile_view_any'] || $message['id_member'] == $user_info['id'] && $context['can_profile_view_own']; $memberContext[$message['id_member']]['is_topic_starter'] = $message['id_member'] == $context['topic_starter_id']; $memberContext[$message['id_member']]['can_see_warning'] = !isset($context['disabled_fields']['warning_status']) && $memberContext[$message['id_member']]['warning_status'] && ($context['user']['can_mod'] || !$user_info['is_guest'] && !empty($modSettings['warning_show']) && ($modSettings['warning_show'] > 1 || $message['id_member'] == $user_info['id'])); $memberContext[$message['id_member']]['is_banned_from_topic'] = !empty($context['topic_banned_members']) ? in_array($message['id_member'], $context['topic_banned_members']) : false; } $memberContext[$message['id_member']]['ip'] = $message['poster_ip']; // Do the censor thang. censorText($message['subject']); // create a cached (= parsed) version of the post on the fly // but only if it's not older than the cutoff time. // and do not cache more than PCACHE_UPDATE_PER_VIEW posts per thread view to reduce load spikes $dateline = max($message['modified_time'], $message['poster_time']); if ($context['pcache_update_counter'] < PCACHE_UPDATE_PER_VIEW && $context['time_cutoff_ref'] - $dateline < $modSettings['post_cache_cutoff'] * 86400) { if (empty($message['cached_body'])) { $context['pcache_update_counter']++; $message['body'] = parse_bbc($message['body'], $message['smileys_enabled'], ''); // don't cache bbc when we pre-parse the post anyway... smf_db_insert('replace', '{db_prefix}messages_cache', array('id_msg' => 'int', 'body' => 'string', 'style' => 'string', 'lang' => 'string', 'updated' => 'int'), array($message['id_msg'], $message['body'], $user_info['smiley_set_id'], $user_info['language_id'], $dateline), array('id_msg', 'body', 'style', 'lang', 'updated')); parse_bbc_stage2($message['body'], $message['id_msg']); } else { $message['body'] =& $message['cached_body']; parse_bbc_stage2($message['body'], $message['id_msg']); } } else { $message['body'] = parse_bbc($message['body'], $message['smileys_enabled'], $message['id_msg'] . '|' . $message['modified_time']); parse_bbc_stage2($message['body'], $message['id_msg']); } censorText($message['body']); // Compose the memory eat- I mean message array. //$t_href = URL::topic($topic, $message['subject'], 0, false, '.msg' . $message['id_msg'] . '#msg'.$message['id_msg']); $output = array('attachment' => loadAttachmentContext($message['id_msg']), 'id' => $message['id_msg'], 'permahref' => URL::parse('?msg=' . $message['id_msg'] . (isset($_REQUEST['perma']) ? '' : ';perma')), 'member' => &$memberContext[$message['id_member']], 'icon' => $message['icon'], 'icon_url' => getPostIcon($message['icon']), 'subject' => $message['subject'], 'time' => timeformat($message['poster_time']), 'timestamp' => $message['poster_time'], 'counter' => $counter, 'permalink' => isset($_REQUEST['perma']) ? $txt['view_in_thread'] : ' #' . ($counter + 1), 'modified' => array('time' => timeformat($message['modified_time']), 'name' => $message['modified_name']), 'body' => &$message['body'], 'new' => empty($message['is_read']), 'approved' => $message['approved'], 'first_new' => isset($context['start_from']) && $context['start_from'] == $counter, 'is_ignored' => !empty($modSettings['enable_buddylist']) && !empty($options['posts_apply_ignore_list']) && in_array($message['id_member'], $context['user']['ignoreusers']), 'can_approve' => !$message['approved'] && $context['can_approve'], 'can_unapprove' => $message['approved'] && $context['can_unapprove'], 'can_modify' => (!$message['locked'] || $context['can_moderate_board']) && ((!$context['is_locked'] || $context['can_moderate_board']) && ($context['can_modify_any'] || $context['can_modify_replies'] && $context['user']['started'] || $context['can_modify_own'] && $message['id_member'] == $user_info['id'] && (empty($modSettings['edit_disable_time']) || !$message['approved'] || $message['poster_time'] + $modSettings['edit_disable_time'] * 60 > time()))), 'can_remove' => (!$message['locked'] || $context['can_moderate_board']) && ($context['can_delete_any'] || $context['can_delete_replies'] && $context['user']['started'] || $context['can_delete_own'] && $message['id_member'] == $user_info['id'] && (empty($modSettings['edit_disable_time']) || $message['poster_time'] + $modSettings['edit_disable_time'] * 60 > time())), 'can_see_ip' => $context['can_moderate_forum'] || $message['id_member'] == $user_info['id'] && !empty($user_info['id']), 'likes_count' => $message['likes_count'], 'like_status' => $message['like_status'], 'liked' => $message['liked'], 'like_updated' => $message['like_updated'], 'id_member' => $message['id_member'], 'postbit_callback' => $message['approved'] ? $message['id_msg'] == $context['first_message'] ? $context['postbit_callbacks']['firstpost'] : $context['postbit_callbacks']['post'] : 'template_postbit_comment', 'postbit_template_class' => $message['approved'] ? $message['id_msg'] == $context['first_message'] ? $context['postbit_template_class']['firstpost'] : $context['postbit_template_class']['post'] : 'c', 'mq_marked' => in_array($message['id_msg'], $context['multiquote_posts']), 'header_class' => $context['can_moderate_member'] && ($memberContext[$message['id_member']]['is_banned_from_topic'] || $memberContext[$message['id_member']]['can_see_warning']) ? ' watched' : ''); if ($context['can_see_like']) { Ratings::addContent($output, $context['can_give_like'], $context['time_cutoff_ref']); } else { $output['likes_count'] = 0; } // Is this user the message author? $output['is_message_author'] = $message['id_member'] == $user_info['id']; $counter += empty($options['view_newest_first']) ? 1 : -1; // hooks can populate these fields with additional content $output['template_hook'] = array('before_sig' => '', 'after_sig' => '', 'postbit_below' => '', 'poster_details' => ''); HookAPI::callHook('display_postbit', array(&$output)); if (isset($output['member']['can_see_warning']) && !empty($output['member']['can_see_warning'])) { $output['member']['warning_status_desc'] = isset($output['member']['warning_status']) ? $txt['user_warn_' . $output['member']['warning_status']] : ''; $output['member']['warning_status_desc1'] = isset($output['member']['warning_status']) ? $txt['warn_' . $output['member']['warning_status']] : ''; } $output['member']['allow_show_email'] = $output['member']['is_guest'] ? !empty($output['member']['email']) && in_array($output['member']['show_email'], array('yes', 'yes_permission_override', 'no_through_forum')) : false; //$context['current_message'] = &$output; if ($output['can_remove']) { $context['removableMessageIDs'][] = $output['id']; } //return $output; }
function create_control_richedit($editorOptions) { global $txt, $modSettings, $options, $smcFunc; global $context, $settings, $user_info, $sourcedir, $scripturl; // Load the Post language file... for the moment at least. loadLanguage('Post'); // Every control must have a ID! assert(isset($editorOptions['id'])); assert(isset($editorOptions['value'])); // Is this the first richedit - if so we need to ensure some template stuff is initialised. if (empty($context['controls']['richedit'])) { // Some general stuff. $settings['smileys_url'] = $modSettings['smileys_url'] . '/' . $user_info['smiley_set']; // This really has some WYSIWYG stuff. $context['html_headers'] .= ' <script type="text/javascript"><!-- // --><![CDATA[ var smf_smileys_url = \'' . $settings['smileys_url'] . '\'; var oEditorStrings= { wont_work: \'' . addcslashes($txt['rich_edit_wont_work'], "'") . '\', func_disabled: \'' . addcslashes($txt['rich_edit_function_disabled'], "'") . '\', prompt_text_email: \'' . addcslashes($txt['prompt_text_email'], "'") . '\', prompt_text_ftp: \'' . addcslashes($txt['prompt_text_ftp'], "'") . '\', prompt_text_url: \'' . addcslashes($txt['prompt_text_url'], "'") . '\', prompt_text_img: \'' . addcslashes($txt['prompt_text_img'], "'") . '\' } // ]]></script> <script type="text/javascript" src="' . $settings['default_theme_url'] . '/scripts/editor.js' . $context['jsver'] . '"></script>'; } // Start off the editor... $context['controls']['richedit'][$editorOptions['id']] = array('id' => $editorOptions['id'], 'value' => $editorOptions['value'], 'rich_value' => bbc_to_html($editorOptions['value']), 'rich_active' => empty($modSettings['disable_wysiwyg']) && (!empty($options['wysiwyg_default']) || !empty($editorOptions['force_rich']) || !empty($_REQUEST[$editorOptions['id'] . '_mode'])), 'disable_smiley_box' => !empty($editorOptions['disable_smiley_box']), 'columns' => isset($editorOptions['columns']) ? $editorOptions['columns'] : 60, 'rows' => isset($editorOptions['rows']) ? $editorOptions['rows'] : 20, 'width' => isset($editorOptions['width']) ? $editorOptions['width'] : '70%', 'height' => isset($editorOptions['height']) ? $editorOptions['height'] : '150px', 'form' => isset($editorOptions['form']) ? $editorOptions['form'] : 'postmodify', 'bbc_level' => !empty($editorOptions['bbc_level']) ? $editorOptions['bbc_level'] : 'full', 'preview_type' => isset($editorOptions['preview_type']) ? (int) $editorOptions['preview_type'] : 1, 'labels' => !empty($editorOptions['labels']) ? $editorOptions['labels'] : array()); // Switch between default images and back... mostly in case you don't have an PersonalMessage template, but do have a Post template. if (isset($settings['use_default_images']) && $settings['use_default_images'] == 'defaults' && isset($settings['default_template'])) { $temp1 = $settings['theme_url']; $settings['theme_url'] = $settings['default_theme_url']; $temp2 = $settings['images_url']; $settings['images_url'] = $settings['default_images_url']; $temp3 = $settings['theme_dir']; $settings['theme_dir'] = $settings['default_theme_dir']; } if (empty($context['bbc_tags'])) { // The below array makes it dead easy to add images to this control. Add it to the array and everything else is done for you! $context['bbc_tags'] = array(); $context['bbc_tags'][] = array(array('image' => 'bold', 'code' => 'b', 'before' => '[b]', 'after' => '[/b]', 'description' => $txt['bold']), array('image' => 'italicize', 'code' => 'i', 'before' => '[i]', 'after' => '[/i]', 'description' => $txt['italic']), array('image' => 'underline', 'code' => 'u', 'before' => '[u]', 'after' => '[/u]', 'description' => $txt['underline']), array('image' => 'strike', 'code' => 's', 'before' => '[s]', 'after' => '[/s]', 'description' => $txt['strike']), array(), array('image' => 'pre', 'code' => 'pre', 'before' => '[pre]', 'after' => '[/pre]', 'description' => $txt['preformatted']), array('image' => 'left', 'code' => 'left', 'before' => '[align=left]', 'after' => '[/align]', 'description' => $txt['left_align']), array('image' => 'center', 'code' => 'center', 'before' => '[align=center]', 'after' => '[/align]', 'description' => $txt['center']), array('image' => 'right', 'code' => 'right', 'before' => '[align=right]', 'after' => '[/align]', 'description' => $txt['right_align'])); $context['bbc_tags'][] = array(array('image' => 'emoticon', 'code' => 'showemoticons', 'before' => '', 'description' => $txt['more_smileys_pick']), array(), array('image' => 'flash', 'code' => 'flash', 'before' => '[flash=200,200]', 'after' => '[/flash]', 'description' => $txt['flash']), array('image' => 'img', 'code' => 'img', 'before' => '[img]', 'after' => '[/img]', 'description' => $txt['image']), array('image' => 'url', 'code' => 'url', 'before' => '[url]', 'after' => '[/url]', 'description' => $txt['hyperlink']), array('image' => 'email', 'code' => 'email', 'before' => '[email]', 'after' => '[/email]', 'description' => $txt['insert_email']), array(), array('image' => 'sup', 'code' => 'sup', 'before' => '[sup]', 'after' => '[/sup]', 'description' => $txt['superscript']), array('image' => 'sub', 'code' => 'sub', 'before' => '[sub]', 'after' => '[/sub]', 'description' => $txt['subscript']), array('image' => 'tele', 'code' => 'tt', 'before' => '[tt]', 'after' => '[/tt]', 'description' => $txt['teletype']), array(), array('image' => 'table', 'code' => 'table', 'before' => '[table]\\n[tr]\\n[td]', 'after' => '[/td]\\n[/tr]\\n[/table]', 'description' => $txt['table']), array('image' => 'code', 'code' => 'code', 'before' => '[code]', 'after' => '[/code]', 'description' => $txt['bbc_code']), array('image' => 'quote', 'code' => 'quote', 'before' => '[quote]', 'after' => '[/quote]', 'description' => $txt['bbc_quote']), array(), array('image' => 'list', 'code' => 'list', 'before' => '[list]\\n[li]', 'after' => '[/li]\\n[li][/li]\\n[/list]', 'description' => $txt['list_unordered']), array('image' => 'orderlist', 'code' => 'orderlist', 'before' => '[list type=decimal]\\n[li]', 'after' => '[/li]\\n[li][/li]\\n[/list]', 'description' => $txt['list_ordered']), array('image' => 'hr', 'code' => 'hr', 'before' => '[hr]', 'description' => $txt['horizontal_rule'])); // Allow mods to modify BBC buttons. HookAPI::callHook('integrate_bbc_buttons', array(&$context['bbc_tags'])); // Show the toggle? if (empty($modSettings['disable_wysiwyg'])) { $context['bbc_tags'][count($context['bbc_tags']) - 1][] = array(); $context['bbc_tags'][count($context['bbc_tags']) - 1][] = array('image' => 'unformat', 'code' => 'unformat', 'before' => '', 'description' => $txt['unformat_text']); $context['bbc_tags'][count($context['bbc_tags']) - 1][] = array('image' => 'toggle', 'code' => 'toggle', 'before' => '', 'description' => $txt['toggle_view']); } $context['bbc_tags'][count($context['bbc_tags']) - 1][] = array(); $context['bbc_tags'][count($context['bbc_tags']) - 1][] = array('image' => 'zoom', 'code' => 'zoom', 'before' => '', 'description' => $txt['zoom_editor']); foreach ($context['bbc_tags'] as $row => $tagRow) { $context['bbc_tags'][$row][count($tagRow) - 1]['isLast'] = true; } } // Initialize smiley array... if not loaded before. if (empty($context['smileys']) && empty($editorOptions['disable_smiley_box'])) { $context['smileys'] = array('postform' => array(), 'popup' => array()); // Load smileys - don't bother to run a query if we're not using the database's ones anyhow. if (empty($modSettings['smiley_enable']) && $user_info['smiley_set'] != 'none') { $context['smileys']['postform'][] = array('smileys' => array(array('code' => ':)', 'filename' => 'smiley.gif', 'description' => $txt['icon_smiley']), array('code' => ';)', 'filename' => 'wink.gif', 'description' => $txt['icon_wink']), array('code' => ':D', 'filename' => 'cheesy.gif', 'description' => $txt['icon_cheesy']), array('code' => ';D', 'filename' => 'grin.gif', 'description' => $txt['icon_grin']), array('code' => '>:(', 'filename' => 'angry.gif', 'description' => $txt['icon_angry']), array('code' => ':(', 'filename' => 'sad.gif', 'description' => $txt['icon_sad']), array('code' => ':o', 'filename' => 'shocked.gif', 'description' => $txt['icon_shocked']), array('code' => '8)', 'filename' => 'cool.gif', 'description' => $txt['icon_cool']), array('code' => '???', 'filename' => 'huh.gif', 'description' => $txt['icon_huh']), array('code' => '::)', 'filename' => 'rolleyes.gif', 'description' => $txt['icon_rolleyes']), array('code' => ':P', 'filename' => 'tongue.gif', 'description' => $txt['icon_tongue']), array('code' => ':-[', 'filename' => 'embarrassed.gif', 'description' => $txt['icon_embarrassed']), array('code' => ':-X', 'filename' => 'lipsrsealed.gif', 'description' => $txt['icon_lips']), array('code' => ':-\\', 'filename' => 'undecided.gif', 'description' => $txt['icon_undecided']), array('code' => ':-*', 'filename' => 'kiss.gif', 'description' => $txt['icon_kiss']), array('code' => ':\'(', 'filename' => 'cry.gif', 'description' => $txt['icon_cry'], 'isLast' => true)), 'isLast' => true); } elseif ($user_info['smiley_set'] != 'none') { if (($temp = CacheAPI::getCache('posting_smileys', 480)) == null) { $request = smf_db_query(' SELECT code, filename, description, smiley_row, hidden FROM {db_prefix}smileys WHERE hidden IN (0, 2) ORDER BY smiley_row, smiley_order', array()); while ($row = mysql_fetch_assoc($request)) { $row['filename'] = htmlspecialchars($row['filename']); $row['description'] = htmlspecialchars($row['description']); $context['smileys']['postform'][$row['smiley_row']]['smileys'][] = $row; } mysql_free_result($request); foreach ($context['smileys'] as $section => $smileyRows) { foreach ($smileyRows as $rowIndex => $smileys) { $context['smileys'][$section][$rowIndex]['smileys'][count($smileys['smileys']) - 1]['isLast'] = true; } if (!empty($smileyRows)) { $context['smileys'][$section][count($smileyRows) - 1]['isLast'] = true; } } CacheAPI::putCache('posting_smileys', $context['smileys'], 480); } else { $context['smileys'] = $temp; } } } // Set a flag so the sub template knows what to do... $context['show_bbc'] = !empty($modSettings['enableBBC']) && !empty($settings['show_bbc']); // Generate a list of buttons that shouldn't be shown - this should be the fastest way to do this. $disabled_tags = array(); if (!empty($modSettings['disabledBBC'])) { $disabled_tags = explode(',', $modSettings['disabledBBC']); } $disabled_tags[] = 'flash'; foreach ($disabled_tags as $tag) { if ($tag == 'list') { $context['disabled_tags']['orderlist'] = true; } $context['disabled_tags'][trim($tag)] = true; } // Switch the URLs back... now we're back to whatever the main sub template is. (like folder in PersonalMessage.) if (isset($settings['use_default_images']) && $settings['use_default_images'] == 'defaults' && isset($settings['default_template'])) { $settings['theme_url'] = $temp1; $settings['images_url'] = $temp2; $settings['theme_dir'] = $temp3; } }
function ModifyProfile($post_errors = array()) { global $txt, $scripturl, $user_info, $context, $sourcedir, $user_profile, $cur_profile; global $modSettings, $memberContext, $profile_vars, $post_errors, $user_settings; $boards = boardsAllowedTo('moderate_board'); $is_mod = !empty($boards) || $user_info['is_admin'] || allowedTo('moderate_forum'); EoS_Smarty::setActive(); // Don't reload this as we may have processed error strings. if (empty($post_errors)) { loadLanguage('Profile'); } EoS_Smarty::getConfigInstance()->registerHookTemplate('sidemenu_top', 'profile/menu_top_content'); //$context['sef_full_rewrite'] = true; require_once $sourcedir . '/lib/Subs-Menu.php'; // Did we get the user by name... if (isset($_REQUEST['user'])) { $memberResult = loadMemberData($_REQUEST['user'], true, 'profile'); } elseif (!empty($_REQUEST['u'])) { $memberResult = loadMemberData((int) $_REQUEST['u'], false, 'profile'); } else { $memberResult = loadMemberData($user_info['id'], false, 'profile'); } // Check if loadMemberData() has returned a valid result. if (!is_array($memberResult)) { fatal_lang_error('not_a_user', false); } // If all went well, we have a valid member ID! list($memID) = $memberResult; $context['id_member'] = $memID; $cur_profile = $user_profile[$memID]; // Let's have some information about this member ready, too. loadMemberContext($memID); $context['member'] = $memberContext[$memID]; // Is this the profile of the user himself or herself? $context['user']['is_owner'] = $memID == $user_info['id']; /* Define all the sections within the profile area! We start by defining the permission required - then SMF takes this and turns it into the relevant context ;) Possible fields: For Section: string $title: Section title. array $areas: Array of areas within this section. For Areas: string $label: Text string that will be used to show the area in the menu. string $file: Optional text string that may contain a file name that's needed for inclusion in order to display the area properly. string $custom_url: Optional href for area. string $function: Function to execute for this section. bool $enabled: Should area be shown? string $sc: Session check validation to do on save - note without this save will get unset - if set. bool $hidden: Does this not actually appear on the menu? bool $password: Whether to require the user's password in order to save the data in the area. array $subsections: Array of subsections, in order of appearance. array $permission: Array of permissions to determine who can access this area. Should contain arrays $own and $any. */ $profile_areas = array('info' => array('title' => $txt['profileInfo'], 'areas' => array('summary' => array('label' => $txt['summary'], 'file' => 'Profile-View.php', 'function' => 'summary', 'permission' => array('own' => 'profile_view_own', 'any' => 'profile_view_any')), 'statistics' => array('label' => $txt['statPanel'], 'file' => 'Profile-View.php', 'function' => 'statPanel', 'permission' => array('own' => 'profile_view_own', 'any' => 'profile_view_any')), 'showposts' => array('label' => $txt['showPosts'], 'file' => 'Profile-View.php', 'function' => 'showPosts', 'subsections' => array('messages' => array($txt['showMessages'], array('profile_view_own', 'profile_view_any')), 'topics' => array($txt['showTopics'], array('profile_view_own', 'profile_view_any')), 'attach' => array($txt['showAttachments'], array('profile_view_own', 'profile_view_any')), 'likes' => array($txt['showLikes'], array('profile_view_own', 'profile_view_any')), 'likesout' => array($txt['showLikesGiven'], array('profile_view_own', 'profile_view_any'))), 'permission' => array('own' => 'profile_view_own', 'any' => 'profile_view_any')), 'activities' => array('label' => $txt['showActivitiesMenu'], 'file' => 'Activities.php', 'function' => 'showActivitiesProfile', 'subsections' => array('activities' => array($txt['showActivities'], array('profile_view_own', 'profile_view_any')), 'notifications' => array($txt['showNotifications'], array('profile_view_own', 'profile_view_any')), 'settings' => array($txt['astreamSettings'], array('profile_view_own', 'profile_view_any'))), 'permission' => array('own' => 'profile_view_own', 'any' => 'profile_view_any')), 'permissions' => array('label' => $txt['showPermissions'], 'file' => 'Profile-View.php', 'function' => 'showPermissions', 'permission' => array('own' => 'manage_permissions', 'any' => 'manage_permissions')), 'tracking' => array('label' => $txt['trackUser'], 'file' => 'Profile-View.php', 'function' => 'tracking', 'subsections' => array('activity' => array($txt['trackActivity'], 'moderate_forum'), 'ip' => array($txt['trackIP'], 'moderate_forum'), 'edits' => array($txt['trackEdits'], 'moderate_forum')), 'permission' => array('own' => 'moderate_forum', 'any' => 'moderate_forum')), 'viewwarning' => array('label' => $txt['profile_view_warnings'], 'enabled' => in_array('w', $context['admin_features']) && $modSettings['warning_settings'][0] == 1 && $cur_profile['warning'] && $context['user']['is_owner'] && !empty($modSettings['warning_show']), 'file' => 'Profile-View.php', 'function' => 'viewWarning', 'permission' => array('own' => 'profile_view_own', 'any' => 'issue_warning')), 'view_topicbans' => array('label' => $txt['profile_view_topicbans'], 'enabled' => $is_mod, 'file' => 'Profile.php', 'function' => 'viewTopicBans', 'permission' => array('own' => 'profile_view_any', 'any' => 'profile_view_any')))), 'edit_profile' => array('title' => $txt['profileEdit'], 'areas' => array('account' => array('label' => $txt['account'], 'file' => 'Profile-Modify.php', 'function' => 'account', 'enabled' => $context['user']['is_admin'] || $cur_profile['id_group'] != 1 && !in_array(1, explode(',', $cur_profile['additional_groups'])), 'sc' => 'post', 'password' => true, 'permission' => array('own' => array('profile_identity_any', 'profile_identity_own', 'manage_membergroups'), 'any' => array('profile_identity_any', 'manage_membergroups'))), 'forumprofile' => array('label' => $txt['forumprofile'], 'file' => 'Profile-Modify.php', 'function' => 'forumProfile', 'sc' => 'post', 'permission' => array('own' => array('profile_extra_any', 'profile_extra_own', 'profile_title_own', 'profile_title_any'), 'any' => array('profile_extra_any', 'profile_title_any'))), 'theme' => array('label' => $txt['theme'], 'file' => 'Profile-Modify.php', 'function' => 'theme', 'sc' => 'post', 'permission' => array('own' => array('profile_extra_any', 'profile_extra_own'), 'any' => array('profile_extra_any'))), 'authentication' => array('label' => $txt['authentication'], 'file' => 'Profile-Modify.php', 'function' => 'authentication', 'enabled' => !empty($modSettings['enableOpenID']) || !empty($cur_profile['openid_uri']), 'sc' => 'post', 'hidden' => empty($modSettings['enableOpenID']) && empty($cur_profile['openid_uri']), 'password' => true, 'permission' => array('own' => array('profile_identity_any', 'profile_identity_own'), 'any' => array('profile_identity_any'))), 'notification' => array('label' => $txt['notification'], 'file' => 'Profile-Modify.php', 'function' => 'notification', 'sc' => 'post', 'permission' => array('own' => array('profile_extra_any', 'profile_extra_own'), 'any' => array('profile_extra_any'))), 'pmprefs' => array('label' => $txt['pmprefs'], 'file' => 'Profile-Modify.php', 'function' => 'pmprefs', 'enabled' => allowedTo(array('profile_extra_own', 'profile_extra_any')), 'sc' => 'post', 'permission' => array('own' => array('pm_read'), 'any' => array('profile_extra_any'))), 'ignoreboards' => array('label' => $txt['ignoreboards'], 'file' => 'Profile-Modify.php', 'function' => 'ignoreboards', 'enabled' => !empty($modSettings['allow_ignore_boards']), 'sc' => 'post', 'permission' => array('own' => array('profile_extra_any', 'profile_extra_own'), 'any' => array('profile_extra_any'))), 'lists' => array('label' => $txt['editBuddyIgnoreLists'], 'file' => 'Profile-Modify.php', 'function' => 'editBuddyIgnoreLists', 'enabled' => !empty($modSettings['enable_buddylist']) && $context['user']['is_owner'], 'sc' => 'post', 'subsections' => array('buddies' => array($txt['editBuddies']), 'ignore' => array($txt['editIgnoreList'])), 'permission' => array('own' => array('profile_extra_any', 'profile_extra_own'), 'any' => array())), 'groupmembership' => array('label' => $txt['groupmembership'], 'file' => 'Profile-Modify.php', 'function' => 'groupMembership', 'enabled' => !empty($modSettings['show_group_membership']) && $context['user']['is_owner'], 'sc' => 'request', 'permission' => array('own' => array('profile_view_own'), 'any' => array('manage_membergroups'))), 'boardnews' => array('label' => $txt['menu_boardnews'], 'file' => 'Profile-Modify.php', 'function' => 'profileManageBoardNews', 'enabled' => $context['user']['is_owner'], 'sc' => 'post', 'permission' => array('own' => array('profile_view_own'), 'any' => array())))), 'profile_action' => array('title' => $txt['profileAction'], 'areas' => array('sendpm' => array('label' => $txt['profileSendIm'], 'custom_url' => $scripturl . '?action=pm;sa=send', 'permission' => array('own' => array(), 'any' => array('pm_send'))), 'issuewarning' => array('label' => $txt['profile_issue_warning'], 'enabled' => in_array('w', $context['admin_features']) && $modSettings['warning_settings'][0] == 1 && (!$context['user']['is_owner'] || $context['user']['is_admin']), 'file' => 'Profile-Actions.php', 'function' => 'issueWarning', 'permission' => array('own' => array('issue_warning'), 'any' => array('issue_warning'))), 'banuser' => array('label' => $txt['profileBanUser'], 'custom_url' => $scripturl . '?action=admin;area=ban;sa=add', 'enabled' => $cur_profile['id_group'] != 1 && !in_array(1, explode(',', $cur_profile['additional_groups'])), 'permission' => array('own' => array(), 'any' => array('manage_bans'))), 'subscriptions' => array('label' => $txt['subscriptions'], 'file' => 'Profile-Actions.php', 'function' => 'subscriptions', 'enabled' => !empty($modSettings['paid_enabled']), 'permission' => array('own' => array('profile_view_own'), 'any' => array('moderate_forum'))), 'deleteaccount' => array('label' => $txt['deleteAccount'], 'file' => 'Profile-Actions.php', 'function' => 'deleteAccount', 'sc' => 'post', 'password' => true, 'permission' => array('own' => array('profile_remove_any', 'profile_remove_own'), 'any' => array('profile_remove_any'))), 'activateaccount' => array('file' => 'Profile-Actions.php', 'function' => 'activateAccount', 'sc' => 'get', 'select' => 'summary', 'permission' => array('own' => array(), 'any' => array('moderate_forum')))))); //if(!$context['user']['is_owner'] || !in_array('dr', $context['admin_features'])) todo: drafts -> plugin unset($profile_areas['info']['areas']['drafts']); if (!in_array('as', $context['admin_features'])) { unset($profile_areas['info']['areas']['activities']); } if (!$user_info['is_admin'] && !$context['user']['is_owner'] && isset($profile_areas['info']['areas']['activities'])) { unset($profile_areas['info']['areas']['activities']['subsections']['notifications']); unset($profile_areas['info']['areas']['activities']['subsections']['settings']); } if (!$context['user']['is_owner'] && !allowedTo('can_view_ratings') || empty($modSettings['karmaMode'])) { unset($profile_areas['info']['areas']['showposts']['subsections']['likes']); unset($profile_areas['info']['areas']['showposts']['subsections']['likesout']); } // Let them modify profile areas easily. HookAPI::callHook('profile_areas', array(&$profile_areas)); // Do some cleaning ready for the menu function. $context['password_areas'] = array(); $current_area = isset($_REQUEST['area']) ? $_REQUEST['area'] : ''; foreach ($profile_areas as $section_id => $section) { // Do a bit of spring cleaning so to speak. foreach ($section['areas'] as $area_id => $area) { // If it said no permissions that meant it wasn't valid! if (empty($area['permission'][$context['user']['is_owner'] ? 'own' : 'any'])) { $profile_areas[$section_id]['areas'][$area_id]['enabled'] = false; } else { $profile_areas[$section_id]['areas'][$area_id]['permission'] = $area['permission'][$context['user']['is_owner'] ? 'own' : 'any']; } // Password required - only if not on OpenID. if (!empty($area['password'])) { $context['password_areas'][] = $area_id; } } } // Is there an updated message to show? if (isset($_GET['updated'])) { $context['profile_updated'] = $txt['profile_updated_own']; } // Set a few options for the menu. $menuOptions = array('disable_url_session_check' => true, 'current_area' => $current_area, 'extra_url_parameters' => array('u' => $context['id_member'])); // Actually create the menu! $profile_include_data = createMenu($profile_areas, $menuOptions); // No menu means no access. if (!$profile_include_data && (!$user_info['is_guest'] || validateSession())) { fatal_lang_error('no_access', false); } // Make a note of the Unique ID for this menu. $context['profile_menu_id'] = $context['max_menu_id']; $context['profile_menu_name'] = 'menu_data_' . $context['profile_menu_id']; // Set the selected item - now it's been validated. $current_area = $profile_include_data['current_area']; $context['menu_item_selected'] = $current_area; // Before we go any further, let's work on the area we've said is valid. Note this is done here just in case we every compromise the menu function in error! $context['completed_save'] = false; $security_checks = array(); $found_area = false; foreach ($profile_areas as $section_id => $section) { // Do a bit of spring cleaning so to speak. foreach ($section['areas'] as $area_id => $area) { // Is this our area? if ($current_area == $area_id) { // This can't happen - but is a security check. if (isset($section['enabled']) && $section['enabled'] == false || isset($area['enabled']) && $area['enabled'] == false) { fatal_lang_error('no_access', false); } // Are we saving data in a valid area? if (isset($area['sc']) && isset($_REQUEST['save'])) { $security_checks['session'] = $area['sc']; $context['completed_save'] = true; } // Does this require session validating? if (!empty($area['validate'])) { $security_checks['validate'] = true; } // Permissions for good measure. if (!empty($profile_include_data['permission'])) { $security_checks['permission'] = $profile_include_data['permission']; } // Either way got something. $found_area = true; } } } // Oh dear, some serious security lapse is going on here... we'll put a stop to that! if (!$found_area) { fatal_lang_error('no_access', false); } // Release this now. unset($profile_areas); // Now the context is setup have we got any security checks to carry out additional to that above? if (isset($security_checks['session'])) { checkSession($security_checks['session']); } if (isset($security_checks['validate'])) { validateSession(); } if (isset($security_checks['permission'])) { isAllowedTo($security_checks['permission']); } // File to include? if (isset($profile_include_data['file'])) { require_once $sourcedir . '/' . $profile_include_data['file']; } // Make sure that the area function does exist! if (!isset($profile_include_data['function']) || !function_exists($profile_include_data['function'])) { destroyMenu(); fatal_lang_error('no_access', false); } // Build the link tree. $context['linktree'][] = array('url' => $scripturl . '?action=profile' . ($memID != $user_info['id'] ? ';u=' . $memID : ''), 'name' => sprintf($txt['profile_of_username'], $context['member']['name'])); if (!empty($profile_include_data['label'])) { $context['linktree'][] = array('url' => $scripturl . '?action=profile' . ($memID != $user_info['id'] ? ';u=' . $memID : '') . ';area=' . $profile_include_data['current_area'], 'name' => $profile_include_data['label']); } if (!empty($profile_include_data['current_subsection']) && $profile_include_data['subsections'][$profile_include_data['current_subsection']][0] != $profile_include_data['label']) { $context['linktree'][] = array('url' => $scripturl . '?action=profile' . ($memID != $user_info['id'] ? ';u=' . $memID : '') . ';area=' . $profile_include_data['current_area'] . ';sa=' . $profile_include_data['current_subsection'], 'name' => $profile_include_data['subsections'][$profile_include_data['current_subsection']][0]); } // Set the template for this area and add the profile layer. $context['sub_template'] = $profile_include_data['function']; $context['template_layers'][] = 'profile'; // All the subactions that require a user password in order to validate. $check_password = $context['user']['is_owner'] && in_array($profile_include_data['current_area'], $context['password_areas']); $context['require_password'] = $check_password && empty($user_settings['openid_uri']); // These will get populated soon! $post_errors = array(); $profile_vars = array(); // Right - are we saving - if so let's save the old data first. if ($context['completed_save']) { // If it's someone elses profile then validate the session. if (!$context['user']['is_owner']) { validateSession(); } // Clean up the POST variables. $_POST = htmltrim__recursive($_POST); $_POST = htmlspecialchars__recursive($_POST); if ($check_password) { // If we're using OpenID try to revalidate. if (!empty($user_settings['openid_uri'])) { require_once $sourcedir . '/lib/Subs-OpenID.php'; smf_openID_revalidate(); } else { // You didn't even enter a password! if (trim($_POST['oldpasswrd']) == '') { $post_errors[] = 'no_password'; } // Since the password got modified due to all the $_POST cleaning, lets undo it so we can get the correct password $_POST['oldpasswrd'] = un_htmlspecialchars($_POST['oldpasswrd']); // Does the integration want to check passwords? $good_password = in_array(true, HookAPI::callHook('integrate_verify_password', array($cur_profile['member_name'], $_POST['oldpasswrd'], false)), true); // Bad password!!! if (!$good_password && $user_info['passwd'] != sha1(strtolower($cur_profile['member_name']) . $_POST['oldpasswrd'])) { $post_errors[] = 'bad_password'; } // Warn other elements not to jump the gun and do custom changes! if (in_array('bad_password', $post_errors)) { $context['password_auth_failed'] = true; } } } // Change the IP address in the database. if ($context['user']['is_owner']) { $profile_vars['member_ip'] = $user_info['ip']; } // Now call the sub-action function... if ($current_area == 'activateaccount') { if (empty($post_errors)) { activateAccount($memID); } } elseif ($current_area == 'deleteaccount') { if (empty($post_errors)) { deleteAccount2($profile_vars, $post_errors, $memID); redirectexit(); } } elseif ($current_area == 'groupmembership' && empty($post_errors)) { $msg = groupMembership2($profile_vars, $post_errors, $memID); // Whatever we've done, we have nothing else to do here... redirectexit('action=profile' . ($context['user']['is_owner'] ? '' : ';u=' . $memID) . ';area=groupmembership' . (!empty($msg) ? ';msg=' . $msg : '')); } elseif ($current_area == 'authentication') { authentication($memID, true); } elseif (in_array($current_area, array('account', 'forumprofile', 'theme', 'pmprefs'))) { saveProfileFields(); } else { $force_redirect = true; // Ensure we include this. require_once $sourcedir . '/Profile-Modify.php'; saveProfileChanges($profile_vars, $post_errors, $memID); } // There was a problem, let them try to re-enter. if (!empty($post_errors)) { // Load the language file so we can give a nice explanation of the errors. loadLanguage('Errors'); $context['post_errors'] = $post_errors; } elseif (!empty($profile_vars)) { // If we've changed the password, notify any integration that may be listening in. if (isset($profile_vars['passwd'])) { HookAPI::callHook('integrate_reset_pass', array($cur_profile['member_name'], $cur_profile['member_name'], $_POST['passwrd2'])); } updateMemberData($memID, $profile_vars); // What if this is the newest member? if ($modSettings['latestMember'] == $memID) { updateStats('member'); } elseif (isset($profile_vars['real_name'])) { updateSettings(array('memberlist_updated' => time())); } // If the member changed his/her birthdate, update calendar statistics. if (isset($profile_vars['birthdate']) || isset($profile_vars['real_name'])) { updateSettings(array('calendar_updated' => time())); } // Anything worth logging? if (!empty($context['log_changes']) && !empty($modSettings['modlog_enabled'])) { $log_changes = array(); foreach ($context['log_changes'] as $k => $v) { $log_changes[] = array('action' => $k, 'id_log' => 2, 'log_time' => time(), 'id_member' => $memID, 'ip' => $user_info['ip'], 'extra' => serialize(array_merge($v, array('applicator' => $user_info['id'])))); } smf_db_insert('', '{db_prefix}log_actions', array('action' => 'string', 'id_log' => 'int', 'log_time' => 'int', 'id_member' => 'int', 'ip' => 'string-16', 'extra' => 'string-65534'), $log_changes, array('id_action')); } // Have we got any post save functions to execute? if (!empty($context['profile_execute_on_save'])) { foreach ($context['profile_execute_on_save'] as $saveFunc) { $saveFunc(); } } // Let them know it worked! $context['profile_updated'] = $context['user']['is_owner'] ? $txt['profile_updated_own'] : sprintf($txt['profile_updated_else'], $cur_profile['member_name']); // Invalidate any cached data. CacheAPI::putCache('member_data-profile-' . $memID, null, 0); } } // Have some errors for some reason? if (!empty($post_errors)) { // Set all the errors so the template knows what went wrong. foreach ($post_errors as $error_type) { $context['modify_error'][$error_type] = true; } } elseif (!empty($profile_vars) && $context['user']['is_owner']) { redirectexit('action=profile;area=' . $current_area . ';updated'); } elseif (!empty($force_redirect)) { redirectexit('action=profile' . ($context['user']['is_owner'] ? '' : ';u=' . $memID) . ';area=' . $current_area); } // Call the appropriate subaction function. $profile_include_data['function']($memID); // Set the page title if it's not already set... if (!isset($context['page_title'])) { $context['page_title'] = $txt['profile'] . (isset($txt[$current_area]) ? ' - ' . $txt[$current_area] : ''); } }