<?php
/**
* Free Wallpaper Script
*
* Free Wallpaper Script by Vepa Halliyev is licensed under a Creative Commons Attribution-Share Alike 3.0 License.
*
* @package Free Wallpaper Script
* @author Vepa Halliyev
* @copyright Copyright (c) 2009, Vepa Halliyev, veppa.com.
* @license http://www.veppa.com/free-wallpaper-script/
* @link http://www.veppa.com/free-wallpaper-script/
* @since Version 1.0
* @filesource
*/
/**
* class Tag
*
* @author Vepa Halliyev
* @since 1
*/
class Tag extends Record
{
const TABLE_NAME = 'tag';
private static $cols = array(
't_id'=>1,
't_name'=>1,
't_banned'=>1
);
public function __construct($data = false, $locale_db = false)
{
$this->setColumns(self::$cols);
parent::__construct($data,$locale_db);
}
static function relatedTags($records,$num=20,$key_name = 'id')
{
// get realted tags
// FIXME fix tag count per entry to 20 or 250 chars for posts
if($num)
{
$limit = "LIMIT 0,".$num;
}
$sql = "SELECT t.t_name
FROM ".TABLE_PREFIX."tag t LEFT JOIN ".TABLE_PREFIX."tag_relation r ON (r.r_tid=t.t_id)
WHERE r.r_wid=?
".$limit;
//echo $sql;
if(is_array($records))
{
foreach($records as $record)
{
$record->arr_tags = self::query($sql,array($record->{$key_name}));
}
}
else
{
$record = $records;
$record->arr_tags = self::query($sql,array($record->{$key_name}));
}
return $records;
}
static function getPopularTags($num = 20, $populer = true)
{
// TODO use cache for tags
// get latest 2000 post id
$latest = 2000;
if($populer)
{
$ord = "GROUP BY r_wid DESC";
}
else
{
//rastgele
$ord = "ORDER BY rand()";
}
$sql = "SELECT DISTINCT r_wid
FROM ".TABLE_PREFIX."tag_relation
$ord
LIMIT $latest";
$ids = Record::queryArraySingle($sql,array(),MAIN_DB,'r_wid');
return self::_convertToTagArray($ids,$num,true);
}
/**
* Get popular tags using latest 1000 records
*
* @param int $type
* @param int $num
* @param bool $populer
* @return array
*/
static public function getPopularTagsByUser($user_id,$num = 20, $populer=true)
{
// get latest 2000 post id
$latest = 1000;
// AND k.k_public=1 bunu eklesek cok yavasliyor cunku indexte yok
// indexe eklesek cok fazla index oluyor
$sql = "SELECT id
FROM ".TABLE_PREFIX."wallpaper w
WHERE w.added_by=? AND w.public=1
ORDER BY w.id DESC
LIMIT $latest";
$ids = Record::queryArraySingle($sql, array($user_id), MAIN_DB, 'id');
return self::_convertToTagArray($ids,$num,$populer);
}
static private function _convertToTagArray($ids,$num, $populer )
{
$arr_r = array();
if($populer)
{
$ord = "ORDER BY t_num DESC";
}
else
{
//rastgele
$ord = "ORDER BY rand()";
}
$ids = array_unique($ids);
if($ids)
{
$sql = "SELECT t.t_name, COUNT(t.t_id) as t_num
FROM ".TABLE_PREFIX."tag t LEFT JOIN
".TABLE_PREFIX."tag_relation r ON (r.r_tid=t.t_id)
WHERE r.r_wid IN (".implode(',',$ids).") AND t.t_banned='0'
GROUP BY r.r_tid $ord
LIMIT $num";
// free memory
unset($ids);
$r = Record::query($sql,array());
$arr_r = self::_makeTagArray($r);
}
return $arr_r;
}
static private function _makeTagArray($records)
{
$arr_r = array();
if($records)
{
$max_yogunluk = 0;
foreach($records as $record)
{
$arr_tag_yogunluk[$record->t_name] = $record->t_num;
if($max_yogunluk < $record->t_num)
{
$max_yogunluk = $record->t_num;
}
}
unset($records);
foreach($arr_tag_yogunluk as $key=>$val)
{
$val = round($val*10/$max_yogunluk);
$arr_r[$key] = $val;
}
ksort( $arr_r );
}
return $arr_r;
}
/**
* Add tags and relation to wallpaper
*
* @uses Tag::str2tags_arr() to convert tags string to array
*
* @param string $str comma seperated tags
* @param int $r_wid wallpaper id
* @param bool $remove_old true remove old tag relations
* @return string comma seperated tags
*/
static function addTags($str, $r_wid, $remove_old = true)
{
$locale_db = MAIN_DB;
$return = '';
// convert tags string to array
$arr_tags = self::str2tags_arr($str,250);
// remove old tags and add new ones
if($remove_old)
{
self::deleteWhere('TagRelation',
"r_wid=?",
array($r_wid),$locale_db);
}
if($arr_tags)
{
//get all tag keys from DB
foreach($arr_tags as $tag)
{
$arr_tags_quoted[] = self::quote($tag,$locale_db);
}
// always use binding on string values or ? mark can come in query and give error
$arr_q = array_fill(0,count($arr_tags),'?');
//add values to database unique keys
$query_extra = "(".implode("),(",$arr_q).")";
$sql = "INSERT IGNORE INTO ".TABLE_PREFIX."tag (t_name) VALUES $query_extra";
self::query($sql,$arr_tags,$locale_db);
// get tags from db
$query_where = "t_name IN (".implode(",",$arr_q).")";
$tags = self::findAllFrom('Tag',$query_where,$arr_tags,$locale_db);
$query_extra = array();
foreach($tags as $tag)
{
$query_extra[] = "('".$tag->t_id."','$r_wid')";
}
$query_extra = implode(",",$query_extra);
//now associate tags with post
$sql = "INSERT INTO ".TABLE_PREFIX."tag_relation
(r_tid,r_wid)
VALUES $query_extra";
self::query($sql,false,$locale_db);
$return = implode(',',$arr_tags);
}
return $return;
}
static function isBanned($tag)
{
$banned = self::findOneFrom('Tag','t_name=? AND t_banned=1',array($tag));
return ($banned?true:false);
}
/**
* convert comma seperated string to tags array, converts chacartest to lowercase
*
* @param string $str comma seperated tags
* @param string $limit 0|int max number of characters if tags combined to a string
* @return array
*/
public static function str2tags_arr($str,$limit = 0)
{
use_helper('StringUtf8');
// remove slashes for safe linking. (direcotory)
$str = str_replace(array("/","\\"),"",$str);
// convert to lowercase
$str = StringUtf8::strtolower($str);
//converts comma seperated tags to array with unique values
$tagler = explode(",",$str);
$arr = array();
foreach($tagler as $tag)
{
$tag = trim($tag);
if(!($tag=='' || $tag=='.' || $tag=='..'))
{
$arr[$tag] = 1;
}
}
//limit
if($limit)
{
$str = '';
$arr_ = array();
foreach($arr as $k => $v)
{
$str .= $k.',';
if(strlen($str)<$limit)
{
$arr_[$k] = 1;
}
}
$arr = $arr_;
}
return array_keys($arr);
}
/**
* Get all tags with weight
* @return array (tag=>weight)
*/
function getAllTags($limit=20)
{
if($limit)
{
$limit_str = "ORDER BY t_num DESC LIMIT $limit";
}
else
{
$limit_str = "";
}
$sql = "SELECT t.t_name, COUNT(t.t_id) as t_num
FROM ".TABLE_PREFIX."tag t LEFT JOIN
".TABLE_PREFIX."tag_relation r ON (r.r_tid=t.t_id)
WHERE t.t_banned='0' AND r.r_tid IS NOT NULL
GROUP BY r.r_tid $limit_str";
$r = self::query($sql,array());
return self::_makeTagArray($r);
}
function beforeDelete()
{
// find wallpapers and update string tag values
$tr = TagRelation::findAllFrom('TagRelation','r_tid=?',array($this->t_id));
TagRelation::appendObject($tr,'r_wid','Wallpaper','id','wallpaper',MAIN_DB,'id,tags');
foreach($tr as $t)
{
$t->wallpaper->tags = ','.$t->wallpaper->tags.',';
$t->wallpaper->tags = str_replace(','.$this->t_name.',',',',$t->wallpaper->tags);
$t->wallpaper->tags = trim($t->wallpaper->tags,',');
if(!$t->wallpaper->save('id'))
{
return false;
}
}
// delete existing unrelated tags
self::deleteUnrelatedTags();
// delete tag relation
return TagRelation::deleteWhere('TagRelation','r_tid=?',array($this->t_id));
}
function deleteUnrelatedTags()
{
$sql = "DELETE t
FROM ".TABLE_PREFIX."tag t LEFT JOIN ".TABLE_PREFIX."tag_relation tr ON (t.t_id=tr.r_tid)
WHERE tr.r_tid is NULL";
self::query($sql);
}
static function url($tag,$order='',$page=1)
{
return get_url('tag/'.rawurlencode($tag).'/'.($order?$order.'/'.$page.'/':''));
}
static function normalizeTagsStr($str)
{
return implode(self::str2tags_arr($str,250),',');
}
static function mixWithCategories($tags,$categories,$sel_cats)
{
// mix tags with selected categories
$tags = self::normalizeTagsStr($tags);
$arr_tags = explode(',',$tags);
$arr_k = array_flip($arr_tags);
foreach($categories as $c)
{
$c_name = strtolower($c->name);
if(in_array($c->id,$sel_cats))
{
// add this category as tag
$arr_k[$c_name] = 1;
}
else
{
// remove this category from tags if exist
unset($arr_k[$c_name]);
}
}
/*echo $tags;
print_r($categories);
print_r($sel_cats);
echo $tags;*/
$tags = implode(',',array_keys($arr_k));
return $tags;
}
static public function changeName($name_old,$name_new)
{
$name_old = Tag::normalizeTagsStr($name_old);
// get tag
$tag_object = Tag::findOneFrom('Tag', 't_name=?', array($name_old));
if ($tag_object)
{
// update tag name and save
$tag_object->t_name = Tag::normalizeTagsStr($name_new);
$tag_object->save('t_id');
// find all wallpapers using same tag and update comma seperated tags string for each wallpaper
$sql = "SELECT w.id,w.tags FROM
" . self::tableNameFromClassName('Wallpaper') . " w LEFT JOIN
" . self::tableNameFromClassName('TagRelation') . " tr ON(w.id=tr.r_wid)
WHERE tr.r_tid=?";
$wallpapers = Wallpaper::query($sql, array($tag_object->t_id));
foreach ($wallpapers as $w)
{
$tags = explode(',', $w->tags);
$tags = array_flip($tags);
// remove old tag name from array
unset($tags[$name_old]);
// add new tag name to array
$tags[$tag_object->t_name] = 1;
// form new tags string using new values
$w->tags = implode(',', array_keys($tags));
// update wallpaper record
Wallpaper::update('Wallpaper', array('tags'=> $w->tags), 'id=?', array($w->id));
}
}
}
}