r2180 - rearrange tag editor portlets
authorDenis Ovsienko <infrastation@yandex.ru>
Fri, 29 Aug 2008 12:02:51 +0000 (12:02 +0000)
committerDenis Ovsienko <infrastation@yandex.ru>
Fri, 29 Aug 2008 12:02:51 +0000 (12:02 +0000)
 - invent "messages" type of report
 - initial detection of RackCode issues

inc/code.php
inc/database.php
inc/interface.php

index 946a9c3..a07cc5a 100644 (file)
@@ -686,10 +686,87 @@ function locateSyntaxError ($stack)
        return 0;
 }
 
-function getRackCodeWarnings ($code)
+function getRackCodeWarnings ()
 {
-       $ret = array ('message 0' => 'this is a dummy message');
+       $ret = array();
+       global $rackCode;
+       // autotags
+       foreach ($rackCode as $sentence)
+               switch ($sentence['type'])
+               {
+                       case 'SYNT_DEFINITION':
+                               $ret = array_merge ($ret, findAutoTagWarnings ($sentence['definition']));
+                               break;
+                       case 'SYNT_GRANT':
+                               $ret = array_merge ($ret, findAutoTagWarnings ($sentence['condition']));
+                               break;
+                       default:
+                               $ret[] = array
+                               (
+                                       'header' => 'internal error',
+                                       'class' => 'error',
+                                       'text' => "Skipped sentence of unknown type '${sentence['type']}'"
+                               );
+               }
+       $nwarnings = count ($ret);
+       $ret[] = array
+       (
+               'header' => 'summary',
+               'class' => $nwarnings ? 'error' : 'success',
+               'text' => "Analysis complete, ${nwarnings} issues discovered."
+       );
        return $ret;
 }
 
+function findAutoTagWarnings ($expr)
+{
+       switch ($expr['type'])
+       {
+               case 'LEX_BOOLCONST':
+               case 'LEX_PREDICATE':
+                       return array();
+               case 'LEX_TAG':
+                       switch (TRUE)
+                       {
+                               case (mb_ereg_match ('^\$id_', $expr['load'])):
+                                       $recid = mb_ereg_replace ('^\$id_', '', $expr['load']);
+                                       if (recordExists ($recid, 'object'))
+                                               return array();
+                                       return array (array
+                                       (
+                                               'header' => 'Line ' . $expr['lineno'],
+                                               'class' => 'warning',
+                                               'text' => "An object with ID '${recid}' does not exist"
+                                       ));
+                               case (mb_ereg_match ('^\$ipv4netid_', $expr['load'])):
+                                       $recid = mb_ereg_replace ('^\$ipv4netid_', '', $expr['load']);
+                                       if (recordExists ($recid, 'ipv4net'))
+                                               return array();
+                                       return array (array
+                                       (
+                                               'header' => 'Line ' . $expr['lineno'],
+                                               'class' => 'warning',
+                                               'text' => "IPv4 network with ID '${recid}' does not exist"
+                                       ));
+                               default:
+                                       return array();
+                       }
+               case 'SYNT_NOTEXPR':
+                       return findAutoTagWarnings ($expr['load']);
+               case 'SYNT_BOOLOP':
+                       return array_merge
+                       (
+                               findAutoTagWarnings ($expr['left']),
+                               findAutoTagWarnings ($expr['right'])
+                       );
+               default:
+                       return array (array
+                       (
+                               'header' => 'internal error',
+                               'class' => 'error',
+                               'text' => "Skipped expression of unknown type '${type['type']}'"
+                       ));
+       }
+}
+
 ?>
index b4aee36..e45ee70 100644 (file)
@@ -3053,6 +3053,33 @@ function objectIsPortless ($id = 0)
        return $count === '0';
 }
 
+function recordExists ($id = 0, $realm = 'object')
+{
+       if ($id <= 0)
+               return FALSE;
+       $table = array
+       (
+               'object' => 'RackObject',
+               'ipv4net' => 'IPRanges'
+       );
+       $idcol = array
+       (
+               'object' => 'id',
+               'ipv4net' => 'id'
+       );
+       $query = 'select count(*) from ' . $table[$realm] . ' where ' . $idcol[$realm] . ' = ' . $id;
+       if (($result = useSelectBlade ($query, __FUNCTION__)) == NULL) 
+       {
+               showError ('SQL query failed', __FUNCTION__);
+               return FALSE;
+       }
+       $row = $result->fetch (PDO::FETCH_NUM);
+       $count = $row[0];
+       $result->closeCursor();
+       unset ($result);
+       return $count === '1';
+}
+
 function tagExistsInDatabase ($tname)
 {
        $result = useSelectBlade ("select count(*) from TagTree where lower(tag) = lower('${tname}')");
index fb08103..9c47175 100644 (file)
@@ -3550,12 +3550,6 @@ function renderSystemReports ()
                        'func' => 'getRackspaceStats'
                ),
                array
