r2631 - judgeEntityRecord(): rename to judgeCell()
authorDenis Ovsienko <infrastation@yandex.ru>
Mon, 13 Apr 2009 15:18:46 +0000 (15:18 +0000)
committerDenis Ovsienko <infrastation@yandex.ru>
Mon, 13 Apr 2009 15:18:46 +0000 (15:18 +0000)
 - filterEntityRecordList(): rename to filterCellList()
 - prepareIPv4Tree(): perform parent_id processing locally instead of relying on getIPv4NetworkList()
 - buildCellFilter(): initial implementation of $_REQUEST to RackCode mapping
 - getUserAccounts(): replaced by listCells()
 - getIPv4NetworkList(): idem
 - loadFullEntityInfo(): rename to amplifyCell() and add IPv4 prefixes processing
 - listCells(): split columns into alias/expression pairs, toss column order a bit
 - init: load tags before trying to build user list, so the latter computation doesn't break
 - authenticate(): switch from getUserAccounts() to listCells() and add necessary temporary transformation
 - renderUserCell(): use workaround to display data returned by search
 - renderCell(): new function for record rendering
 - renderCellList(): new function for list rendering
 - renderUserList(): use renderCellList()
 - renderIPv4Space(): switch to cell framework
 - renderIPv4SpaceEditor(): idem
 - renderSearchResults(): employ renderCell()

inc/auth.php
inc/database.php
inc/functions.php
inc/init.php
inc/interface.php

index c884270..72f2685 100644 (file)
@@ -18,12 +18,17 @@ function authenticate ()
                showError ('secret.php misconfiguration: either user_auth_src or require_valid_user are missing', __FUNCTION__);
                exit (1);
        }
-       $accounts = getUserAccounts();
-       if ($accounts === NULL)
+       // This reindexing is necessary after switching to listCells(), which
+       // returns list indexed by id (while many other functions expect the
+       // user list to be indexed by username).
+       if (NULL === ($tmplist = listCells ('user')))
        {
                showError ('Failed to initialize access database.', __FUNCTION__);
                exit (1);
        }
+       $accounts = array();
+       foreach ($tmplist as $tmpval)
+               $accounts[$tmpval['user_name']] = $tmpval;
        if (isset ($script_mode) and $script_mode === TRUE)
                return;
        if (isset ($_REQUEST['logout']))
index 78c026d..c127eb3 100644 (file)
@@ -218,22 +218,50 @@ function getObjectList ($type_id = 0, $tagfilter = array(), $tfmode = 'any')
 
 // For a given realm return a list of entity records, each with
 // enough information for judgeEntityRecord() to execute.
