OSDN Git Service

FIX: NP_ThumbnailをNucleus 3.65/PHP5.4/MySQL5.5で動作するよう修正
[nucleus-jp/nucleus-plugins.git] / trunk / NP_Related / NP_Related.php
1 <?php
2
3 /*
4         NP_Related developed by Sir_Psycho (http://www.fuckhedz.com/)
5                    Ver0.25.1 by radek (http://hulan.info/)
6                    Ver0.4    by yu (http://nucleus.datoka.jp/)
7         
8         USAGE
9         -----
10         Template:
11                 <%Related(mode,max,snippet,searchcond)%>
12         Skin:
13                 <%Related(mode,max,snippet,,searchcond)%> ... in item/search page
14                 <%Related(mode,max,snippet,query,searchcond)%>
15         
16                 mode               ... local / google
17                 max[option]        ... max amount.  default:5
18                 snippet[option]    ... true / false.  default:false
19                 query[option]      ... search keyword.  (if in item/search page, it's filled automatically)
20                 searchcond[option] ... and / or.  default:or
21         
22         EXAMPLE
23         -------
24         In item template or item skintype:
25         (search skintype is also available)
26         <%Related(local,5)%>
27         <%Related(google,5,true)%>
28         
29         In other skintype:
30         <%Related(local,5,true,queryword,and)%>
31         
32         
33         HISTORY
34         -------
35         Ver0.4 2007/02/27:
36         [Chg] remove Amazon mode
37         [Chg] change to use Ajax Search API instead of Soap Search API (google)
38         
39         Ver0.32 2006/09/17:
40         [Fix] remove tags from url, title, snippet (google)
41         [Chg] change name of function soapclient() to soaplient_old() in nusoap.php (for PHP5 reason).
42         
43         Ver0.31 2005/10/16:
44         [Add] option "erase cache data now", "show snippet", "no header", "search range".
45         [Chg] delete inline style "font-size:smaller" for snippets.
46         [Chg] cancel keyword manupilation for google search.
47         [Chg] include multiple keywords on Amazon search.
48         [Fix] in google search, invalid max results is set when max results is larger than 5.
49         [Fix] version expression in delete style.
50         [Fix] 'DONOTSEARCH' output.
51         [Fix] encoding keyword for google search - by nakahara21 (http://nakahara21.com/) 
52         [Fix] set input encoding to google "more link" - by mao (http://kirsche.mods.jp/catid/6)
53         [Fix] convert encoding for Amazon search - by sakuracandle (http://juntwo.s57.xrea.com/)
54         [Fix] remove tags from snippet in title attribute - by pushman (http://blog.heartfield-web.com/)
55
56         Ver0.3jp 2004/11/23:
57         [Add] Amazon search in books-jp mode.
58         [Add] support FancyURLs - by mao (http://kirsche.mods.jp/catid/6)
59         [Fix] loop bug when "()" is used in keyword.
60         [Fix] debug code remained.
61
62         Main updates before Ver0.3jp ...
63         - SkinVar. This plugin can be used in both skin and template.
64         - Multi-keyword search.
65         - Pharase search (phrase = quoted words).
66         - Snippet for local search.
67         
68 */
69
70
71 // plugin needs to work on Nucleus versions <=2.0 as well
72 if (!function_exists('sql_table')){
73         function sql_table($name) {
74                 return 'nucleus_' . $name;
75         }
76 }
77
78 class NP_Related extends NucleusPlugin {
79         
80         // name of plugin
81         function getName() {
82                 return 'Related items/sites'; 
83         }
84         
85         // author of plugin
86         function getAuthor()  { 
87                 return 'Tim Broddin + radek + yu'; 
88         }
89         
90         // version of the plugin
91         function getVersion() { return '0.4'; }
92         function getMinNucleusVersion() { return '250'; }
93         
94         // an URL to the plugin website
95         // can also be of the form mailto:foo@bar.com
96         function getURL() {
97                 return 'http://japan.nucleuscms.org/wiki/plugins:related'; 
98         }
99         
100         function supportsFeature($what) {
101                 switch($what){
102                         case 'SqlTablePrefix':
103                                 return 1;
104                         default:
105                                 return 0;
106                 }
107         }
108         
109         function getTableList() {
110                 return array( sql_table('plug_related'), sql_table('plug_related_cache') );
111         }
112         
113         function getEventList() { 
114                 return array('PostAddItem','PreUpdateItem','AddItemFormExtras','EditItemFormExtras','PostPluginOptionsUpdate'); 
115         }
116         
117         // Let's get started
118         function init() {
119                 global $manager, $blog, $CONF;
120                 
121                 // include language file for this plugin
122                 $language = ereg_replace( '[\\|/]', '', getLanguageName());
123                 if (file_exists($this->getDirectory().$language.'.php'))
124                         include_once($this->getDirectory().$language.'.php');
125                 else
126                         include_once($this->getDirectory().'english.php');
127                 
128                 if ($blog) $b =& $blog; 
129                 else $b =& $manager->getBlog($CONF['DefaultBlog']);
130                 $bid = $b->getID();
131                 
132                 if ($this->getBlogOption($bid, "googlekey") != '') $this->google_key = $this->getBlogOption($bid, "googlekey");
133                 else $this->google_key = $this->getOption("googlekey");
134                 $this->toexclude = $this->getOption("toexclude");
135 //              $this->amazontoken = $this->getOption("amazontoken");
136 //              $this->aso_id = $this->getOption("aso_id");
137
138                 $this->header_lc = $this->getOption("header_lc");
139                 $this->header_go = $this->getOption("header_go");
140 //              $this->header_am = $this->getOption("header_am");
141                 $this->header_end = $this->getOption("header_end");
142                 
143                 $this->list_header = $this->getOption("listheading");
144                 $this->list_footer = $this->getOption("listfooter");
145                 $this->item_header = $this->getOption("itemheading");
146                 $this->item_footer = $this->getOption("itemfooter");
147
148                 $this->notitle = $this->getOption("notitle");
149                 $this->noresults = $this->getOption("noresults");
150                 $this->flg_noheader = $this->getOption("flg_noheader");
151                 $this->morelink = $this->getOption("morelink");
152                 $this->maxlength = $this->getOption("maxlength");
153                 $this->maxlength2 = $this->getOption("maxlength2");
154                 $this->flg_snippet = $this->getOption('flg_snippet');
155                 $this->flg_timelocal = $this->getOption('flg_timelocal');
156                 $this->currentblog = $this->getOption("currentblog");
157                 $this->searchrange = $this->getOption("searchrange");
158                 $this->flg_srchcond_and = $this->getOption("flg_srchcond_and");
159                 
160 //              $this->interval = $this->getOption("interval");
161                 $this->_check_cache_size();
162         }
163         
164         // a description to be shown on the installed plugins listing
165         function getDescription() { 
166                 return _RELATED_MESSAGE_DESC;
167         }
168         
169         // Installation
170         function install() {
171                 $this->createOption("googlekey", _RELATED_OPTION_GOOGLEKEY, "text", "");
172                 $this->createBlogOption("googlekey", _RELATED_OPTION_GOOGLEKEY, "text", "");
173                 $this->createOption("toexclude", _RELATED_OPTION_TOEXCLUDE, "text", "yourdomain.com");
174 //              $this->createOption("amazontoken", _RELATED_OPTION_AMAZONTOKEN, "text", "");
175 //              $this->createOption("aso_id", _RELATED_OPTION_ASO_ID, "text", "");
176
177                 $this->createOption("header_lc", _RELATED_OPTION_HEADER_LC, "text", "<h3>Local search for: <em>");
178                 $this->createOption("header_go", _RELATED_OPTION_HEADER_GO, "text", "<h3>Google search for: <em>");
179 //              $this->createOption("header_am", _RELATED_OPTION_HEADER_AM, "text", "<h3>Amazon search for: <em>");
180                 $this->createOption("header_end",  _RELATED_OPTION_HEADER_END, "text", "</em></h3>");
181                 $this->createOption("listheading", _RELATED_OPTION_LISTHEADING, "text", "<ul class='related'>\n");
182                 $this->createOption("listfooter",  _RELATED_OPTION_LISTFOOTER, "text", "</ul>\n");              
183                 $this->createOption("itemheading", _RELATED_OPTION_ITEMHEADING, "text", "<li>\n");
184                 $this->createOption("itemfooter",  _RELATED_OPTION_ITEMFOOTER, "text", "</li>\n");
185
186                 $this->createOption("notitle",   _RELATED_OPTION_NOTITLE, "text", "(no title)");
187                 $this->createOption("noresults", _RELATED_OPTION_NORESULTS, "text", "<p>No related items.</p>");
188                 $this->createOption("flg_noheader", _RELATED_OPTION_FLG_NOHEADER, "yesno", "no");
189                 $this->createOption("morelink",  _RELATED_OPTION_MORELINK, "text", "and more...");
190                 $this->createOption("maxlength", _RELATED_OPTION_MAXLENGTH, "text", "60");
191                 $this->createOption("maxlength2", _RELATED_OPTION_MAXLENGTH2, "text", "220");
192                 $this->createOption("flg_snippet", _RELATED_OPTION_FLG_SNIPPET, "yesno", "yes");
193                 $this->createOption("flg_timelocal", _RELATED_OPTION_FLG_TIMELOCAL, "yesno", "no");
194                 $this->createOption("currentblog", _RELATED_OPTION_CURRENTBLOG, "yesno", "yes");
195                 $this->createOption('searchrange', _RELATED_OPTION_SEARCHRANGE, 'select', 'type2', 
196                         'Title|type1|Title, Body|type2|Title, Body, More|type3');
197                 $this->createOption("flg_srchcond_and", _RELATED_OPTION_FLG_SRCHCOND_AND, "yesno", "no");
198
199 //              $this->createOption("interval",  _RELATED_OPTION_INTERVAL, "text", "96");
200 //              $this->createOption("language", _RELATED_OPTION_LANGUAGE, "text", "lang_ja|lang_en");
201                 $this->createOption("flg_cache_erase", _RELATED_OPTION_FLG_CACHE_ERASE, "yesno", "no");
202                 $this->createOption("flg_erase", _RELATED_OPTION_FLG_ERASE, "yesno", "no");
203
204                 mysql_query("CREATE TABLE IF NOT EXISTS ". sql_table("plug_related") 
205                         ." ( 
206                         itemid INT(9) NOT NULL, 
207                         localkey VARCHAR(255) NOT NULL DEFAULT '', 
208                         googlekey VARCHAR(255) NOT NULL DEFAULT '', 
209                         amazonkey VARCHAR(255) NOT NULL DEFAULT '', 
210                         mode VARCHAR(100) NOT NULL DEFAULT '', 
211                         PRIMARY KEY (itemid)
212                         )");
213                 mysql_query("CREATE TABLE IF NOT EXISTS ". sql_table("plug_related_cache") 
214                         ." ( 
215                         id INT(9) NOT NULL AUTO_INCREMENT PRIMARY KEY, 
216                         type VARCHAR(255) NOT NULL, 
217                         keyword VARCHAR(255) NOT NULL, 
218                         rank INT(9) NOT NULL, 
219                         url VARCHAR(255) NOT NULL, 
220                         title VARCHAR(255) NOT NULL, 
221                         stamp VARCHAR(14) NOT NULL, 
222                         snippet VARCHAR(255) 
223                         )");
224         }
225         
226         function uninstall() {
227                 if ($this->getOption('flg_erase') == 'yes') {
228                         mysql_query ( "DROP table IF EXISTS ". sql_table("plug_related") );
229                         mysql_query ( "DROP table IF EXISTS ". sql_table("plug_related_cache") );
230                 }
231         }
232
233         function event_PostPluginOptionsUpdate($data) {
234                 if ($this->getOption('flg_cache_erase') == 'yes') {
235                         sql_query("TRUNCATE TABLE ". sql_table("plug_related_cache"));
236                         $this->setOption('flg_cache_erase', 'no');
237                         return;
238                 }
239         }
240
241         //Add options to add item form/bookmarklet
242         function event_AddItemFormExtras($data) {
243                 ?>
244                         <h3>Related Keyword</h3>
245                         <p>
246                                 <label for="related_local">Local keyword(s):</label>
247                                 <input type="text" value="" id="related_local" name="local_keyword" size="60" />
248                         </p>
249                         <p>
250                                 <label for="related_google">Google keyword(s):</label>
251                                 <input type="text" value="" id="related_google" name="google_keyword" size="60" />
252                         </p>
253                 <?php
254         }
255         
256         //Add options to edit item form/bookmarklet
257         function event_EditItemFormExtras($data) {
258                         $id = $data['variables']['itemid'];
259                         $result = mysql_query("SELECT itemid, localkey, googlekey, amazonkey, mode FROM ". sql_table("plug_related"). " WHERE itemid='$id'");
260                         if (@mysql_num_rows($result) > 0) {
261                                 $localkey  = mysql_result($result,0,"localkey");
262                                 $googlekey = mysql_result($result,0,"googlekey");
263                         }
264                 ?>
265                         <h3>Related Keyword</h3>
266                         <p>
267                                 <label for="related_local">Local keyword(s):</label>
268                                 <input type="text" value="<?php echo htmlspecialchars($localkey) ?>" id="related_local" name="local_keyword" size="60" />
269                         </p>
270                         <p>
271                                 <label for="related_google">Google keyword(s):</label>
272                                 <input type="text" value="<?php echo htmlspecialchars($googlekey) ?>" id="related_google" name="google_keyword" size="60" />
273                         </p>
274                 <?php
275         }
276         
277         //PostAddItem Event
278         function event_PostAddItem($data) {
279                 $local  = requestVar('local_keyword');
280                 $google = requestVar('google_keyword');
281                 $amazon = requestVar('amazon_keyword');
282                 
283                 // Nothing to do? Get out!!
284                 if ((!$local) && (!$google) && (!$amazon)) return;
285                 
286                 $itemid = $data['itemid'];
287                 
288                 $local  = mysql_escape_string($local);
289                 $google = mysql_escape_string($google);
290                 $amazon = mysql_escape_string($amazon);
291                 
292                 mysql_query("INSERT INTO ". sql_table("plug_related") ." VALUES ('$itemid','$local','$google','$amazon','')");
293         }
294         
295         //PreUpdateItem Event
296         function event_PreUpdateItem($data) {
297                 $local  = requestVar('local_keyword');
298                 $google = requestVar('google_keyword');
299                 $amazon = requestVar('amazon_keyword');
300                 
301                 $itemid = $data['itemid'];
302                 
303                 $local  = mysql_escape_string($local);
304                 $google = mysql_escape_string($google);
305                 $amazon = mysql_escape_string($amazon);
306                 
307                 $result = mysql_query("SELECT * FROM ". sql_table("plug_related") ." WHERE itemid='$itemid'");
308                 
309                 if (@mysql_num_rows($result) > 0) {
310                         // Nothing to do? Delete it!!
311                         if ((!$local) && (!$google) && (!$amazon)) {
312                                 mysql_query("DELETE FROM ". sql_table("plug_related") ." WHERE itemid='$itemid'");
313                                 return;
314                         }
315                         
316                         mysql_query("UPDATE ". sql_table("plug_related") ." SET localkey='$local',googlekey='$google',amazonkey='$amazon' WHERE itemid='$itemid'");
317                         
318                 } else {
319                         // Nothing to do? Get out!!
320                         if ((!$local) && (!$google) && (!$amazon)) return;
321                         mysql_query("INSERT INTO ". sql_table("plug_related") ." VALUES ('$itemid','$local','$google','$amazon','')");
322                 }               
323         }
324         
325         // Skinvar Wrapper
326         function doSkinVar($skinType, $mode='local', $max='5', $showsnippet='', $skinquery='', $searchcond='') {
327                 global $manager, $itemid;
328                 
329                 if ($skinType == 'item') {
330                         $item =& $manager->getItem($itemid,0,0);
331                 }
332                 else if ($skinquery != '') {
333                         $item = array(
334                                         'itemid' => 0, //dummy
335                                         'title' => $skinquery,
336                                 );
337                 }
338                 else if ($skinType == 'search') {
339                         $item = array(
340                                         'itemid' => 0, //dummy
341                                         'title' => requestVar('query'),
342                                 );
343                 }
344                 else {
345                         return;
346                 }
347                 
348                 $this->doTemplateVar($item, $mode, $max, $showsnippet, $searchcond, $skinType);
349         }
350         
351         // Handle Related Items
352         function doTemplateVar(&$item, $mode='local', $max='5', $showsnippet='', $searchcond='', $skinType='item') {
353                 global $manager, $blog, $CONF;
354                 
355                 if ($showsnippet == '') $showsnippet = $this->flg_snippet;
356                 if ($showsnippet == 'true' or $showsnippet == 'yes') $showsnippet = true;
357                 else if ($showsnippet == 'false' or $showsnippet == 'no') $showsnippet = false;
358                 $this->showsnippet = $showsnippet;
359                 
360                 if($blog){
361                         $b =& $blog; 
362                 }else{
363                         $b =& $manager->getBlog($CONF['DefaultBlog']);
364                 }
365                 if (is_object($item)) $item = get_object_vars($item);
366                 $max = intval($max);
367                 
368                 //$del_char['local']  = array("\\", '/');
369                 $del_char['google'] = array('-', '+');
370                 //$del_char['amazon'] = array('!','?');
371                 $del_style   = array("/(ver|version)[0-9.]+[0-9a-z.]*$/i", "/\.$/", "/-[0-9]+-$/");
372                 $quote_style = _RELATED_REGEXP_QUOTESTYLE;
373                 
374                 $websvc_url['google'] = "http://api.google.com/search/beta2";
375                 $websvc_url['amazon'] = "http://soap.amazon.co.jp/schemas3/AmazonWebServices.wsdl"; //E amazon.com
376                 
377                 switch($mode) {
378                         
379                         //
380                         // Related LOCAL items
381                         //
382                         
383                         case 'local':
384                                 $q = '';
385                                 $id = $item['itemid'];
386                                 $result = mysql_query("SELECT localkey FROM ". sql_table("plug_related") ." WHERE itemid='$id'");
387                                 if ($msg = mysql_fetch_array($result)) {
388                                         if ($msg['localkey'] == "DONOTSEARCH") $donotsearch = true;
389                                         else $q = $msg['localkey'];
390                                 }
391                                 
392                                 // Is there a keyword present?
393                                 if ($q == "") { 
394                                         $q = strip_tags($item['title']);
395                                 }
396                                 
397                                 if ($donotsearch) {
398                                         if ($this->flg_noheader == 'yes') return;
399                                         $this->_show_header($mode, $q);
400                                         echo $this->noresults;
401                                         return;
402                                 }
403                                 else if ($q == ""){
404                                         if ($this->flg_noheader == 'yes') return;
405                                         $this->_show_header($mode, '(No words)');
406                                         echo $this->noresults;
407                                         return;
408                                 }
409                                 
410                                 // prepare for multi-word search
411                                 $q = trim($q);
412                                 $dispq = $q;
413                                 $str_where = '';
414                                 $ary_modq = array();
415                                 
416                                 // quoted words
417                                 $qt_num = 0;
418                                 $ary_quote = array();
419                                 while ( preg_match($quote_style, $q, $quoted_keys) ) {
420                                         $qlastidx = count($quoted_keys) -1;
421
422 //E                                     if (preg_match("/^[0-9]+$/", $quoted_keys[$qlastidx]) ) { 
423                                         if (preg_match("/^[0-9]+$/", mb_convert_kana($quoted_keys[$qlastidx], 'n', _CHARSET)) ) { 
424                                                 // delete series num
425                                                 $q = preg_replace("/". preg_quote($quoted_keys[0]) ."/", '', $q);
426                                                 continue;
427                                         }
428                                         $qrep = "__QUOTED{$qt_num}__";
429                                         
430                                         // add comma around a quote for splitting
431                                         $ary_quote[$qt_num][0] = stripslashes($quoted_keys[0]); // use first match(with quote chars)
432                                         $ary_quote[$qt_num][1] = stripslashes($quoted_keys[$qlastidx]); //use last(without quote chars)
433                                         $q = preg_replace("/". preg_quote($quoted_keys[0]) ."/", ",$qrep,", $q);
434                                         $qt_num ++;
435                                 }
436                                 
437                                 // split and make multi keywords
438                                 $q = mb_convert_kana($q, 's', _CHARSET);
439                                 $ary_q = preg_split(_RELATED_REGEXP_DELIMITER, $q, -1, PREG_SPLIT_NO_EMPTY);
440                                 
441                                 // set search condition type
442                                 if (strtoupper($searchcond) == 'AND' ||
443                                         strtoupper($searchcond) == 'OR') $qcat = $searchcond;
444                                 else if ($this->flg_srchcond_and == 'yes') $qcat = 'AND';
445                                 else $qcat = 'OR';
446                                 
447                                 foreach ($ary_q as $qpiece) {
448                                         if (preg_match("/^__QUOTED([0-9]+)__$/", $qpiece, $qmatch)) {
449                                                 $ary_modq[] = $ary_quote[$qmatch[1]][0]; // with quote chars
450                                                 $qpiece = $ary_quote[$qmatch[1]][1];  // without quote chars
451                                         }
452                                         else {
453                                                 $qpiece = preg_replace($del_style, '', $qpiece);
454                                                 if (mb_strlen($qpiece,_CHARSET) < 2) continue; // skip if the key is one letter
455                                                 $ary_modq[] = $qpiece;
456                                         }
457                                         
458                                         $qpiece = mysql_escape_string($qpiece);
459                                         
460                                         $str_cat = ($str_where) ? " $qcat " : '';
461                                         
462                                         switch ($this->searchrange) {
463                                                 case 'type1':
464                                                         $str_where .= $str_cat ."( ititle LIKE '%$qpiece%' )";
465                                                         break;
466                                                 case 'type2':
467                                                         $str_where .= $str_cat ."( ititle LIKE '%$qpiece%' OR ibody LIKE '%$qpiece%' )";
468                                                         break;
469                                                 case 'type3':
470                                                         $str_where .= $str_cat ."( ititle LIKE '%$qpiece%' OR ibody LIKE '%$qpiece%' OR imore LIKE '%$qpiece%' )";
471                                                         break;
472                                         }
473                                         
474                                         if (count($ary_modq) == 3) break; // max 3 words
475                                 }
476                                 $qmore = join($ary_modq, ' '); // for 'and more' query link
477                                 
478                                 // Select only from same weblog?
479                                 if ($this->currentblog == 'yes' and $skinType == 'item') {
480                                         $result = mysql_query("SELECT iblog FROM ". sql_table("item") ." WHERE inumber='$item[itemid]'");
481                                         $msg = mysql_fetch_array($result);
482                                         $bid = $msg['iblog'];
483                                         $str_iblog = " AND iblog='$bid'";
484                                 } else {
485                                         $str_iblog = '';
486                                 }
487                                 $result = mysql_query("SELECT inumber, ititle, itime, ibody FROM ". sql_table("item") 
488                                         ." WHERE ($str_where)" . $str_iblog
489                                         ." AND idraft=0 AND inumber<>'$id'" 
490                                         ." AND itime<=" . mysqldate($b->getCorrectTime())
491                                         ." ORDER BY inumber DESC LIMIT 0,$max");
492                                 
493                                 // Do we have any rows?
494                                 if (@mysql_num_rows($result) > 0) {
495                                         $this->_show_header($mode, $qmore);
496                                 
497                                         $first=true;
498                                         while ($row = mysql_fetch_object($result)) {
499                                                 
500                                                 if ($first){
501                                                         $first=false; 
502                                                         echo $this->list_header;
503                                                 }
504                                                 
505                                                 // prepare
506                                                 if (empty($row->ititle)) $title = $this->notitle;
507                                                 else $title = shorten(strip_tags($row->ititle),$this->maxlength,'...');
508                                                 $itime = "[$row->itime]";
509                                                 $snippet = shorten(strip_tags($row->ibody),$this->maxlength2,'...');
510                                                 
511                                                 $iid = $row->inumber;
512                                                 $bid = getBlogIDFromItemID($iid);
513                                                 $b_tmp =& $manager->getBlog($bid);
514                                                 $blogurl = $b_tmp->getURL() ;
515                                                 if(!$blogurl){ 
516                                                         $blogurl = $this->defaultblogurl; 
517                                                 } 
518                                                 if ($CONF['URLMode'] == 'pathinfo'){ 
519                                                         if(substr($blogurl, -1) != '/') 
520                                                         $blogurl .= '/';
521                                                         $url = $blogurl .'item/'. $iid;
522                                                 }
523                                                 else {
524                                                         $url = createItemLink($iid);
525                                                 }
526                                                 
527                                                 $this->_show_list($mode, $url, $title, $snippet, $itime);
528                                         }
529                                         
530                                         $this->_show_morelink($mode, $qmore, $b->getID());
531                                         
532                                         if (!$first) echo $this->list_footer;
533                                 } 
534                                 else {
535                                         if ($this->flg_noheader == 'yes') return;
536                                         $this->_show_header($mode, $qmore);
537                                         echo $this->noresults;
538                                 }
539                         break;
540                         
541                         //
542                         // Related GOOGLE sites
543                         //
544                         
545                         case 'google':
546                         
547                                 $q = '';
548                                 $id = $item['itemid'];
549                                 if ($max > 10) $max = 10;
550                                 $apikey = $this->google_key;
551                                 
552                                 $result = mysql_query("SELECT googlekey FROM ". sql_table("plug_related") ." WHERE itemid='$id'");
553                                 if ($msg = mysql_fetch_array($result)) {
554                                         if ($msg['googlekey'] == "DONOTSEARCH") $donotsearch = true;
555                                         else $q = $msg['googlekey'];
556                                 } 
557                                 
558                                 // Search keyword if no Q is found
559                                 if ($q == ""){
560                                         $q = strip_tags($item['title']);
561                                         $q = str_replace($del_char[$mode], '', $q);
562                                 }
563                                 
564                                 if ($donotsearch) {
565                                         if ($this->flg_noheader == 'yes') return;
566                                         $this->_show_header($mode, $q);
567                                         echo $this->noresults;
568                                         return;
569                                 }
570                                 else if ($q == "") {
571                                         if ($this->flg_noheader == 'yes') return;
572                                         $this->_show_header($mode, '(No words)');
573                                         echo $this->noresults;
574                                         return;
575                                 }
576                                 
577                                 $q = mb_convert_kana($q, 's', _CHARSET); //E comment out
578                                 $q = trim($q);
579                                 $dispq = $q;
580                                 if ($this->toexclude != '') $q .= " -site:". $this->toexclude;
581                                 $q = mysql_escape_string($q);
582                                 
583                                 $this->_show_header($mode, $dispq);
584                                 echo <<<EOS
585 <style type="text/css">
586         @import "http://www.google.com/uds/css/gsearch.css";
587         .gsc-control { width: auto; }
588 </style>
589 <script src="http://www.google.com/uds/api?file=uds.js&amp;v=1.0&amp;key=$apikey" type="text/javascript"></script>
590 <script language="Javascript" type="text/javascript">
591 //<![CDATA[
592
593 function OnLoad() {
594         // Create a search control
595         var searchControl = new GSearchControl();
596         
597         searchControl.addSearcher(new GwebSearch());
598         searchControl.addSearcher(new GblogSearch());
599         //searchControl.addSearcher(new GvideoSearch());
600         
601         // Tell the searcher to draw itself and tell it where to attach
602         searchControl.draw(document.getElementById("searchcontrol"));
603         
604         // Execute an inital search
605         searchControl.execute("$q");
606 }
607 GSearch.setOnLoadCallback(OnLoad);
608
609 //]]>
610 </script>
611 <div id="searchcontrol"></div>
612 EOS;
613                         break;
614                 } //end of switch
615         }
616
617         // Custom functions
618         
619         function _make_stamp() {
620                 return strtotime ("now");
621         }
622         
623         function _check_cache_size() {
624                 // We don't have to check this every time. By creating a random number between 0 and 50 we can reduce
625                 // server load (I guess?)
626                 
627                 $rand =  mt_rand (0,50);
628                 if ($rand == 50) {
629                         $cache = sql_query("SELECT * FROM ". sql_table("plug_related_cache"));
630                         if (@mysql_num_rows($cache) > 2000) {
631                                 sql_query("TRUNCATE TABLE ". sql_table("plug_related_cache"));
632                         }
633                 }
634         }
635
636         function _show_header($mode, $q) {
637                 switch ($mode) {
638                         case "local":
639                                 echo $this->header_lc .$q. $this->header_end;
640                                 break;
641                         case "google":
642                                 echo $this->header_go .$q. $this->header_end;
643                                 break;
644                         case "amazon":
645                                 echo $this->header_am .$q. $this->header_end;
646                                 break;
647                 }
648         }
649
650         function _show_list($mode, $url, $title, $snippet='', $time='') {
651                 echo "\n" . $this->item_header;
652                 
653                 switch ($mode) {
654                         case "local":
655                                 if ($this->showsnippet) {
656                                         if ($this->flg_timelocal == 'yes') 
657                                                 echo '<a href="'. $url .'">'. $title .' '. $time .'</a>';
658                                         else 
659                                                 echo '<a href="'. $url .'" title="'. $time .'">'. $title .'</a>';
660                                         echo '<br /> <span class="iteminfo">'. $snippet .'</span>';
661                                 }
662                                 else {
663                                         if ($this->flg_timelocal == 'yes') 
664                                                 echo '<a href="'. $url .'" title="'. $snippet .'">'. $title .' '. $time .'</a>';
665                                         else 
666                                                 echo '<a href="'. $url .'" title="'. $snippet . $time .'">'. $title . '</a>';
667                                 }
668                                 break;
669                                 
670                         case "google":
671                         case "amazon":
672                                 if ($this->showsnippet) {
673                                         echo '<a href="'. $url .'" target="_blank">'. $title .' </a>';
674                                         echo '<br /> <span class="iteminfo">'. $snippet .'</span>';
675                                 }
676                                 else {
677                                         echo '<a href="'. $url .'" title="'. $snippet .'" target="_blank">'. $title .' </a>';
678                                 }
679                                 break;
680                 }
681                 
682                 echo $this->item_footer;
683         }
684
685         function _show_morelink($mode, $q, $extra='') {
686                 global $CONF;
687                 
688                 if ($this->morelink == '') return;
689                 
690                 echo "\n". $this->item_header;
691                 switch ($mode) {
692                         case 'local':
693                                 $bid = $extra;
694                                 if ($CONF['URLMode'] == 'pathinfo'){
695                                         $moreurl = $CONF['BlogURL'].'?amount=0&amp;query='. urlencode($q) .'&blogid='.$bid;
696                                 }
697                                 else {
698                                         $moreurl = createBlogidLink($bid) . '&amp;amount=0&amp;query='. urlencode($q);
699                                 }
700                                 echo '<a href="' . $moreurl . '" title="'. _RELATED_MSG_JUMP_LC .'">'
701                                         . $this->morelink.'</a>';
702                                 break;
703                                 
704                         case 'google':
705                                 $moreurl = 'http://www.google.com/search?hl=ja&amp;ie='. _CHARSET //E 'hl=en'
706                                         .'&amp;q='. urlencode(stripslashes($q)) .'&lr=';
707                                 echo '<a href="' . $moreurl . '" target="_blank" title="'. _RELATED_MSG_JUMP_GO .'">' 
708                                         . $this->morelink.'</a>';
709                                 break;
710                 }
711                 echo $this->item_footer;
712         }
713
714 }
715 ?>