<?php
/*======================================================================*\
|| #################################################################### ||
|| # Automatic Thread Tagger                                          # ||
|| # ---------------------------------------------------------------- # ||
|| # Originally created by NLP-er (4.0.0)                             # ||
|| # Copyright 2009 Michal Podbielski. All Rights Reserved.           # ||
|| #################################################################### ||
\*======================================================================*/ 

function tokenizeTextBySeparators($text,$separators) {
  $text = str_replace($separators,' ',$text);
  return split(' ', $text);
}

function tokenizeText($text) {
  return tokenizeTextBySeparators($text,tokenizeSeparators());
}

//for php4 users
if(!function_exists('str_split')) {
  function str_split($string, $split_length = 1) {
    $array = explode("\r\n", chunk_split($string, $split_length));
    array_pop($array);
    return $array;
  }
}

function tokenizeSeparators() {
	global $vbulletin;
  $separators = $vbulletin->options['autotaggerfromcontentandtitle_separators'];
  $escape = array ('\n','\t', ' ');
  $separators =str_replace($escape,'',$separators);
  return str_split($separators);
}

function simpleContains($text, $tag) {
	global $vbulletin;
  $separators = $vbulletin->options['autotaggerfromcontentandtitle_separators'];

  $index = strpos($text,$tag);
  if ($index === false) {
    return false;
  }
  
  if ($index != 0) {
    $pre = substr($text, $index-1, 1);
    if (strrpos($separators, $pre) === false) { 
        return false;
    }
  }
  
  $shift = $index + strlen($tag);
  if ($shift < (strlen($text)-1)) {
    $post = substr($text, $shift, 1);
    if (strrpos($separators, $post) === false) { 
        return false;
    }
  }

  return true;
}

function contains($text, $tag, $related_words) {
  if ($tag && simpleContains($text, $tag) ) {
    return true;
  }

  if ($related_words) {
    foreach ($related_words as $related) {
      if ($related && simpleContains($text, $related) ) {
        return true;
      }
    } 
  }
  
  return false;
}

function csvToArray($csv) {
  if ($csv) {
    if (function_exists(split_tag_list)) {
      return split_tag_list($csv);
    } else {
      return split(',', $csv);
    }
  } else {
    return array();
  }
}