-function listEntities ($realm)
+function listCells ($realm)
 {
        switch ($realm)
        {
        case 'object':
                $table = 'RackObject';
-               $columns = array ('id', 'name', 'objtype_id');
+               $columns = array
+               (
+                       'id' => 'id',
+                       'name' => 'name',
+                       'objtype_id' => 'objtype_id'
+               );
+               $keycolumn = 'id';
+               break;
+       case 'user':
+               $table= 'UserAccount';
+               $columns = array
+               (
+                       'user_id' => 'user_id',
+                       'user_name' => 'user_name',
+                       'user_password_hash' => 'user_password_hash',
+                       'user_realname' => 'user_realname'
+               );
+               $keycolumn = 'user_id';
+               break;
+       case 'ipv4net':
+               $table = 'IPv4Network';
+               $columns = array
+               (
+                       'id' => 'id',
+                       'ip' => 'INET_NTOA(IPv4Network.ip)',
+                       'mask' => 'mask',
+                       'name' => 'name'
+               );
                $keycolumn = 'id';
                break;
        default:
                showError ('invalid arg', __FUNCTION__);
-               break;
+               return NULL;
        }
        $query = 'select tag_id';
-       foreach ($columns as $column)
-               $query .= ", ${table}.${column}";
+       foreach ($columns as $alias => $expression)
+               // Automatically prepend table name to each single column, but leave all others intact.
+               $query .= ', ' . ($alias == $expression ? "${table}.${alias}" : "${expression} as ${alias}");
        $query .= " from ${table} left join TagStorage on entity_realm = '${realm}' and entity_id = ${table}.${keycolumn}";
        $query .= " order by ${table}.${keycolumn}, tag_id";
        $result = useSelectBlade ($query, __FUNCTION__);
@@ -246,9 +274,10 @@ function listEntities ($realm)
                // Init the first record anyway, but store tag only if there is one.
                if (!isset ($ret[$entity_id]))
                {
-                       $ret[$entity_id] = array ('realm' => $realm, 'etags' => array());
-                       foreach ($columns as $column)
-                               $ret[$entity_id][$column] = $row[$column];
+                       $ret[$entity_id] = array ('realm' => $realm);
+                       foreach (array_keys ($columns) as $alias)
+                               $ret[$entity_id][$alias] = $row[$alias];
+                       $ret[$entity_id]['etags'] = array();
                        if ($row['tag_id'] != NULL && isset ($taglist[$row['tag_id']]))
                                $ret[$entity_id]['etags'][] = array
                                (
@@ -275,9 +304,8 @@ function listEntities ($realm)
 }
 
 // This function can be used with array_walk().
-function loadFullEntityInfo (&$record, $dummy = NULL)
+function amplifyCell (&$record, $dummy = NULL)
 {
-       $record['test'] = __FUNCTION__ . ' was here';
        switch ($record['realm'])
        {
        case 'object':
@@ -287,6 +315,10 @@ function loadFullEntityInfo (&$record, $dummy = NULL)
                $record['ipv4rspools'] = getRSPoolsForObject ($record['id']);
                $record['files'] = getFilesOfEntity ($record['realm'], $record['id']);
                break;
+       case 'ipv4net':
+               $record['ip_bin'] = ip2long ($record['ip']);
+               $record['parent_id'] = getIPv4AddressNetworkId ($record['ip'], $record['mask']);
+               break;
        default:
        }
 }
@@ -1345,39 +1377,6 @@ function bindIpToObject ($ip = '', $object_id = 0, $name = '', $type = '')
        return $result ? '' : (__FUNCTION__ . '(): useInsertBlade() failed');
 }
 
-// Collect data necessary to build a tree. Calling functions should care about
-// setting the rest of data.
-function getIPv4NetworkList ($tagfilter = array(), $tfmode = 'any')
-{
-       $whereclause = getWhereClause ($tagfilter);
-       $query =
-               "select distinct id, INET_NTOA(ip) as ip, mask, name " .
-               "from IPv4Network left join TagStorage on id = entity_id and entity_realm = 'ipv4net' " .
-               "where true ${whereclause} order by IPv4Network.ip, IPv4Network.mask";
-       $result = useSelectBlade ($query, __FUNCTION__);
-       $ret = array();
-       while ($row = $result->fetch (PDO::FETCH_ASSOC))
-       {
-               // ip_bin and mask are used by iptree_fill()
-               $row['ip_bin'] = ip2long ($row['ip']);
-               $ret[$row['id']] = $row;
-       }
-       // After all the keys are known we can update parent_id appropriately. Also we don't
-       // run two queries in parallel this way.
-       $keys = array_keys ($ret);
-       foreach ($keys as $netid)
-       {
-               // parent_id is for treeFromList()
-               $ret[$netid]['parent_id'] = getIPv4AddressNetworkId ($ret[$netid]['ip'], $ret[$netid]['mask']);
-               if ($ret[$netid]['parent_id'] and !in_array ($ret[$netid]['parent_id'], $keys))
-               {
-                       $ret[$netid]['real_parent_id'] = $ret[$netid]['parent_id'];
-                       $ret[$netid]['parent_id'] = NULL;
-               }
-       }
-       return $ret;
-}
-
 // Return the id of the smallest IPv4 network containing the given IPv4 address
 // or NULL, if nothing was found. When finding the covering network for
 // another network, it is important to filter out matched records with longer
@@ -1455,26 +1454,6 @@ function unbindIpFromObject ($ip='', $object_id=0)
        return '';
 }
 
