/** * Get the entry for $type, $id from the cache. * * If $id is not yet in the cache, the $id will be queried from the DB. * To keep number of total DB queries low, all $ids that have been queued * up to here will be fetched in the same query as well. * */ function google_seo_url_cache($type, $id) { global $db, $settings; global $google_seo_url_cache, $google_seo_url_lazy; // If it's not in the cache, try loading the cache. if ($google_seo_url_cache[$type][$id] === NULL && $db->google_seo_query_limit > 0) { $google_seo_url_cache['dirty'] = 1; // Special case: Lazy Mode if ($google_seo_url_lazy !== false) { if ($google_seo_url_lazy === true) { // first time call global $plugins; $plugins->add_hook('pre_output_page', 'google_seo_url_lazy', 1000); ob_start('google_seo_url_lazy'); register_shutdown_function(create_function('', 'while(@ob_end_flush());')); $google_seo_url_lazy = array(); } // Create a temporary placeholder (but working) URL. $url = google_seo_expand($db->google_seo_url[$type]['lazy'], array('id' => $id)); // strtr is SO much faster if all strings have the exact same length // 64 is the longest lazy url assuming 10 digit ids $url = str_pad($url, 64, "+"); $google_seo_url_cache[$type][$id] = $url; $google_seo_url_lazy[$type][$id] = $url; return $url; } // Full Mode // Prepare database query. if ($settings["google_seo_url_lowercase"]) { $what = "LOWER(url) AS url,id,idtype"; } else { $what = "url,id,idtype"; } // Optimize by collecting more IDs for this query. $ids = google_seo_url_optimize($type, $id); $condition = array(); foreach ($ids as $key => $value) { if ($value) { $condition[] = "(idtype={$key} AND id IN (" . implode(",", array_map('intval', array_keys($value))) . "))"; } } $condition = implode(" OR ", $condition); // Run database query. $db->google_seo_query_limit--; $query = $db->query("SELECT {$what}\n FROM " . TABLE_PREFIX . "google_seo\n WHERE active=1\n AND ({$condition})"); // Process the query results. while ($row = $db->fetch_array($query)) { $rowid = (int) $row['id']; $rowtype = (int) $row['idtype']; $google_seo_url_cache[$rowtype][$rowid] = google_seo_url_finalize($row['url'], $db->google_seo_url[$rowtype]['scheme']); unset($ids[$rowtype][$rowid]); } // Create URLs for the remaining IDs. foreach ($ids as $key => $value) { unset($value[0]); if (count($value)) { google_seo_url_create($key, array_keys($value)); } } } // Return the cached entry for the originally requested type and id. return $google_seo_url_cache[$type][$id]; }
/** * Initialize a page variable */ function google_seo_meta_page($page) { global $settings, $lang; global $google_seo_page; if ($page > 1 && $settings['google_seo_meta_page']) { $google_seo_page = google_seo_expand($settings['google_seo_meta_page'], array('page' => $lang->googleseo_meta_page, 'number' => (int) $page)); } }
/** * Build the main Index sitemap. * * This index includes all pages for all types and is made * by calling google_seo_sitemap_gen for each type. * * The resulting list of items is handed off to google_seo_sitemap() * to produce the XML Sitemap output. * * @param string XML Sitemap URL scheme * @param int Page number (page 1 == custom, static items) * @param int Number of items that should appear per page. */ function google_seo_sitemap_index($scheme, $page, $pagination) { global $settings; if ($page) { // Additional pages. $locs = explode("\n", $settings['google_seo_sitemap_additional']); foreach ($locs as $loc) { $loc = trim($loc); if ($loc) { $items[] = array('loc' => htmlspecialchars($loc, ENT_QUOTES, "UTF-8")); } } google_seo_sitemap("url", $items); return; } $items = array(); foreach (array("forums", "threads", "users", "announcements", "calendars", "events") as $type) { $gen = google_seo_sitemap_gen($scheme, $type, $page, $pagination); if (sizeof($gen)) { $items = array_merge($items, $gen); } } if ($settings['google_seo_sitemap_additional']) { $url = google_seo_expand($scheme, array('url' => 'index')); $url .= (strpos($url, '?') === false ? '?' : '&') . 'page=1'; $items[] = array('loc' => $url); } google_seo_sitemap("sitemap", $items); }
/** * 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; }