<?php

/**
  * BLOG:CMS: PHP/MySQL Personal Content Management System (CMS)
  * http://blogcms.com/
  * ----------------------------------------------------------------
  *
  * Copyright (C) 2003-2005 Radek HULÁN
  * http://hulan.cz/contact/
  *
  * Based on: 
  * ----------------------------------------------------------------
  * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/) 
  * Copyright (C) 2002-2003 The Nucleus Group
  *
  * ----------------------------------------------------------------
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
  * as published by the Free Software Foundation; either version 2
  * of the License, or (at your option) any later version.
**/

class NP_Related extends NucleusPlugin {
	var $google_key;
	var $list_header;
	var $item_header;
	var $item_footer;
	var $list_footer;
	var $notitle;
	var $noresults;
	var $maxlenght;
	var $currentblog;

	function init() {
		$this->google_key = $this->getOption("googlekey");
		$this->list_header = $this->getOption("listheading");
		$this->item_header = $this->getOption("itemheading");
		$this->item_footer = $this->getOption("itemfooter");
		$this->list_footer = $this->getOption("listfooter");
		$this->notitle = $this->getOption("notitle");
		$this->noresults = $this->getOption("noresults");
		$this->maxlenght = $this->getOption("maxlenght");
		$this->currentblog = $this->getOption("currentblog");
	}
	function getName() {return 'Related items/sites'; }
	function getAuthor()  { return 'Tim Broddin - v0.1, Radek HULAN v0.2 and 0.3'; }
	function getURL() {return 'http://blogcms.com/'; }
	function getVersion() {return '0.3';}
	function getDescription() {
		return 'Allows to make a list of related articles/sites.<br />
				List can be shown with &lt;%Related(local,15)%&gt; for a list of local items which are related,<br />
				with &lt;%Related(google,15)%&gt; for a list of related sites found on Google and with
				When you use &lt;%Related%&gt; a list of 15 local items will be shown.<br /><br />
				You need a special access key for the 1 webservice (Google). ';
	}
	function supportsFeature($feature) { if ($feature=='SqlTablePrefix') return 1; else return 0;}
	function install() {
		$this->createOption("googlekey", "Google API key:", "text", "");
		$this->createOption("listheading", "Related list heading", "text", "<ul>");
		$this->createOption("itemheading", "Related item heading", "text", "<li>");
		$this->createOption("listfooter", "Related list footer", "text", "</ul>");
		$this->createOption("itemfooter", "Related item footer", "text", "</li>");
		$this->createOption("notitle", "String to display when there's no title present", "text", "(no title)");
		$this->createOption("noresults", "String to display when there are no results", "text", "<p>No results found or search not configured.</p>");
		$this->createOption("maxlenght", "Maximum lenght of an item", "text", "80");
		$this->createOption("currentblog", "Show only items related to same weblog?", "yesno", "yes");
		$this->createOption("interval", "The time between two external API calls (in hours)", "text", "24");
		$this->createOption("header1", "Heading_start for local search", "text", "<h4>Local search <em>");
		$this->createOption("header2", "Heading_start for google search", "text", "<h4>Google search <em>");
		$this->createOption("header3", "Heading_finish for local/google search", "text", "</em></h4>");
		$this->createOption("language", "Language for search", "text", "lang_en");
		$this->createOption("toexclude", "Domain name to exclude", "text", "yourwebsitename.com");
	}

	function getTableList() {
	  return array(
	    sql_table('plug_related')
	    /* ,sql_table('plug_related_cache')  - no need to backup this table */
	  );	
	}
	function getEventList() {
    return array(
      'PostAddItem',
      'PreUpdateItem',
      'AddItemFormExtras',
      'EditItemFormExtras');
  }


	function event_AddItemFormExtras($data){
		?>
			<h3>Related</h3>
			<table>
      <tr><td><b>Local keyword</b></td><td><b>Google keyword</b></td></tr>
			<tr>
      <td><input tabindex="59" type="text" value="" name="local_keyword" size="30" /></td>
    	<td><input tabindex="60" type="text" value="" name="google_keyword" size="30" /></td>
    	</tr>
    	</table>
		<?php
	}

