r4188 update: UI: ability to clear object ports list at one blow
[racktables] / inc / ophandlers.php
index 7f10587..9545734 100644 (file)
@@ -7,8 +7,10 @@
 
 // This array is deprecated. Please do not add new message constants to it.
 // use the new showError, showWarning, showSuccess functions instead
+global $msgcode;
 $msgcode = array();
 
+global $opspec_list;
 $opspec_list = array();
 
 $opspec_list['rackspace-edit-addRow'] = array
@@ -52,6 +54,15 @@ $opspec_list['object-ports-delPort'] = array
                array ('url_argname' => 'object_id', 'assertion' => 'uint'),
        ),
 );
+$opspec_list['object-ports-deleteAll'] = array
+(
+       'table' => 'Port',
+       'action' => 'DELETE',
+       'arglist' => array
+       (
+               array ('url_argname' => 'object_id', 'assertion' => 'uint'),
+       ),
+);
 $opspec_list['object-ports-unlinkPort'] = array
 (
        'table' => 'Link',
@@ -86,6 +97,25 @@ $opspec_list['object-editrspvs-delLB'] = array
                array ('url_argname' => 'vs_id', 'assertion' => 'uint'),
        ),
 );
+$opspec_list['ipv4vs-editlblist-updLB'] =
+$opspec_list['ipv4rspool-editlblist-updLB'] =
+$opspec_list['object-editrspvs-updLB'] = array
+(
+       'table' => 'IPv4LB',
+       'action' => 'UPDATE',
+       'set_arglist' => array
+       (
+               array ('url_argname' => 'vsconfig', 'assertion' => 'string0', 'if_empty' => 'NULL'),
+               array ('url_argname' => 'rsconfig', 'assertion' => 'string0', 'if_empty' => 'NULL'),
+               array ('url_argname' => 'prio', 'assertion' => 'uint0', 'if_empty' => 'NULL'),
+       ),
+       'where_arglist' => array
+       (
+               array ('url_argname' => 'object_id', 'assertion' => 'uint'),
+               array ('url_argname' => 'pool_id', 'table_colname' => 'rspool_id', 'assertion' => 'uint'),
+               array ('url_argname' => 'vs_id', 'assertion' => 'uint'),
+       ),
+);
 $opspec_list['ipv4net-properties-editRange'] = array
 (
        'table' => 'IPv4Network',
@@ -123,6 +153,56 @@ $opspec_list['ipv4rspool-editrslist-delRS'] = array
                array ('url_argname' => 'id', 'assertion' => 'uint'),
        ),
 );
+$opspec_list['ipv4rspool-edit-updIPv4RSP'] = array
+(
+       'table' => 'IPv4RSPool',
+       'action' => 'UPDATE',
+       'set_arglist' => array
+       (
+               array ('url_argname' => 'name', 'assertion' => 'string0', 'if_empty' => 'NULL'),
+               array ('url_argname' => 'vsconfig', 'assertion' => 'string0', 'if_empty' => 'NULL'),
+               array ('url_argname' => 'rsconfig', 'assertion' => 'string0', 'if_empty' => 'NULL'),
+       ),
+       'where_arglist' => array
+       (
+               array ('url_argname' => 'pool_id', 'table_colname' => 'id', 'assertion' => 'uint')
+       ),
+);
+$opspec_list['file-edit-updateFile'] = array
+(
+       'table' => 'File',
+       'action' => 'UPDATE',
+       'set_arglist' => array
+       (
+               array ('url_argname' => 'file_name', 'table_colname' => 'name', 'assertion' => 'string'),
+               array ('url_argname' => 'file_type', 'table_colname' => 'type', 'assertion' => 'string'),
+               array ('url_argname' => 'file_comment', 'table_colname' => 'comment', 'assertion' => 'string0', 'if_empty' => 'NULL'),
+       ),
+       'where_arglist' => array
+       (
+               array ('url_argname' => 'file_id', 'table_colname' => 'id', 'assertion' => 'uint')
+       ),
+);
+$opspec_list['parentmap-edit-add'] = array
+(
+       'table' => 'ObjectParentCompat',
+       'action' => 'INSERT',
+       'arglist' => array
+       (
+               array ('url_argname' => 'parent_objtype_id', 'assertion' => 'uint'),
+               array ('url_argname' => 'child_objtype_id', 'assertion' => 'uint'),
+       ),
+);
+$opspec_list['parentmap-edit-del'] = array
+(
+       'table' => 'ObjectParentCompat',
+       'action' => 'DELETE',
+       'arglist' => array
+       (
+               array ('url_argname' => 'parent_objtype_id', 'assertion' => 'uint'),
+               array ('url_argname' => 'child_objtype_id', 'assertion' => 'uint'),
+       ),
+);
 $opspec_list['portmap-edit-add'] = array
 (
        'table' => 'PortCompat',
@@ -182,6 +262,19 @@ $opspec_list['attrs-editattrs-del'] = array
                array ('url_argname' => 'attr_id', 'table_colname' => 'id', 'assertion' => 'uint'),
        ),
 );
+$opspec_list['attrs-editattrs-upd'] = array
+(
+       'table' => 'Attribute',
+       'action' => 'UPDATE',
+       'set_arglist' => array
+       (
+               array ('url_argname' => 'attr_name', 'table_colname' => 'name', 'assertion' => 'string'),
+       ),
+       'where_arglist' => array
+       (
+               array ('url_argname' => 'attr_id', 'table_colname' => 'id', 'assertion' => 'uint'),
+       ),
+);
 $opspec_list['dict-chapters-add'] = array
 (
        'table' => 'Chapter',
@@ -247,6 +340,32 @@ $opspec_list['tagtree-edit-updateTag'] = array
                array ('url_argname' => 'tag_id', 'table_colname' => 'id', 'assertion' => 'uint'),
        ),
 );
