4 * TAGGING PLUG-IN FOR NucleusCMS
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 * (see nucleus/documentation/index.html#license for more info)
14 * @author Original Author nakahara21
15 * @copyright 2005-2006 nakahara21
16 * @license http://www.gnu.org/licenses/gpl.txt
17 * GNU GENERAL PUBLIC LICENSE Version 2, June 1991
19 * @link http://nakahara21.com
22 * 0.64 modified createTagLink function
23 * 0.63 fix Magical code
24 * 0.62 add function doIf() for NucleusCMS version3.3
25 * 0.6 fix delete tags when item update(425)
26 * mod scanExistTags function
27 * mod get tagLink title
29 * 0.5 TAG sort modified
30 * 0.43 fix URL generate
31 * 0.42 add URL selected tag check
32 * 0.41 security fix and add some trick
33 * 0.4 fixed bug: numlic only
34 * 0.3 fixed bug: delete action
35 * 0.2 supports and/or query
38 * THESE PLUG-INS ARE DEDICATED TO ALL THOSE NucleusCMS USERS
39 * WHO FIGHT CORRUPTION AND IRRATIONAL IN EVERY DAY OF THEIR LIVES.
43 if (!defined('_TAGEX_TABLE_DEFINED')) {
44 define('_TAGEX_TABLE_DEFINED', 1);
45 define('_TAGEX_TABLE', sql_table('plug_tagex'));
46 define('_TAGEX_KLIST_TABLE', sql_table('plug_tagex_klist'));
49 class NP_TagEX extends NucleusPlugin
54 return 'Tags Extension';
58 return 'nakahara21 + shizuki';
62 return 'http://nakahara21.com';
68 function getDescription()
70 return 'Tags Extension (for Japanese users)';
73 function supportsFeature($what)
76 case 'SqlTablePrefix':
85 $this->createOption('flg_erase', 'Erase data on uninstall.', 'yesno', 'no');
86 // <editable template mod by shizuki>
87 $this->createOption('editTagOrder', 'editform tag order', 'select',
88 '1', 'amount(desc)|1|amount(asc)|2|tag\'s order|3|random|4');
89 $this->createOption('and', 'template for \'and\'', 'textarea',
90 '<span style="font-family:tahoma;font-size:smaller;"> '
91 . ' <a href="<%andurl%>" title="narrow">&</a>.');
92 $this->createOption('or', 'template for \'or\'', 'textarea',
93 '<a href="<%orurl%>" title="expand">or</a> </span>');
94 $this->createOption('tagIndex', 'template for \'tagIndex\'', 'textarea',
95 '<%and%><%or%><span style="font-size:<%fontlevel%>em" '
96 . 'title="<%tagamount%> post(s)! <%tagitems%>"><a href="<%taglinkurl%>"><%tag%></a></span>');
97 $this->createOption('tagItemHeader', 'template for \'tagItemHeader\'', 'textarea',
99 $this->createOption('tagItem', 'template for \'tagItem\'', 'textarea',
100 '<%itemid%>:<%itemtitle%>');//<%
101 $this->createOption('tagItemSeparator', 'template for \'tagItemSeparator\'', 'text',
103 $this->createOption('tagItemFooter', 'template for \'tagItemFooter\'', 'textarea',
105 $this->createOption('tagIndexSeparator', 'template for \'tagIndexSeparator\'', 'text',
107 $this->createOption('tagsonlycurrent', 'show tags only current blog have', 'yesno',
109 $this->createOption('colorfulhighlight', 'colorful highlight mode ?', 'yesno',
111 $this->createOption('highlight', 'template for normal highlightmode', 'text',
112 '<span class="highlight">\0</span>');
113 //</mod by shizuki>*/
114 $table_q = 'CREATE TABLE IF NOT EXISTS ' . _TAGEX_TABLE . ' ('
115 . ' `inum` INT(9) NOT NULL default "0" PRIMARY KEY, '
116 . ' `itags` TEXT NOT NULL, '
117 . ' `itagreg` TIMESTAMP(14) NOT NULL'
120 $table_q = 'CREATE TABLE IF NOT EXISTS ' . _TAGEX_KLIST_TABLE . ' ('
121 . ' `listid` INT(9) NOT NULL AUTO_INCREMENT PRIMARY KEY, '
122 . ' `tag` VARCHAR(255) default NULL, '
123 . ' `inums` TEXT NOT NULL, '
124 . ' `inums_count` INT(11) NOT NULL default "0", '
125 . ' `ireg` TIMESTAMP(14) NOT NULL'
132 if ($this->getOption('flg_erase') == 'yes') {
133 sql_query('DROP TABLE IF EXISTS ' . _TAGEX_TABLE);
134 sql_query('DROP TABLE IF EXISTS ' . _TAGEX_KLIST_TABLE);
138 function getTableList()
146 function getEventList()
152 'EditItemFormExtras',
160 * Nucleus event functions
163 function quote_smart($value)
165 // Escape SQL query strings
166 if (is_array($value)) {
167 if (get_magic_quotes_gpc()) {
168 $value = array_map("stripslashes", $value);
170 if (!array_map("is_numeric",$value)) {
171 if (version_compare(phpversion(),"4.3.0") == "-1") {
172 $value = array_map("mysql_escape_string", $value);
174 $value = array_map("mysql_real_escape_string", $value);
177 $value = intval($value);
180 if (get_magic_quotes_gpc()) {
181 $value = stripslashes($value);
183 if (!is_numeric($value)) {
184 if (version_compare(phpversion(), "4.3.0") == "-1") {
185 $value = "'" . mysql_escape_string($value) . "'";
187 $value = "'" . mysql_real_escape_string($value) . "'";
190 $value = intval($value);
196 function event_PreItem($data)
199 global $currentTemplateName;
200 $currTemplateName = $this->quote_smart($currentTemplateName);
201 $templateDescTable = sql_table('template_desc');
202 $q_query = 'SELECT tddesc as result '
204 . 'WHERE tdname = %s';
205 $q_query = sprintf($q_query, $templateDescTable, $currTemplateName);
206 $currentTemplateDesc = quickQuery($q_query);
207 if (eregi('<highlightTagsAll>', $currentTemplateDesc)) {
208 $tags = $this->scanExistTags(0, 99999999);
212 $highlightKeys = array_keys($tags);
214 } elseif (eregi('<highlightTags>', $currentTemplateDesc)) {
215 $requestT = $this->getNoDecodeQuery('tag');
216 if (empty($requestT)) {
219 $requestTarray = $this->splitRequestTags($requestT);
220 $reqAND = array_map(array(&$this, "_rawdecode"), $requestTarray['and']);
221 if ($requestTarray['or']) {
222 $reqOR = array_map(array(&$this, "_rawdecode"), $requestTarray['or']);
225 $highlightKeys = array_merge($reqAND, $reqOR);
227 $highlightKeys = $reqAND;
232 $template['highlight'] = $this->getOption('highlight');
233 $curItem =& $data['item'];
234 if ($this->getOption('colorfulhighlight') == 'no') {// original mode
235 $curItem->body = highlight($curItem->body, $highlightKeys, $template['highlight']);
236 $curItem->more = highlight($curItem->more, $highlightKeys, $template['highlight']);
240 * use other color for each tags
245 foreach ($highlightKeys as $qValue) {
246 $pattern = '<span class=\'highlight_' . $sh . '\'>\0</span>';
247 $curItem->body = highlight($curItem->body, $qValue, $pattern);
253 if ($curItem->more) {
255 foreach ($highlightKeys as $qValue) {
256 $pattern = '<span class=\'highlight_' . $sh . '\'>\0</span>';
257 $curItem->more = highlight($curItem->more, $qValue, $pattern);
269 * extra forms function
277 * TAGs only current blog
279 * From http://blog.uribou.net/
282 function _ItemFormExtras($oldforj = '', $itags = '', $tagrows, $tagcols, $blogid = 0)
284 $blogid = intval($blogid);
285 // Exstra form for add or update Item
286 if (strstr(serverVar('HTTP_USER_AGENT'), 'Gecko')) {
287 $divStyles = 'height: 24em;'
289 . 'border:1px solid lightblue;'
290 . 'margin-top:3.8em;'
291 . 'padding-left:0.5em;'
292 . '-moz-column-count: 3;'
293 . '-moz-column-gap: 0.5em;';
294 $txAStyles = 'width:10em;'
298 $divStyles = 'height: 200px;'
300 $txAStyles = 'width:60%;';
303 . "<h3>TagEX</h3>\n\t\t"
304 . '<p style="float:left">' . "\n\t\t\t"
305 . '<label for="tagex">Tag(s):</label>' . "\n\t\t\t"
306 . '<a href="javascript:resetOlder'
307 . "('" . $oldforj . "')"
308 . '">[Reset]</a><br />' . "\n\t\t\t"
309 . '<textarea id="tagex" name="itags" rows="' . intval($tagrows)
310 . '" cols="' . intval($tagcols) . '" style="' . $txAStyles . '"'
312 . htmlspecialchars($itags) . '</textarea>' . "\n\t\t"
314 . '<script language="JavaScript" type="text/javascript">' . "\n"
316 . 'function insertag(tag){' . "\n\t"
317 . "if(document.getElementById('tagex').value != '')\n\t\t"
318 . 'tag = "\n" + tag;' . "\n\t"
319 . "document.getElementById('tagex').value += tag;\n"
321 . "function resetOlder(old){\n\t"
322 . "document.getElementById('tagex').value = old;\n"
325 . '<div style="' . $divStyles . '" class="tagex">' . "\n";
327 $tagOrder = intval($this->getOption('editTagOrder'));
328 if ($this->getOption('tagsonlycurrent') == no) {
329 $existTags = $this->scanExistTags(0, 99999999, $tagOrder);
331 $existTags = $this->scanExistTags(1, 99999999, $tagOrder, $blogid);
334 $existTags = array_keys($existTags);
336 for ($i=0; $i < count($existTags); $i++) {
337 $exTags = htmlspecialchars($existTags[$i]);
338 $printData = '<li><a href="javascript:insertag'
339 . "('" . $exTags . "')" . '">'
340 . $exTags . '</a></li>' . "\n";
343 echo '</div><br style="clear:all;" />' . "\n";
346 function event_AddItemFormExtras($data)
348 global $CONF, $blogid;
349 if (is_numeric($blogid)) {
350 $blogid = intval($blogid);
352 $blogid = intval(getBlogIDFromName($blogid));
354 if (empty($blogid)) {
355 $blogid = intval($CONF['DefaultBlog']);
358 $oldforj = $itags = '';
359 $this->_ItemFormExtras($oldforj, $itags, 3, 40, $blogid);// <current blog only />
362 function event_EditItemFormExtras($data)
364 // Initialize tags when it have
365 $item_id = intval($data['variables']['itemid']);
366 $query = 'SELECT itags FROM %s WHERE inum = %d';
367 $result = sql_query(sprintf($query, _TAGEX_TABLE, $item_id));
368 if (mysql_num_rows($result) > 0) {
369 $itags = mysql_result($result,0,0);
371 $oldforj = str_replace("\n", '\n', htmlspecialchars($itags));
372 $blogid = getBlogIDFromItemID($item_id);
373 $blogid = intval($blogid);
375 // current blog onry mode
376 $this->_ItemFormExtras($oldforj, $itags, 5, 20, $blogid);
379 function event_PostAddItem($data)
381 // Add tags when it add for Item
382 $itags = trim(requestVar('itags'));
386 $inum = intval($data['itemid']);
387 $query = 'INSERT INTO %s (inum, itags) VALUES (%d, %s)';
388 $query = sprintf($query, _TAGEX_TABLE, $inum, $this->quote_smart($itags));
390 $temp_tags_array = preg_split("/[\r\n,]+/", $itags);
391 for ($i=0; $i < count($temp_tags_array); $i++) {
392 $this->mergeTags(trim($temp_tags_array[$i]), $inum);
396 function event_PreUpdateItem($data)
398 // Add tags when it add for Item
399 $itags = trim(requestVar('itags'));
400 $inum = intval($data['itemid']);
401 $query = 'SELECT itags as result FROM %s WHERE inum = %d';
402 $oldTags = quickQuery(sprintf($query, _TAGEX_TABLE, $inum));
403 if ($itags == $oldTags) {
406 $query = 'DELETE FROM %s WHERE inum = %d';
407 sql_query(sprintf($query, _TAGEX_TABLE, $inum));
408 if (!empty($itags)) {
409 $query = 'INSERT INTO %s (inum, itags) VALUES (%d, %s)';
410 $query = sprintf($query, _TAGEX_TABLE, $inum, $this->quote_smart($itags));
413 $old_tags_array = $this->getTags($oldTags);
414 $new_tags_array = $this->getTags($itags);
415 $deleteTags = $this->array_minus_array($old_tags_array, $new_tags_array);
416 for ($i=0; $i < count($deleteTags); $i++) {
417 $this->deleteTags($deleteTags[$i], $inum);
419 $addTags = $this->array_minus_array($new_tags_array, $old_tags_array);
420 for ($i=0; $i < count($addTags); $i++) {
421 $this->mergeTags($addTags[$i], $inum);
426 function event_PreDeleteItem($data)
428 // Delete tags when it for deleted Item
429 // or delete Itemid from TAG table
430 $inum = intval($data['itemid']);
431 $query = 'SELECT itags as result FROM %s WHERE inum = %d';
432 $oldTags = quickQuery(sprintf($query, _TAGEX_TABLE, $inum));
433 if (empty($oldTags)) {
436 $query = 'DELETE FROM %s WHERE inum = %d';
437 sql_query(sprintf($query, _TAGEX_TABLE, $inum));
438 $deleteTags = $this->getTags($oldTags);
439 for ($i=0; $i < count($deleteTags); $i++) {
440 $this->deleteTags($deleteTags[$i], $inum);
445 //------------------------------------------------------
447 function getTags($str)
449 // extract Item's TAG for array
450 $tempArray = preg_split("/[\r\n,]+/", $str);
451 $returnArray = array_map('trim', $tempArray);
452 return array_unique($returnArray);
455 function array_minus_array($a, $b)
457 // update Item's TAGs
458 $c = array_diff($a,$b);
459 $c = array_intersect($c, $a);
460 return array_values($c);
463 function deleteTags($tag, $inum)
465 // Delete TAGs and TAG's Item
466 $inum = intval($inum);
467 $tag = $this->quote_smart($tag);
468 $f_query = "SELECT inums FROM " . _TAGEX_KLIST_TABLE
469 . " WHERE tag = " . $tag
470 . ' AND inums REGEXP "(^|,)' . $inum . '(,|$)"'
471 . ' ORDER BY ireg DESC';
472 $findres = sql_query($f_query);
473 if (mysql_num_rows($findres) == 0) {
476 $temp_inums = mysql_result($findres, 0, 0);
477 if ($temp_inums == $inum) {
478 $query = 'DELETE FROM %s WHERE tag = %s';
479 sql_query(sprintf($query, _TAGEX_KLIST_TABLE, $tag));
482 $inums_array = array();
483 $inums_array = explode(',', $temp_inums);
484 $trans = array_flip($inums_array);
485 unset($trans[$inum]);
486 $inums_array = array_flip($trans);
487 $inums_count = count($inums_array);
488 // $inums = @implode(",", $inums_array);
489 $inums = implode(",", $inums_array);
490 if (!empty($inums)) {
491 $update_query = 'UPDATE %s '
493 . 'inums_count = %d '
495 $iCount = intval($inums_count);
496 $quoteInums = $this->quote_smart($inums);
497 sql_query(sprintf($update_query, _TAGEX_KLIST_TABLE, $quoteInums, $iCount, $tag));
501 function mergeTags($tag, $inum)
508 $inums_array = array();
510 $inum = intval($inum);
511 $tag = $this->quote_smart($tag);
512 $f_query = 'SELECT inums'
513 . ' FROM ' . _TAGEX_KLIST_TABLE
514 . ' WHERE tag = ' . $tag
515 . ' ORDER BY ireg DESC';
516 $findres = sql_query($f_query);
517 if (mysql_num_rows($findres) > 0) {
518 $temp_inums = mysql_result($findres, 0, 0);
519 $inums_array = explode(',', $temp_inums);
520 if (!in_array($inum, $inums_array)) {
521 $inums = $temp_inums . ',' . $inum;
522 $inums_count = count($inums_array) + 1;
525 $q_query = 'INSERT INTO %s '
526 . '(tag, inums, inums_count) '
527 . 'VALUES (%s, %d, 1)';
528 sql_query(sprintf($q_query, _TAGEX_KLIST_TABLE, $tag, intval($inum)));
531 if (!empty($inums)) {
532 $q_query = 'UPDATE %s SET inums = %s, inums_count = %d WHERE tag = %s';
533 $iCount = intval($inums_count);
534 $quoteInums = $this->quote_smart($inums);
535 sql_query(sprintf($q_query, _TAGEX_KLIST_TABLE, $quoteInums, $iCount, $tag));
539 function scanExistItem($narrowMode = 0, $blogid = 0)
541 /// Select Items when Categories or Sub-categories or Archive selected
542 global $manager, $CONF, $blog, $catid, $archive;
547 $b =& $manager->getBlog($blogid);
551 $b =& $manager->getBlog($CONF['DefaultBlog']);
554 if ($narrowMode > 0) {
555 $where .= ' and i.iblog = ' . intval($b->getID());
557 if ($catid && $narrowMode > 1) {
558 $catid = intval($catid);
559 if ($manager->pluginInstalled('NP_MultipleCategories')) {
560 $where .= ' and ((i.inumber = p.item_id'
561 . ' and (p.categories REGEXP "(^|,)' . $catid . '(,|$)"'
562 . ' or i.icat = ' . $catid . '))'
563 . ' or (i.icat = ' . $catid
564 . ' and p.item_id IS NULL))';
565 $mtable = ' LEFT JOIN '
566 . sql_table('plug_multiple_categories') . ' as p'
567 . ' ON i.inumber = p.item_id';
568 $mplugin =& $manager->getPlugin('NP_MultipleCategories');
570 if ($subcatid && method_exists($mplugin, 'getRequestName')) {
572 $subcatid = intval($subcatid);
573 $scatTable = sql_table('plug_multiple_categories_sub');
574 $tres_query = 'SELECT * FROM %s WHERE scatid = %d';
575 $tres_query = sprintf($tres_query, $scatTable, $subcatid);
576 $tres = sql_query($tres_query);
577 $ra = mysql_fetch_array($tres, MYSQL_ASSOC);
578 if (array_key_exists('parentid', $ra)) {
580 $Children = explode('/', $subcatid . $this->getChildren($subcatid));
582 if ($loop = count($Children) >= 2) {
583 for ($i=0; $i < $loop; $i++) {
584 $chidID = intval($Children[$i]);
585 $temp_whr[] = ' p.subcategories REGEXP "(^|,)' . $chidID . '(,|$)" ';
588 . implode (' or ', $temp_whr)
591 $where .= ' and p.subcategories REGEXP "(^|,)' . $subcatid . '(,|$)"';
596 $where .= ' and i.icat = ' . $catid;
602 sscanf($archive, '%d-%d-%d', $y, $m, $d);
604 $timestamp_start = mktime(0, 0, 0, $m, $d, $y);
605 $timestamp_end = mktime(0, 0, 0, $m, $d+1, $y);
607 $timestamp_start = mktime(0, 0, 0, $m, 1, $y);
608 $timestamp_end = mktime(0, 0, 0, $m+1, 1, $y);
610 $timestamp_start = mktime(0, 0, 0, 1, 1, $y);
611 $timestamp_end = mktime(0, 0, 0, 1, 1, $y+1);
613 $where .= ' and i.itime >= ' . mysqldate($timestamp_start)
614 . ' and i.itime < ' . mysqldate($timestamp_end);
616 $where .= ' and i.itime <= ' . mysqldate($b->getCorrectTime());
619 $iquery = 'SELECT i.inumber '
622 . ' WHERE i.idraft = 0'
624 $res = sql_query(sprintf($iquery, sql_table('item')));
625 while ($row = mysql_fetch_row($res)) {
626 $existInums[] = $row[0];
634 * add TAG's order and Random sort
636 * From http://blog.uribou.net/
639 function sortTags($tags, $sortMode = 0)
642 // sortMode 1:max first
643 // sortMode 2:min first
644 // sortMode 3:tag's order
646 $sortMode = intval($sortMode);
647 if (!$tags || $sortMode == 0) {
650 foreach ($tags as $tag => $inums) {
651 $tagCount[$tag] = count($inums);
661 uksort($tagCount, array(&$this, 'sortTagOrder'));
664 srand ((float) microtime() * 10000000);
665 $tmp_key = array_rand($tagCount, count($tagCount));
668 foreach ($tmp_key as $k => $v) {
675 foreach ($tagCount as $k => $v) {
681 function sortTagOrder($a, $b)
683 return strcasecmp($a, $b);
686 function scanExistTags($narrowMode = 0, $amount = 99999999, $sortmode = 0, $blogid = 0)
689 // $narrowMode = 0: all blogs
690 // $narrowMode = 1: currentblog only
691 // $narrowMode = 2: narrowed with catid/subcatid
692 $narrowMode = intval($narrowMode);
693 $amount = intval($amount);
694 $sortmode = intval($sortmode);
695 // <mod by shizuki />
696 if (is_numeric($blogid)) {
697 $blogid = intval($blogid);
699 $blogid = intval(getBlogIDFromName($blogid));
701 $existInums = array();
702 $existInums = $this->scanExistItem($narrowMode, $blogid);
703 $res = sql_query(sprintf('SELECT * FROM %s', _TAGEX_KLIST_TABLE));
704 while ($o = mysql_fetch_object($res)) {
705 $tagsk[$o->tag] = explode(',', $o->inums);
707 $tagsk[$o->tag] = array_intersect($tagsk[$o->tag], $existInums);
708 $tagsk[$o->tag] = array_values($tagsk[$o->tag]);
710 if (empty($tagsk[$o->tag])) {
711 unset($tagsk[$o->tag]);
714 $tagsk = $this->sortTags($tagsk, $sortmode);
715 if (count($tagsk) > $amount) {
716 $tagsk = array_slice($tagsk, 0, $amount);
721 function scanCount($tags)
723 // ? count TAGs have Item ?
725 foreach ($tags as $tag) {
726 $tempCount = count($tag);
727 $max = max($max, $tempCount);
728 $min = min($min, $tempCount);
730 return array($max, $min);
733 function getNoDecodeQuery($q)
735 // Get urlencoded TAGs
736 global $CONF, $manager;
738 if ($CONF['URLMode'] == 'pathinfo') {
739 $urlq = serverVar('REQUEST_URI');
740 $tempq = explode($q . '/', $urlq, 2);
741 if ($manager->pluginInstalled('NP_MagicalURL2') || $manager->pluginInstalled('NP_Magical')) {
742 $tempq = explode($q . '_', $urlq, 2);
745 if (!empty($tempq[1])) {
746 $tagq = explode('/', $tempq[1]);
747 if ($manager->pluginInstalled('NP_MagicalURL2') || $manager->pluginInstalled('NP_Magical')) {
748 $tagq = explode('_', $tempq[1]);
750 $str = preg_replace('|[^a-z0-9-~+_.#;,:@%]|i', '', $tagq[0]);
755 $urlq = serverVar('QUERY_STRING');
756 $urlq = str_replace('?', '', $urlq);
757 $urlq = explode('&', $urlq);
758 $qCnt = count($urlq);
759 for ($i=0; $i<$qCnt; $i++) {
760 $tempq = explode('=', $urlq[$i]);
761 if ($tempq[0] == $q) {
762 $str = preg_replace('|[^a-z0-9-~+_.#;,:@%]|i', '', $tempq[1]);
770 function splitRequestTags($q)
772 // extract TAGs to array
773 if (!strpos($q, '+') && !strpos($q, ':')) {
781 $tempAnd = explode('+', $q);
782 $andCnt = count($tempAnd);
783 for ($i=0; $i < $andCnt; $i++) {
784 $temp = explode(':', $tempAnd[$i]);
785 $res['and'][] = array_shift($temp);
786 if ($temp != array()) {
787 $res['or'] = array_merge($res['or'], $temp);
793 function doIf($key, $value)
798 $reqTags = $this->getNoDecodeQuery('tag');
799 if (!empty($reqTags)) {
800 $reqTagsArr = $this->splitRequestTags($reqTags);
801 $reqAND = array_map(array(&$this, "_rawdecode"), $reqTagsArr['and']);
802 if ($requestTarray['or']) {
803 $reqOR = array_map(array(&$this, "_rawdecode"), $reqTagsArr['or']);
811 $tagsArray = ($reqOR) ? array_merge($reqAND, $reqOR) : $reqAND;
812 return in_array($value, $tagsArray);
816 function doSkinVar($skinType, $type='list20/1/0/1/4')
818 // type[0]: type ( + amount (int))
819 // type[1]: $narrowMode (0/1/2)
820 // type[2]: sortMode (1/2/3/4)
821 // type[3]: Minimum font-sizem(em) 0.5/1/1.5/2...
822 // type[4]: Maximum font-sizem(em)
825 $type = 'list20/2/1/1/4';
827 $type = explode('/', $type);
828 if (eregi('list', $type[0])) {
829 $amount = eregi_replace("list", "", $type[0]);
832 } elseif (eregi('meta', $type[0])) {
833 $amount = eregi_replace("meta", "", $type[0]);
837 $amount = (!empty($amount)) ? intval($amount): 99999999;
839 $defaultType = array('list', '1', '0', '1', '4');
840 $type = $type + $defaultType;
841 $requestT = $this->getNoDecodeQuery('tag');
842 if (!empty($requestT)) {
843 $requestTarray = $this->splitRequestTags($requestT);
844 $reqAND = array_map(array(&$this, "_rawdecode"), $requestTarray['and']);
845 if ($requestTarray['or']) {
846 $reqOR = array_map(array(&$this, "_rawdecode"), $requestTarray['or']);
852 if ($requestTarray) {
853 $reqAndLink = array();
854 foreach ($reqAND as $val) {
855 $reqAndLink[] = '<a href="'
856 . $this->creatTagLink($val)
857 . '" title="' . $val . '">'
860 $reqANDp = implode('" + "', $reqAndLink);
862 $reqOrLink = array();
863 foreach ($reqOR as $val) {
864 $reqOrLink[] = '<a href="'
865 . $this->creatTagLink($val)
866 . '" title="' . $val . '">'
869 $reqORp = '"</u> or <u>"'
870 . implode('"</u> or <u>"', $reqOrLink);
872 echo '<h1> Tag for <u>"' . $reqANDp . $reqORp . '"</u></h1>';
876 // meta keywords="TAG"
879 global $manager, $itemid;
880 $itemid = intval($itemid);
881 if ($type[3] != 'ad') {
882 echo '<meta name="keywords" content="';
884 } elseif ($type[3] == 'ad') {
887 if ($skinType == 'item') {
888 $q = 'SELECT * FROM %s WHERE inum = %d';
889 $res = sql_query(sprintf($q, _TAGEX_TABLE, $itemid));
890 while ($o = mysql_fetch_object($res)) {
891 $temp_tags_array = preg_split("/[\n,]+/", trim($o->itags));
892 $temp_tags_count = count($temp_tags_array);
893 for ($i=0; $i < $temp_tags_count; $i++) {
894 $tag = trim($temp_tags_array[$i]);
895 $taglist[$i] = htmlspecialchars($tag, ENT_QUOTES, _CHARSET);
899 echo implode(' ', $taglist);
901 if ($tags = $this->scanExistTags(intval($type[1]), $amount, intval($type[2]))) {
904 foreach ($tags as $tag => $inums) {
905 $eachTag[$t] = htmlspecialchars($tag, ENT_QUOTES, _CHARSET);
908 if ($type[3] != 'ad') {
909 echo implode($sep, $eachTag);
910 } elseif ($type[3] == 'ad') {
911 $tag_str = implode($sep, $eachTag);
915 if ($type[3] != 'ad') {
917 } elseif ($type[3] == 'ad') {
918 // $tag_str = mb_convert_encoding($tag_str, 'UTF-8', 'UTF-8');
919 $tag_str = urlencode($tag_str);
923 // TAG list(tag cloud)
925 $template['and'] = $this->getOption('and');
926 $template['or'] = $this->getOption('or');
927 $template['tagIndex'] = $this->getOption('tagIndex');
928 $template['tagItemHeader'] = $this->getOption('tagItemHeader');
929 $template['tagItem'] = $this->getOption('tagItem');
930 $template['tagItemSeparator'] = $this->getOption('tagItemSeparator');
931 $template['tagItemFooter'] = $this->getOption('tagItemFooter');
932 $template['tagIndexSeparator'] = $this->getOption('tagIndexSeparator');
933 if ($tags = $this->scanExistTags($type[1])) {
934 if ($type[3] != $type[4]) {
935 $minFontSize = min((float)$type[3], (float)$type[4]) - 0.5;
936 $maxFontSize = max((float)$type[3], (float)$type[4]);
937 $levelsum = ($maxFontSize - $minFontSize) / 0.5;
938 list($maxCount, $minCount) = $this->scanCount($tags);
939 $eachCount = ceil(($maxCount - $minCount) / $levelsum);
943 $req = ($reqOR) ? array_merge($reqAND, $reqOR) : $reqAND;
944 foreach ($req as $tag) {
945 if (array_key_exists($tag, $tags)) {
946 $select = array_merge($select, $tags[$tag]);
947 $selected = array_unique($select);
951 foreach ($tags as $tag => $inums) {
953 if (!in_array($tag, $req)) {
955 // if (!in_array($tag, $req) && !array_diff($tags[$tag], $selected)) {
956 $tagCount[$tag] = count($inums);
959 $tagCount[$tag] = count($inums);
964 foreach ($tagCount as $k => $v) {
968 if (count($r) > $amount) {
969 $r = array_slice($r, 0, $amount);
972 if (count($r) == 1) {
975 $tags = $this->sortTags($r, intval($type[2]));
983 foreach ($tags as $tag => $inums) {
985 $tagAmount = count($inums);
987 $fontlevel = ceil($tagAmount / $eachCount) * 0.5 + $minFontSize;
992 /// Item's name had TAGs
993 $iids = array_slice($inums, 0, 4);
996 . ' SUBSTRING(ititle, 1, 12) as short_title'
1000 . ' inumber in (' . implode(',', $iids) . ') '
1003 $sTitles = sql_query($qQuery);
1005 while ($sTitle = mysql_fetch_assoc($sTitles)) {
1006 $shortTitle = mb_convert_encoding($sTitle['short_title'], _CHARSET, _CHARSET);
1007 $shortTitle = htmlspecialchars($shortTitle, ENT_QUOTES, _CHARSET);
1008 $printData['tagItem']
1010 'itemid' => intval($iids[$i]),
1011 'itemtitle' => $shortTitle . '..',
1014 $tagitems[] = TEMPLATE::fill($template['tagItem'], $printData['tagItem']);
1016 $tagitem = implode($template['tagItemSeparator'], $tagitems) . '...etc.';
1018 // Generate URL link to TAGs
1020 /*********************
1021 * comment out this line when nodisplay selected TAGs */
1022 // $req = ($reqOR) ? array_merge($reqAND, $reqOR) : $reqAND;
1023 /*********************/
1024 if ($req && !in_array($tag, $req)) {
1025 $printData['and'] = array(
1026 'andurl' => $this->creatTagLink($tag, $type[1], $requestT, '+') //AND link
1028 $printData['or'] = array(
1029 'orurl' => $this->creatTagLink($tag, $type[1], $requestT, ':') //OR link
1031 $and = TEMPLATE::fill($template['and'], $printData['and']); // insert URL to template
1032 $or = TEMPLATE::fill($template['or'], $printData['or']);
1035 // insert data to template
1036 $printData['tagIndex'] = array(
1039 'tag' => htmlspecialchars($tag, ENT_QUOTES, _CHARSET),
1040 'tagamount' => $tagAmount,
1041 'fontlevel' => $fontlevel,
1042 'taglinkurl' => $this->creatTagLink($tag, intval($type[1])),
1043 'tagitems' => $tagitem
1045 $eachTag[$t] = TEMPLATE::fill($template['tagIndex'], $printData['tagIndex']);
1047 // format outputdata and data output
1048 $eachTag[$t] .= $template['tagItemHeader'];
1049 if (!ereg('<%tagitems%>', $template['tagIndex'])) {//<%
1050 $eachTag[$t] .= $tagitem;
1052 $eachTag[$t] .= $template['tagItemFooter'];
1055 echo implode($template['tagIndexSeparator'], $eachTag);
1059 // show selected TAGs for <title></title>
1062 $req = ($reqOR) ? array_merge($reqAND, $reqOR) : $reqAND;
1063 $data = htmlspecialchars(implode('|', $req), ENT_QUOTES, _CHARSET);
1064 echo ' : Selected Tag(s) » "' . $data . '"';
1070 // end of switch(type)
1073 function doTemplateVar(&$item, $type = '')
1075 // <highlight selected TAGs mod by shizuki>
1076 $requestT = $this->getNoDecodeQuery('tag');
1077 if (!empty($requestT)) {
1078 $requestTarray = $this->splitRequestTags($requestT);
1079 $reqAND = array_map(array(&$this, "_rawdecode"), $requestTarray['and']);
1080 if($requestTarray['or']) {
1081 $reqOR = array_map(array(&$this, "_rawdecode"), $requestTarray['or']);
1083 $words = ($reqOR)? array_merge($reqAND, $reqOR): $reqAND;
1087 $iid = intval($item->itemid);
1088 $q = 'SELECT * FROM %s WHERE inum = %d';
1089 $res = sql_query(sprintf($q, _TAGEX_TABLE, $iid));
1090 while ($o = mysql_fetch_object($res)) {
1091 $temp_tags_array = preg_split("/[\n,]+/", trim($o->itags));
1092 $temp_tags_count = count($temp_tags_array);
1093 for ($i=0; $i < $temp_tags_count; $i++) {
1094 $tag = trim($temp_tags_array[$i]);
1095 $taglink = $this->creatTagLink($tag, 0);
1096 // highlight selected TAGs
1097 $key = array_search($tag, $words);
1101 if (in_array($tag, $words)) {
1102 $taglist[$i] = '<a href="'
1103 . $this->creatTagLink($tag, 0)
1104 . '" class="highlight_0" rel="tag">'
1105 . htmlspecialchars($tag, ENT_QUOTES, _CHARSET) . '</a>';
1107 $taglist[$i] = '<a href="'
1108 . $this->creatTagLink($tag, 0)
1110 . htmlspecialchars($tag, ENT_QUOTES, _CHARSET) . '</a>';
1115 // echo 'Tag: ' . implode(' / ', $taglist);
1116 echo implode(' / ', $taglist);
1120 function _rawencode($str)
1123 if (_CHERSET != 'UTF-8') {
1124 $str = mb_convert_encoding($str, "UTF-8", _CHARSET);
1126 $str = rawurlencode($str);
1127 $str = preg_replace('|[^a-z0-9-~+_.?#=&;,/:@%]|i', '', $str);
1131 function _rawdecode($str)
1133 $str = rawurldecode($str);
1134 if (_CHERSET != 'UTF-8') {
1135 $str = mb_convert_encoding($str, _CHARSET, "UTF-8");
1137 $str = htmlspecialchars($str);
1141 function getChildren($subcat_id)
1143 $subcat_id = intval($subcat_id);
1152 $mcatTable = sql_table('plug_multiple_categories_sub');
1153 $que = sprintf($que, $mcatTable, $subcat_id);
1154 $res = sql_query($que);
1155 while ($so = mysql_fetch_object($res)) {
1156 $r .= $this->getChildren($so->scatid)
1163 function creatTagLink($tag, $narrowMode = 0, $ready = '', $sep = '')
1165 global $manager, $CONF, $blogid, $catid; //, $subcatid;
1166 $linkparams = array();
1167 if (is_numeric($blogid)) {
1168 $blogid = intval($blogid);
1170 $blogid = intval(getBlogIDFromName($blogid));
1173 $blogid = $CONF['DefaultBlog'];
1175 $b =& $manager->getBlog($blogid);
1176 if ($narrowMode == 2) {
1178 $linkparams['catid'] = intval($catid);
1180 if ($manager->pluginInstalled('NP_MultipleCategories')) {
1181 $mcategories =& $manager->getPlugin('NP_MultipleCategories');
1182 if (method_exists($mcategories, 'getRequestName')) {
1183 $subrequest = $mcategories->getRequestName();
1185 $subrequest = 'subcatid';
1187 $mcategories->event_PreSkinParse(array());
1190 $linkparams[$subrequest] = intval($subcatid);
1195 if (!empty($ready)) {
1196 $requestTagsArray = $this->splitRequestTags($ready);
1197 foreach ($requestTagsArray['and'] as $key => $val) {
1198 if (!$this->_isValidTag($val)) {
1199 $trush = array_splice($requestTagsArray['and'], $key, 1);
1202 $reqAnd = implode('+', $requestTagsArray['and']);
1203 if (!empty($requestTagsArray['or'])) {
1204 foreach ($requestTagsArray['or'] as $key => $val) {
1205 if (!$this->_isValidTag($val)) {
1206 $trush = array_splice($requestTagsArray['and'], $key, 1);
1209 $reqOr = ':' . implode(':', $requestTagsArray['or']);
1211 $ready = $reqAnd . $reqOr;
1218 /*// <Original URL Generate code>
1219 // if ($CONF['URLMode'] == 'pathinfo')
1220 // $link = $CONF['IndexURL'] . '/tag/' . $ready . $sep . $this->_rawencode($tag);
1222 // $link = $CONF['IndexURL'] . '?tag=' . $ready . $sep . $this->_rawencode($tag);
1223 $link = $b->getURL();
1224 if (substr($link, -1) != '/') {
1225 if (substr($link, -4) != '.php') {
1229 if ($CONF['URLMode'] == 'pathinfo') {
1230 $link .= 'tag/' . $ready . $sep . $this->_rawencode($tag);
1232 $link .= '?tag=' . $ready . $sep . $this->_rawencode($tag);
1234 // </ Original URL Generate code> */
1237 $CONF['BlogURL'] = $b->getURL();
1238 $linkparams['tag'] = $ready . $sep . $this->_rawencode($tag);
1239 $uri = createBlogidLink($blogid, $linkparams);
1240 if (strstr ($uri, '//')) {
1241 $uri = preg_replace("/([^:])\/\//", "$1/", $uri);
1246 // </mod by shizuki>*/
1249 // if ($manager->pluginInstalled('NP_CustomURL')) {
1250 $linkparams['tag'] = $ready . $sep . $this->_rawencode($tag);
1251 $uri = createBlogidLink($blogid, $linkparams);
1252 if (strstr ($uri, '//')) {
1253 $uri = preg_replace("/([^:])\/\//", "$1/", $uri);
1256 /* } elseif ($manager->pluginInstalled('NP_MagicalURL2') || $manager->pluginInstalled('NP_Magical')) {
1257 $uri = createBlogidLink($blogid, $linkparams);
1258 if (strstr ($uri, '//')) {
1259 $uri = preg_replace("/([^:])\/\//", "$1/", $uri);
1261 $uri = substr($uri, 0, -5) . '_tag' . $ready . $sep . $this->_rawencode($tag);
1264 // </mod by shizuki>*/
1266 // return addLinkParams($link, $linkparams);
1270 * function Tag valid
1273 function _isValidTag($encodedTag)
1275 $encodedTag = rawurldecode($encodedTag);
1276 if (_CHERSET != 'UTF-8') {
1277 $str = mb_convert_encoding($encodedTag, _CHARSET, "UTF-8");
1279 $str = $this->quote_smart($str);
1280 $q = 'SELECT listid as result FROM %s WHERE tag = %s';
1281 $Vali = quickQuery(sprintf($q, _TAGEX_KLIST_TABLE, $str));
1282 if (!empty($Vali)) {