r3011 - getTagChart(): new function
authorDenis Ovsienko <infrastation@yandex.ru>
Mon, 27 Jul 2009 16:44:28 +0000 (16:44 +0000)
committerDenis Ovsienko <infrastation@yandex.ru>
Mon, 27 Jul 2009 16:44:28 +0000 (16:44 +0000)
 - renderTagStats(): move to interface.php, use data from getTagChart()
 - renderTagCheckbox(): do not attempt recursion, when there is no data
 - renderEntityTagsPortlet(): new function with code from renderEntityTags()
 - renderEntityTags(): use above; show tags quick list, when it helps
 - getTagList(): compute totals for refc

ChangeLog
inc/database.php
inc/functions.php
inc/interface.php
inc/ophandlers.php
install/init-dictbase.sql
upgrade.php

index 7ce9aec7338cb416f8d40dd76985437d18b943f1..e8c17560120de0112684b308733386074f893316 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,6 @@
 0.17.3
        update: even better search function (ticket:20)
+       new feature: tags quick list on "Tags" tab (ticket:259)
 0.17.2 2009-07-22
        new feature: configure default SNMP community (by jthurman)
        new feature: "$untagged", "$portless", "$nameless" and "$masklen_OP_NN" autotags
index 22e733536df7b1fe8c2eb28685b5f347016f16d5..aa1f87a79753c5cd85c16f6067586fef6720371c 100644 (file)
@@ -2008,49 +2008,6 @@ function getRackspaceStats ()
        return $ret;
 }
 