+$opspec_list['8021q-vstlist-upd'] = array
+(
+       'table' => 'VLANSwitchTemplate',
+       'action' => 'UPDATE',
+       'set_arglist' => array
+       (
+               array ('url_argname' => 'vst_descr', 'table_colname' => 'description', 'assertion' => 'string'),
+       ),
+       'where_arglist' => array
+       (
+               array ('url_argname' => 'vst_id', 'table_colname' => 'id', 'assertion' => 'uint'),
+       ),
+);
+$opspec_list['8021q-vdlist-upd'] = array
+(
+       'table' => 'VLANDomain',
+       'action' => 'UPDATE',
+       'set_arglist' => array
+       (
+               array ('url_argname' => 'vdom_descr', 'table_colname' => 'description', 'assertion' => 'string'),
+       ),
+       'where_arglist' => array
+       (
+               array ('url_argname' => 'vdom_id', 'table_colname' => 'id', 'assertion' => 'uint'),
+       ),
+);
 $opspec_list['vlandomain-vlanlist-add'] = array
 (
        'table' => 'VLANDescription',
@@ -289,7 +408,7 @@ function buildWideRedirectURL ($log = NULL, $nextpage = NULL, $nexttab = NULL, $
                        $_SESSION['log'] = array_merge_recursive($log, $_SESSION['log']);
                elseif ($log['v'] == 1 and $_SESSION['log']['v'] == 2)
                        foreach ($log['m'] as $msg)
-                               setMessage($msg['message'], $msg['code'], FALSE);
+                               setMessage ($msg['code'], $msg['message'], FALSE);
                elseif ($log['v'] == 2 and $_SESSION['log']['v'] == 1)
                {
                        foreach ($_SESSION['log'] as $msg)
@@ -413,15 +532,12 @@ function updPortForwarding ()
 }
 
 $msgcode['addPortForObject']['OK'] = 48;
-$msgcode['addPortForObject']['ERR1'] = 101;
-$msgcode['addPortForObject']['ERR2'] = 100;
 function addPortForObject ()
 {
        assertStringArg ('port_name', TRUE);
        genericAssertion ('port_l2address', 'l2address0');
-       if (!strlen ($_REQUEST['port_name']))
-               return buildRedirectURL (__FUNCTION__, 'ERR1');
-       $error = commitAddPort
+       genericAssertion ('port_name', 'string');
+       commitAddPort
        (
                $_REQUEST['object_id'],
                trim ($_REQUEST['port_name']),
@@ -429,31 +545,20 @@ function addPortForObject ()
                trim ($_REQUEST['port_label']),
                trim ($_REQUEST['port_l2address'])
        );
-       if ($error != '')
-               return buildRedirectURL (__FUNCTION__, 'ERR2', array ($error));
-       else
-               return buildRedirectURL (__FUNCTION__, 'OK', array ($_REQUEST['port_name']));
+       return buildRedirectURL (__FUNCTION__, 'OK', array ($_REQUEST['port_name']));
 }
 
-$msgcode['editPortForObject']['OK'] = 7;
-$msgcode['editPortForObject']['ERR1'] = 101;
-$msgcode['editPortForObject']['ERR2'] = 100;
+$msgcode['editPortForObject']['OK'] = 6;
 function editPortForObject ()
 {
+       global $sic;
        assertUIntArg ('port_id');
        assertUIntArg ('port_type_id');
        assertStringArg ('reservation_comment', TRUE);
        genericAssertion ('l2address', 'l2address0');
-       // tolerate empty value now to produce custom informative message later
-       assertStringArg ('name', TRUE);
-       if (!strlen ($_REQUEST['name']))
-               return buildRedirectURL (__FUNCTION__, 'ERR1');
-
-       $error = commitUpdatePort ($_REQUEST['object_id'], $_REQUEST['port_id'], $_REQUEST['name'], $_REQUEST['port_type_id'], $_REQUEST['label'], $_REQUEST['l2address'], $_REQUEST['reservation_comment']);
-       if ($error != '')
-               return buildRedirectURL (__FUNCTION__, 'ERR2', array ($error));
-       else
-               return buildRedirectURL (__FUNCTION__, 'OK', array ($_REQUEST['name']));
+       genericAssertion ('name', 'string');
+       commitUpdatePort ($sic['object_id'], $sic['port_id'], $sic['name'], $sic['port_type_id'], $sic['label'], $sic['l2address'], $sic['reservation_comment']);
+       return buildRedirectURL (__FUNCTION__, 'OK', array ($_REQUEST['name']));
 }
 
 $msgcode['linkPortForObject']['OK'] = 8;
@@ -579,19 +684,13 @@ http://www.cisco.com/en/US/products/hw/routers/ps274/products_tech_note09186a008
                $port_ids = getPortIDs ($object_id, $port['name']);
                if (!count ($port_ids))
                {
-                       $result = commitAddPort ($object_id, $port['name'], $port_type, $port['label'], $port['l2address']);
-                       if ($result == '')
-                               $added_count++;
-                       else
-                               $error_count++;
+                       commitAddPort ($object_id, $port['name'], $port_type, $port['label'], $port['l2address']);
+                       $added_count++;
                }
                elseif (count ($port_ids) == 1) // update only single-socket ports
                {
-                       $result = commitUpdatePort ($object_id, $port_ids[0], $port['name'], $port_type, $port['label'], $port['l2address']);
-                       if ($result == '')
-                               $updated_count++;
-                       else
-                               $error_count++;
+                       commitUpdatePort ($object_id, $port_ids[0], $port['name'], $port_type, $port['label'], $port['l2address']);
+                       $updated_count++;
                }
        }
        return buildRedirectURL (__FUNCTION__, 'OK', array ($added_count, $updated_count, $error_count));
@@ -618,11 +717,8 @@ function addBulkPorts ()
                $port_name .= '%u';
        for ($i=0,$c=$port_numbering_start; $i<$port_numbering_count; $i++,$c++)
        {
-               $result = commitAddPort ($object_id, @sprintf($port_name,$c), $port_type_id, @sprintf($port_label,$c), '');
-               if ($result == '')
-                       $added_count++;
-               else
-                       $error_count++;
+               commitAddPort ($object_id, @sprintf($port_name,$c), $port_type_id, @sprintf($port_label,$c), '');
+               $added_count++;
        }
        return buildRedirectURL (__FUNCTION__, 'OK', array ($added_count, $error_count));
 }