	function event_EditItemFormExtras($data) {
		$query=sql_query("SELECT localkey, googlekey FROM ".sql_table('plug_related')." WHERE itemid=".strval($data['itemid']));
		if ($row=sql_fetch_object($query)){
		  $local=$row->localkey;
		  $google=$row->googlekey;
    } else {
		  $local='';
		  $google='';
    }
		?>
			<h3>Related</h3>
			<table>
      <tr><td><b>Local keyword</b></td><td><b>Google keyword</b></td></tr>
			<tr>
      <td><input tabindex="59" type="text" value="<?php echo $local; ?>" name="local_keyword" size="30" /></td>
    	<td><input tabindex="60" type="text" value="<?php echo $google; ?>" name="google_keyword" size="30" /></td>
    	</tr>
    	</table>
		<?php
	}

	//PostAddItem Evenent
	function event_PostAddItem($data) {
		$local = requestVar('local_keyword');
		$google = requestVar('google_keyword');
		if (!$local) {$local=$_POST['local_keyword'];};
		if (!$google) {$google=$_POST['google_keyword'];};
		// Nothing to do? Get out!!
		if ((!$local) && (!$google)) return;
		$itemid = $data['itemid'];
		$local = sql_escape($local);
		$google = sql_escape($google);
		sql_query("INSERT INTO ".sql_table('plug_related')." VALUES ('$itemid','$local','$google')");
	}

	//PreUpdateItem Event
	function event_PreUpdateItem($data) {
		$local = requestVar('local_keyword');
		$google = requestVar('google_keyword');
		$local = sql_escape($local);
		$google = sql_escape($google);
		if (!$local) {$local=$_POST['local_keyword'];};
		if (!$google) {$google=$_POST['google_keyword'];};
		// Nothing to do? Get out!!
		if ((!$local) && (!$google)) return;
		$itemid = $data['itemid'];
		$result = sql_query("SELECT * FROM ".sql_table('plug_related')." WHERE itemid='$itemid'");
		if (sql_num_rows($result) > 0) {
			sql_query("UPDATE ".sql_table('plug_related')." SET localkey='$local', googlekey='$google' WHERE itemid='$itemid'");
		} else {
			sql_query("INSERT INTO ".sql_table('plug_related')." VALUES ('$itemid','$local','$google')");
		}
	}

		function doSkinVar($skinType,$param1='local') {
			global $itemid;
			if (isset($itemid))
				$result = sql_query("SELECT localkey, googlekey FROM ".sql_table('plug_related')." WHERE itemid='$itemid'");
				if ($msg = sql_fetch_array($result)) {
					switch($param1) {
						case 'local':
							echo $msg['localkey'];
							break;
						case 'google': 
							echo $msg['googlekey'];
							break;
					}
			}
		}