-// This function returns either all or one user account. Array key is user name.
-function getUserAccounts ($tagfilter = array(), $tfmode = 'any')
-{
-       $whereclause = getWhereClause ($tagfilter);
-       $query =
-               'select user_id, user_name, user_password_hash, user_realname ' .
-               'from UserAccount left join TagStorage ' .
-               "on UserAccount.user_id = TagStorage.entity_id and entity_realm = 'user' " .
-               "where true ${whereclause} " .
-               'order by user_name';
-       $result = useSelectBlade ($query, __FUNCTION__);
-       $ret = array();
-       $clist = array ('user_id', 'user_name', 'user_realname', 'user_password_hash');
-       while ($row = $result->fetch (PDO::FETCH_ASSOC))
-               foreach ($clist as $cname)
-                       $ret[$row['user_name']][$cname] = $row[$cname];
-       $result->closeCursor();
-       return $ret;
-}
-
 function searchByl2address ($port_l2address)
 {
        if (NULL === ($db_l2address = l2addressForDatabase ($port_l2address)))
@@ -1582,7 +1561,11 @@ function getAccountSearchResult ($terms)
                                unset ($byRealname[$key2]);
                                continue 2;
                        }
-       return array_merge ($byUsername, $byRealname);
+       $ret = array_merge ($byUsername, $byRealname);
+       // Set realm, so it's renderable.
+       foreach (array_keys ($ret) as $key)
+               $ret[$key]['realm'] = 'user';
+       return $ret;
 }
 
 function getFileSearchResult ($terms)
index 9d092b9..c91fe92 100644 (file)
@@ -812,6 +812,8 @@ function treeFromList ($mytaglist, $threshold = 0)
 }
 
 // Build a tree from the tag list and return everything _except_ the tree.
+// IOW, return taginfo items, which have parent_id set and pointing outside
+// of the "normal" tree, which originates from the root.
 function getOrphanedTags ()
 {
        global $taglist;
@@ -1214,6 +1216,24 @@ function getTagFilterStr ($tagfilter = array())
        return $ret;
 }
 
+// Generate RackCode expression according to provided tag filter.
+function buildCellFilter ()
+{
+       if (!isset ($_REQUEST['tagfilter']) or !is_array ($_REQUEST['tagfilter']))
+               return array();
+       $ret = array();
+       $or = $text = '';
+       global $taglist;
+       foreach ($_REQUEST['tagfilter'] as $req_id)
+               if (isset ($taglist[$req_id]))
+               {
+                       $text .= $or . '{' . $taglist[$req_id]['tag'] . '}';
+                       $or = ' or ';
+               }
+       $expr = spotPayload ($text, 'SYNT_EXPR');
+       return $expr['load'];
+}
+
 function buildWideRedirectURL ($log, $nextpage = NULL, $nexttab = NULL, $moreArgs = array())
 {
        global $root, $page, $pageno, $tabno;
@@ -1655,6 +1675,13 @@ function loadOwnIPv4Addresses (&$node)
 
 function prepareIPv4Tree ($netlist, $expanded_id = 0)
 {
+       // treeFromList() requires parent_id to be correct for an item to get onto the tree,
+       // so perform necessary pre-processing to make orphans belong to root. This trick
+       // was earlier performed by getIPv4NetworkList().
+       $netids = array_keys ($netlist);
+       foreach ($netids as $cid)
+               if (!in_array ($netlist[$cid]['parent_id'], $netids))
+                       $netlist[$cid]['parent_id'] = NULL;
        $tree = treeFromList ($netlist); // medium call
        sortTree ($tree, 'IPv4NetworkCmp');
        // complement the tree before markup to make the spare networks have "symbol" set
@@ -1944,7 +1971,6 @@ function filterEntityList ($list_in, $realm, $expression = array())
                return array();
        if (!count ($expression))
                return $list_in;
-       global $rackCode;
        $list_out = array();
        foreach ($list_in as $item_key => $item_value)
                if (TRUE === judgeEntity ($realm, $item_key, $expression))
@@ -1952,16 +1978,15 @@ function filterEntityList ($list_in, $realm, $expression = array())
        return $list_out;
 }
 
-function filterEntityRecordList ($list_in, $expression = array())
+function filterCellList ($list_in, $expression = array())
 {
        if ($expression === NULL)
                return array();
        if (!count ($expression))
                return $list_in;
-       global $rackCode;
        $list_out = array();
        foreach ($list_in as $item_key => $item_value)
-               if (TRUE === judgeEntityRecord ($item_value, $expression))
+               if (TRUE === judgeCell ($item_value, $expression))
                        $list_out[$item_key] = $item_value;
        return $list_out;
 }
@@ -1986,7 +2011,7 @@ function judgeEntity ($realm, $id, $expression)
 }
 
 // Idem, but use complete record instead of key.