@@ -737,7 +833,6 @@ function addIPv6Allocation ()
 }
 
 $msgcode['addIPv4Prefix']['OK'] = 48;
-$msgcode['addIPv4Prefix']['ERR'] = 100;
 function addIPv4Prefix ()
 {
        assertStringArg ('range');
@@ -746,15 +841,11 @@ function addIPv4Prefix ()
        $is_bcast = isset ($_REQUEST['is_bcast']) ? $_REQUEST['is_bcast'] : 'off';
        $taglist = isset ($_REQUEST['taglist']) ? $_REQUEST['taglist'] : array();
        global $sic;
-       $error = createIPv4Prefix ($_REQUEST['range'], $sic['name'], $is_bcast == 'on', $taglist);
-       if ($error != '')
-               return buildRedirectURL (__FUNCTION__, 'ERR', array ($error));
-       else
-               return buildRedirectURL (__FUNCTION__, 'OK');
+       createIPv4Prefix ($_REQUEST['range'], $sic['name'], $is_bcast == 'on', $taglist);
+       return buildRedirectURL (__FUNCTION__, 'OK');
 }
 
 $msgcode['addIPv6Prefix']['OK'] = 48;
-$msgcode['addIPv6Prefix']['ERR'] = 100;
 function addIPv6Prefix ()
 {
        assertStringArg ('range');
@@ -762,35 +853,24 @@ function addIPv6Prefix ()
 
        $taglist = isset ($_REQUEST['taglist']) ? $_REQUEST['taglist'] : array();
        global $sic;
-       $error = createIPv6Prefix ($_REQUEST['range'], $sic['name'], $taglist);
-       if ($error != '')
-               return buildRedirectURL (__FUNCTION__, 'ERR', array ($error));
-       else
-               return buildRedirectURL (__FUNCTION__, 'OK');
+       createIPv6Prefix ($_REQUEST['range'], $sic['name'], $taglist);
+       return buildRedirectURL (__FUNCTION__, 'OK');
 }
 
 $msgcode['delIPv4Prefix']['OK'] = 49;
-$msgcode['delIPv4Prefix']['ERR'] = 100;
 function delIPv4Prefix ()
 {
        assertUIntArg ('id');
-       $error = destroyIPv4Prefix ($_REQUEST['id']);
-       if ($error != '')
-               return buildRedirectURL (__FUNCTION__, 'ERR', array ($error));
-       else
-               return buildRedirectURL (__FUNCTION__, 'OK');
+       destroyIPv4Prefix ($_REQUEST['id']);
+       return buildRedirectURL (__FUNCTION__, 'OK');
 }
 
 $msgcode['delIPv6Prefix']['OK'] = 49;
-$msgcode['delIPv6Prefix']['ERR'] = 100;
 function delIPv6Prefix ()
 {
        assertUIntArg ('id');
-       $error = destroyIPv6Prefix ($_REQUEST['id']);
-       if ($error != '')
-               return buildRedirectURL (__FUNCTION__, 'ERR', array ($error));
-       else
-               return buildRedirectURL (__FUNCTION__, 'OK');
+       destroyIPv6Prefix ($_REQUEST['id']);
+       return buildRedirectURL (__FUNCTION__, 'OK');
 }
 
 $msgcode['editAddress']['OK'] = 51;
@@ -845,7 +925,7 @@ function createUser ()
        return buildRedirectURL (__FUNCTION__, 'OK', array ($username));
 }
 
-$msgcode['updateUser']['OK'] = 7;
+$msgcode['updateUser']['OK'] = 6;
 $msgcode['updateUser']['ERR2'] = 104;
 function updateUser ()
 {
@@ -866,27 +946,43 @@ function updateUser ()
 }
 
 $msgcode['updateDictionary']['OK'] = 51;
-$msgcode['updateDictionary']['ERR'] = 109;
 function updateDictionary ()
 {
        assertUIntArg ('dict_key');
        assertStringArg ('dict_value');
-       if (FALSE !== commitUpdateDictionary ($_REQUEST['chapter_no'], $_REQUEST['dict_key'], $_REQUEST['dict_value']))
-               return buildRedirectURL (__FUNCTION__, 'OK');
-       else
-               return buildRedirectURL (__FUNCTION__, 'ERR');
+       // this request must be built with chapter_no
+       usePreparedUpdateBlade
+       (
+               'Dictionary',
+               array ('dict_value' => $sic['dict_value']),
+               array
+               (
+                       'chapter_id' => $sic['chapter_no'],
+                       'dict_key' => $sic['dict_key'],
+               )
+       );
+       return buildRedirectURL (__FUNCTION__, 'OK');
 }
 
 $msgcode['updateChapter']['OK'] = 51;
-$msgcode['updateChapter']['ERR'] = 109;
 function updateChapter ()
 {
        assertUIntArg ('chapter_no');
        assertStringArg ('chapter_name');
-       if (FALSE !== commitUpdateChapter ($_REQUEST['chapter_no'], $_REQUEST['chapter_name']))
-               return buildRedirectURL (__FUNCTION__, 'OK');
-       else
-               return buildRedirectURL (__FUNCTION__, 'ERR');
+       usePreparedUpdateBlade
+       (
+               'Chapter',
+               array
+               (
+                       'name' => $chapter_name,
+               ),
+               array
+               (
+                       'id' => $chapter_no,
+                       'sticky' => 'no', // note this constant, it protects system chapters
+               )
+       );
+       return buildRedirectURL (__FUNCTION__, 'OK');
 }
 
 $msgcode['delChapter']['OK'] = 49;