//ads tag when new post arrives
function addTags($post, $threadinfo) {
	$contenttypeid = 2;  
	global $vbulletin;
//echo 'TEST addTags <br/>';
  if (!$vbulletin->options['autotaggerfromcontentandtitle_new_threads_only'] || $post['threadid']) {	
    require_once(DIR . '/includes/functions.php');
//echo 'TEST addTags  inside<br/>';
    $content = strtolower($post['message']);
    $title = strtolower($post['title']);
    $threadid = $threadinfo['threadid'] ? $threadinfo['threadid'] : $post['threadid'];
    $contentid = $threadid;
//echo 'TEST addTags  inside contentid:'.$contentid.'<br/>';
    $userid = $vbulletin->userinfo['userid'];
    		
//    $forum = $vbulletin->forumcache["$foruminfo[forumid]"];
//    $default_tags_ids = $forum['default_tags_ids'];
    $foruminfo = fetch_foruminfo($threadinfo['forumid']);
    $default_tags_ids = $foruminfo['default_tags_ids'];
       
    $taglist = $threadinfo['taglist'];
    $taglist = csvToArray($taglist);
        
    $maxtags = $vbulletin->options['tagmaxthread'];
    
    if (sizeof($taglist) < $maxtags) {
      $toAddTagsSQL = array();
      
      //add from default if new thread
      if ($post['threadid'] && $default_tags_ids) {
        foreach (csvToArray($default_tags_ids) as $tagid ) {
          $toAddTagsSQL[] = "(". $tagid .", ". $contenttypeid .", ". $threadid .", " . $userid . ", " . TIMENOW . ")";
        }
      }
      
      //add tags propositions from title
      if ($vbulletin->options['autotaggerfromcontentandtitle_semiautomat_on'] && $title) {
        $propositions = tokenizeText($title); 
        $propositions = array_diff($propositions,csvToArray($vbulletin->options['autotaggerfromcontentandtitle_semiautomat_ignored_words']));
        
        $toAddPropositionsSQL = array();
        
        foreach ($propositions as $proposition) {
          $proposition = trim($proposition);
          $length =  strlen($proposition);
          if ($length < $vbulletin->options['tagminlen'] || ($vbulletin->options['tagmaxlen'] && $length > $vbulletin->options['tagmaxlen'])) {
            continue;
          }        
          $proposition = $vbulletin->db->escape_string($proposition);
          
          $toAddPropositionsSQL[] = "('". $proposition ."', " . TIMENOW .")";          
        }

        if ($toAddPropositionsSQL) {
          $vbulletin->db->query_write("INSERT IGNORE INTO " . TABLE_PREFIX . "tag_proposition(tagtext, dateline) VALUES " . implode(',', $toAddPropositionsSQL));
        }
      }

      //add from title and content
      if ((sizeof($taglist) + sizeof($toAddTagsSQL)) < $maxtags) {
        $tags = $vbulletin->db->query_read("SELECT tagid, tagtext, related_words FROM " . TABLE_PREFIX . "tag");    
        
        while ($tag = $vbulletin->db->fetch_array($tags)) {
          $tag['related_words'] = csvToArray($tag['related_words']);
          
          if (!in_array($tag['tagtext'], $taglist) && (contains($title,$tag['tagtext'],$tag['related_words']) || contains($content,$tag['tagtext'],$tag['related_words']))) {
            $toAddTagsSQL[] = "(". $tag['tagid'] .", ". $contenttypeid .", ". $threadid .", " . $userid . ", " . TIMENOW . ")";
            if ((sizeof($taglist) + sizeof($toAddTagsSQL)) == $maxtags) {
              break;
            }
          } 
        }
      }
          
      if ($toAddTagsSQL) {
      	$vbulletin->db->query_write("INSERT IGNORE INTO " . TABLE_PREFIX . "tagcontent (tagid, contenttypeid, contentid, userid, dateline) VALUES " . implode(',', $toAddTagsSQL));
//		rebuild_thread_taglist($threadid); 
/*   actual solution     
	$content = vB_Taggable_Content_Item::create($vbulletin, $contenttypeid, $contentid);
	if ($vbulletin->GPC['taglist'] AND $show['add_option'])
	{
		$limits = $content->fetch_tag_limits();
		$errors = $content->add_tags_to_content($vbulletin->GPC['taglist'], $limits);
	}
*/
	    require_once(DIR . '/includes/class_taggablecontent.php');
		$content = vB_Taggable_Content_Item::create($vbulletin, $contenttypeid, $contentid);
		$content->rebuild_content_tags();
      }      
    }      
  }
}

function changePropositionsToTags($maxdateline) {
	global $vbulletin;
  $propositions = $vbulletin->db->query_read("SELECT tagid, tagtext FROM " . TABLE_PREFIX . "tag_proposition where status=0 and dateline<=".$maxdateline);    
  $toAddTagsSQL = array();
  $ids = array();

  while ($proposition = $vbulletin->db->fetch_array($propositions)) {
    $toAddTagsSQL[] = "('". $vbulletin->db->escape_string($proposition['tagtext']) ."', " . TIMENOW . ")";
    $ids[] = $proposition['tagid'];
  }
  $vbulletin->db->free_result($propositions); 

  if ($toAddTagsSQL) {
    $vbulletin->db->query_write("INSERT IGNORE INTO " . TABLE_PREFIX . "tag (tagtext,dateline) VALUES " . implode(',', $toAddTagsSQL));
    $vbulletin->db->query_write("UPDATE " . TABLE_PREFIX . "tag_proposition SET status=4 where tagid in (" . implode(',', $ids).")");
  }
  
  return sizeof($toAddTagsSQL);
}