-function judgeEntityRecord ($record, $expression)
+function judgeCell ($cell, $expression)
 {
        global $pTable;
        return eval_expression
@@ -1994,9 +2019,9 @@ function judgeEntityRecord ($record, $expression)
                $expression,
                array_merge
                (
-                       $record['etags'],
-                       $record['itags'],
-                       $record['atags']
+                       $cell['etags'],
+                       $cell['itags'],
+                       $cell['atags']
                ),
                $pTable,
                TRUE
index 562ce2e..9583b85 100644 (file)
@@ -132,6 +132,10 @@ $pTable = buildPredicateTable ($rackCode);
 // things running is to maintain application cache for them.
 $parseCache = array();
 
+$taglist = getTagList();
+$tagtree = treeFromList ($taglist);
+sortTree ($tagtree, 'taginfoCmp');
+
 require_once 'inc/auth.php';
 $auto_tags = array();
 authenticate(); // sometimes this generates autotags, but never --- given tags
@@ -169,14 +173,8 @@ elseif (basename($_SERVER['PHP_SELF']) == 'index.php' and getConfigVar ('SHOW_LA
 else
        $tabno = 'default';
 
-
-
 $op = (isset ($_REQUEST['op'])) ? $_REQUEST['op'] : '';
 
-$taglist = getTagList();
-$tagtree = treeFromList ($taglist);
-sortTree ($tagtree, 'taginfoCmp');
-
 require_once 'inc/navigation.php';
 require_once 'inc/pagetitles.php';
 require_once 'inc/ophandlers.php';
index cdcb1c9..f49106d 100644 (file)
@@ -1901,8 +1901,6 @@ function renderObjectGroup ()
        echo '</td><td class=pcleft>';
 
        $objects = getObjectList ($group_id, $tagfilter, getTFMode());
-       if (isset ($_REQUEST['pfilter']))
-               $objects = filterEntityList ($objects, 'object', interpretPredicate ($_REQUEST['pfilter']));
        startPortlet ('Objects (' . count ($objects) . ')');
        if ($objects === NULL)
        {
@@ -2150,8 +2148,8 @@ function renderIPv4Space ()
 {
        global $pageno, $tabno;
        $tagfilter = getTagFilter();
-       $netlist = getIPv4NetworkList ($tagfilter, getTFMode());
-
+       $netlist = filterCellList (listCells ('ipv4net'), buildCellFilter());
+       array_walk ($netlist, 'amplifyCell');
 
        $netcount = count ($netlist);
        // expand request can take either natural values or "ALL". Zero means no expanding.
@@ -2289,7 +2287,8 @@ function renderIPv4SpaceEditor ()
        echo "</form></table><br><br>\n";
        finishPortlet();
 
-       $addrspaceList = getIPv4NetworkList();
+       $addrspaceList = listCells ('ipv4net');
+       array_walk ($addrspaceList, 'amplifyCell');
        if (count ($addrspaceList))
        {
                startPortlet ('Manage existing (' . count ($addrspaceList) . ')');
@@ -3244,7 +3243,7 @@ function renderSearchResults ()
                                        foreach ($what as $item)
                                        {
                                                echo "<tr class=row_${order}><td class=tdleft>";
-                                               renderUserCell ($item);
+                                               renderCell ($item);
                                                echo "</td></tr>";
                                                $order = $nextorder[$order];
                                        }
@@ -3302,29 +3301,38 @@ function renderAtomGrid ($data)
        }
 }
 
-function renderUserList ()
+function renderCellList ($realm = NULL, $title = 'list')
 {
-       global $nextorder, $accounts, $root, $pageno;
+       if ($realm === NULL)
+       {
+               global $pageno;
+               $realm = $pageno;
+       }
+       global $nextorder;
        echo "<table border=0 class=objectview>\n";
        echo "<tr><td class=pcleft>";
-       startPortlet ('User accounts');
+       startPortlet ($title);
        echo "<table class=cooltable border=0 cellpadding=5 cellspacing=0 align=center>\n";
        $order = 'odd';
-       $tagfilter = getTagFilter();
-       foreach (getUserAccounts ($tagfilter, getTFMode()) as $user)
+       foreach (filterCellList (listCells ($realm), buildCellFilter()) as $cell)
        {
                echo "<tr class=row_${order}><td>";
-               renderUserCell ($user);
+               renderCell ($cell);
                echo "</td></tr>\n";
                $order = $nextorder[$order];
        }
        echo '</table>';
        finishPortlet();
        echo '</td><td class=pcright>';
-       renderTagFilterPortlet ($tagfilter, 'user');
+       renderTagFilterPortlet (getTagFilter(), $realm);
        echo "</td></tr></table>\n";
 }
 
+function renderUserList ()
+{
+       renderCellList ('user', 'User accounts');
+}
+
 function renderUserListEditor ()
 {
        function printNewItemTR ()
@@ -5580,7 +5588,7 @@ function renderFile ($file_id = 0)
                                        if (NULL === $username or !isset ($accounts[$username]))
                                                echo "Internal error: user id ${link['entity_id']} not found";
                                        else
-                                               renderUserCell ($accounts[$username]);
+                                               renderCell ($accounts[$username]);
                                        break;
                                case 'ipv4net':
                                        renderIPv4NetCell (getIPv4NetworkInfo ($link['entity_id']));
@@ -5935,6 +5943,19 @@ function renderIPv4NetCell ($netinfo)
        echo "</td></tr></table>";
 }
 
+function renderCell ($cell)
+{
+       switch ($cell['realm'])
+       {
+       case 'user':
+               renderUserCell ($cell);
+               break;
+       default:
+               showError ('odd data', __FUNCTION__);
+               break;
+       }
+}
+
 function renderUserCell ($account)
 {
        global $root;
@@ -5947,8 +5968,9 @@ function renderUserCell ($account)
        else
                echo "<tr><td class=sparenetwork>no name</td></tr>";
        echo '<td>';
-       $tags = loadEntityTags ('user', $account['user_id']);
-       echo count ($tags) ? ("<small>" . serializeTags ($tags) . "</small>") : '&nbsp;';
+       if (!isset ($account['etags']))
+               $account['etags'] = loadEntityTags ('user', $account['user_id']);
+       echo count ($account['etags']) ? ("<small>" . serializeTags ($account['etags']) . "</small>") : '&nbsp;';
        echo "</td></tr></table>";
 }