@@ -900,18 +996,6 @@ function delChapter ()
                return buildRedirectURL (__FUNCTION__, 'ERR');
 }
 
-$msgcode['changeAttribute']['OK'] = 51;
-$msgcode['changeAttribute']['ERR'] = 109;
-function changeAttribute ()
-{
-       assertUIntArg ('attr_id');
-       assertStringArg ('attr_name');
-       if (FALSE !== commitUpdateAttribute ($_REQUEST['attr_id'], $_REQUEST['attr_name']))
-               return buildRedirectURL (__FUNCTION__, 'OK');
-       else
-               return buildRedirectURL (__FUNCTION__, 'ERR');
-}
-
 $msgcode['supplementAttrMap']['OK'] = 48;
 $msgcode['supplementAttrMap']['ERR1'] = 154;
 $msgcode['supplementAttrMap']['ERR2'] = 110;
@@ -954,6 +1038,7 @@ function clearSticker ()
 $msgcode['updateObjectAllocation']['OK'] = 63;
 function updateObjectAllocation ()
 {
+       global $remote_username, $sic;
        if (!isset ($_REQUEST['got_atoms']))
        {
                unset($_GET['page']);
@@ -999,7 +1084,6 @@ function updateObjectAllocation ()
                return buildRedirectURL (__FUNCTION__, 'OK', $changecnt);
        // Log a record.
        $newMolecule = getMoleculeForObject ($object_id);
-       global $remote_username;
        usePreparedInsertBlade
        (
                'MountOperation', 
@@ -1009,7 +1093,7 @@ function updateObjectAllocation ()
                        'old_molecule_id' => count ($oldMolecule) ? createMolecule ($oldMolecule) : NULL,
                        'new_molecule_id' => count ($newMolecule) ? createMolecule ($newMolecule) : NULL,
                        'user_name' => $remote_username,
-                       'comment' => empty ($_REQUEST['comment']) ? NULL : $_REQUEST['comment'],
+                       'comment' => empty ($sic['comment']) ? NULL : $sic['comment'],
                )
        );
        $log[] = array ('code' => 200, 'message' => 'history logged');
@@ -1084,7 +1168,7 @@ function updateObject ()
 
        // Invalidate thumb cache of all racks objects could occupy.
        foreach (getResidentRacksData ($_REQUEST['object_id'], FALSE) as $rack_id)
-               resetThumbCache ($rack_id);
+               usePreparedUpdateBlade ('Rack', array ('thumb_data' => NULL), array ('id' => $rack_id));
 
        return buildRedirectURL (__FUNCTION__, 'OK');
 }
@@ -1101,6 +1185,15 @@ function addMultipleObjects()
                        $log = mergeLogs ($log, oneLiner (184, array ($i + 1)));
                        break;
                }
+
+               // set to empty values for virtual objects
+               if (isset ($_REQUEST['virtual_objects']))
+               {
+                       $_REQUEST["${i}_object_label"] = '';
+                       $_REQUEST["${i}_object_barcode"] = '';
+                       $_REQUEST["${i}_object_asset_no"] = '';
+               }
+
                assertUIntArg ("${i}_object_type_id", TRUE);
                assertStringArg ("${i}_object_name", TRUE);
                assertStringArg ("${i}_object_label", TRUE);
@@ -1176,7 +1269,7 @@ function deleteObject ()
        $racklist = getResidentRacksData ($_REQUEST['object_id'], FALSE);
        commitDeleteObject ($_REQUEST['object_id']);
        foreach ($racklist as $rack_id)
-               resetThumbCache ($rack_id);
+               usePreparedUpdateBlade ('Rack', array ('thumb_data' => NULL), array ('id' => $rack_id));
        return buildRedirectURL (__FUNCTION__, 'OK', array ($oinfo['dname']));
 }
 
@@ -1188,19 +1281,29 @@ function resetObject ()
        $racklist = getResidentRacksData ($_REQUEST['object_id'], FALSE);
        commitResetObject ($_REQUEST['object_id']);
        foreach ($racklist as $rack_id)
-               resetThumbCache ($rack_id);
+               usePreparedUpdateBlade ('Rack', array ('thumb_data' => NULL), array ('id' => $rack_id));
        return buildRedirectURL (__FUNCTION__, 'OK');
 }
 
 $msgcode['useupPort']['OK'] = 49;
-$msgcode['useupPort']['ERR'] = 111;
 function useupPort ()
 {
+       global $sic;
        assertUIntArg ('port_id');
-       if (FALSE !== commitUseupPort ($_REQUEST['port_id']))
-               return buildRedirectURL (__FUNCTION__, 'OK');
-       else
-               return buildRedirectURL (__FUNCTION__, 'ERR');
+       usePreparedUpdateBlade
+       (
+               'Port',
+               array
+               (
+                       'reservation_comment' => NULL,
+               ),
+               array
+               (
+                       'object_id' => $sic['object_id'],
+                       'id' => $sic['port_id'],
+               )
+       );
+       return buildRedirectURL (__FUNCTION__, 'OK');
 }
 
 $msgcode['updateUI']['OK'] = 51;
@@ -1224,7 +1327,7 @@ function updateUI ()
        return buildRedirectURL (__FUNCTION__, 'OK');
 }
 
-$msgcode['saveMyPreferences']['OK'] = 56;
+$msgcode['saveMyPreferences']['OK'] = 51;
 function saveMyPreferences ()
 {
        assertUIntArg ('num_vars');
@@ -1244,7 +1347,7 @@ function saveMyPreferences ()
        return buildRedirectURL (__FUNCTION__, 'OK');
 }
 
