/** * Finalize URLs. (Lowercase step done by the caller.) * * @param string URL to be finalized. * @param string Scheme to be used for this URL. * @return string Finalized URL. */ function google_seo_url_finalize($url, $scheme) { global $settings; $url = google_seo_expand($scheme, array('url' => $url)); $test = explode('?', $url); $test = explode('/', $test[0]); foreach ($test as $element) { /** * Maximum URL length hack. * * Most hosts do not allow for filenames > 255 bytes in URLs. * Trying to access such an URL results in 403 Forbidden. * * Since MyBB already limits length of user names and topic * subjects this is normally not a problem. However it is still * possible to hit the limit with UTF-8 multibyte characters. * * This hack causes Google SEO to fall back to stock URLs in * the rare case where the Google SEO URL would be unuseable. * */ if (strlen($element) >= 256) { return 0; } } $url = google_seo_encode($url); return $url; }
/** * Redirect if necessary. * */ function google_seo_redirect_hook() { global $db, $mybb, $settings, $plugins, $google_seo_redirect; if ($mybb->request_method == "post") { // Never touch posts. return; } // Build the target URL we should be at: switch (THIS_SCRIPT) { case 'forumdisplay.php': $fid = (int) $mybb->input['fid']; $page = (int) $mybb->input['page']; if ($fid) { // forum as index tweak if ($fid == $settings['google_seo_tweak_index_fid']) { $target = ""; if ($page > 1) { $target = "?page={$page}"; } } else { $target = get_forum_link($fid, $page); } $kill['fid'] = ''; $kill['page'] = ''; $kill['google_seo_forum'] = ''; $kill['google_seo'] = ''; } break; case 'showthread.php': // pid overrules tid, so we must check pid first, // even at the cost of an additional query. if ((int) $mybb->input['pid']) { $tid = google_seo_tid((int) $mybb->input['pid'], (int) $mybb->input['tid'], $settings['google_seo_redirect_posts']); $target = get_post_link((int) $mybb->input['pid'], $tid); $kill['pid'] = ''; $kill['tid'] = ''; $kill['google_seo_thread'] = ''; $kill['google_seo'] = ''; } else { if ((int) $mybb->input['tid']) { $target = get_thread_link((int) $mybb->input['tid'], (int) $mybb->input['page'], (string) $mybb->input['action']); $kill['tid'] = ''; $kill['action'] = ''; $kill['google_seo_thread'] = ''; $kill['google_seo'] = ''; if ($mybb->input['page'] != 'last') { $kill['page'] = ''; } } } break; case 'announcements.php': if ((int) $mybb->input['aid']) { $target = get_announcement_link((int) $mybb->input['aid']); $kill['aid'] = ''; $kill['google_seo_announcement'] = ''; $kill['google_seo'] = ''; } break; case 'member.php': if ((int) $mybb->input['uid']) { if ($settings['google_seo_redirect_litespeed'] && $mybb->input['action'] != 'profile') { // Work around rewrite bug in LiteSpeed (double action conflict). break; } $target = get_profile_link((int) $mybb->input['uid']); $kill['uid'] = ''; $kill['google_seo_user'] = ''; $kill['google_seo'] = ''; if ($mybb->input['action'] == 'profile') { $kill['action'] = ''; } } break; case 'calendar.php': if ((int) $mybb->input['eid']) { if ($settings['google_seo_redirect_litespeed'] && $mybb->input['action'] != 'profile') { // Work around rewrite bug in LiteSpeed (double action conflict). break; } $target = get_event_link((int) $mybb->input['eid']); $kill['eid'] = ''; $kill['google_seo_event'] = ''; $kill['google_seo'] = ''; if ($mybb->input['action'] == 'event') { $kill['action'] = ''; } } else { if (!(int) $mybb->input['calendar']) { // Special case: Default calendar. // Code taken from calendar.php $query = $db->simple_select("calendars", "cid", "", array('order_by' => 'disporder', 'limit' => 1)); $cid = $db->fetch_field($query, "cid"); $mybb->input['calendar'] = $cid; } if ($mybb->input['action'] == "weekview") { $target = get_calendar_week_link((int) $mybb->input['calendar'], (int) str_replace('n', '-', $mybb->input['week'])); $kill['calendar'] = ''; $kill['week'] = ''; $kill['action'] = ''; $kill['google_seo_calendar'] = ''; $kill['google_seo'] = ''; } else { $target = get_calendar_link((int) $mybb->input['calendar'], (int) $mybb->input['year'], (int) $mybb->input['month'], (int) $mybb->input['day']); $kill['calendar'] = ''; $kill['year'] = ''; $kill['month'] = ''; $kill['day'] = ''; $kill['google_seo_calendar'] = ''; $kill['google_seo'] = ''; } } break; } // Verify that we are already at the target. if (isset($target)) { $target = $settings['bburl'] . '/' . urldecode($target); $current = google_seo_redirect_current_url(); // Not identical (although it may only be the query string). if ($current != $target) { // Parse current and target $target_parse = explode("?", $target, 2); $current_parse = explode("?", $current, 2); // Location $location_target = $target_parse[0]; $location_current = $current_parse[0]; // Fix broken query strings (e.g. search.php) $broken_query = preg_replace("/\\?([^&?=]+)([=&])/u", '&$1$2', $current_parse[1]); if ($current_parse[1] != $broken_query) { $change = 1; $current_parse[2] = $current_parse[1]; $current_parse[1] = $broken_query; } // Query $current_dynamic = google_seo_dynamic('?' . $current_parse[1]); $target_dynamic = google_seo_dynamic('?' . $target_parse[1]); parse_str(htmlspecialchars_decode($target_parse[1]), $query_target); parse_str($current_parse[1], $query_current); if (@get_magic_quotes_gpc()) { // Dear PHP, I don't need magic, thank you very much. $mybb->strip_slashes_array($query_target); $mybb->strip_slashes_array($query_current); } $query = $query_current; // Kill query string elements that already are part of the URL. if (!$query[$target_dynamic]) { unset($query[$target_dynamic]); unset($query_current[$target_dynamic]); unset($query_target[$target_dynamic]); } if (!$query[$current_dynamic]) { unset($query[$current_dynamic]); unset($query_current[$current_dynamic]); unset($query_target[$current_dynamic]); } foreach ($kill as $k => $v) { unset($query[$k]); } // Final query, current parameters retained $query = array_merge($query_target, $query); if (count($query) != count($query_current)) { $change = 2; } else { if ($current_dynamic != $target_dynamic) { $change = 3; } else { foreach ($query as $k => $v) { if ($query_current[$k] != $v) { $change = 4; } } } } // Definitely not identical? if ($change || $location_target != $location_current) { // Check if redirect debugging is enabled. if ($settings['google_seo_redirect_debug'] && $mybb->usergroup['cancp'] == 1) { if ($query['google_seo_redirect']) { // print out information about this redirect and return header("Content-type: text/html; charset=UTF-8"); echo "<pre style=\"text-align: left\">"; echo "Google SEO Redirect Debug Information:\n"; echo "!!! WARNING: This may contain cookie authentication data. Don't post debug info in public. !!!\n"; echo htmlspecialchars(print_r(array('THIS_SCRIPT' => THIS_SCRIPT, '_SERVER' => array_merge($_SERVER, array('HTTP_COOKIE' => '')), 'mybb->input' => $mybb->input, 'kill' => $kill, 'target' => $target, 'current' => $current, 'target_parse' => $target_parse, 'current_parse' => $current_parse, 'target_dynamic' => $target_dynamic, 'current_dynamic' => $current_dynamic, 'location_target' => $location_target, 'location_current' => $location_current, 'broken_query' => $broken_query, 'change' => $change, 'query_target' => $query_target, 'query_current' => $query_current, 'query' => $query), true), ENT_COMPAT, "UTF-8"); echo "</pre>"; return; } else { $query['google_seo_redirect'] = "debug"; } } // Redirect but retain query. if ($target_dynamic) { $querystr[] = google_seo_encode($target_dynamic); } foreach ($query as $k => $v) { $querystr[] = urlencode($k) . "=" . urlencode($v); } $location_target = google_seo_encode($location_target); if (sizeof($querystr)) { $location_target .= "?" . implode("&", $querystr); } $google_seo_redirect = $location_target; if ($settings['google_seo_redirect_permission'] && THIS_SCRIPT != "member.php") { // Leave permission checks to the current page. // Add hooks to issue redirect later on. $plugins->add_hook("forumdisplay_end", "google_seo_redirect_header", 2); $plugins->add_hook("postbit", "google_seo_redirect_header", 2); $plugins->add_hook("postbit_announcement", "google_seo_redirect_header", 2); $plugins->add_hook("calendar_editevent_end", "google_seo_redirect_header", 2); $plugins->add_hook("calendar_event_end", "google_seo_redirect_header", 2); $plugins->add_hook("calendar_end", "google_seo_redirect_header", 2); $plugins->add_hook("pre_output_page", "google_seo_redirect_header", 2); // Except on error. $plugins->add_hook("error", "google_seo_redirect_remove_hooks", 2); $plugins->add_hook("no_permission", "google_seo_redirect_remove_hooks", 2); } else { google_seo_redirect_header(); } } } } }