Merge pull request #324 from justinbrewer/editcloud_revamp
Tag Edit Cloud improvements
This commit is contained in:
commit
4fd58019e5
@ -2,31 +2,21 @@
|
|||||||
/*
|
/*
|
||||||
* Name: Tag EditCloud
|
* Name: Tag EditCloud
|
||||||
* Author: AtomicDryad
|
* Author: AtomicDryad
|
||||||
|
* Contributors:
|
||||||
|
* Schizius (Relevance Sort, Category Integration, Cleanup)
|
||||||
* Description: Add or remove tags to the editor via clicking.
|
* Description: Add or remove tags to the editor via clicking.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Todo:
|
/* Todo:
|
||||||
* Be less kludgy
|
* usepref(todo2: port userpref)
|
||||||
* $cfgstub->board prefs
|
|
||||||
* toggle sorting method via javascript || usepref(todo2: port userpref)
|
|
||||||
* colorize used tags in cloud || always show used tags in front of cloud
|
|
||||||
* theme junk
|
* theme junk
|
||||||
*/
|
*/
|
||||||
class TagEditCloud extends Extension {
|
class TagEditCloud extends Extension {
|
||||||
public function onImageInfoBoxBuilding(ImageInfoBoxBuildingEvent $event) {
|
public function onImageInfoBoxBuilding(ImageInfoBoxBuildingEvent $event) {
|
||||||
global $config;
|
global $config;
|
||||||
|
|
||||||
if(!$config->get_bool("tageditcloud_disable")) {
|
if(!$config->get_bool("tageditcloud_disable") && $this->can_tag($event->image)) {
|
||||||
if($this->can_tag($event->image)) {
|
$event->add_part($this->build_tag_map($event->image),40);
|
||||||
if(!$cfg_minusage=$config->get_int("tageditcloud_minusage")) $cfg_minusage=2;
|
|
||||||
if(!$cfg_defcount=$config->get_int("tageditcloud_defcount")) $cfg_defcount=40;
|
|
||||||
if(!$cfg_maxcount=$config->get_int("tageditcloud_maxcount")) $cfg_maxcount=4096;
|
|
||||||
if($config->get_string("tageditcloud_sort") != "p") {
|
|
||||||
$event->add_part($this->build_tag_map($event->image,$cfg_minusage,false),40);
|
|
||||||
} else {
|
|
||||||
$event->add_part($this->build_tag_map($event->image,$cfg_defcount,$cfg_maxcount),40);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -38,10 +28,11 @@ class TagEditCloud extends Extension {
|
|||||||
$config->set_default_int("tageditcloud_minusage",2);
|
$config->set_default_int("tageditcloud_minusage",2);
|
||||||
$config->set_default_int("tageditcloud_defcount",40);
|
$config->set_default_int("tageditcloud_defcount",40);
|
||||||
$config->set_default_int("tageditcloud_maxcount",4096);
|
$config->set_default_int("tageditcloud_maxcount",4096);
|
||||||
|
$config->set_default_string("tageditcloud_ignoretags",'tagme');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function onSetupBuilding(SetupBuildingEvent $event) {
|
public function onSetupBuilding(SetupBuildingEvent $event) {
|
||||||
$sort_by = array('Alphabetical'=>'a','Popularity'=>'p');
|
$sort_by = array('Alphabetical'=>'a','Popularity'=>'p','Relevance'=>'r');
|
||||||
|
|
||||||
$sb = new SetupBlock("Tag Edit Cloud");
|
$sb = new SetupBlock("Tag Edit Cloud");
|
||||||
$sb->add_bool_option("tageditcloud_disable", "Disable Tag Selection Cloud: ");
|
$sb->add_bool_option("tageditcloud_disable", "Disable Tag Selection Cloud: ");
|
||||||
@ -49,84 +40,117 @@ class TagEditCloud extends Extension {
|
|||||||
$sb->add_bool_option("tageditcloud_usedfirst","<br>Always show used tags first: ");
|
$sb->add_bool_option("tageditcloud_usedfirst","<br>Always show used tags first: ");
|
||||||
$sb->add_label("<br><b>Alpha sort</b>:<br>Only show tags used at least ");
|
$sb->add_label("<br><b>Alpha sort</b>:<br>Only show tags used at least ");
|
||||||
$sb->add_int_option("tageditcloud_minusage");
|
$sb->add_int_option("tageditcloud_minusage");
|
||||||
$sb->add_label(" times.<br><b>Popularity sort</b>:<br>Show ");
|
$sb->add_label(" times.<br><b>Popularity/Relevance sort</b>:<br>Show ");
|
||||||
$sb->add_int_option("tageditcloud_defcount");
|
$sb->add_int_option("tageditcloud_defcount");
|
||||||
$sb->add_label(" tags by default.<br>Show a maximum of ");
|
$sb->add_label(" tags by default.<br>Show a maximum of ");
|
||||||
$sb->add_int_option("tageditcloud_maxcount");
|
$sb->add_int_option("tageditcloud_maxcount");
|
||||||
$sb->add_label(" tags.");
|
$sb->add_label(" tags.");
|
||||||
|
$sb->add_label("<br><b>Relevance sort</b>:<br>Ignore tags (space separated): ");
|
||||||
|
$sb->add_text_option("tageditcloud_ignoretags");
|
||||||
|
|
||||||
$event->panel->add_block($sb);
|
$event->panel->add_block($sb);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function tag_link($tag) {
|
private function build_tag_map($image) {
|
||||||
$u_tag = url_escape($tag);
|
|
||||||
return make_link("post/list/$u_tag/1");
|
|
||||||
}
|
|
||||||
///// build_tag_map: output cloud of clickable tags
|
|
||||||
// build_tag_map($image|false, $defcount, $maxcount|false) -- taglist sorted by usage, displaying $defcount by default, up to $maxcount via toggle.
|
|
||||||
// build_tag_map($image|false, $minusage|false) -- taglist sorted by alpha, only showing tags with usage >= $minusage
|
|
||||||
|
|
||||||
private function build_tag_map($image,$defcount,$maxcount) { //
|
|
||||||
global $database, $config;
|
global $database, $config;
|
||||||
$html="";$cloud="";$precloud="";
|
|
||||||
$itags=Array();
|
|
||||||
$tags_min=1;
|
|
||||||
$alphasort=false;
|
|
||||||
$usedfirst=$config->get_bool("tageditcloud_usedfirst");
|
|
||||||
|
|
||||||
if(!is_int($defcount)) $defcount=20;
|
$html = "";
|
||||||
if(!is_int($maxcount)) { // Derp this is pretty cheesy.
|
$cloud = "";
|
||||||
$maxcount=4096; // Hurrrr
|
$precloud = "";
|
||||||
$tags_min=$defcount;
|
$postcloud = "";
|
||||||
$alphasort=true;
|
|
||||||
|
$sort_method = $config->get_string("tageditcloud_sort");
|
||||||
|
$tags_min = $config->get_int("tageditcloud_minusage");
|
||||||
|
$used_first = $config->get_bool("tageditcloud_usedfirst");
|
||||||
|
$max_count = $config->get_int("tageditcloud_maxcount");
|
||||||
|
$def_count = $config->get_int("tageditcloud_defcount");
|
||||||
|
|
||||||
|
$ignore_tags = Tag::explode($config->get_string("tageditcloud_ignoretags"));
|
||||||
|
|
||||||
|
if(class_exists("TagCategories")){
|
||||||
|
$categories = $database->get_all("SELECT category, color FROM image_tag_categories");
|
||||||
|
$cat_color = array();
|
||||||
|
foreach($categories as $row){
|
||||||
|
$cat_color[$row['category']] = $row['color'];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((gettype($image) == 'object') && (isset($image->tag_array)) && ($itags=$image->tag_array)) $itags=array_fill_keys(array_values($itags),true);
|
switch($sort_method){
|
||||||
|
case 'a':
|
||||||
$tag_data = $database->get_all(" SELECT tag, FLOOR(LOG(2.7, LOG(2.7, count - ? + 1)+1)*1.5*100)/100 AS scaled, count
|
case 'p':
|
||||||
FROM tags WHERE count >= ? ORDER BY ".
|
$tag_data = $database->get_all("SELECT tag, FLOOR(LN(LN(count - :tag_min1 + 1)+1)*150)/200 AS scaled, count
|
||||||
(!$alphasort ? "count DESC":"tag").
|
FROM tags WHERE count >= :tag_min2 ORDER BY ".($sort_method == 'a' ? "tag" : "count DESC")." LIMIT :limit",
|
||||||
" limit $maxcount",
|
array("tag_min1" => $tags_min, "tag_min2" => $tags_min, "limit" => $max_count));
|
||||||
array($tags_min,$tags_min)
|
break;
|
||||||
);
|
case 'r':
|
||||||
|
$relevant_tags = implode(",",array_map(array($database,"escape"),array_diff($image->get_tag_array(),$ignore_tags)));
|
||||||
|
$tag_data = $database->get_all("SELECT t2.tag AS tag, COUNT(image_id) AS count, FLOOR(LN(LN(COUNT(image_id) - :tag_min1 + 1)+1)*150)/200 AS scaled
|
||||||
|
FROM image_tags it1 JOIN image_tags it2 USING(image_id) JOIN tags t1 ON it1.tag_id = t1.id JOIN tags t2 ON it2.tag_id = t2.id
|
||||||
|
WHERE t1.count >= :tag_min2 AND t1.tag IN($relevant_tags) GROUP BY t2.tag ORDER BY count DESC LIMIT :limit",
|
||||||
|
array("tag_min1" => $tags_min, "tag_min2" => $tags_min, "limit" => $max_count));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
$counter = 1;
|
$counter = 1;
|
||||||
foreach($tag_data as $row) {
|
foreach($tag_data as $row) {
|
||||||
if((!$alphasort)&&($counter==$defcount)) $cloud .= "<div id=\"tagcloud_extra\" style=\"display: none;\">";
|
$full_tag = $row['tag'];
|
||||||
|
|
||||||
|
if(class_exists("TagCategories")){
|
||||||
|
$tc = explode(':',$row['tag']);
|
||||||
|
if(isset($tc[1]) && isset($cat_color[$tc[0]])){
|
||||||
|
$h_tag = html_escape($tc[1]);
|
||||||
|
$color = '; color:'.$cat_color[$tc[0]];
|
||||||
|
} else {
|
||||||
$h_tag = html_escape($row['tag']);
|
$h_tag = html_escape($row['tag']);
|
||||||
$size = sprintf("%.2f", (float)$row['scaled']/2);
|
$color = '';
|
||||||
$usecount=$row['count'];
|
|
||||||
$link = $this->tag_link($row['tag']);
|
|
||||||
if($size<0.5) $size = 0.5;
|
|
||||||
|
|
||||||
if(isset($itags[$row['tag']])) {
|
|
||||||
if($usedfirst) {
|
|
||||||
$precloud .= " <span onclick=\"tageditcloud_toggle_tag(this)\" class=\"tag-selected\" style='font-size: ${size}em' title='$usecount'>$h_tag</span> \n";
|
|
||||||
} else {
|
|
||||||
$counter++;
|
|
||||||
$cloud .= " <span onclick=\"tageditcloud_toggle_tag(this)\" class=\"tag-selected\" style='font-size: ${size}em' title='$usecount'>$h_tag</span> \n";
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$counter++;
|
$h_tag = html_escape($row['tag']);
|
||||||
$cloud .= " <span onclick=\"tageditcloud_toggle_tag(this)\" style='font-size: ${size}em' title='$usecount'>$h_tag</span> \n";
|
$color = '';
|
||||||
}
|
|
||||||
}
|
|
||||||
if ($precloud != '') $html .= "<div id=\"tagcloud_set\">$precloud</div>";
|
|
||||||
$html .="<div id=\"tagcloud_unset\">$cloud</div>";
|
|
||||||
$rem=count($tag_data)-$defcount;
|
|
||||||
if((!$alphasort)&&($counter>=$defcount)) $html .= "</div><br>[<span onclick=\"tageditcloud_toggle_extra('tagcloud_extra',this);\" style=\"color: #0000EF; font-weight:bold;\">show $rem more tags</span>]";
|
|
||||||
// $html.='<pre>'.var_export($itags,true).'</pre>';
|
|
||||||
return "<div id=\"tageditcloud\" class=\"tageditcloud\">$html</div>"; // FIXME: stupidasallhell
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$size = sprintf("%.2f", max($row['scaled'],0.5));
|
||||||
|
$js = htmlspecialchars('tageditcloud_toggle_tag(this,'.json_encode($full_tag).')',ENT_QUOTES); //Ugly, but it works
|
||||||
|
|
||||||
|
if(array_search($row['tag'],$image->tag_array) !== FALSE) {
|
||||||
|
if($used_first) {
|
||||||
|
$precloud .= " <span onclick='$js' class='tag-selected' style='font-size: ${size}em$color' title='${row['count']}'>$h_tag</span> \n";
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
$entry = " <span onclick='$js' class='tag-selected' style='font-size: ${size}em$color' title='${row['count']}'>$h_tag</span> \n";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$entry = " <span onclick='$js' style='font-size: ${size}em$color' title='${row['count']}'>$h_tag</span> \n";
|
||||||
|
}
|
||||||
|
|
||||||
|
if($counter++ <= $def_count) {
|
||||||
|
$cloud .= $entry;
|
||||||
|
} else {
|
||||||
|
$postcloud .= $entry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if($precloud != '') {
|
||||||
|
$html .= "<div id='tagcloud_set'>$precloud</div>";
|
||||||
|
}
|
||||||
|
|
||||||
|
if($postcloud != '') {
|
||||||
|
$postcloud = "<div id='tagcloud_extra' style='display: none;'>$postcloud</div>";
|
||||||
|
}
|
||||||
|
|
||||||
|
$html .= "<div id='tagcloud_unset'>$cloud$postcloud</div>";
|
||||||
|
|
||||||
|
if($sort_method != 'a' && $counter > $def_count) {
|
||||||
|
$rem = $counter - $def_count;
|
||||||
|
$html .= "</div><br>[<span onclick='tageditcloud_toggle_extra(this);' style='color: #0000EF; font-weight:bold;'>show $rem more tags</span>]";
|
||||||
|
}
|
||||||
|
|
||||||
|
return "<div id='tageditcloud' class='tageditcloud'>$html</div>"; // FIXME: stupidasallhell
|
||||||
|
}
|
||||||
|
|
||||||
private function can_tag($image) {
|
private function can_tag($image) {
|
||||||
global $config, $user;
|
global $user;
|
||||||
return (
|
return ($user->can("edit_image_tag") && (!$image->is_locked() || $user->can("edit_image_lock")));
|
||||||
$user->can("edit_image_tag") &&
|
|
||||||
(!$image->is_locked() || $user->can("edit_image_lock"))
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
|
@ -18,29 +18,29 @@ Array.prototype.editcloud_remove = function (ele) {
|
|||||||
return arr;
|
return arr;
|
||||||
};
|
};
|
||||||
|
|
||||||
function tageditcloud_toggle_extra(obj,hide) {
|
var hide_text = null;
|
||||||
var el = document.getElementById(obj);
|
function tageditcloud_toggle_extra(hide) {
|
||||||
el.style.display = (el.style.display != 'none' ? 'none' : '' );
|
if (hide_text == null) {
|
||||||
hide.innerHTML=(el.style.display != 'none' ? 'show less tags' : 'show more tags' );
|
hide_text = hide.innerHTML;
|
||||||
}
|
}
|
||||||
|
|
||||||
function tageditcloud_toggle_tag(ele) {
|
var el = document.getElementById('tagcloud_extra');
|
||||||
var thisTag = ele.innerHTML;
|
el.style.display = (el.style.display != 'none' ? 'none' : '' );
|
||||||
|
hide.innerHTML = (el.style.display != 'none' ? 'show fewer tags' : hide_text );
|
||||||
|
}
|
||||||
|
|
||||||
|
function tageditcloud_toggle_tag(ele,fullTag) {
|
||||||
var taglist = document.getElementById('tag_editor');
|
var taglist = document.getElementById('tag_editor');
|
||||||
var tags = taglist.value.split(' ');
|
var tags = taglist.value.split(' ');
|
||||||
|
|
||||||
// If tag is already listed, remove it
|
if (tags.editcloud_contains(fullTag)) {
|
||||||
if (tags.editcloud_contains(thisTag)) {
|
tags = tags.editcloud_remove(fullTag);
|
||||||
tags = tags.editcloud_remove(thisTag);
|
|
||||||
ele.className = 'tag-unselected';
|
ele.className = 'tag-unselected';
|
||||||
|
|
||||||
// Otherwise add it
|
|
||||||
} else {
|
} else {
|
||||||
tags.splice(0, 0, thisTag);
|
tags.splice(0, 0, fullTag);
|
||||||
ele.className = 'tag-selected';
|
ele.className = 'tag-selected';
|
||||||
}
|
}
|
||||||
|
|
||||||
taglist.value = tags.join(' ');
|
taglist.value = tags.join(' ');
|
||||||
|
|
||||||
document.getElementById('tags').focus();
|
document.getElementById('tags').focus();
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user