-$msgcode['resetMyPreference']['OK'] = 56;
+$msgcode['resetMyPreference']['OK'] = 51;
 function resetMyPreference ()
 {
        assertStringArg ("varname");
@@ -1255,7 +1358,7 @@ function resetMyPreference ()
 $msgcode['resetUIConfig']['OK'] = 57;
 function resetUIConfig()
 {
-       setConfigVar ('MASSCOUNT','15');
+       setConfigVar ('MASSCOUNT','8');
        setConfigVar ('MAXSELSIZE','30');
        setConfigVar ('ROW_SCALE','2');
        setConfigVar ('PORTS_PER_ROW','12');
@@ -1284,7 +1387,7 @@ function resetUIConfig()
        setConfigVar ('PREVIEW_IMAGE_MAXPXS', '320');
        setConfigVar ('VENDOR_SIEVE', '');
        setConfigVar ('IPV4LB_LISTSRC', '{$typeid_4}');
-       setConfigVar ('IPV4OBJ_LISTSRC','{$typeid_4} or {$typeid_7} or {$typeid_8} or {$typeid_12} or {$typeid_445} or {$typeid_447} or {$typeid_798}');
+       setConfigVar ('IPV4OBJ_LISTSRC','{$typeid_4} or {$typeid_7} or {$typeid_8} or {$typeid_12} or {$typeid_445} or {$typeid_447} or {$typeid_798} or {$typeid_1504}');
        setConfigVar ('IPV4NAT_LISTSRC','{$typeid_4} or {$typeid_7} or {$typeid_8} or {$typeid_798}');
        setConfigVar ('ASSETWARN_LISTSRC','{$typeid_4} or {$typeid_7} or {$typeid_8}');
        setConfigVar ('NAMEWARN_LISTSRC','{$typeid_4} or {$typeid_7} or {$typeid_8}');
@@ -1322,6 +1425,8 @@ function resetUIConfig()
        setConfigVar ('SHRINK_TAG_TREE_ON_CLICK', 'yes');
        setConfigVar ('MAX_UNFILTERED_ENTITIES', '0');
        setConfigVar ('SYNCDOMAIN_MAX_PROCESSES', '0');
+    setConfigVar ('VIRTUAL_OBJ_LISTSRC', '{$typeid_1504} or {$typeid_1505} or {$typeid_1506} or {$typeid_1507}');
+    setConfigVar ('PORT_EXCLUSION_LISTSRC', '{$typeid_3} or {$typeid_10} or {$typeid_11} or {$typeid_1505} or {$typeid_1506}');
        return buildRedirectURL (__FUNCTION__, 'OK');
 }
 
@@ -1477,31 +1582,6 @@ function updateRealServer ()
                return buildRedirectURL (__FUNCTION__, 'OK');
 }
 
-$msgcode['updateLoadBalancer']['OK'] = 51;
-$msgcode['updateLoadBalancer']['ERR'] = 109;
-function updateLoadBalancer ()
-{
-       assertUIntArg ('object_id');
-       assertUIntArg ('pool_id');
-       assertUIntArg ('vs_id');
-       assertStringArg ('vsconfig', TRUE);
-       assertStringArg ('rsconfig', TRUE);
-       if (! empty($_REQUEST['prio']))
-               assertUIntArg('prio', TRUE);
-
-       if (FALSE === commitUpdateLB (
-               $_REQUEST['object_id'],
-               $_REQUEST['pool_id'],
-               $_REQUEST['vs_id'],
-               $_REQUEST['vsconfig'],
-               $_REQUEST['rsconfig'],
-               $_REQUEST['prio']
-       ))
-               return buildRedirectURL (__FUNCTION__, 'ERR');
-       else
-               return buildRedirectURL (__FUNCTION__, 'OK');
-}
-
 $msgcode['updateVService']['OK'] = 51;
 $msgcode['updateVService']['ERR'] = 109;
 function updateVService ()
@@ -1553,23 +1633,19 @@ function addLoadBalancer ()
 }
 
 $msgcode['addRSPool']['OK'] = 48;
-$msgcode['addRSPool']['ERR'] = 100;
 function addRSPool ()
 {
-       assertStringArg ('name', TRUE);
+       assertStringArg ('name');
        assertStringArg ('vsconfig', TRUE);
        assertStringArg ('rsconfig', TRUE);
-       $error = commitCreateRSPool
+       commitCreateRSPool
        (
                $_REQUEST['name'],
                $_REQUEST['vsconfig'],
                $_REQUEST['rsconfig'],
                isset ($_REQUEST['taglist']) ? $_REQUEST['taglist'] : array()
        );
-       if ($error != '')
-               return buildRedirectURL (__FUNCTION__, 'ERR', array ($error));
-       else
-               return buildRedirectURL (__FUNCTION__, 'OK');
+       return buildRedirectURL (__FUNCTION__, 'OK');
 }
 
 $msgcode['deleteRSPool']['OK'] = 49;
@@ -1583,26 +1659,6 @@ function deleteRSPool ()
                return buildRedirectURL (__FUNCTION__, 'OK');
 }
 
-$msgcode['updateRSPool']['OK'] = 51;
-$msgcode['updateRSPool']['ERR'] = 109;
-function updateRSPool ()
-{
-       assertStringArg ('name', TRUE);
-       assertStringArg ('vsconfig', TRUE);
-       assertStringArg ('rsconfig', TRUE);
-       if (FALSE === commitUpdateRSPool
-               (
-                       $_REQUEST['pool_id'],
-                       $_REQUEST['name'],
-                       $_REQUEST['vsconfig'],
-                       $_REQUEST['rsconfig']
-               )
-       )
-               return buildRedirectURL (__FUNCTION__, 'ERR');
-       else
-               return buildRedirectURL (__FUNCTION__, 'OK');
-}
-
 $msgcode['updateRSInService']['OK'] = 26;
 $msgcode['updateRSInService']['ERR'] = 141;
 function updateRSInService ()