		function doTemplateVar(&$item, $param1='local', $param2 = '15', $showsnippet = false) {

		switch($param1) {

			//
			// Related LOCAL items
			//

			case 'local':
				$id = $item->itemid;
				$max = $param2;
				if (intval($max)>10) $max='10';
				$result = sql_query("SELECT localkey FROM ".sql_table('plug_related')." WHERE itemid='$id'");
				if ($msg = sql_fetch_array($result)) {
					$key = $msg['localkey'];
					if ($key == "DONOTSEARCH") {
						echo $this->getOption('header1').$this->getOption('header3').$this->noresults;
						return;
					}
				}

				// Is there a keyword present?
				if (empty($key)) {
				  $key = strip_tags($item->title);
				  $arr = array("'","!","?",":",".",",","-","\"","|","\\","/","_");
				  foreach ($arr as $s) $key=str_replace($s,"",$key);
					$key = sql_escape($key);
				}
				if (empty($key)) {
					echo $this->getOption('header1').$this->getOption('header3').$this->noresults;
					return;
				}

				global $blog;
				if ($this->currentblog == 'yes') {
					$result = sql_query("SELECT iblog FROM ".sql_table('item')." WHERE inumber=$id");
					$msg = sql_fetch_array($result);
					$myblogid = strval($msg['iblog']);
					$result = sql_query("SELECT inumber, ititle, iurltitle, UNIX_TIMESTAMP(itime) as itime FROM ".sql_table('item')." WHERE inumber<>$id AND (ititle LIKE '%$key%' OR ibody LIKE '%$key%' OR imore LIKE '%$key%') AND iblog=$myblogid AND idraft=0 ORDER BY inumber DESC LIMIT 0,$max");
				} else {
					$result = sql_query("SELECT inumber, ititle, iurltitle, UNIX_TIMESTAMP(itime) as itime FROM ".sql_table('item')." WHERE inumber<>$id AND (ititle LIKE '%$key%' OR ibody LIKE '%$key%' OR imore LIKE '%$key%') AND idraft=0 ORDER BY inumber DESC LIMIT 0,$max");
				}

				// Do we have any rows?
				if (sql_num_rows($result) > 0) {
			    $first=true;
					while ($row = sql_fetch_object($result)) {
						if ($first){
							$first=false;
							echo $this->getOption('header1')." ".$key.$this->getOption('header3').$this->list_header;
						};
						echo $this->item_header;
						echo '<a href="' . fancyTitle($row->inumber,$row->iurltitle,$row->itime) . '">' . substr($row->ititle,0,$this->maxlenght) . '</a>';
						echo $this->item_footer."\n";
					}
					if (!$first) echo $this->list_footer;
				} else
				  echo $this->getOption('header1')." ".$key.$this->getOption('header3').$this->noresults;;
				break;

			//
			// Related GOOGLE sites
			//

			case 'google':
				$id = $item->itemid;
				$max = intval($param2);
				if (($max)<1) $max=1;
				$apikey = $this->google_key;
				$result = sql_query("SELECT googlekey FROM ".sql_table('plug_related')." WHERE itemid='$id'");
				if ($msg = sql_fetch_array($result)) {
					$q = $msg['googlekey'];
					if ($q == "DONOTSEARCH") {
            echo $this->getOption('header2').$this->getOption('header3').$this->noresults;
            return;
          }
				}
				if (empty($q)){
				  $q = strip_tags($item->title);
				  $arr = array("'","!","?",":",".",",","-","\"","|","\\","/","_");
				  foreach ($arr as $s) $q=str_replace($s,"",$q);
					$q = sql_escape($q);
        }
				if (empty($q)) {
          echo $this->getOption('header2').$this->getOption('header3').$this->noresults;
          return;
        }

        $r=trim($this->getOption('toexclude'));
        if (!empty($r)) $q.=" -".$r;

				// Caching system
				$qdb=substr($q,0,strpos($q,'-')-1);

				$result = sql_query("SELECT stamp FROM ".sql_table('plug_related_cache')." WHERE keyword='$qdb' AND type='google'");
				if ($msg = sql_fetch_array($result)) {
					$stamp = $msg['stamp'];
					$nextupdate = strval(60*60*(intval($this->getOption("interval")))+intval($stamp));
				} else {
				  $stamp="";
				  $nextupdate="";
        }
				$now = strval(time());

 				// Get cached result from database
 				$first=true;
				if ( intval($nextupdate)>intval($now) ) {
					$result2 = sql_query("SELECT url, title, snippet FROM ".sql_table('plug_related_cache')." WHERE keyword='$qdb' AND type='google' ORDER BY rank ASC LIMIT 0,$param2");
					while ($row = sql_fetch_object($result2)) {
					  if ($row->url != 'NONE') {
						 if ($first){
              $first=false;
              echo $this->getOption('header2').$qdb.$this->getOption('header3').$this->list_header;
             }
						 echo $this->item_header;
						 $row->url=strtolower(str_replace('&',"&amp;",str_replace("&amp;",'&',$row->url)));

             /* domain */
			       $domain=$row->url;
						 $pos=strpos($domain,'//');
						 if (!$pos===false) $domain=substr($domain,$pos+2);
						 $pos=strpos($domain,'\\\\');
						 if (!$pos===false) $domain=substr($domain,$pos+2);
						 $pos=strpos($domain,'/');
						 if (!$pos===false) $domain=substr($domain,0,$pos);
						 $pos=strpos($domain,'\\');
						 if (!$pos===false) $domain=substr($domain,0,$pos);

			       echo $domain." ";

						 $row->title=sql_unescape($row->title);
						 $row->snippet=sql_unescape($row->snippet);
						 if ($row->title=="") {
						  if ($showsnippet)
							  echo '<a href="' . SEOlink($row->url) . '">' . $this->notitle . '</a> <small>'.$row->snippet.'</small>';
						  else
						    echo '<a href="' . SEOlink($row->url) . '">' . $this->notitle . '</a>';
						 } else {
						  if ($showsnippet)
							  echo '<a href="' . SEOlink($row->url) . '">' . substr($row->title,0,$this->maxlenght) . ' </a> <small>'.$row->snippet.'</small>';
						  else
						    echo '<a href="' . SEOlink($row->url) . '">' . substr($row->title,0,$this->maxlenght) . ' </a>';
						 }
						 echo $this->item_footer."\n";
						}
					}
  				if (!$first)
            echo $this->list_footer;
          else {
  				  echo $this->getOption('header2')." ".$qdb.$this->getOption('header3').$this->noresults;
          }
				}	else {
				  /* new query */
					$round=1;
					$number=0;
					if (empty($apikey)){
					  echo $this->getOption('header2').$this->getOption('header3').$this->noresults;
					  return;
          }
					while ( ($round<=3) && ($number<$max) ){
            $parameters = array(
              "key"         => $apikey,
              "q"           => $q,
              "start"       => ($round-1)*10, /* start at 0,10 or 20 */
              "maxResults"  => 10,
              "filter"      => true, /* filter out similar results */
              "restrict"    => "",   /* no country restriction */
              "safeSearch"  => true, /* no adult sites */
              "lr"          => $this->getOption('language'),  /* languages prefered */
              "ie"          => "",
              "oe"          => ""
            );

				    $soapclient = new soapclientw("http://api.google.com/search/beta2");
					  $result = $soapclient->call('doGoogleSearch',$parameters, 'urn:GoogleSearch');
					  $i = 0;

					  /* there are some results */
					  if ($result['estimatedTotalResultsCount']>0) {
					    if ($result['estimatedTotalResultsCount']<10) $round=3;
						  foreach ($result['resultElements'] as $r){
							  $url=$r['URL'];
							  $title = $r['title'];
							  $snippet = $r['snippet'];

 						    $url = strip_tags($url);
							  $title = strip_tags($title);
							  $snippet = strip_tags($snippet);

							  $url=substr($url,0,255);
							  $title=htmlspecialchars(sql_unescape(substr($title,0,100)));
							  $snippet=htmlspecialchars(sql_unescape(substr($snippet,0,255)));

						    $url=strtolower(str_replace("&","&amp;",str_replace("&amp;","&",$url)));

                /* domain */
						    $domain=$url;
						    $pos=strpos($domain,'//');
						    if (!$pos===false) $domain=substr($domain,$pos+2);
						    $pos=strpos($domain,'\\\\');
						    if (!$pos===false) $domain=substr($domain,$pos+2);
						    $pos=strpos($domain,'/');
						    if (!$pos===false) $domain=substr($domain,0,$pos);
						    $pos=strpos($domain,'\\');
						    if (!$pos===false) $domain=substr($domain,0,$pos);

						    if ( (!isset($arr[$domain])) && ($number<$max) ){
						      if ($first){
                    $first=false;
                    echo $this->getOption('header2').$qdb.$this->getOption('header3').$this->list_header;
						        sql_query("DELETE FROM ".sql_table('plug_related_cache')." WHERE keyword='$qdb' AND type='google'");
                  }
							    echo $this->item_header;
						      echo $domain." ";
							    if ($title != "") {
							      if ($showsnippet)
								      echo '<a href="'.SEOlink($url).'">'.substr($title,0,$this->maxlenght).'</a> <small>'.$snippet.'</small>';
								    else
								      echo '<a href="'.SEOlink($url).'">'.substr($title,0,$this->maxlenght).'</a>';
							    } else {
							      if ($showsnippet)
								      echo '<a href="' . SEOlink($url) . '">' . $this->notitle . '</a> <small>'.$snippet.'</small>';
							      else
							        echo '<a href="' . SEOlink($url) . '">' . $this->notitle . '</a>';
							    }
							    // Insert in database
							    $i++;
							    sql_query("INSERT INTO ".sql_table('plug_related_cache')." (`id`, `type`, `keyword`, `rank`, `url`, `title`, `stamp`, `snippet`) VALUES ('', 'google', '$qdb', '$i', '$url', '$title', '$now', '$snippet')");
							    echo $this->item_footer."\n";
							    $arr[$domain]=1;
							    $number++;
							  } // isset($arr)
						  } // foreach
					  } else {
					    if ($number==0){
					      /* no results found on Google, insert a fake NONE entry */
					      sql_query("DELETE FROM ".sql_table('plug_related_cache')." WHERE keyword='$qdb' AND type='google'");
					      sql_query("INSERT INTO ".sql_table('plug_related_cache')." (`id`, `type`, `keyword`, `rank`, `url`, `title`, `stamp`, `snippet`) VALUES ('', 'google', '$qdb', '0', 'NONE', 'NONE', '$now', 'NONE')");
					    }
					    $round=3;
					  }
					  $round++;
					} // while
  				if (!$first)
            echo $this->list_footer;
          else {
  				  echo $this->getOption('header2')." ".$qdb.$this->getOption('header3').$this->noresults;
          }
				} // Get new result
			  break;

		}	// switch
	} // doTemplateVar
}
?>