-               (
-                       'title' => 'RackCode',
-                       'type' => 'counters',
-                       'func' => 'getRackCodeStats'
-               ),
-               array
                (
                        'title' => 'Tags top-50',
                        'type' => 'custom',
@@ -3577,8 +3571,14 @@ function renderRackCodeReports ()
        (
                array
                (
-                       'title' => 'Warnings',
+                       'title' => 'Stats',
                        'type' => 'counters',
+                       'func' => 'getRackCodeStats'
+               ),
+               array
+               (
+                       'title' => 'Warnings',
+                       'type' => 'messages',
                        'func' => 'getRackCodeWarnings'
                ),
        );
@@ -3599,6 +3599,10 @@ function renderReports ($what)
                                foreach ($item['func'] () as $header => $data)
                                        echo "<tr><td class=tdright>${header}:</td><td class=tdleft>${data}</td></tr>\n";
                                break;
+                       case 'messages':
+                               foreach ($item['func'] () as $msg)
+                                       echo "<tr class='msg_${msg['class']}'><td class=tdright>${msg['header']}:</td><td class=tdleft>${msg['text']}</td></tr>\n";
+                               break;
                        case 'custom':
                                echo "<tr><td colspan=2>";
                                $item['func'] ();
@@ -4737,7 +4741,31 @@ function renderTagTreeEditor ()
 {
        global $taglist, $tagtree;
        showMessageOrError();
-       echo "<table class=objview border=0 width='100%'><tr><td class=pcleft>";
+
+       $otags = getOrphanedTags();
+       if (count ($otags))
+       {
+               startPortlet ('fallen leaves');
+               echo "<table cellspacing=0 cellpadding=5 align=center class=widetable>\n";
+               echo "<tr><th>tag</th><th>parent</th><th>&nbsp;</th></tr>\n";
+               foreach ($otags as $taginfo)
+               {
+                       printOpFormIntro ('updateTag', array ('tag_id' => $taginfo['id'], 'tag_name' => $taginfo['tag']));
+                       echo "<tr><td>${taginfo['tag']}</td><td><select name=parent_id>";
+                       echo "<option value=0>-- NONE --</option>\n";
+                       foreach ($taglist as $tlinfo)
+                       {
+                               echo "<option value=${tlinfo['id']}" . ($tlinfo['id'] == $taglist[$taginfo['id']]['parent_id'] ? ' selected' : '');
+                               echo ">${tlinfo['tag']}</option>";
+                       }
+                       echo "</select></td><td>";
+                       printImageHREF ('save', 'Save changes', TRUE);
+                       echo "</form></td></tr>\n";
+               }
+               echo '</table>';
+               finishPortlet();
+       }
+
        startPortlet ('tag tree');
        echo "<table cellspacing=0 cellpadding=5 align=center class=widetable>\n";
        echo "<tr><th>&nbsp;</th><th>tag</th><th>parent</th><th>&nbsp;</th></tr>\n";
@@ -4754,30 +4782,6 @@ function renderTagTreeEditor ()
        echo "</form>\n";
        echo '</table>';
        finishPortlet();
-
-       echo "</td><td><td class=pcright>";
-
-       startPortlet ('fallen leaves');
-       echo "<table cellspacing=0 cellpadding=5 align=center class=widetable>\n";
-       echo "<tr><th>tag</th><th>parent</th><th>&nbsp;</th></tr>\n";
-       foreach (getOrphanedTags() as $taginfo)
-       {
-               echo '<tr><td>';
-               printOpFormIntro ('updateTag', array ('tag_id' => $taginfo['id'], 'tag_name' => $taginfo['tag']));
-               echo "${taginfo['tag']}</td><td><select name=parent_id>";
-               echo "<option value=0>-- NONE --</option>\n";
-               foreach ($taglist as $tlinfo)
-               {
-                       echo "<option value=${tlinfo['id']}" . ($tlinfo['id'] == $taglist[$taginfo['id']]['parent_id'] ? ' selected' : '');
-                       echo ">${tlinfo['tag']}</option>";
-               }
-               echo "</select></td><td>";
-               printImageHREF ('save', 'Save changes', TRUE);
-               echo "</form></td></tr>\n";
-       }
-       echo '</table>';
-       finishPortlet();
-       echo "</td></tr></table>";
 }
 
 // Output a sequence of OPTION elements, selecting those, which are present on the