@@ -1928,7 +1984,8 @@ function updateRack ()
        assertStringArg ('rack_name');
        assertStringArg ('rack_comment', TRUE);
 
-       resetThumbCache ($_REQUEST['rack_id']);
+       global $sic;
+       usePreparedUpdateBlade ('Rack', array ('thumb_data' => NULL), array ('id' => $sic['rack_id']));
        if (TRUE === commitUpdateRack ($_REQUEST['rack_id'], $_REQUEST['rack_name'], $_REQUEST['rack_height'], $_REQUEST['rack_row_id'], $_REQUEST['rack_comment']))
                return buildRedirectURL (__FUNCTION__, 'OK', array ($_REQUEST['rack_name']));
        else
@@ -1981,8 +2038,39 @@ function querySNMPData ()
        return doSNMPmining ($_REQUEST['object_id'], $snmpsetup);
 }
 
+$msgcode['linkEntities']['OK'] = 51;
+$msgcode['linkEntities']['ERR2'] = 109;
+function linkEntities ()
+{
+       assertStringArg ('parent_entity_type');
+       assertUIntArg ('parent_entity_id');
+       assertStringArg ('child_entity_type');
+       assertUIntArg ('child_entity_id');
+       $result = usePreparedInsertBlade
+       (
+               'EntityLink',
+               array
+               (
+                       'parent_entity_type' => $_REQUEST['parent_entity_type'],
+                       'parent_entity_id' => $_REQUEST['parent_entity_id'],
+                       'child_entity_type' => $_REQUEST['child_entity_type'],
+                       'child_entity_id' => $_REQUEST['child_entity_id'],
+               )
+       );
+       if ($result === FALSE)
+               return buildRedirectURL (__FUNCTION__, 'ERR2');
+       return buildRedirectURL (__FUNCTION__, 'OK');
+}
+
+$msgcode['unlinkEntities']['OK'] = 49;
+$msgcode['unlinkEntities']['ERR'] = 111;
+function unlinkEntities ()
+{
+       assertUIntArg ('link_id');
+       return buildRedirectURL (__FUNCTION__, commitUnlinkEntities ($_REQUEST['link_id']) === FALSE ? 'ERR' : 'OK');
+}
+
 $msgcode['addFileWithoutLink']['OK'] = 5;
-$msgcode['addFileWithoutLink']['ERR2'] = 110;
 // File-related functions
 function addFileWithoutLink ()
 {
@@ -1994,57 +2082,64 @@ function addFileWithoutLink ()
 
        $fp = fopen($_FILES['file']['tmp_name'], 'rb');
        global $sic;
-       if (FALSE === commitAddFile ($_FILES['file']['name'], $_FILES['file']['type'], $_FILES['file']['size'], $fp, $sic['comment']))
-               return buildRedirectURL (__FUNCTION__, 'ERR2');
+       commitAddFile ($_FILES['file']['name'], $_FILES['file']['type'], $fp, $sic['comment']);
        if (isset ($_REQUEST['taglist']))
                produceTagsForLastRecord ('file', $_REQUEST['taglist']);
        return buildRedirectURL (__FUNCTION__, 'OK', array (htmlspecialchars ($_FILES['file']['name'])));
 }
 
 $msgcode['addFileToEntity']['OK'] = 5;
-$msgcode['addFileToEntity']['ERR2'] = 181;
-$msgcode['addFileToEntity']['ERR3'] = 110;
 function addFileToEntity ()
 {
        global $pageno, $etype_by_pageno;
        if (!isset ($etype_by_pageno[$pageno]))
                throw new RackTablesError ('key not found in etype_by_pageno', RackTablesError::INTERNAL);
        $realm = $etype_by_pageno[$pageno];
-       $entity_id = getBypassValue();
        assertStringArg ('comment', TRUE);
 
        // Make sure the file can be uploaded
        if (get_cfg_var('file_uploads') != 1)
-               return buildRedirectURL (__FUNCTION__, 'ERR2');
+               throw new RackTablesError ('file uploads not allowed, change "file_uploads" parameter in php.ini', RackTablesError::MISCONFIGURED);
 
        $fp = fopen($_FILES['file']['tmp_name'], 'rb');
        global $sic;
-       if (FALSE === commitAddFile ($_FILES['file']['name'], $_FILES['file']['type'], $_FILES['file']['size'], $fp, $sic['comment']))
-               return buildRedirectURL (__FUNCTION__, 'ERR3');
-       if (FALSE === commitLinkFile (lastInsertID(), $realm, $entity_id))
-               return buildRedirectURL (__FUNCTION__, 'ERR3');
-
+       commitAddFile ($_FILES['file']['name'], $_FILES['file']['type'], $fp, $sic['comment']);
+       usePreparedInsertBlade
+       (
+               'FileLink',
+               array
+               (
+                       'file_id' => lastInsertID(),
+                       'entity_type' => $realm,
+                       'entity_id' => getBypassValue(),
+               )
+       );
        return buildRedirectURL (__FUNCTION__, 'OK', array (htmlspecialchars ($_FILES['file']['name'])));
 }
 
 $msgcode['linkFileToEntity']['OK'] = 71;
-$msgcode['linkFileToEntity']['ERR2'] = 110;
 function linkFileToEntity ()
 {
        assertUIntArg ('file_id');
-       global $pageno, $etype_by_pageno;
+       global $pageno, $etype_by_pageno, $sic;
        if (!isset ($etype_by_pageno[$pageno]))
                throw new RackTablesError ('key not found in etype_by_pageno', RackTablesError::INTERNAL);
 
-       $fi = spotEntity ('file', $_REQUEST['file_id']);
-       if (FALSE === commitLinkFile ($_REQUEST['file_id'], $etype_by_pageno[$pageno], getBypassValue()))
-               return buildRedirectURL (__FUNCTION__, 'ERR2');
-
+       $fi = spotEntity ('file', $sic['file_id']);
+       usePreparedInsertBlade
+       (
+               'FileLink',
+               array
+               (
+                       'file_id' => $sic['file_id'],
+                       'entity_type' => $etype_by_pageno[$pageno],
+                       'entity_id' => getBypassValue(),
+               )
+       );
        return buildRedirectURL (__FUNCTION__, 'OK', array (htmlspecialchars ($fi['name'])));
 }
 
 $msgcode['replaceFile']['OK'] = 7;