//adds tag to old thread - used by cron
function addTagsToOld($userid, $tagmindateline) {
    require_once(DIR . '/includes/class_taggablecontent.php');
	global $vbulletin;
	$contenttypeid = 2;

	$newTagsCounter=0;
	$addedTagsCounter=0; 
	$inThreadsCounter=0;
  $maxtags = $vbulletin->options['tagmaxthread'];

  //get all tags not older than $tagmindateline
  $tags = null;
  if ($tagmindateline > 0) {
    $tags = $vbulletin->db->query_read("SELECT tagid, tagtext, related_words FROM " . TABLE_PREFIX . "tag where dateline>=".$tagmindateline);    
  } else {
    $tags = $vbulletin->db->query_read("SELECT tagid, tagtext, related_words FROM " . TABLE_PREFIX . "tag");      
  }
  
  $newTags = array();
  while ($tag = $vbulletin->db->fetch_array($tags)) {
    $tag['related_words'] = csvToArray($tag['related_words']);
    $newTags[] = $tag;
  }
  $vbulletin->db->free_result($tags); 

  //get posts to tag
  if ($newTags) {
    $newTagsCounter = sizeof($newTags);
    require_once(DIR . '/includes/functions_newpost.php');

    $posts = null;
    if ($vbulletin->options['autotaggerfromcontentandtitle_new_threads_only']) {	
      $posts = $vbulletin->db->query_read("SELECT threadid, title, pagetext FROM " . TABLE_PREFIX . "post WHERE parentid=0");
    } else {
      $posts = $vbulletin->db->query_read("SELECT threadid, title, pagetext FROM " . TABLE_PREFIX . "post ORDER BY threadid");
    }

    $toAddTagsSQL = array();
    $threadid = -1;
    $taglist = array();
    while ($post = $vbulletin->db->fetch_array($posts)) {
      if (($threadid <> -1) && ($threadid <> $post['threadid'])) {
        //add tags to this thread
        if ($toAddTagsSQL) {
	      $vbulletin->db->query_write("INSERT IGNORE INTO " . TABLE_PREFIX . "tagcontent (tagid, contenttypeid, contentid, userid, dateline) VALUES " . implode(',', $toAddTagsSQL));
          $content = vB_Taggable_Content_Item::create($vbulletin, $contenttypeid, $threadid);
		  $content->rebuild_content_tags();
		  unset($content);
          $addedTagsCounter += sizeof($toAddTagsSQL);
          $inThreadsCounter += 1;
        }	       
        
        unset($toAddTagsSQL);
        unset($taglist);
        
        $toAddTagsSQL = array();
        $threadid = -1;
        $taglist = array();        
      }
    
      //collect tags for this thread
      if ($threadid == -1) {
        $threadid = $post['threadid'];
      }
      
      if (sizeof($toAddTagsSQL) < $maxtags) {
        $content = strtolower($post['pagetext']);
        $title = strtolower($post['title']);

        foreach($newTags as $tag){
          if (!in_array($tag['tagtext'], $taglist) && (contains($title,$tag['tagtext'],$tag['related_words']) || contains($content,$tag['tagtext'],$tag['related_words']))) {
            $toAddTagsSQL[] = "(". $tag['tagid'] .", ". $contenttypeid .", ". $threadid .", " . $userid . ", " . TIMENOW . ")";
            $taglist[] = $tag['tagtext'];
            if (sizeof($toAddTagsSQL) == $maxtags) {
              break;
            }            
          }   
        }
      }
    }
    $vbulletin->db->free_result($posts); 
    
    //add tags to last one
    if ($toAddTagsSQL) {
      $vbulletin->db->query_write("INSERT IGNORE INTO " . TABLE_PREFIX . "tagcontent (tagid, contenttypeid, contentid, userid, dateline) VALUES " . implode(',', $toAddTagsSQL));
	  $content = vB_Taggable_Content_Item::create($vbulletin, $contenttypeid, $threadid);
	  $content->rebuild_content_tags();
	  unset($content);
      $addedTagsCounter += sizeof($toAddTagsSQL);
      $inThreadsCounter += 1;
    }	       
  }
  
  return array($newTagsCounter, $addedTagsCounter, $inThreadsCounter);
}

?>