Current Path : /proc/self/root/home/sudancam/.trash/google_seo/ |
Current File : //proc/self/root/home/sudancam/.trash/google_seo/url.php |
<?php /** * This file is part of Google SEO plugin for MyBB. * Copyright (C) 2008-2011 Andreas Klauer <Andreas.Klauer@metamorpher.de> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * */ // Disallow direct access to this file for security reasons if(!defined("IN_MYBB")) { die("Direct initialization of this file is not allowed.<br /><br /> Please make sure IN_MYBB is defined."); } /* --- Global Variables: --- */ global $db, $mybb, $settings, $plugins, $cache; // Required for database queries to the google_seo table. In theory this // could be used to coerce Google SEO into managing URLs of other types. // In practice there is no guarantee that this API will stay stable. $db->google_seo_url = array( GOOGLE_SEO_USER => array( 'table' => TABLE_PREFIX.'users', 'id' => 'uid', 'name' => 'username', 'scheme' => str_replace('&', '&', $settings['google_seo_url_users']), ), GOOGLE_SEO_ANNOUNCEMENT => array( 'table' => TABLE_PREFIX.'announcements', 'id' => 'aid', 'name' => 'subject', 'scheme' => str_replace('&', '&', $settings['google_seo_url_announcements']), ), GOOGLE_SEO_FORUM => array( 'table' => TABLE_PREFIX.'forums', 'id' => 'fid', 'name' => 'name', 'scheme' => str_replace('&', '&', $settings['google_seo_url_forums']), ), GOOGLE_SEO_THREAD => array( 'table' => TABLE_PREFIX.'threads', 'id' => 'tid', 'name' => 'subject', 'scheme' => str_replace('&', '&', $settings['google_seo_url_threads']), ), GOOGLE_SEO_EVENT => array( 'table' => TABLE_PREFIX.'events', 'id' => 'eid', 'name' => 'name', 'scheme' => str_replace('&', '&', $settings['google_seo_url_events']), ), GOOGLE_SEO_CALENDAR => array( 'table' => TABLE_PREFIX.'calendars', 'id' => 'cid', 'name' => 'name', 'scheme' => str_replace('&', '&', $settings['google_seo_url_calendars']), ), ); // Lazy Mode. global $google_seo_url_lazy; $google_seo_url_lazy = false; if($settings['google_seo_url_mode'] == 'lazy' && $mybb->request_method != 'post') { $google_seo_url_lazy = random_str(4); $db->google_seo_url[GOOGLE_SEO_ANNOUNCEMENT]['lazy'] = "announcements.php?aid={id}&google_seo={$google_seo_url_lazy}"; $db->google_seo_url[GOOGLE_SEO_CALENDAR]['lazy'] = "calendar.php?calendar={id}&google_seo={$google_seo_url_lazy}"; $db->google_seo_url[GOOGLE_SEO_EVENT]['lazy'] = "calendar.php?action=event&eid={id}&google_seo={$google_seo_url_lazy}"; $db->google_seo_url[GOOGLE_SEO_FORUM]['lazy'] = "forumdisplay.php?fid={id}&google_seo={$google_seo_url_lazy}"; $db->google_seo_url[GOOGLE_SEO_THREAD]['lazy'] = "showthread.php?tid={id}&google_seo={$google_seo_url_lazy}"; $db->google_seo_url[GOOGLE_SEO_USER]['lazy'] = "member.php?action=profile&uid={id}&google_seo={$google_seo_url_lazy}"; $google_seo_url_lazy = true; } // Thread Prefix if($settings['google_seo_url_threadprefix']) { $db->google_seo_url[GOOGLE_SEO_THREAD]['extra'] .= ',prefix'; } // Parents if($db->google_seo_url[GOOGLE_SEO_FORUM]['scheme']) { if($settings['google_seo_url_parent_announcement']) { $db->google_seo_url[GOOGLE_SEO_ANNOUNCEMENT]['extra'] .= ',fid AS parent'; $db->google_seo_url[GOOGLE_SEO_ANNOUNCEMENT]['parent'] = $settings['google_seo_url_parent_announcement']; $db->google_seo_url[GOOGLE_SEO_ANNOUNCEMENT]['parent_type'] = GOOGLE_SEO_FORUM; } if($settings['google_seo_url_parent_forum']) { $db->google_seo_url[GOOGLE_SEO_FORUM]['extra'] .= ',pid AS parent'; $db->google_seo_url[GOOGLE_SEO_FORUM]['parent'] = $settings['google_seo_url_parent_forum']; $db->google_seo_url[GOOGLE_SEO_FORUM]['parent_type'] = GOOGLE_SEO_FORUM; } if($settings['google_seo_url_parent_thread']) { $db->google_seo_url[GOOGLE_SEO_THREAD]['extra'] .= ',fid AS parent'; $db->google_seo_url[GOOGLE_SEO_THREAD]['parent'] = $settings['google_seo_url_parent_thread']; $db->google_seo_url[GOOGLE_SEO_THREAD]['parent_type'] = GOOGLE_SEO_FORUM; } } if($db->google_seo_url[GOOGLE_SEO_CALENDAR]['scheme'] && $settings['google_seo_url_parent_event']) { $db->google_seo_url[GOOGLE_SEO_EVENT]['extra'] .= ',cid AS parent'; $db->google_seo_url[GOOGLE_SEO_EVENT]['parent'] = $settings['google_seo_url_parent_event']; $db->google_seo_url[GOOGLE_SEO_EVENT]['parent_type'] = GOOGLE_SEO_CALENDAR; } // Query limit. Decreases by 1 for every query. $db->google_seo_query_limit = (int)$settings['google_seo_url_query_limit']; if($db->google_seo_query_limit <= 0) { $db->google_seo_query_limit = 32767; } // Cache global $google_seo_url_cache; if($settings['google_seo_url_cache']) { $data = $cache->read('google_seo_url'); if(is_array($data) && $data['time'] >= TIME_NOW) { $google_seo_url_cache = $data; } if(in_array(THIS_SCRIPT, explode(",", $settings['google_seo_url_cache']))) { $plugins->add_hook("post_output_page", "google_seo_url_cache_hook", 100); } } // There are several more global variables defined in functions below. /* --- Hooks: --- */ $plugins->add_hook("moderation_do_merge", "google_seo_url_merge_hook", 1); $plugins->add_hook("moderation_do_multimoveposts", "google_seo_url_merge_hook", 1); $plugins->add_hook("class_moderation_merge_threads", "google_seo_url_after_merge_hook"); // Originally a global_start hook, it's called too late for session location google_seo_url_hook(); /* --- URL processing: --- */ /** * Character translation for URLs (optional). * * @param string The input string * @return string The output string */ function google_seo_url_translation($str) { // Required for URL translation. global $settings; global $google_seo_url_translation; if(!is_array($google_seo_url_translation)) { // Build the translation array. $google_seo_translation = array(); $lines = explode("\n", $settings['google_seo_url_translation']); foreach($lines as $line) { $fields = explode('=', $line); if(count($fields) == 2) { $key = trim($fields[0]); if(strlen($key)) { $value = trim($fields[1]); $google_seo_url_translation[$key] = $value; } } } } if($google_seo_url_translation) { $str = strtr($str, $google_seo_url_translation); } return $str; } /** * Separate a string by punctuation for use in URLs. * * @param string The input string that may contain punctuation * @return string The string with punctuation replaced with separator */ function google_seo_url_separate($str) { global $settings; $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); // Cut off punctuation at beginning and end. $str = preg_replace("/^[$pattern]+|[$pattern]+$/u", "", $str); // Replace middle punctuation with one separator. $str = preg_replace("/[$pattern]+/u", $settings['google_seo_url_separator'], $str); } return $str; } /** * Truncate too long URLs. * * @param string The string to be truncated. * @param string The word separator. * @param int The soft limit. * @param int The hard limit. * @return string truncated string */ function google_seo_url_truncate($str) { global $settings; $separator = $settings['google_seo_url_separator']; $soft = $settings['google_seo_url_length_soft']; $hard = $settings['google_seo_url_length_hard']; // Cut off word past soft limit. if($soft && my_strlen($str) > $soft) { // Search the separator after the soft limit. $part = my_substr($str, $soft); $pos = my_strpos($part, $separator); if($pos === 0 || $pos > 0) { $str = my_substr($str, 0, $soft + $pos); } } // Truncate hard limit. if($hard && my_strlen($str) > $hard) { $str = my_substr($str, 0, $hard); } return $str; } /** * Uniquify URLs. * * @param string The URL that collided with something * @param int The ID of this item * @return string The uniquified URL */ function google_seo_url_uniquify($url, $id) { global $settings; $separator = $settings['google_seo_url_separator']; $str = $settings['google_seo_url_uniquifier']; $str = google_seo_expand($str, array('url' => $url, 'id' => $id, 'separator' => $separator)); return $str; } /** * 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; } /* --- URL Creation: --- */ /** * Create a unique URL in the database for a specific item type,id. * First fetch the title of the item from the MyBB database, * then process (translate, separate, truncate, uniquify) that title, * then check for existing entries in the Google SEO database, * finally insert it into the database if it's not already there. * * @param string Type of the item (forums, threads, etc.) * @param array IDs of the item (fid for forums, tid for threads, etc.) */ function google_seo_url_create($type, $ids) { global $db, $settings; global $google_seo_url_cache; $ids = array_map('intval', (array)$ids); foreach($ids as $id) { $google_seo_url_cache[$type][$id] = 0; } if($db->google_seo_query_limit <= 0) { return; } $data = $db->google_seo_url[$type]; // Is Google SEO URL enabled for this type? if($data['scheme']) { // Query the item title as base for our URL. $db->google_seo_query_limit--; $titles = $db->query("SELECT {$data['name']},{$data['id']}{$data['extra']} FROM {$data['table']} WHERE {$data['id']} IN (" .implode(",", $ids) .")"); while($row = $db->fetch_array($titles)) { $url = $row[$data['name']]; // MyBB unfortunately allows HTML in forum names. if($type == GOOGLE_SEO_FORUM) { $url = strip_tags($url); } // Thread Prefixes if($row['prefix']) { $prefix = build_prefixes($row['prefix']); if($prefix['prefix']) { $url = google_seo_expand( $settings['google_seo_url_threadprefix'], array('url' => $url, 'prefix' => $prefix['prefix'], 'separator' => $settings['google_seo_url_separator'])); } } $id = $row[$data['id']]; // Prepare the URL. if($settings['google_seo_url_translation']) { $url = google_seo_url_translation($url); } $url = google_seo_url_separate($url); $url = google_seo_url_truncate($url); $uniqueurl = google_seo_url_uniquify($url, $id); // Special case: for empty URLs we must use the unique variant if($url == "" || $settings['google_seo_url_uniquifier_force']) { $url = $uniqueurl; } // Parents if($row['parent']) { $parent_type = $db->google_seo_url[$type]['parent_type']; $parent_id = (int)$row['parent']; // TODO: Parents costs us an extra query. Cache? $db->google_seo_query_limit--; $query = $db->simple_select('google_seo', 'url AS parent', "active=1 AND idtype={$parent_type} AND id={$parent_id}"); $parent = $db->fetch_field($query, 'parent'); if($parent) { $url = google_seo_expand($db->google_seo_url[$type]['parent'], array('url' => $url, 'parent' => $parent)); $uniqueurl = google_seo_expand($db->google_seo_url[$type]['parent'], array('url' => $url, 'parent' => $parent)); } } // Check for existing entry and possible collisions. $db->google_seo_query_limit--; $query = $db->query("SELECT url,id FROM ".TABLE_PREFIX."google_seo WHERE active=1 AND idtype={$type} AND id<={$id} AND url IN ('" .$db->escape_string($url)."','" .$db->escape_string($uniqueurl)."') AND EXISTS(SELECT {$data['id']} FROM {$data['table']} WHERE {$data['id']}=id) ORDER BY id ASC"); $urlrow = $db->fetch_array($query); $uniquerow = $db->fetch_array($query); // Check if the entry was not up to date anyway. if($urlrow && $urlrow['id'] == $id && $urlrow['url'] == $url) { // It's up to date. Do nothing. } else if($uniquerow && $uniquerow['id'] == $id && $uniquerow['url'] == $uniqueurl) { // It's up to date for the unique URL. $url = $uniqueurl; } else { // Use unique URL if there was a row with a different id. if($urlrow && $urlrow['id'] != $id) { $url = $uniqueurl; } // Set old entries for us to not active. $db->google_seo_query_limit--; $db->write_query("UPDATE ".TABLE_PREFIX."google_seo SET active=NULL WHERE active=1 AND idtype={$type} AND id={$id}"); // Insert new entry (while possibly replacing old ones). $db->google_seo_query_limit--; $db->write_query("REPLACE INTO ".TABLE_PREFIX."google_seo VALUES (active,idtype,id,url), ('1','{$type}','{$id}','".$db->escape_string($url)."')"); } // Finalize URL. if($settings['google_seo_url_lowercase']) { $url = my_strtolower($url); } $url = google_seo_url_finalize($url, $data['scheme']); $google_seo_url_cache[$type][$id] = $url; } } } /* --- URL Cache: --- */ /** * Optimize queries by collecting as many IDs as possible before sending * a request off to a database. This is a dirty trick, a hack, black magic. * * This list of IDs is obtained by either accessing global data structures * of MyBB (possible when MyBB stores data in some sort of cache) or by * querying the IDs from the database (necessary when MyBB doesn't cache * the data by itself). * * The list of IDs obtained here is used later to fetch Google SEO URLs * in a single query, and create URLs for IDs that do not have an URL yet. * * @param string Type of the item that caused the query. * @param int ID of the item that caused the query. * @return array IDs (ID as index, value 0) to be merged into the cache. */ function google_seo_url_optimize($type, $id) { global $db, $mybb, $settings, $cache; global $google_seo_url_optimize, $google_seo_url_cache; switch(THIS_SCRIPT) { case 'index.php': // fcache global $fcache, $google_seo_fcache; if($fcache !== $google_seo_fcache) { $GLOBALS['google_seo_fcache'] =& $fcache; foreach($fcache as $a) { foreach($a as $b) { foreach($b as $c) { $google_seo_url_optimize[GOOGLE_SEO_FORUM][$c['fid']] = 0; $google_seo_url_optimize[GOOGLE_SEO_USER][$c['lastposteruid']] = 0; $google_seo_url_optimize[GOOGLE_SEO_THREAD][$c['lastposttid']] = 0; } } } } global $google_seo_index; if(!$google_seo_index) { $google_seo_index = true; // last user $stats = $cache->read("stats"); $google_seo_url_optimize[GOOGLE_SEO_USER][$stats['lastuid']] = 0; // who's online if($mybb->settings['showwol'] != 0 && $mybb->usergroup['canviewonline'] != 0) { $timesearch = TIME_NOW - $mybb->settings['wolcutoff']; $db->google_seo_query_limit--; $query = $db->query("SELECT uid FROM ".TABLE_PREFIX."sessions WHERE uid != '0' AND time > '$timesearch'"); while($user = $db->fetch_array($query)) { $google_seo_url_optimize[GOOGLE_SEO_USER][$user['uid']] = 0; } } } break; case 'portal.php': global $query, $google_seo_portal_query; // Hack: Let's hijack queries made by MyBB. Do not try this at home! if($query !== $google_seo_portal_query) { $GLOBALS['google_seo_portal_query'] &= $query; if($query) { $num_rows = $db->num_rows($query); } if($num_rows) { // Loop from current pointer to end of query. $i = 0; while($row = $db->fetch_array($query)) { $i++; $google_seo_url_optimize[GOOGLE_SEO_USER][$row['uid']] = 0; $google_seo_url_optimize[GOOGLE_SEO_USER][$row['lastposteruid']] = 0; $google_seo_url_optimize[GOOGLE_SEO_THREAD][$row['tid']] = 0; $google_seo_url_optimize[GOOGLE_SEO_FORUM][$row['fid']] = 0; $google_seo_url_optimize[GOOGLE_SEO_ANNOUNCEMENT][$row['aid']] = 0; } // Determine original pointer position. $pointer = $num_rows - $i; // Seek to beginning of query. $db->data_seek($query, 0); // Loop from beginning until we reach the original position. $i = 0; while($i < $pointer && $row = $db->fetch_array($query)) { $i++; $google_seo_url_optimize[GOOGLE_SEO_USER][$row['uid']] = 0; $google_seo_url_optimize[GOOGLE_SEO_USER][$row['lastposteruid']] = 0; $google_seo_url_optimize[GOOGLE_SEO_THREAD][$row['tid']] = 0; $google_seo_url_optimize[GOOGLE_SEO_FORUM][$row['fid']] = 0; $google_seo_url_optimize[GOOGLE_SEO_ANNOUNCEMENT][$row['aid']] = 0; } } } break; case 'forumdisplay.php': // forum_cache global $forum_cache, $google_seo_forum_cache; if($forum_cache !== $google_seo_forum_cache) { $GLOBALS['google_seo_forum_cache'] =& $forum_cache; foreach($forum_cache as $f) { $google_seo_url_optimize[GOOGLE_SEO_FORUM][$f['fid']] = 0; $google_seo_url_optimize[GOOGLE_SEO_USER][$f['lastposteruid']] = 0; } } // threadcache optimization (forumdisplay.php) global $threadcache, $google_seo_threadcache; if($threadcache !== $google_seo_threadcache) { $GLOBALS['google_seo_threadcache'] =& $threadcache; foreach($threadcache as $t) { $google_seo_url_optimize[GOOGLE_SEO_THREAD][$t['tid']] = 0; $google_seo_url_optimize[GOOGLE_SEO_FORUM][$t['fid']] = 0; $google_seo_url_optimize[GOOGLE_SEO_USER][$t['uid']] = 0; $google_seo_url_optimize[GOOGLE_SEO_USER][$t['lastposteruid']] = 0; } } break; case 'search.php': // thread_cache global $thread_cache, $google_seo_thread_cache; if($thread_cache !== $google_seo_thread_cache) { $GLOBALS['google_seo_thread_cache'] =& $thread_cache; foreach($thread_cache as $t) { $google_seo_url_optimize[GOOGLE_SEO_THREAD][$t['tid']] = 0; $google_seo_url_optimize[GOOGLE_SEO_FORUM][$t['fid']] = 0; $google_seo_url_optimize[GOOGLE_SEO_USER][$t['uid']] = 0; $google_seo_url_optimize[GOOGLE_SEO_USER][$t['lastposteruid']] = 0; } } break; case 'calendar.php': // events_cache global $events_cache, $google_seo_events_cache; if($events_cache !== $google_seo_events_cache) { $GLOBALS['google_seo_events_cache'] =& $events_cache; foreach($events_cache as $d) { foreach($d as $e) { $google_seo_url_optimize[GOOGLE_SEO_USER][$e['uid']] = 0; $google_seo_url_optimize[GOOGLE_SEO_EVENT][$e['eid']] = 0; $google_seo_url_optimize[GOOGLE_SEO_CALENDAR][$e['cid']] = 0; } } } break; case 'online.php': if($settings['google_seo_url_wol']) { global $uid_list, $aid_list, $eid_list, $fid_list, $tid_list; // uid_list if(count($uid_list) && $uid_list !== $google_seo_uid_list) { $GLOBALS['google_seo_uid_list'] =& $uid_list; foreach($uid_list as $uid) { $google_seo_url_optimize[GOOGLE_SEO_USER][$uid] = 0; } } // aid_list if(count($aid_list) && $aid_list !== $google_seo_aid_list) { $GLOBALS['google_seo_aid_list'] =& $aid_list; foreach($aid_list as $aid) { $google_seo_url_optimize[GOOGLE_SEO_ANNOUNCEMENT][$aid] = 0; } } // eid_list if(count($eid_list) && $eid_list !== $google_seo_eid_list) { $GLOBALS['google_seo_eid_list'] =& $eid_list; foreach($eid_list as $eid) { $google_seo_url_optimize[GOOGLE_SEO_EVENT][$eid] = 0; } } // fid_list if(count($fid_list) && $fid_list !== $google_seo_fid_list) { $GLOBALS['google_seo_fid_list'] =& $fid_list; foreach($fid_list as $fid) { $google_seo_url_optimize[GOOGLE_SEO_FORUM][$fid] = 0; } } // tid_list if(count($tid_list) && $tid_list !== $google_seo_tid_list) { $GLOBALS['google_seo_tid_list'] =& $tid_list; foreach($tid_list as $tid) { $google_seo_url_optimize[GOOGLE_SEO_THREAD][$tid] = 0; } } } break; } // Include the ID that was originally requested. $google_seo_url_optimize[$type][$id] = 0; // Clean up foreach($google_seo_url_optimize as $key => $value) { if(!$db->google_seo_url[$key]['scheme']) { unset($google_seo_url_optimize[$key]); } unset($google_seo_url_optimize[$key][0]); unset($google_seo_url_optimize[$key]['']); } // return the collected IDs $result = $google_seo_url_optimize; $google_seo_url_optimize = array(); return $result; } /** * 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 FROM ".TABLE_PREFIX."google_seo WHERE active=1 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]; } /* * Lazy Mode */ function google_seo_url_lazy($message) { global $plugins; global $google_seo_url_lazy, $google_seo_url_optimize, $google_seo_url_cache; if(!$google_seo_url_lazy) { // Do nothing. return $message; } $lazy = $google_seo_url_lazy; $google_seo_url_lazy = false; // We've been lazy and now we have to pay the price. // Prepare cache and optimize. foreach($lazy as $key => $value) { // substract lazy from cache so it will redo these URLs $google_seo_url_cache[$key] = array_diff_key((array)$google_seo_url_cache[$key], (array)$lazy[$key]); // add lazy to optimize so it will use a single query when redoing them $google_seo_url_optimize[$key] = (array)$google_seo_url_optimize[$key] + (array)$lazy[$key]; } // Make it load the URLs. reset($lazy); $type = key($lazy); reset($lazy[$type]); $id = key($lazy[$type]); google_seo_url_cache($type, $id); // Build the replacement foo. $strtr = array(); foreach($lazy as $type => $list) { foreach($list as $id => $url) { $seourl = $google_seo_url_cache[$type][$id]; if($seourl) { $strtr[$url] = $seourl; } } } // This is the most expensive bit. $message = strtr($message, $strtr); return $message; } /* * Populate MyBB's Cache */ function google_seo_url_cache_hook() { global $settings, $cache; global $google_seo_url_cache; // Do we need to update the cache? if($google_seo_url_cache['dirty']) { unset($google_seo_url_cache['dirty']); // New cache? if(!$google_seo_url_cache['time']) { $delta = (int)$settings['google_seo_url_cache']; if(!$delta) { // Default: 15 Minutes $delta = 15; } $google_seo_url_cache['time'] = TIME_NOW + $delta * 60; } $cache->update('google_seo_url', $google_seo_url_cache); } } /* --- URL Lookup: --- */ /** * Convert a given URL to ID. * * @param string Type of the item * @param string Given URL of the item * @return int ID of the requested item if found. */ function google_seo_url_id($type, $url) { global $db, $settings; $db->google_seo_query_limit--; $query = $db->query("SELECT id FROM ".TABLE_PREFIX."google_seo WHERE idtype={$type} AND url='".$db->escape_string($url)."'"); $id = $db->fetch_field($query, "id"); if(!$id) { // Fallback for wrong punctuation, character translation: $urls[0] = $db->escape_string(google_seo_url_separate($url)); if($settings['google_seo_url_translation']) { $urls[1] = $db->escape_string(google_seo_url_translation($url)); $urls[2] = $db->escape_string(google_seo_url_separate($urls[1])); } $db->google_seo_query_limit--; $query = $db->query("SELECT id FROM ".TABLE_PREFIX."google_seo WHERE idtype={$type} AND url IN ('".implode("','", $urls)."') ORDER BY id ASC LIMIT 1"); $id = $db->fetch_field($query, "id"); } if($id) { return $id; } return 0; } /* * Dynamic URLs, e.g. showthread.php?Subject-Here * */ function google_seo_url_dynamic($url='') { if(!strlen((string)$url)) { $url = google_seo_dynamic($_SERVER['REQUEST_URI']); } return $url; } /** * Google SEO URL hook. * * Converts requested Google SEO URLs back to the ID number parameters * which are required and expected by stock MyBB to find the correct * forum / thread / etc. to display. * * This is also the point where Google SEO updates the URLs in case * the requested item changed its name since the last update. */ function google_seo_url_hook() { global $db, $mybb, $settings; // Translate URL name to ID and verify. switch(THIS_SCRIPT) { case 'forumdisplay.php': // Translation. $url = google_seo_url_dynamic($mybb->input['google_seo_forum']); if(strlen($url) && !array_key_exists('fid', $mybb->input)) { $fid = google_seo_url_id(GOOGLE_SEO_FORUM, $url); $mybb->input['fid'] = $fid; $location = get_current_location(); $location = str_replace("google_seo_forum={$url}", "fid={$fid}", $location); } // Verification. $fid = (int)$mybb->input['fid']; if($fid) { google_seo_url_create(GOOGLE_SEO_FORUM, $fid); } break; case 'showthread.php': // Translation. $url = google_seo_url_dynamic($mybb->input['google_seo_thread']); if(strlen($url) && !array_key_exists('tid', $mybb->input)) { $tid = google_seo_url_id(GOOGLE_SEO_THREAD, $url); $mybb->input['tid'] = $tid; $location = get_current_location(); $location = str_replace("google_seo_thread={$url}", "tid={$tid}", $location); } // Verification. $tid = (int)$mybb->input['tid']; if($tid) { google_seo_url_create(GOOGLE_SEO_THREAD, $tid); } $pid = $mybb->input['pid']; break; case 'announcements.php': // Translation. $url = google_seo_url_dynamic($mybb->input['google_seo_announcement']); if(strlen($url) && !array_key_exists('aid', $mybb->input)) { $aid = google_seo_url_id(GOOGLE_SEO_ANNOUNCEMENT, $url); $mybb->input['aid'] = $aid; $location = get_current_location(); $location = str_replace("google_seo_announcement={$url}", "aid={$aid}", $location); } // Verification. $aid = (int)$mybb->input['aid']; if($aid) { google_seo_url_create(GOOGLE_SEO_ANNOUNCEMENT, $aid); } break; case 'member.php': // Translation. $url = google_seo_url_dynamic($mybb->input['google_seo_user']); if(strlen($url) && !array_key_exists('uid', $mybb->input)) { $uid = google_seo_url_id(GOOGLE_SEO_USER, $url); $mybb->input['uid'] = $uid; $location = get_current_location(); $location = str_replace("google_seo_user={$url}", "uid={$uid}", $location); } // Verification. $uid = (int)$mybb->input['uid']; if($uid && $mybb->input['action'] == 'profile') { google_seo_url_create(GOOGLE_SEO_USER, $uid); } break; case 'calendar.php': // Translation. // Event. $url = google_seo_url_dynamic($mybb->input['google_seo_event']); if(strlen($url) && !array_key_exists('eid', $mybb->input)) { $eid = google_seo_url_id(GOOGLE_SEO_EVENT, $url); $mybb->input['eid'] = $eid; $location = get_current_location(); $location = str_replace("google_seo_event={$url}", "eid={$eid}", $location); } // Verification. $eid = (int)$mybb->input['eid']; if($eid) { google_seo_url_create(GOOGLE_SEO_EVENT, $eid); } else { // Calendar. $url = google_seo_url_dynamic($mybb->input['google_seo_calendar']); if(strlen($url) && !array_key_exists('calendar', $mybb->input)) { $cid = google_seo_url_id(GOOGLE_SEO_CALENDAR, $url); // Hack to cause invalid calendar message to appear: // If cid is not set, the default calendar would be shown. // However in this case it means an invalid URL was given. if(!$cid) { $cid = -1; } $mybb->input['calendar'] = $cid; $location = get_current_location(); $location = str_replace("google_seo_calendar={$cid}", "calendar={$cid}", $location); } // Verification. $cid = (int)$mybb->input['calendar']; if($cid) { google_seo_url_create(GOOGLE_SEO_CALENDAR, $cid); } } break; } if($location) { $location = substr($location, 0, 150); global $google_seo_location; $google_seo_location = $location; } } /** * Google SEO Merge hook. * * Unfortunately MyBB asks for a thread URL when merging threads. * We have to translate Google SEO URLs back to showthread.php?tid=x URLs. */ function google_seo_url_merge_hook() { global $mybb; // Build regexp to match URL. $regexp = "{$mybb->settings['bburl']}/{$mybb->settings['google_seo_url_threads']}"; if($regexp) { $regexp = preg_quote($regexp, '#'); $regexp = str_replace('\\{\\$url\\}', '([^./]+)', $regexp); $regexp = str_replace('\\{url\\}', '([^./]+)', $regexp); $regexp = "#^{$regexp}$#u"; } // Fetch the (presumably) Google SEO URL: $url = $mybb->input['threadurl']; // $url can be either 'http://host/Thread-foobar' or just 'foobar'. // Kill anchors and parameters. $url = preg_replace('/^([^#?]*)[#?].*$/u', '\\1', $url); // Extract the name part of the URL. $url = preg_replace($regexp, '\\1', $url); // Unquote the URL. $url = urldecode($url); // If $url was 'http://host/Thread-foobar', it is just 'foobar' now. // Look up the ID for this item. $tid = google_seo_url_id(GOOGLE_SEO_THREAD, $url); // If we have an ID, produce an URL suitable for merge. if($tid) { $mybb->input['threadurl'] = "{$mybb->settings['bburl']}/showthread.php?tid={$tid}"; } } /** * * Google SEO After Merge hook. * * When two threads are merged, one of them is actually deleted. * As a result, all URLs pointing to the old thread would be lost. * * However if we merge the URL entries in the google_seo table as well, * Google SEO Redirect can redirect URLs of the old thread to the new thread. * */ function google_seo_url_after_merge_hook($arguments) { global $db; $mergetid = (int)$arguments['mergetid']; $tid = (int)$arguments['tid']; // Integrate mergetid into tid: $type = GOOGLE_SEO_THREAD; $db->google_seo_query_limit--; $db->write_query("UPDATE ".TABLE_PREFIX."google_seo SET active=NULL, id={$tid} WHERE idtype={$type} AND id={$mergetid}"); } /* --- URL API: --- */ /** * Replacement for get_profile_link() * * @param int ID of the linked user profile. * @return string User profile URL. */ function google_seo_url_profile($uid=0) { global $settings; if($settings['google_seo_url_users'] && $uid > 0) { return google_seo_url_cache(GOOGLE_SEO_USER, $uid); } } /** * Replacement for get_announcement_link() * * @param int ID of the linked announcement. * @return string Announcement URL. */ function google_seo_url_announcement($aid=0) { global $settings; if($settings['google_seo_url_announcements'] && $aid > 0) { return google_seo_url_cache(GOOGLE_SEO_ANNOUNCEMENT, $aid); } } /** * Replacement for get_forum_link() * * @param int ID of the linked forum. * @param int Optional page number. * @return string Forum URL. */ function google_seo_url_forum($fid, $page=0) { global $settings; if($settings['google_seo_url_forums'] && $fid > 0) { $url = google_seo_url_cache(GOOGLE_SEO_FORUM, $fid); if($url && $page && $page != 1) { // forum as index tweak if($fid == $settings['google_seo_tweak_index_fid']) { $url = ""; // only works for ?page due to href="" } $glue = (strpos($url, '?') === false ? '?' : '&'); $url .= "{$glue}page={$page}"; } return $url; } } /** * Replacement for get_thread_link() * * @param int ID of the linked thread. * @param int Optional page number. * @param string Optional action. * @return string Thread URL. */ function google_seo_url_thread($tid, $page=0, $action='') { global $settings; if($settings['google_seo_url_threads'] && $tid > 0) { $url = google_seo_url_cache(GOOGLE_SEO_THREAD, $tid); if($url) { $glue = (strpos($url, '?') === false ? '?' : '&'); if($page && $page != 1 && $action) { $url .= "{$glue}page={$page}&action={$action}"; } else if($page && $page != 1) { $url .= "{$glue}page={$page}"; } else if($action) { $url .= "{$glue}action={$action}"; } return $url; } } } /** * Replacement for get_post_link() * * @param int ID of the linked posting. * @param int Optional thread ID if known (has to be looked up otherwise). * @return string Post URL. */ function google_seo_url_post($pid, $tid=0) { global $db, $settings; global $google_seo_url_tid; if($settings['google_seo_url_threads'] && $pid > 0) { $tid = google_seo_tid($pid, $tid, $settings['google_seo_url_posts'], $db->google_seo_query_limit); if($tid > 0) { $url = google_seo_url_cache(GOOGLE_SEO_THREAD, $tid); if($url) { $glue = (strpos($url, '?') === false ? '?' : '&'); $url .= "{$glue}pid={$pid}"; return $url; } } } } /** * Replacement for get_event_link() * * @param int ID of the linked event. * @return string Event URL. */ function google_seo_url_event($eid) { global $settings; if($settings['google_seo_url_events'] && $eid > 0) { return google_seo_url_cache(GOOGLE_SEO_EVENT, $eid); } } /** * Replacement for get_calendar_link() * * @param int ID of the linked calendar. * @param int Optional year. * @param int Optional month. * @param int Optional day. * @return string Calendar URL. */ function google_seo_url_calendar($cid, $year=0, $month=0, $day=0) { global $settings; if($settings['google_seo_url_calendars'] && $cid > 0) { $url = google_seo_url_cache(GOOGLE_SEO_CALENDAR, $cid); if($url && $year) { $glue = (strpos($url, '?') === false ? '?' : '&'); $url .= "{$glue}year={$year}"; if($month) { $url .= "&month=$month"; if($day) { $url .= "&day=$day&action=dayview"; } } } return $url; } } /** * Replacement for get_calendar_week_link() * * @param int ID of the linked calendar. * @param int Week. * @return string Calendar Week URL. */ function google_seo_url_calendar_week($cid, $week) { global $settings; if($settings['google_seo_url_calendars'] && $cid > 0) { $url = google_seo_url_cache(GOOGLE_SEO_CALENDAR, $cid); if($url) { $week = str_replace('-', 'n', $week); $glue = (strpos($url, '?') === false ? '?' : '&'); $url .= "{$glue}action=weekview&week={$week}"; return $url; } } } /** * Replacement for multipage links * * @param string base URL of the multipage * @return string new base URL of the multipage */ function google_seo_url_multipage($url) { switch(THIS_SCRIPT) { case 'forumdisplay.php': // Initialize variables for forumdisplay. global $fid; $id = $fid; $urlcheck = FORUM_URL_PAGED; $idname = "fid"; $type = "forum"; break; case 'showthread.php': // Initialize variables for showthread. global $tid; $id = $tid; $urlcheck = THREAD_URL_PAGED; $idname = "tid"; $type = "thread"; break; } // The actual code that builds the new multipage URL: if($id) { $getlink = "get_{$type}_link"; $getlink_googleseo = "google_seo_url_{$type}"; // replace {idname} with the id to get the default URL $urlcheck = str_replace("{{$idname}}", $id, $urlcheck); // see if we have a default multipage URL here if($url == $urlcheck || strpos($url, $urlcheck.'?') === 0 || strpos($url, $urlcheck.'&') === 0) { // Check that the Google SEO URLs are being used. $seourl = $getlink_googleseo($id, "{page}"); if($seourl == $getlink($id, "{page}")) { // Replace it with the Google SEO URL $newurl = $seourl; // Append extra parameters. $extra = substr($url, strlen($urlcheck)); if($extra) { $newurl .= $extra; } } } } return $newurl; } /* --- End of file. --- */ ?>