-$msgcode['replaceFile']['ERR1'] = 181;
 $msgcode['replaceFile']['ERR2'] = 207;
 $msgcode['replaceFile']['ERR3'] = 109;
 function replaceFile ()
@@ -2053,7 +2148,7 @@ function replaceFile ()
 
        // Make sure the file can be uploaded
        if (get_cfg_var('file_uploads') != 1)
-               return buildRedirectURL (__FUNCTION__, 'ERR1');
+               throw new RackTablesError ('file uploads not allowed, change "file_uploads" parameter in php.ini', RackTablesError::MISCONFIGURED);
        $shortInfo = spotEntity ('file', $sic['file_id']);
 
        $fp = fopen($_FILES['file']['tmp_name'], 'rb');
@@ -2071,19 +2166,6 @@ function replaceFile ()
        return buildRedirectURL (__FUNCTION__, 'OK', array (htmlspecialchars ($shortInfo['name'])));
 }
 
-$msgcode['updateFile']['OK'] = 70;
-$msgcode['updateFile']['ERR'] = 109;
-function updateFile ()
-{
-       assertStringArg ('file_name');
-       assertStringArg ('file_type');
-       assertStringArg ('file_comment', TRUE);
-       global $sic;
-       if (FALSE === commitUpdateFile ($sic['file_id'], $sic['file_name'], $sic['file_type'], $sic['file_comment']))
-               return buildRedirectURL (__FUNCTION__, 'ERR');
-       return buildRedirectURL (__FUNCTION__, 'OK', array ($_REQUEST['file_name']));
-}
-
 $msgcode['unlinkFile']['OK'] = 72;
 $msgcode['unlinkFile']['ERR'] = 111;
 function unlinkFile ()
@@ -2093,16 +2175,11 @@ function unlinkFile ()
 }
 
 $msgcode['deleteFile']['OK'] = 6;
-$msgcode['deleteFile']['ERR'] = 111;
 function deleteFile ()
 {
        assertUIntArg ('file_id');
        $shortInfo = spotEntity ('file', $_REQUEST['file_id']);
-       $error = commitDeleteFile ($_REQUEST['file_id']);
-
-       if ($error != '')
-               return buildRedirectURL (__FUNCTION__, 'ERR', array ($error));
-
+       commitDeleteFile ($_REQUEST['file_id']);
        return buildRedirectURL (__FUNCTION__, 'OK', array (htmlspecialchars ($shortInfo['name'])));
 }
 
@@ -2237,7 +2314,6 @@ function delVLANDescription ()
 
 $msgcode['updVLANDescription']['OK'] = 51;
 $msgcode['updVLANDescription']['ERR1'] = 105;
-$msgcode['updVLANDescription']['ERR2'] = 109;
 function updVLANDescription ()
 {
        assertUIntArg ('vlan_id');
@@ -2246,14 +2322,21 @@ function updVLANDescription ()
        global $sic;
        if ($sic['vlan_id'] == VLAN_DFL_ID)
                return buildRedirectURL (__FUNCTION__, 'ERR1');
-       $result = commitUpdateVLANDescription
+       usePreparedUpdateBlade
        (
-               $sic['vdom_id'],
-               $sic['vlan_id'],
-               $sic['vlan_type'],
-               $sic['vlan_descr']
+               'VLANDescription',
+               array
+               (
+                       'vlan_descr' => !mb_strlen ($sic['vlan_descr']) ? NULL : $sic['vlan_descr'],
+                       'vlan_type' => $sic['vlan_type'],
+               ),
+               array
+               (
+                       'domain_id' => $sic['vdom_id'],
+                       'vlan_id' => $sic['vlan_id'],
+               )
        );
-       return buildRedirectURL (__FUNCTION__, $result !== FALSE ? 'OK' : 'ERR2');
+       return buildRedirectURL (__FUNCTION__, 'OK');
 }
 
 $msgcode['createVLANDomain']['OK'] = 48;
@@ -2294,17 +2377,6 @@ function destroyVLANDomain ()
        return buildRedirectURL (__FUNCTION__, $result ? 'OK' : 'ERR');
 }
 
-$msgcode['updateVLANDomain']['OK'] = 51;
-$msgcode['updateVLANDomain']['ERR'] = 109;
-function updateVLANDomain ()
-{
-       assertUIntArg ('vdom_id');
-       assertStringArg ('vdom_descr');
-       global $sic;
-       $result = FALSE !== commitUpdateVLANDomain ($sic['vdom_id'], $sic['vdom_descr']);
-       return buildRedirectURL (__FUNCTION__, $result ? 'OK' : 'ERR');
-}
-
 $msgcode['save8021QPorts']['OK1'] = 63;
 $msgcode['save8021QPorts']['OK2'] = 41;
 $msgcode['save8021QPorts']['ERR2'] = 109;
@@ -2584,18 +2656,11 @@ function addVLANSwitchTemplate()
 {
        assertStringArg ('vst_descr');
        global $sic;
-       $max_local_vlans = NULL;
-       if (array_key_exists ('vst_maxvlans', $sic) && mb_strlen ($sic['vst_maxvlans']))
-       {
-               assertUIntArg ('vst_maxvlans');
-               $max_local_vlans = $sic['vst_maxvlans'];
-       }
        $result = usePreparedInsertBlade
        (
                'VLANSwitchTemplate',
                array
                (
-                       'max_local_vlans' => $max_local_vlans,
                        'description' => $sic['vst_descr'],
                )
        );
@@ -2612,49 +2677,27 @@ function delVLANSwitchTemplate()
        return buildRedirectURL (__FUNCTION__, $result ? 'OK' : 'ERR');
 }
 