-function renderTagStats ()
-{
-       global $taglist, $root;
-       $query = "select id, tag, count(tag_id) as refcnt from " .
-               "TagTree inner join TagStorage on TagTree.id = TagStorage.tag_id " .
-               "group by tag_id order by refcnt desc limit 50";
-       // The same data is already present in pre-loaded tag list, but not in
-       // the form we need. So let's ask the DB server for cooked top list and
-       // use the cooked tag list to break it down.
-       $result = useSelectBlade ($query, __FUNCTION__);
-       $refc = $result->fetchAll (PDO::FETCH_ASSOC);
-       echo '<table border=1><tr><th>tag</th><th>total</th><th>objects</th><th>IPv4 nets</th><th>racks</th>';
-       echo '<th>IPv4 VS</th><th>IPv4 RS pools</th><th>users</th><th>files</th></tr>';
-       $pagebyrealm = array
-       (
-               'file' => 'files&tab=default',
-               'ipv4net' => 'ipv4space&tab=default',
-               'ipv4vs' => 'ipv4vslist&tab=default',
-               'ipv4rspool' => 'ipv4rsplist&tab=default',
-               'object' => 'depot&tab=default',
-               'rack' => 'rackspace&tab=default',
-               'user' => 'userlist&tab=default'
-       );
-       foreach ($refc as $ref)
-       {
-               echo "<tr><td>${ref['tag']}</td><td>${ref['refcnt']}</td>";
-               foreach (array ('object', 'ipv4net', 'rack', 'ipv4vs', 'ipv4rspool', 'user', 'file') as $realm)
-               {
-                       echo '<td>';
-                       if (!isset ($taglist[$ref['id']]['refcnt'][$realm]))
-                               echo '&nbsp;';
-                       else
-                       {
-                               echo "<a href='${root}?page=" . $pagebyrealm[$realm] . "&cft[]=${ref['id']}'>";
-                               echo $taglist[$ref['id']]['refcnt'][$realm] . '</a>';
-                       }
-                       echo '</td>';
-               }
-               echo '</tr>';
-       }
-       echo '</table>';
-}
-
 /*
 
 The following allows figuring out records in TagStorage, which refer to non-existing entities:
@@ -2984,10 +2941,13 @@ function getTagList ()
                                'tag' => $row['tag'],
                                'ci' => $ci++,
                                'parent_id' => $row['parent_id'],
-                               'refcnt' => array()
+                               'refcnt' => array ('total' => 0)
                        );
                if ($row['realm'])
+               {
                        $ret[$row['id']]['refcnt'][$row['realm']] = $row['refcnt'];
+                       $ret[$row['id']]['refcnt']['total'] += $row['refcnt'];
+               }
        }
        $result->closeCursor();
        return $ret;
index 80cfe91c6c4f1ffd798112efe89c899c4028587f..d4b0ac4393d79cbc8525895c503c09c90d53b513 100644 (file)
@@ -2114,4 +2114,33 @@ function dump ($var)
        echo '</pre></div>';
 }
 
+function getTagChart ($limit = 0, $realm = 'total', $special_tags = array())
+{
+       global $taglist;
+       // first build top-N chart...
+       $toplist = array();
+       foreach ($taglist as $taginfo)
+               if (isset ($taginfo['refcnt'][$realm]))
+                       $toplist[$taginfo['id']] = $taginfo['refcnt'][$realm];
+       arsort ($toplist, SORT_NUMERIC);
+       $ret = array();
+       $done = 0;
+       foreach (array_keys ($toplist) as $tag_id)
+       {
+               $ret[$tag_id] = $taglist[$tag_id];
+               if (++$done == $limit)
+                       break;
+       }
+       // ...then make sure, that every item of the special list is shown
+       // (using the same sort order)
+       $extra = array();
+       foreach ($special_tags as $taginfo)
+               if (!array_key_exists ($taginfo['id'], $ret))
+                       $extra[$taginfo['id']] = $taglist[$taginfo['id']]['refcnt'][$realm];
+       arsort ($extra, SORT_NUMERIC);
+       foreach (array_keys ($extra) as $tag_id)
+               $ret[] = $taglist[$tag_id];
+       return $ret;
+}
+
 ?>
index dd6352c7677b345cdce611675e3804a8e1bf34c5..6a31c4d747970c5107526c495395a2a1f4560287 100644 (file)
@@ -3583,7 +3583,7 @@ function renderSystemReports ()
                ),
                array
                (
-                       'title' => 'Tags top-50',
+                       'title' => 'Tags top list',
                        'type' => 'custom',
                        'func' => 'renderTagStats'
                ),
@@ -3662,6 +3662,41 @@ function renderReports ($what)
        echo "</table>\n";
 }
 
+function renderTagStats ()
+{
+       global $taglist, $root;
+       echo '<table border=1><tr><th>tag</th><th>total</th><th>objects</th><th>IPv4 nets</th><th>racks</th>';
+       echo '<th>IPv4 VS</th><th>IPv4 RS pools</th><th>users</th><th>files</th></tr>';
+       $pagebyrealm = array
+       (
+               'file' => 'files&tab=default',
+               'ipv4net' => 'ipv4space&tab=default',
+               'ipv4vs' => 'ipv4vslist&tab=default',
+               'ipv4rspool' => 'ipv4rsplist&tab=default',
+               'object' => 'depot&tab=default',
+               'rack' => 'rackspace&tab=default',
+               'user' => 'userlist&tab=default'
+       );
+       foreach (getTagChart (getConfigVar ('TAGS_TOPLIST_SIZE')) as $taginfo)
+       {
+               echo "<tr><td>${taginfo['tag']}</td><td>" . $taginfo['refcnt']['total'] . "</td>";
+               foreach (array ('object', 'ipv4net', 'rack', 'ipv4vs', 'ipv4rspool', 'user', 'file') as $realm)
+               {
+                       echo '<td>';
+                       if (!isset ($taginfo['refcnt'][$realm]))
+                               echo '&nbsp;';
+                       else
+                       {
+                               echo "<a href='${root}?page=" . $pagebyrealm[$realm] . "&cft[]=${taginfo['id']}'>";
+                               echo $taginfo['refcnt'][$realm] . '</a>';
+                       }
+                       echo '</td>';
+               }
+               echo '</tr>';
+       }
+       echo '</table>';
+}
+
 function dragon ()
 {
        startPortlet ('Here be dragons');
@@ -4703,23 +4738,22 @@ function renderTagCheckbox ($inputname, $preselect, $taginfo, $refcnt_realm = ''
        if (strlen ($refcnt_realm) and isset ($taginfo['refcnt'][$refcnt_realm]))
                echo ' <i>(' . $taginfo['refcnt'][$refcnt_realm] . ')</i>';
        echo "</label></td></tr>\n";
-       foreach ($taginfo['kids'] as $kid)
-               $self ($inputname, $preselect, $kid, $refcnt_realm, $level + 1);
+       if (isset ($taginfo['kids']))
+               foreach ($taginfo['kids'] as $kid)
+                       $self ($inputname, $preselect, $kid, $refcnt_realm, $level + 1);
 }
 
-function renderEntityTags ($entity_id)
+function renderEntityTagsPortlet ($title, $tags, $preselect, $realm)
 {
-       global $tagtree, $target_given_tags, $pageno, $etype_by_pageno, $target_given_tags;
-       startPortlet ('Tag list');
+       startPortlet ($title);
        echo '<table border=0 cellspacing=0 cellpadding=3 align=center>';
        printOpFormIntro ('saveTags');
-       // Show a tree of tags with preselection, which matches current chain.
-       foreach ($tagtree as $taginfo)
-               renderTagCheckbox ('taglist', $target_given_tags, $taginfo, $etype_by_pageno[$pageno]);
+       foreach ($tags as $taginfo)
+               renderTagCheckbox ('taglist', $preselect, $taginfo, $realm);
        echo '<tr><td class=tdleft>';
        printImageHREF ('SAVE', 'Save changes', TRUE);
        echo "</form></td><td class=tdright>";
-       if (!count ($target_given_tags))
+       if (!count ($preselect))
                printImageHREF ('CLEAR gray');
        else
        {
@@ -4731,6 +4765,31 @@ function renderEntityTags ($entity_id)
        finishPortlet();
 }
 
+function renderEntityTags ($entity_id)
+{
+       global $tagtree, $taglist, $target_given_tags, $pageno, $etype_by_pageno;
+       echo '<table border=0 width="100%"><tr>';
+
+       if (count ($taglist) > getConfigVar ('TAGS_QUICKLIST_THRESHOLD'))
+       {
+               $minilist = getTagChart (getConfigVar ('TAGS_QUICKLIST_SIZE'), $etype_by_pageno[$pageno], $target_given_tags);
+               // It could happen, that none of existing tags have been used in the current realm.
+               if (count ($minilist))
+               {
+                       echo '<td class=pcleft width="50%">';
+                       renderEntityTagsPortlet ('Quick list', $minilist, $target_given_tags, $etype_by_pageno[$pageno]);
+                       echo '</td>';
+               }
+       }
+
+       // do not do anything about empty tree, trigger function ought to work this out
+       echo '<td class=pcright>';
+       renderEntityTagsPortlet ('Full tree', $tagtree, $target_given_tags, $etype_by_pageno[$pageno]);
+       echo '</td>';
+
+       echo '</tr></table>';
+}
+
 function printTagTRs ($cell, $baseurl = '')
 {
        if (getConfigVar ('SHOW_EXPLICIT_TAGS') == 'yes' and count ($cell['etags']))
@@ -4810,7 +4869,7 @@ function renderCellFilterPortlet ($preselect, $realm, $bypass_name = '', $bypass
                // Repack matching predicates in a way, which tagOnChain() understands.
                foreach (array_keys ($pTable) as $pname)
                        if (mb_ereg_match ($psieve, $pname))
-                               $myPredicates[] = array ('id' => $pname, 'tag' => $pname, 'kids' => array());
+                               $myPredicates[] = array ('id' => $pname, 'tag' => $pname);
                if (!count ($myPredicates))
                        echo "<tr><td colspan=2 class='tagbox sparenetwork'>(no predicates to show)</td></tr>";
                else
index b0321ccd017815658cc698be3f9fd80d26eca549..7f13eda20672412a07092af06eda039fd5989292 100644 (file)
@@ -1010,6 +1010,9 @@ function resetUIConfig()
        setConfigVar ('FILTER_SUGGEST_EXTRA','no');
         setConfigVar ('DEFAULT_SNMP_COMMUNITY','public');
        setConfigVar ('IPV4_ENABLE_KNIGHT','yes');
+       setConfigVar ('TAGS_TOPLIST_SIZE','50');
+       setConfigVar ('TAGS_QUICKLIST_SIZE','20');
+       setConfigVar ('TAGS_QUICKLIST_THRESHOLD','50');
        return buildRedirectURL (__FUNCTION__, 'OK');
 }
 
index 961056147f3801d5d5906bd17a98c6b920cd1186..214ba9ecd270168984c1d889e64c711195719255 100644 (file)
@@ -229,6 +229,9 @@ INSERT INTO `Config` (varname, varvalue, vartype, emptyok, is_hidden, descriptio
 ('FILTER_SUGGEST_EXTRA','no','string','no','no','Suggest extra expression in list filter'),
 ('DEFAULT_SNMP_COMMUNITY','public','string','no','no','Default SNMP Community string'),
 ('IPV4_ENABLE_KNIGHT','yes','string','no','no','Enable IPv4 knight feature'),
+('TAGS_TOPLIST_SIZE','50','uint','yes','no','Tags top list size'),
+('TAGS_QUICKLIST_SIZE','20','uint','no','no','Tags quick list size'),
+('TAGS_QUICKLIST_THRESHOLD','50','uint','yes','no','Tags quick list threshold'),
 ('DB_VERSION','0.17.2','string','no','yes','Database version.');
 
 INSERT INTO `Script` VALUES ('RackCode','allow {$userid_1}');
index 923bce1ae1efc1a13a942fb6e39ff92f08e16b91..3ba492821551ea1968242cf208cfbdaf1e6d5827 100644 (file)
@@ -34,6 +34,7 @@ function getDBUpgradePath ($v1, $v2)
                '0.17.0',
                '0.17.1',
                '0.17.2',
+               '0.17.3',
        );
        if (!in_array ($v1, $versionhistory) or !in_array ($v2, $versionhistory))
                return NULL;
@@ -255,6 +256,12 @@ CREATE TABLE `LDAPCache` (
                        $query[] = "INSERT INTO `AttributeMap` (`objtype_id`, `attr_id`, `chapter_id`) VALUES (2,2,27)";
                        $query[] = "UPDATE Config SET varvalue = '0.17.2' WHERE varname = 'DB_VERSION'";
                        break;
+               case '0.17.3':
+                       $query[] = "INSERT INTO `Config` (varname, varvalue, vartype, emptyok, is_hidden, description) VALUES ('TAGS_TOPLIST_SIZE','50','uint','yes','no','Tags top list size')";
+                       $query[] = "INSERT INTO `Config` (varname, varvalue, vartype, emptyok, is_hidden, description) VALUES ('TAGS_QUICKLIST_SIZE','20','uint','no','no','Tags quick list size')";
+                       $query[] = "INSERT INTO `Config` (varname, varvalue, vartype, emptyok, is_hidden, description) VALUES ('TAGS_QUICKLIST_THRESHOLD','50','uint','yes','no','Tags quick list threshold')";
+                       $query[] = "UPDATE Config SET varvalue = '0.17.3' WHERE varname = 'DB_VERSION'";
+                       break;
                default:
                        showFailure ("executeUpgradeBatch () failed, because batch '${batchid}' isn't defined", __FILE__);
                        die;