/** * Additional status information about the plugin. * * @return string status string */ function google_seo_plugin_status() { global $lang, $mybb, $config, $settings, $db; global $PL; $PL or (require_once PLUGINLIBRARY); $success = array(); $warning = array(); $error = array(); $htaccess = array(); $lines = array(); if (!$settings['google_seo_url'] || !$settings['google_seo_url_cache']) { // Good place as any to delete cache if disabled. $PL->cache_delete('google_seo_url'); } // Required for 404 and URL $base = $settings['bburl']; $base = preg_replace('#^[^/]*://[^/]*#', '', $base); // Warning about disabled plugins. if (defined("NO_PLUGINS") || $settings['no_plugins']) { $warning[] = $lang->googleseo_plugin_no_plugins; } // UTF-8 is required: if ($mybb->config['database']['encoding'] != 'utf8' && $mybb->config['database']['encoding'] != 'utf8mb4') { $warning[] = $lang->sprintf($lang->googleseo_plugin_warn_encoding, $mybb->config['database']['encoding']); } // Google SEO 404: if ($settings['google_seo_404']) { $success[] = $lang->googleseo_plugin_404; $htaccess[] = array("ErrorDocument 404 {$base}/misc.php?google_seo_error=404", 0, $lang->googleseo_plugin_htaccess_404); } else { $error[] = $lang->googleseo_plugin_404; } // Google SEO Meta: if ($settings['google_seo_meta']) { $success[] = $lang->googleseo_plugin_meta; } else { $error[] = $lang->googleseo_plugin_meta; } // Google SEO Redirect: if ($settings['google_seo_redirect']) { $success[] = $lang->googleseo_plugin_redirect; if (!$settings['google_seo_url']) { $warning[] = $lang->googleseo_plugin_redirect_warn_url; } $current_url = google_seo_redirect_current_url(); $pos = my_strpos($current_url, "/{$config['admin_dir']}/index.php"); if ($pos) { $current_url = my_substr($current_url, 0, $pos); } if (!$settings['bburl'] || $settings['bburl'] != $current_url) { $warning[] = $lang->sprintf($lang->googleseo_plugin_redirect_warn_bburl, htmlspecialchars($settings['bburl'], ENT_COMPAT, "UTF-8"), htmlspecialchars($current_url), ENT_COMPAT, "UTF-8"); } } else { $error[] = $lang->googleseo_plugin_redirect; } // Google SEO Sitemap: if ($settings['google_seo_sitemap']) { if ($settings['google_seo_sitemap_url']) { $link = "{$settings['bburl']}/{$settings['google_seo_sitemap_url']}"; $htaccess[] = array($settings['google_seo_sitemap_url'], 'misc.php', 'google_seo_sitemap', $lang->googleseo_plugin_htaccess_sitemap); } else { $link = "{$settings['bburl']}/misc.php?google_seo_sitemap={url}"; } $link = google_seo_expand($link, array('url' => 'index')); $success[] = "<a href=\"{$link}\" target=\"_blank\">{$lang->googleseo_plugin_sitemap}</a>"; } else { $error[] = $lang->googleseo_plugin_sitemap; } // Google SEO URL: if ($settings['google_seo_url']) { $urldb = $PL->url_append('index.php', array('module' => 'config-plugins', 'google_seo' => 'database', 'my_post_key' => $mybb->post_code)); $success[] = "<a href=\"{$urldb}\">{$lang->googleseo_plugin_url}</a>"; if ($settings['google_seo_url_translate'] && !file_exists(MYBB_ROOT . "inc/plugins/google_seo/translate.php")) { $warning[] = $lang->googleseo_plugin_url_warn_translate; } if ($settings['google_seo_url_forums']) { $htaccess[] = array($settings['google_seo_url_forums'], 'forumdisplay.php', 'google_seo_forum', $lang->googleseo_plugin_htaccess_forums); } if ($settings['google_seo_url_threads']) { $htaccess[] = array($settings['google_seo_url_threads'], 'showthread.php', 'google_seo_thread', $lang->googleseo_plugin_htaccess_threads); } if ($settings['google_seo_url_announcements']) { $htaccess[] = array($settings['google_seo_url_announcements'], 'announcements.php', 'google_seo_announcement', $lang->googleseo_plugin_htaccess_announcements); } if ($settings['google_seo_url_users']) { $htaccess[] = array($settings['google_seo_url_users'], 'member.php', 'google_seo_user', $lang->googleseo_plugin_htaccess_users, 'action=profile&'); } if ($settings['google_seo_url_calendars']) { $htaccess[] = array($settings['google_seo_url_calendars'], 'calendar.php', 'google_seo_calendar', $lang->googleseo_plugin_htaccess_calendars); } if ($settings['google_seo_url_events']) { $htaccess[] = array($settings['google_seo_url_events'], 'calendar.php', 'google_seo_event', $lang->googleseo_plugin_htaccess_events, 'action=event&'); } } else { $error[] = $lang->googleseo_plugin_url; } // URL scheme conflict detection $pattern = $settings['google_seo_url_punctuation']; if ($pattern) { // Escape the pattern. // (preg_quote breaks UTF-8 and doesn't escape -) $pattern = preg_replace("/[\\\\\\^\\-\\[\\]\\/]/u", "\\\\\\0", $pattern); } for ($a = count($htaccess); $a--;) { if (!$htaccess[$a][1]) { continue; } for ($b = $a; $b--;) { if (!$htaccess[$b][1]) { continue; } // for any pair a-b: $rule_a = explode('?', $htaccess[$a][0]); $rule_a = $rule_a[0]; $rule_b = explode('?', $htaccess[$b][0]); $rule_b = $rule_b[0]; $test_a = google_seo_expand($rule_a, array('url' => '')); $test_b = google_seo_expand($rule_b, array('url' => '')); if ($pattern) { $test_a = preg_replace("/^[{$pattern}]+|[{$pattern}]+\$/u", "", $test_a); $test_b = preg_replace("/^[{$pattern}]+|[{$pattern}]+\$/u", "", $test_b); } $test_ab = google_seo_expand($rule_a, array('url' => $test_b)); $test_ba = google_seo_expand($rule_b, array('url' => $test_a)); $regexp_a = preg_quote($rule_a, '#'); $regexp_a = preg_replace('/\\\\{(\\\\\\$|)url\\\\}/', '{url}', $regexp_a); $regexp_a = google_seo_expand($regexp_a, array('url' => '([^./]+)')); $regexp_b = preg_quote($rule_b, '#'); $regexp_b = preg_replace('/\\\\{(\\\\\\$|)url\\\\}/', '{url}', $regexp_b); $regexp_b = google_seo_expand($regexp_b, array('url' => '([^./]+)')); // Could there be a conflict? if (preg_match("#^{$regexp_a}\$#u", $test_ab) && preg_match("#^{$regexp_b}\$#u", $test_ab) || preg_match("#^{$regexp_a}\$#u", $test_ba) && preg_match("#^{$regexp_b}\$#u", $test_ba) || preg_match("#^{$regexp_a}\$#u", $test_ab) && preg_match("#^{$regexp_a}\$#u", $test_ba) || preg_match("#^{$regexp_b}\$#u", $test_ab) && preg_match("#^{$regexp_b}\$#u", $test_ba)) { $warning[] = $lang->sprintf($lang->googleseo_plugin_htaccess_conflict, htmlspecialchars_uni($htaccess[$a][0]), htmlspecialchars_uni($htaccess[$b][0])); } } } // Check htaccess. if (count($htaccess) || !$settings['google_seo_404']) { $file = @file_get_contents(MYBB_ROOT . ".htaccess"); if ($file) { $file = preg_replace('/^[\\s\\t]*#.*$/m', '', $file); $file = preg_replace("/\\s*\n\\s*/m", "\n", $file); $file .= "\n"; // no newline at end of file } foreach ($htaccess as $v) { if ($v[1]) { $rewrite = 1; $rule = explode('?', $v[0]); // ignore dynamic part, if present $rule = $rule[0]; if ($rule != $v[1]) { $rule = preg_quote($rule); $rule = preg_replace('/\\\\{(\\\\\\$|)url\\\\}/', '{url}', $rule); if (strpos($rule, '{url}') !== false) { $url = "([^./]+)"; $rule = google_seo_expand($rule, array('url' => $url)); $rule = "RewriteRule ^{$rule}\$ {$v[1]}?{$v[4]}{$v[2]}=\$1 [L,QSA,NC]"; } else { $rule = "RewriteRule ^{$rule}\$ {$v[1]}?{$v[4]} [L,QSA,NC]"; } if (strpos($file, "{$rule}\n") === false) { $line = "# {$v[3]}:\n{$rule}\n"; } } } else { if (strpos($file, "{$v[0]}\n") === false) { $line = "# {$v[2]}:\n{$v[0]}\n"; } } if ($line) { $lines[] = $line; $line = ''; } } // Special case: search.php workaround must be the first rewrite rule. $workaround = 'RewriteRule ^([^&]*)&(.*)$ ' . $mybb->settings['bburl'] . '/$1?$2 [L,QSA,R=301]'; $pos = strpos($file, "{$workaround}\n"); if ($rewrite && ($pos === false || $pos != strpos($file, "RewriteRule"))) { array_unshift($lines, "# {$lang->googleseo_plugin_htaccess_search}\n# {$lang->googleseo_plugin_htaccess_search_first}\n{$workaround}\n"); } $pos = strpos($file, "RewriteBase {$base}/\n"); if ($rewrite && ($pos === false || $pos > strpos($file, "RewriteRule"))) { array_unshift($lines, "# {$lang->googleseo_plugin_htaccess_rewritebase}\nRewriteBase {$base}/\n"); } if ($rewrite && strpos($file, "RewriteEngine on\n") === false) { array_unshift($lines, "RewriteEngine on\n"); } if (count($lines)) { $warning[] = $lang->googleseo_plugin_warn_htaccess . "<pre dir=\"ltr\" style=\"background-color: #ffffff; margin: 2px; padding: 2px;\">" . htmlspecialchars(implode($lines, "\n")) . "</pre>"; } // Special case: remove ErrorDocument if 404 is disabled if (!$settings['google_seo_404'] && strpos($file, "google_seo_error=404")) { $warning[] = $lang->googleseo_plugin_warn_errordocument; } } // Check if mbstring is available: if ($rewrite && !function_exists("mb_internal_encoding")) { $warning[] = $lang->googleseo_plugin_warn_mbstring; } // Check edits to core files. if (google_seo_plugin_apply() !== true) { if ($settings['google_seo_url']) { $warning[] = $lang->googleseo_plugin_warn_url_apply; if ($settings['google_seo_redirect']) { $warning[] = $lang->googleseo_plugin_warn_url_redirect; } } $apply = $PL->url_append('index.php', array('module' => 'config-plugins', 'google_seo' => 'apply', 'my_post_key' => $mybb->post_code)); $edits[] = "<a href=\"{$apply}\">{$lang->googleseo_plugin_edit_apply}</a>"; } if (google_seo_plugin_revert() !== true) { if (!$settings['google_seo_url']) { $warning[] = $lang->googleseo_plugin_warn_url_revert; } $revert = $PL->url_append('index.php', array('module' => 'config-plugins', 'google_seo' => 'revert', 'my_post_key' => $mybb->post_code)); $edits[] = "<a href=\"{$revert}\">{$lang->googleseo_plugin_edit_revert}</a>"; } // Configure URL $query = $db->simple_select("settinggroups", "gid", "name='google_seo'"); $gid = $db->fetch_field($query, 'gid'); if ($gid) { $configure = $PL->url_append('index.php', array('module' => 'config', 'action' => 'change', 'gid' => $gid)); $configure = $lang->sprintf($lang->googleseo_plugin_configure, $configure); } else { $warning[] = $lang->googleseo_plugin_warn_setting; } // Build a list with success, warnings, errors: if (count($error)) { $list = google_seo_plugin_list($error); if (count($error) > 1) { $e = $lang->sprintf($lang->googleseo_plugin_error_plural, $list); } else { $e = $lang->sprintf($lang->googleseo_plugin_error, $list); } $status .= " <li style=\"list-style-image: url(styles/default/images/icons/error.gif)\">" . $e . " {$configure}</li>\n"; } foreach ($warning as $w) { $status .= " <li style=\"list-style-image: url(styles/default/images/icons/warning.gif)\">" . $w . "</li>\n"; } if (count($success)) { $list = google_seo_plugin_list($success); if (count($success) > 1) { $s = $lang->sprintf($lang->googleseo_plugin_success_plural, $list); } else { $s = $lang->sprintf($lang->googleseo_plugin_success, $list); } $status .= " <li style=\"list-style-image: url(styles/default/images/icons/success.gif)\">" . $s . " {$configure}</li>\n"; } if (count($edits)) { $list = google_seo_plugin_list($edits); $e = $lang->sprintf($lang->googleseo_plugin_edit, $list); $status .= " <li style=\"list-style-image: url(styles/default/images/icons/custom.gif)\">" . $e . "</li>\n"; } $status = "\n<ul>\n{$status}</ul>\n"; // URL Database info: if ($urldb) { $status .= google_seo_plugin_database($urldb); } return $status; }
/** * 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(); } } } } }