-$msgcode['updVLANSwitchTemplate']['OK'] = 51;
-$msgcode['updVLANSwitchTemplate']['ERR'] = 109;
-function updVLANSwitchTemplate()
+$msgcode['cloneVST']['OK'] = 48;
+$msgcode['cloneVST']['ERR'] = 179;
+function cloneVST()
 {
-       assertUIntArg ('vst_id');
-       assertStringArg ('vst_descr');
-       global $sic;
-       $max_local_vlans = NULL;
-       if (array_key_exists ('vst_maxvlans', $sic) && mb_strlen ($sic['vst_maxvlans']))
-       {
-               assertUIntArg ('vst_maxvlans');
-               $max_local_vlans = $sic['vst_maxvlans'];
-       }
-       $result = commitUpdateVST ($sic['vst_id'], $max_local_vlans, $sic['vst_descr']);
-       return buildRedirectURL (__FUNCTION__, $result !== FALSE ? 'OK' : 'ERR');
-}
-
-$msgcode['cloneVSTRule']['OK'] = 48;
-$msgcode['cloneVSTRule']['ERR'] = 179;
-function cloneVSTRule()
-{
-       global $dbxlink;
-       $message = '';
        assertUIntArg ('mutex_rev', TRUE);
-       $dst_vst = getVLANSwitchTemplate ($_REQUEST['vst_id']);
-       if ($dst_vst['mutex_rev'] != $_REQUEST['mutex_rev'])
-               $message = "User ${dst_vst['saved_by']} saved this template after you started to edit it. Please concern differencies";
-       else
-       {
-               assertUIntArg ('from_id');
-               $src_vst = getVLANSwitchTemplate ($_REQUEST['from_id']);
-               if (! commitUpdateVSTRules ($_REQUEST['vst_id'], $src_vst['rules']))
-                       $message = 'DB error';
-       }
-       $result = !(BOOL) $message;
-       if ($result)
-               $message = 'Supplement succeeded';
-       return buildWideRedirectURL (array (array ('code' => $result ? 'success' : 'error', 'message' => $message)));
+       assertUIntArg ('from_id');
+       $src_vst = getVLANSwitchTemplate ($_REQUEST['from_id']);
+       commitUpdateVSTRules (getBypassValue(), $_REQUEST['mutex_rev'], $src_vst['rules']);
+       return buildRedirectURL (__FUNCTION__, 'OK');
 }
 
 $msgcode['updVSTRule']['OK'] = 43;
 function updVSTRule()
 {
+       // this is used for making throwing an invalid argument exception easier.
+       function updVSTRule_get_named_param ($name, $haystack, &$last_used_name)
+       {
+               $last_used_name = $name;
+               return isset ($haystack[$name]) ? $haystack[$name] : NULL;
+       }
+
        global $port_role_options, $sic;
        assertUIntArg ('mutex_rev', TRUE);
        genericAssertion ('template_json', 'json');
@@ -2662,20 +2705,21 @@ function updVSTRule()
        $rule_no = 0;
        try
        {
+               $last_field = '';
                foreach ($data as $rule)
                {
                        $rule_no++;
                        if
                        (
-                               ! isInteger ($rule['rule_no'])
-                               or ! isPCRE ($rule['port_pcre'])
-                               or ! isset ($rule['port_role'])
-                               or ! array_key_exists ($rule['port_role'], $port_role_options)
-                               or ! isset ($rule['wrt_vlans'])
-                               or ! preg_match ('/^[ 0-9\-,]*$/', $rule['wrt_vlans'])
-                               or ! isset ($rule['description'])
+                               ! isInteger (updVSTRule_get_named_param ('rule_no', $rule, $last_field))
+                               or ! isPCRE (updVSTRule_get_named_param ('port_pcre', $rule, $last_field))
+                               or NULL === updVSTRule_get_named_param ('port_role', $rule, $last_field)
+                               or ! array_key_exists (updVSTRule_get_named_param ('port_role', $rule, $last_field), $port_role_options)
+                               or NULL ===  updVSTRule_get_named_param ('wrt_vlans', $rule, $last_field)
+                               or ! preg_match ('/^[ 0-9\-,]*$/',  updVSTRule_get_named_param ('wrt_vlans', $rule, $last_field))
+                               or NULL ===  updVSTRule_get_named_param ('description', $rule, $last_field)
                        )
-                               throw new InvalidRequestArgException ('form', '(JSON)', "invalid rule #$rule_no");
+                               throw new InvalidRequestArgException ($last_field, $rule[$last_field], "rule #$rule_no");
                }
                commitUpdateVSTRules ($_REQUEST['vst_id'], $_REQUEST['mutex_rev'], $data);
        }
@@ -2732,8 +2776,7 @@ function addObjectlog ()
        global $remote_username, $sic;
        $oi = spotEntity ('object', $sic['object_id']);
        usePreparedExecuteBlade ('INSERT INTO ObjectLog SET object_id=?, user=?, date=NOW(), content=?', array ($sic['object_id'], $remote_username, $sic['logentry']));
-       $ob_url = makeHref (array ('page' => 'object', 'tab' => 'objectlog', 'object_id' => $sic['object_id']));
-       return buildRedirectURL (__FUNCTION__, 'OK', array ("Log entry for <a href=" . ${ob_url} . ">${oi['dname']}</a> added by ${remote_username}"));
+       return buildRedirectURL (__FUNCTION__, 'OK', array ('Log entry for ' . mkA ($oi['dname'], 'object', $sic['object_id'], 'log') . " added by ${remote_username}"));
 }
 
 function getOpspec()