ソースを参照

Ticket #4515 - Export/Import tools: Studio changes for builders.

AntonLV 3 年 前
親
コミット
fe679aabfd

+ 132 - 78
studio/classes/BxDolStudioBuilderPageQuery.php

@@ -58,7 +58,34 @@ class BxDolStudioBuilderPageQuery extends BxDolStudioPageQuery
     function getPages($aParams)
     {
         $aMethod = array('name' => 'getAll', 'params' => array(0 => 'query'));
-        $sSelectClause = $sJoinClause = $sWhereClause = $sGroupClause = $sOrderClause = $sLimitClause = "";
+        $sSelectClause = "
+            `tp`.`id` AS `id`,
+            `tp`.`object` AS `object`,
+            `tp`.`uri` AS `uri`,
+            `tp`.`title_system` AS `title_system`,
+            `tp`.`title` AS `title`,
+            `tp`.`module` AS `module`,
+            `tp`.`cover` AS `cover`,
+            `tp`.`cover_image` AS `cover_image`,
+            `tp`.`cover_title` AS `cover_title`,
+            `tp`.`type_id` AS `type_id`,
+            `tp`.`layout_id` AS `layout_id`,
+            `tp`.`submenu` AS `submenu`,
+            `tp`.`visible_for_levels` AS `visible_for_levels`,
+            `tp`.`visible_for_levels_editable` AS `visible_for_levels_editable`,
+            `tp`.`url` AS `url`,
+            `tp`.`meta_description` AS `meta_description`,
+            `tp`.`meta_keywords` AS `meta_keywords`,
+            `tp`.`meta_robots` AS `meta_robots`,
+            `tp`.`cache_lifetime` AS `cache_lifetime`,
+            `tp`.`cache_editable` AS `cache_editable`,
+            `tp`.`inj_head` AS `inj_head`,
+            `tp`.`inj_footer` AS `inj_footer`,
+            `tp`.`sticky_columns` AS `sticky_columns`,
+            `tp`.`deletable` AS `deletable`,
+            `tp`.`override_class_name` AS `override_class_name`,
+            `tp`.`override_class_file` AS `override_class_file`";
+        $sJoinClause = $sWhereClause = $sGroupClause = $sOrderClause = $sLimitClause = "";
 
         if(!isset($aParams['order']) || empty($aParams['order']))
            $sOrderClause = "ORDER BY `tp`.`object` ASC";
@@ -67,7 +94,7 @@ class BxDolStudioBuilderPageQuery extends BxDolStudioPageQuery
             case 'by_id':
                 $aMethod['name'] = 'getRow';
                 $aMethod['params'][1] = array(
-                	'id' => $aParams['value']
+                    'id' => $aParams['value']
                 );
 
                 $sWhereClause = " AND `tp`.`id`=:id ";
@@ -75,16 +102,16 @@ class BxDolStudioBuilderPageQuery extends BxDolStudioPageQuery
             case 'by_object':
                 $aMethod['name'] = 'getRow';
                 $aMethod['params'][1] = array(
-                	'object' => $aParams['value']
+                    'object' => $aParams['value']
                 );
 
                 $sWhereClause = " AND `tp`.`object`=:object ";
                 break;
 
-			case 'by_uri':
+            case 'by_uri':
                 $aMethod['name'] = 'getRow';
                 $aMethod['params'][1] = array(
-                	'uri' => $aParams['value']
+                    'uri' => $aParams['value']
                 );
 
                 $sWhereClause = " AND `tp`.`uri`=:uri ";
@@ -93,64 +120,63 @@ class BxDolStudioBuilderPageQuery extends BxDolStudioPageQuery
             case 'by_object_full':
                 $aMethod['name'] = 'getRow';
                 $aMethod['params'][1] = array(
-                	'object' => $aParams['value']
+                    'object' => $aParams['value']
                 );
 
-                $sSelectClause = ", `tpl`.`name` AS `layout_name`, `tpl`.`icon` AS `layout_icon`, `tpl`.`title` AS `layout_title`, `tpl`.`template` AS `layout_template`, `tpl`.`cells_number` AS `layout_cells_number`";
+                $sSelectClause .= ", `tpl`.`name` AS `layout_name`, `tpl`.`icon` AS `layout_icon`, `tpl`.`title` AS `layout_title`, `tpl`.`template` AS `layout_template`, `tpl`.`cells_number` AS `layout_cells_number`";
                 $sJoinClause = "LEFT JOIN `sys_pages_layouts` AS `tpl` ON `tp`.`layout_id`=`tpl`.`id`";
                 $sWhereClause = " AND `tp`.`object`=:object ";
                 break;
 
             case 'by_module':
             	$aMethod['params'][1] = array(
-                	'module' => $aParams['value']
+                    'module' => $aParams['value']
                 );
 
                 $sWhereClause = " AND `tp`.`module`=:module ";
                 break;
 
+            case 'export':
+                $sSelectClause = "`tp`.*";
+                break;
+
             case 'all':
                 break;
         }
 
         $aMethod['params'][0] = "SELECT 
-                `tp`.`id` AS `id`,
-                `tp`.`object` AS `object`,
-                `tp`.`uri` AS `uri`,
-                `tp`.`title_system` AS `title_system`,
-                `tp`.`title` AS `title`,
-                `tp`.`module` AS `module`,
-                `tp`.`cover` AS `cover`,
-                `tp`.`cover_image` AS `cover_image`,
-                `tp`.`cover_title` AS `cover_title`,
-                `tp`.`type_id` AS `type_id`,
-                `tp`.`layout_id` AS `layout_id`,
-                `tp`.`submenu` AS `submenu`,
-                `tp`.`visible_for_levels` AS `visible_for_levels`,
-                `tp`.`visible_for_levels_editable` AS `visible_for_levels_editable`,
-                `tp`.`url` AS `url`,
-                `tp`.`meta_description` AS `meta_description`,
-                `tp`.`meta_keywords` AS `meta_keywords`,
-                `tp`.`meta_robots` AS `meta_robots`,
-                `tp`.`cache_lifetime` AS `cache_lifetime`,
-                `tp`.`cache_editable` AS `cache_editable`,
-                `tp`.`inj_head` AS `inj_head`,
-                `tp`.`inj_footer` AS `inj_footer`,
-                `tp`.`sticky_columns` AS `sticky_columns`,
-                `tp`.`deletable` AS `deletable`,
-                `tp`.`override_class_name` AS `override_class_name`,
-                `tp`.`override_class_file` AS `override_class_file`" . $sSelectClause . "
+                " . $sSelectClause . "
             FROM `sys_objects_page` AS `tp` " . $sJoinClause . "
             WHERE 1 " . $sWhereClause . " " . $sGroupClause . " " . $sOrderClause . " " . $sLimitClause;
 
         return call_user_func_array(array($this, $aMethod['name']), $aMethod['params']);
     }
 
+    function isPageExists($sObject)
+    {
+        $aPage = $this->getPages(['type' => 'by_object', 'value' => $sObject]);
+        return !empty($aPage) && is_array($aPage);
+    }
+
+    function addPage($aFields)
+    {
+        $sSql = "INSERT INTO `sys_objects_page` SET `" . implode("`=?, `", array_keys($aFields)) . "`=?";
+        $sSql = call_user_func_array(array($this, 'prepare'), array_merge(array($sSql), array_values($aFields)));
+        return (int)$this->query($sSql) > 0 ? $this->lastId() : 0;
+    }
+
     function updatePage($iId, $aFields)
     {
         $sSql = "UPDATE `sys_objects_page` SET `" . implode("`=?, `", array_keys($aFields)) . "`=?  WHERE `id`=?";
-        $oStml = call_user_func_array(array($this, 'prepare'), array_merge(array($sSql), array_values($aFields), array($iId)));
-        return $this->res($oStml);
+        $sSql = call_user_func_array(array($this, 'prepare'), array_merge(array($sSql), array_values($aFields), array($iId)));
+        return $this->query($sSql);
+    }
+    
+    function updatePageByObject($sObject, $aFields)
+    {
+        return $this->query("UPDATE `sys_objects_page` SET " . $this->arrayToSQL($aFields) . " WHERE `object`=:object", [
+            'object' => $sObject
+        ]);
     }
 
     function deletePages($aParams)
@@ -342,7 +368,32 @@ class BxDolStudioBuilderPageQuery extends BxDolStudioPageQuery
     function getBlocks($aParams, &$aItems, $bReturnCount = true)
     {
         $aMethod = array('name' => 'getAll', 'params' => array(0 => 'query'));
-        $sSelectClause = $sJoinClause = $sWhereClause = $sGroupClause = $sOrderClause = $sLimitClause = "";
+        $sSelectClause = "
+            `tpb`.`id` AS `id`,
+            `tpb`.`object` AS `object`,
+            `tpb`.`cell_id` AS `cell_id`,
+            `tpb`.`module` AS `module`,
+            `tpb`.`title_system` AS `title_system`,
+            `tpb`.`title` AS `title`,
+            `tpb`.`designbox_id` AS `designbox_id`,
+            `tpb`.`class` AS `class`,
+            `tpb`.`async` AS `async`,
+            `tpb`.`cache_lifetime` AS `cache_lifetime`,
+            `tpb`.`submenu` AS `submenu`,
+            `tpb`.`tabs` AS `tabs`,
+            `tpb`.`hidden_on` AS `hidden_on`,
+            `tpb`.`visible_for_levels` AS `visible_for_levels`,
+            `tpb`.`type` AS `type`,
+            `tpb`.`content` AS `content`,
+            `tpb`.`content_empty` AS `content_empty`,
+            `tpb`.`help` AS `help`,
+            `tpb`.`deletable` AS `deletable`,
+            `tpb`.`copyable` AS `copyable`,
+            `tpb`.`active` AS `active`,
+            `tpb`.`active_api` AS `active_api`,
+            `tpb`.`order` AS `order`
+        ";
+        $sJoinClause = $sWhereClause = $sGroupClause = $sOrderClause = $sLimitClause = "";
 
         if(!isset($aParams['order']) || empty($aParams['order']))
            $sOrderClause = "ORDER BY `tpb`.`order` ASC";
@@ -351,17 +402,23 @@ class BxDolStudioBuilderPageQuery extends BxDolStudioPageQuery
             case 'by_id':
                 $aMethod['name'] = 'getRow';
                 $aMethod['params'][1] = array(
-                	'id' => $aParams['value']
+                    'id' => $aParams['value']
                 );
 
                 $sWhereClause = "AND `tpb`.`id`=:id ";
                 break;
+            
+            case 'by_fields':
+                $aMethod['name'] = 'getRow';
+
+                $sWhereClause = "AND " . $this->arrayToSQL($aParams['fields'], ' AND ');
+                break;
 
             case 'skeleton_by_type':
                 $aMethod['name'] = 'getRow';
                 $aMethod['params'][1] = array(
-                	'module' => BX_DOL_STUDIO_BP_SKELETONS,
-                	'type' => $aParams['value']
+                    'module' => BX_DOL_STUDIO_BP_SKELETONS,
+                    'type' => $aParams['value']
                 );
 
                 $sWhereClause = "AND `tpb`.`object`='' AND `tpb`.`module`=:module AND `tpb`.`type`=:type ";
@@ -373,16 +430,25 @@ class BxDolStudioBuilderPageQuery extends BxDolStudioPageQuery
 
             case 'by_object':
             	$aMethod['params'][1] = array(
-                	'object' => $aParams['value']
+                    'object' => $aParams['value']
                 );
 
                 $sWhereClause = "AND `tpb`.`object`=:object";
                 break;
+            
+            case 'export_by_object':
+                $aMethod['params'][1] = [
+                    'object' => $aParams['value']
+                ];
+
+                $sSelectClause = "`tpb`.*";
+                $sWhereClause = "AND `tpb`.`object`=:object";
+                break;
 
             case 'by_object_cell':
             	$aMethod['params'][1] = array(
-                	'object' => $aParams['object'],
-            		'cell_id' => $aParams['cell']
+                    'object' => $aParams['object'],
+                    'cell_id' => $aParams['cell']
                 );
 
                 $sWhereClause = "AND `tpb`.`object`=:object AND `tpb`.`cell_id`=:cell_id";
@@ -390,7 +456,7 @@ class BxDolStudioBuilderPageQuery extends BxDolStudioPageQuery
 
             case 'by_module_to_copy':
             	$aMethod['params'][1] = array(
-                	'module' => $aParams['value']
+                    'module' => $aParams['value']
                 );
 
                 $sWhereClause = "AND `tpb`.`module`=:module AND `tpb`.`copyable`=1";
@@ -403,7 +469,7 @@ class BxDolStudioBuilderPageQuery extends BxDolStudioPageQuery
                 $aMethod['name'] = 'getPairs';
                 $aMethod['params'][1] = 'object';
                 $aMethod['params'][2] = 'counter';
-                $sSelectClause = ", COUNT(*) AS `counter`";
+                $sSelectClause .= ", COUNT(*) AS `counter`";
                 $sGroupClause = "GROUP BY `tpb`.`object`";
                 break;
 
@@ -411,30 +477,7 @@ class BxDolStudioBuilderPageQuery extends BxDolStudioPageQuery
                 break;
         }
 
-        $aMethod['params'][0] = "SELECT " . ($bReturnCount ? "SQL_CALC_FOUND_ROWS" : "") . "
-                `tpb`.`id` AS `id`,
-                `tpb`.`object` AS `object`,
-                `tpb`.`cell_id` AS `cell_id`,
-                `tpb`.`module` AS `module`,
-                `tpb`.`title_system` AS `title_system`,
-                `tpb`.`title` AS `title`,
-                `tpb`.`designbox_id` AS `designbox_id`,
-                `tpb`.`class` AS `class`,
-                `tpb`.`async` AS `async`,
-                `tpb`.`cache_lifetime` AS `cache_lifetime`,
-                `tpb`.`submenu` AS `submenu`,
-                `tpb`.`tabs` AS `tabs`,
-                `tpb`.`hidden_on` AS `hidden_on`,
-                `tpb`.`visible_for_levels` AS `visible_for_levels`,
-                `tpb`.`type` AS `type`,
-                `tpb`.`content` AS `content`,
-                `tpb`.`content_empty` AS `content_empty`,
-                `tpb`.`help` AS `help`,
-                `tpb`.`deletable` AS `deletable`,
-                `tpb`.`copyable` AS `copyable`,
-                `tpb`.`active` AS `active`,
-                `tpb`.`active_api` AS `active_api`,
-                `tpb`.`order` AS `order`" . $sSelectClause . "
+        $aMethod['params'][0] = "SELECT " . ($bReturnCount ? "SQL_CALC_FOUND_ROWS" : "") . $sSelectClause . "
             FROM `sys_pages_blocks` AS `tpb` " . $sJoinClause . "
             WHERE 1 " . $sWhereClause . " " . $sGroupClause . " " . $sOrderClause . " " . $sLimitClause;
         $aItems = call_user_func_array(array($this, $aMethod['name']), $aMethod['params']);
@@ -445,20 +488,31 @@ class BxDolStudioBuilderPageQuery extends BxDolStudioPageQuery
         return (int)$this->getOne("SELECT FOUND_ROWS()");
     }
 
-    function insertBlock($aFields)
+    function isBlockExists($aFields)
     {
-        $aFields['order'] = $this->getBlockOrderMax($aFields['object']) + 1;
+        $aBlock = [];
+        $this->getBlocks(['type' => 'by_fields', 'fields' => $aFields], $aBlock, false);
 
-        $sSql = "INSERT INTO `sys_pages_blocks` SET " . $this->arrayToSQL($aFields);
-        if (!$this->query($sSql))
-            return false;
-        return $this->lastId();
+        return !empty($aBlock) && is_array($aBlock);
     }
+            
+    function insertBlock($aData)
+    {
+        $aData['order'] = $this->getBlockOrderMax($aData['object']) + 1;
 
-    function updateBlock($iId, $aFields)
+        return $this->query("INSERT INTO `sys_pages_blocks` SET " . $this->arrayToSQL($aData)) ? $this->lastId() : false;
+    }
+
+    function updateBlock($iId, $aData)
+    {
+        return $this->query("UPDATE `sys_pages_blocks` SET " . $this->arrayToSQL($aData) . " WHERE `id`=:id", [
+            'id' => $iId
+        ]) ? true : false;
+    }
+    
+    function updateBlockByFields($aFields, $aData)
     {
-        $oStmt = $this->prepare("UPDATE `sys_pages_blocks` SET " . $this->arrayToSQL($aFields) . " WHERE `id`=:id");
-        return $this->res($oStmt, array('id' => $iId)) ? true : false;
+        return $this->query("UPDATE `sys_pages_blocks` SET " . $this->arrayToSQL($aData) . " WHERE " . $this->arrayToSQL($aFields, ' AND ')) ? true : false;
     }
 
     function deleteBlocks($aParams)

+ 158 - 50
studio/classes/BxDolStudioFormsQuery.php

@@ -17,7 +17,24 @@ class BxDolStudioFormsQuery extends BxDolDb
     function getForms($aParams, &$aItems, $bReturnCount = true)
     {
         $aMethod = array('name' => 'getAll', 'params' => array(0 => 'query'));
-        $sSelectClause = $sJoinClause = $sWhereClause = $sGroupClause = $sOrderClause = $sLimitClause = "";
+        $sSelectClause = "
+            `tf`.`id` AS `id`,
+            `tf`.`object` AS `object`,
+            `tf`.`module` AS `module`,
+            `tf`.`title` AS `title`,
+            `tf`.`action` AS `action`,
+            `tf`.`form_attrs` AS `form_attrs`,
+            `tf`.`table` AS `table`,
+            `tf`.`key` AS `key`,
+            `tf`.`uri` AS `uri`,
+            `tf`.`uri_title` AS `uri_title`,
+            `tf`.`submit_name` AS `submit_name`,
+            `tf`.`params` AS `params`,
+            `tf`.`deletable` AS `deletable`,
+            `tf`.`active` AS `active`,
+            `tf`.`override_class_name` AS `override_class_name`,
+            `tf`.`override_class_file` AS `override_class_file`";
+        $sJoinClause = $sWhereClause = $sGroupClause = $sOrderClause = $sLimitClause = "";
 
         if(!isset($aParams['order']) || empty($aParams['order']))
            $sOrderClause = "ORDER BY `tf`.`title` ASC";
@@ -26,17 +43,26 @@ class BxDolStudioFormsQuery extends BxDolDb
             case 'by_id':
                 $aMethod['name'] = 'getRow';
                 $aMethod['params'][1] = array(
-                	'id' => $aParams['value']
+                    'id' => $aParams['value']
                 );
 
                 $sWhereClause = " AND `tf`.`id`=:id ";
                 break;
 
+            case 'by_object':
+                $aMethod['name'] = 'getRow';
+                $aMethod['params'][1] = [
+                    'object' => $aParams['value'],
+                ];
+
+                $sWhereClause = "AND `tf`.`object`=:object ";
+                break;
+
             case 'by_object_display':
                 $aMethod['name'] = 'getRow';
                 $aMethod['params'][1] = array(
-                	'object' => $aParams['object'],
-                	'display_name' => $aParams['display']
+                    'object' => $aParams['object'],
+                    'display_name' => $aParams['display']
                 );
 
                 $sJoinClause = "LEFT JOIN `sys_form_displays` AS `td` ON `tf`.`object`=`td`.`object` ";
@@ -45,7 +71,7 @@ class BxDolStudioFormsQuery extends BxDolDb
 
             case 'by_module':
             	$aMethod['params'][1] = array(
-                	'module' => $aParams['value']
+                    'module' => $aParams['value']
                 );
 
                 $sWhereClause = "AND `tf`.`module`=:module";
@@ -55,7 +81,7 @@ class BxDolStudioFormsQuery extends BxDolDb
                 $aMethod['name'] = 'getPairs';
                 $aMethod['params'][1] = 'module';
                 $aMethod['params'][2] = 'counter';
-                $sSelectClause = ", COUNT(*) AS `counter`";
+                $sSelectClause .= ", COUNT(*) AS `counter`";
                 $sGroupClause = "GROUP BY `tf`.`module`";
                 break;
                 
@@ -64,7 +90,7 @@ class BxDolStudioFormsQuery extends BxDolDb
                 $aMethod['params'][1] = 'object';
                 $aMethod['params'][2] = 'title';
                 $aMethod['params'][3] = array(
-                	'parent_form' => $aParams['parent_form']
+                    'parent_form' => $aParams['parent_form']
                 );
                 $sSubQuery = "SELECT `value` FROM `sys_form_inputs` sfi WHERE `type`='nested_form' AND `object` = :parent_form ";
                 if (!@empty($aParams['ids'])){
@@ -72,28 +98,16 @@ class BxDolStudioFormsQuery extends BxDolDb
                 }
                 $sWhereClause = "AND `tf`.`parent_form`=:parent_form AND `object` NOT IN (" . $sSubQuery . ")";
                 break;
-             
+
+            case 'export':
+                $sSelectClause = "`tf`.*";
+                break;
+
             case 'all':
                 break;
         }
 
-        $aMethod['params'][0] = "SELECT " . ($bReturnCount ? "SQL_CALC_FOUND_ROWS" : "") . "
-                `tf`.`id` AS `id`,
-                `tf`.`object` AS `object`,
-                `tf`.`module` AS `module`,
-                `tf`.`title` AS `title`,
-                `tf`.`action` AS `action`,
-                `tf`.`form_attrs` AS `form_attrs`,
-                `tf`.`table` AS `table`,
-                `tf`.`key` AS `key`,
-                `tf`.`uri` AS `uri`,
-                `tf`.`uri_title` AS `uri_title`,
-                `tf`.`submit_name` AS `submit_name`,
-                `tf`.`params` AS `params`,
-                `tf`.`deletable` AS `deletable`,
-                `tf`.`active` AS `active`,
-                `tf`.`override_class_name` AS `override_class_name`,
-                `tf`.`override_class_file` AS `override_class_file`" . $sSelectClause . "
+        $aMethod['params'][0] = "SELECT " . ($bReturnCount ? "SQL_CALC_FOUND_ROWS" : "") . $sSelectClause . "
             FROM `sys_objects_form` AS `tf` " . $sJoinClause . "
             WHERE 1 " . $sWhereClause . " " . $sGroupClause . " " . $sOrderClause . " " . $sLimitClause;
         $aItems = call_user_func_array(array($this, $aMethod['name']), $aMethod['params']);
@@ -103,11 +117,39 @@ class BxDolStudioFormsQuery extends BxDolDb
 
         return (int)$this->getOne("SELECT FOUND_ROWS()");
     }
+    
+    function isForm($sName)
+    {
+        $aForm = [];
+        $this->getForms(['type' => 'by_object', 'value' => $sName], $aForm, false);
+
+        return !empty($aForm) && is_array($aForm);
+    }
+
+    function addForm($aFields)
+    {
+        return $this->query("INSERT INTO `sys_objects_form` SET " . $this->arrayToSQL($aFields));
+    }
+
+    function updateFormByObject($sObject, $aFields)
+    {
+        return $this->query("UPDATE `sys_objects_form` SET " . $this->arrayToSQL($aFields) . " WHERE `object`=:object", [
+            'object' => $sObject
+        ]);
+    }
 
     function getDisplays($aParams, &$aItems, $bReturnCount = true)
     {
         $aMethod = array('name' => 'getAll', 'params' => array(0 => 'query'));
-        $sSelectClause = $sJoinClause = $sWhereClause = $sGroupClause = $sOrderClause = $sLimitClause = "";
+        $sSelectClause = "
+            `td`.`id` AS `id`,
+            `td`.`object` AS `object`,
+            `td`.`display_name` AS `name`,
+            `td`.`display_name` AS `display_name`,
+            `td`.`module` AS `module`,
+            `td`.`view_mode` AS `view_mode`,
+            `td`.`title` AS `title`";
+        $sJoinClause = $sWhereClause = $sGroupClause = $sOrderClause = $sLimitClause = "";
 
         if(!isset($aParams['order']) || empty($aParams['order']))
            $sOrderClause = "ORDER BY `td`.`title` ASC";
@@ -116,7 +158,7 @@ class BxDolStudioFormsQuery extends BxDolDb
             case 'by_id':
                 $aMethod['name'] = 'getRow';
                 $aMethod['params'][1] = array(
-                	'id' => $aParams['value']
+                    'id' => $aParams['value']
                 );
 
                 $sWhereClause = " AND `td`.`id`=:id ";
@@ -126,8 +168,8 @@ class BxDolStudioFormsQuery extends BxDolDb
             case 'by_object_display':
                 $aMethod['name'] = 'getRow';
                 $aMethod['params'][1] = array(
-                	'object' => $aParams['object'],
-                	'display_name' => $aParams['display']
+                    'object' => $aParams['object'],
+                    'display_name' => $aParams['display']
                 );
 
                 $sWhereClause = " AND `td`.`object`=:object AND `td`.`display_name`=:display_name ";
@@ -136,7 +178,7 @@ class BxDolStudioFormsQuery extends BxDolDb
 
             case 'by_name':
             	$aMethod['params'][1] = array(
-                	'display_name' => $aParams['value']
+                    'display_name' => $aParams['value']
                 );
 
                 $sWhereClause = " AND `td`.`display_name`=:display_name ";
@@ -145,7 +187,7 @@ class BxDolStudioFormsQuery extends BxDolDb
 
             case 'by_module':
             	$aMethod['params'][1] = array(
-                	'module' => $aParams['value']
+                    'module' => $aParams['value']
                 );
 
                 $sWhereClause = " AND `td`.`module`=:module ";
@@ -153,10 +195,10 @@ class BxDolStudioFormsQuery extends BxDolDb
 
             case 'by_module_with_forms':
             	$aMethod['params'][1] = array(
-                	'module' => $aParams['value']
+                    'module' => $aParams['value']
                 );
 
-                $sSelectClause = ", `tf`.`title` AS `form_title`";
+                $sSelectClause .= ", `tf`.`title` AS `form_title`";
                 $sJoinClause = "LEFT JOIN `sys_objects_form` AS `tf` ON `td`.`object`=`tf`.`object` ";
                 $sWhereClause = " AND `td`.`module`=:module ";
                 $sOrderClause = "ORDER BY `td`.`object` ASC, `td`.`title` ASC";
@@ -164,17 +206,26 @@ class BxDolStudioFormsQuery extends BxDolDb
 
             case 'by_object':
             	$aMethod['params'][1] = array(
-                	'object' => $aParams['value']
+                    'object' => $aParams['value']
                 );
 
                 $sWhereClause = " AND `td`.`object`=:object ";
                 break;
 
+            case 'export_by_object':
+                $aMethod['params'][1] = [
+                    'object' => $aParams['value']
+                ];
+
+                $sSelectClause = "`td`.*";
+                $sWhereClause = " AND `td`.`object`=:object ";
+                break;
+
             case 'counter_by_forms':
                 $aMethod['name'] = 'getPairs';
                 $aMethod['params'][1] = 'object';
                 $aMethod['params'][2] = 'counter';
-                $sSelectClause = ", COUNT(*) AS `counter`";
+                $sSelectClause .= ", COUNT(*) AS `counter`";
                 $sGroupClause = "GROUP BY `td`.`object`";
                 break;
 
@@ -182,7 +233,7 @@ class BxDolStudioFormsQuery extends BxDolDb
                 $aMethod['name'] = 'getPairs';
                 $aMethod['params'][1] = 'module';
                 $aMethod['params'][2] = 'counter';
-                $sSelectClause = ", COUNT(*) AS `counter`";
+                $sSelectClause .= ", COUNT(*) AS `counter`";
                 $sGroupClause = "GROUP BY `td`.`module`";
                 break;
 
@@ -190,20 +241,13 @@ class BxDolStudioFormsQuery extends BxDolDb
                 break;
 
             case 'all_with_forms':
-                $sSelectClause = ", `tf`.`title` AS `form_title`";
+                $sSelectClause .= ", `tf`.`title` AS `form_title`";
                 $sJoinClause = "LEFT JOIN `sys_objects_form` AS `tf` ON `td`.`object`=`tf`.`object` ";
                 $sOrderClause = "ORDER BY `td`.`object` ASC, `td`.`title` ASC";
                 break;
         }
 
-        $aMethod['params'][0] = "SELECT " . ($bReturnCount ? "SQL_CALC_FOUND_ROWS" : "") . "
-                `td`.`id` AS `id`,
-                `td`.`object` AS `object`,
-                `td`.`display_name` AS `name`,
-                `td`.`display_name` AS `display_name`,
-                `td`.`module` AS `module`,
-                `td`.`view_mode` AS `view_mode`,
-                `td`.`title` AS `title`" . $sSelectClause . "
+        $aMethod['params'][0] = "SELECT " . ($bReturnCount ? "SQL_CALC_FOUND_ROWS" : "") . $sSelectClause . "
             FROM `sys_form_displays` AS `td` " . $sJoinClause . "
             WHERE 1 " . $sWhereClause . " " . $sGroupClause . " " . $sOrderClause . " " . $sLimitClause;
         $aItems = call_user_func_array(array($this, $aMethod['name']), $aMethod['params']);
@@ -214,10 +258,25 @@ class BxDolStudioFormsQuery extends BxDolDb
         return (int)$this->getOne("SELECT FOUND_ROWS()");
     }
 
-    function isInput($sObject, $sName)
+    function isDisplay($sName, $sDisplay)
     {
-        $sSql = $this->prepare("SELECT `id` FROM `sys_form_inputs` WHERE `object`=? AND `name`=? LIMIT 1", $sObject, $sName);
-        return (int)$this->getOne($sSql) > 0;
+        $aDisplay = [];
+        $this->getDisplays(['type' => 'by_object_display', 'object' => $sName, 'display' => $sDisplay], $aDisplay, false);
+
+        return !empty($aDisplay) && is_array($aDisplay);
+    }
+
+    function addDisplay($aFields)
+    {
+        return $this->query("INSERT INTO `sys_form_displays` SET " . $this->arrayToSQL($aFields));
+    }
+
+    function updateDisplayByObjectAndName($sObject, $sName, $aFields)
+    {
+        return $this->query("UPDATE `sys_form_displays` SET " . $this->arrayToSQL($aFields) . " WHERE `object`=:object AND `display_name`=:display_name ", [
+            'object' => $sObject,
+            'display_name' => $sName
+        ]);
     }
 
     function getInputs($aParams, &$aItems, $bReturnCount = true)
@@ -290,7 +349,7 @@ class BxDolStudioFormsQuery extends BxDolDb
 
             case 'dump_inputs':
             	$aMethod['params'][1] = array(
-                	'object' => $aParams['value']
+                    'object' => $aParams['value']
                 );
 
                 $sSelectClause = "`ti`.*";
@@ -300,9 +359,16 @@ class BxDolStudioFormsQuery extends BxDolDb
                 $sOrderClause = "";
                 break;
 
+            case 'dump_display_inputs':
+                $sSelectClause = "`tdi`.*";
+                $sJoinClause = "";
+                $sWhereClause = " AND `tdi`.`display_name` IN (" . $this->implode_escape($aParams['displays']) . ") ";
+                $sOrderClause = "";
+                break;
+
             case 'dump_connections':
             	$aMethod['params'][1] = array(
-                	'object' => $aParams['value']
+                    'object' => $aParams['value']
                 );
 
                 $sSelectClause = "`tdi`.*";
@@ -346,6 +412,48 @@ class BxDolStudioFormsQuery extends BxDolDb
         return (int)$this->getOne("SELECT FOUND_ROWS()");
     }
 
+    function isInput($sObject, $sName)
+    {
+        return (int)$this->getOne("SELECT `id` FROM `sys_form_inputs` WHERE `object`=:object AND `name`=:name LIMIT 1", [
+            'object' => $sObject,
+            'name' => $sName
+        ]) > 0;
+    }
+
+    function isDisplayInput($sDisplay, $sInput)
+    {
+        return (int)$this->getOne("SELECT `id` FROM `sys_form_display_inputs` WHERE `display_name`=:display AND `input_name`=:input LIMIT 1", [
+            'display' => $sDisplay,
+            'input' => $sInput
+        ]) > 0;
+    }
+
+    function addInput($aFields)
+    {
+        return $this->query("INSERT INTO `sys_form_inputs` SET " . $this->arrayToSQL($aFields));
+    }
+    
+    function addDisplayInput($aFields)
+    {
+        return $this->query("INSERT INTO `sys_form_display_inputs` SET " . $this->arrayToSQL($aFields));
+    }
+
+    function updateInputByObjectAndName($sObject, $sName, $aFields)
+    {
+        return $this->query("UPDATE `sys_form_inputs` SET " . $this->arrayToSQL($aFields) . " WHERE `object`=:object AND `name`=:name ", [
+            'object' => $sObject,
+            'name' => $sName
+        ]);
+    }
+
+    function updateDisplayInputByDisplayAndInput($sDisplay, $sInput, $aFields)
+    {
+        return $this->query("UPDATE `sys_form_display_inputs` SET " . $this->arrayToSQL($aFields) . " WHERE `display_name`=:display_name AND `input_name`=:input_name ", [
+            'display_name' => $sDisplay,
+            'input_name' => $sInput
+        ]);
+    }
+
     function deleteInputs($aParams)
     {
     	$aBindings = array();

+ 137 - 63
studio/classes/BxDolStudioNavigationQuery.php

@@ -17,7 +17,18 @@ class BxDolStudioNavigationQuery extends BxDolDb
     function getMenus($aParams, &$aItems, $bReturnCount = true)
     {
         $aMethod = array('name' => 'getAll', 'params' => array(0 => 'query'));
-        $sSelectClause = $sJoinClause = $sWhereClause = $sGroupClause = $sOrderClause = $sLimitClause = "";
+        $sSelectClause = "
+            `tm`.`id` AS `id`,
+            `tm`.`object` AS `object`,
+            `tm`.`title` AS `title`,
+            `tm`.`set_name` AS `set_name`,
+            `tm`.`module` AS `module`,
+            `tm`.`template_id` AS `template_id`,
+            `tm`.`deletable` AS `deletable`,
+            `tm`.`active` AS `active`,
+            `tm`.`override_class_name` AS `override_class_name`,
+            `tm`.`override_class_file` AS `override_class_file`";
+        $sJoinClause = $sWhereClause = $sGroupClause = $sOrderClause = $sLimitClause = "";
 
         if(!isset($aParams['order']) || empty($aParams['order']))
            $sOrderClause = "ORDER BY `tm`.`id` ASC";
@@ -26,7 +37,7 @@ class BxDolStudioNavigationQuery extends BxDolDb
             case 'by_id':
                 $aMethod['name'] = 'getRow';
                 $aMethod['params'][1] = array(
-                	'id' => $aParams['value']
+                    'id' => $aParams['value']
                 );
 
                 $sWhereClause = " AND `tm`.`id`=:id ";
@@ -35,7 +46,7 @@ class BxDolStudioNavigationQuery extends BxDolDb
             case 'by_object':
                 $aMethod['name'] = 'getRow';
                 $aMethod['params'][1] = array(
-                	'object' => $aParams['value']
+                    'object' => $aParams['value']
                 );
 
                 $sWhereClause = " AND `tm`.`object`=:object ";
@@ -43,7 +54,7 @@ class BxDolStudioNavigationQuery extends BxDolDb
 
             case 'by_set_name':
             	$aMethod['params'][1] = array(
-                	'set_name' => $aParams['value']
+                    'set_name' => $aParams['value']
                 );
 
                 $sWhereClause = " AND `tm`.`set_name`=:set_name ";
@@ -53,25 +64,19 @@ class BxDolStudioNavigationQuery extends BxDolDb
                 $aMethod['name'] = 'getPairs';
                 $aMethod['params'][1] = 'module';
                 $aMethod['params'][2] = 'counter';
-                $sSelectClause = ", COUNT(*) AS `counter`";
+                $sSelectClause .= ", COUNT(*) AS `counter`";
                 $sGroupClause = "GROUP BY `tm`.`module`";
                 break;
+            
+            case 'export':
+                $sSelectClause = "`tm`.*";
+                break;
 
             case 'all':
                 break;
         }
 
-        $aMethod['params'][0] = "SELECT " . ($bReturnCount ? "SQL_CALC_FOUND_ROWS" : "") . "
-                `tm`.`id` AS `id`,
-                `tm`.`object` AS `object`,
-                `tm`.`title` AS `title`,
-                `tm`.`set_name` AS `set_name`,
-                `tm`.`module` AS `module`,
-                `tm`.`template_id` AS `template_id`,
-                `tm`.`deletable` AS `deletable`,
-                `tm`.`active` AS `active`,
-                `tm`.`override_class_name` AS `override_class_name`,
-                `tm`.`override_class_file` AS `override_class_file`" . $sSelectClause . "
+        $aMethod['params'][0] = "SELECT " . ($bReturnCount ? "SQL_CALC_FOUND_ROWS" : "") . $sSelectClause . "
             FROM `sys_objects_menu` AS `tm` " . $sJoinClause . "
             WHERE 1 " . $sWhereClause . " " . $sGroupClause . " " . $sOrderClause . " " . $sLimitClause;
         $aItems = call_user_func_array(array($this, $aMethod['name']), $aMethod['params']);
@@ -81,17 +86,37 @@ class BxDolStudioNavigationQuery extends BxDolDb
 
         return (int)$this->getOne("SELECT FOUND_ROWS()");
     }
+    
+    function isMenuExists($sObject)
+    {
+        $aMenu = [];
+        $this->getMenus(['type' => 'by_object', 'value' => $sObject], $aMenu, false);
 
-    function isSetExists($sName)
+        return !empty($aMenu) && is_array($aMenu);
+    }
+
+    function addMenu($aFields)
+    {
+        return $this->query("INSERT INTO `sys_objects_menu` SET " . $this->arrayToSQL($aFields));
+    }
+
+    function updateMenuByObject($sObject, $aFields)
     {
-        $sSql = $this->prepare("SELECT COUNT(*) FROM `sys_menu_sets` WHERE `set_name`=? LIMIT 1", $sName);
-        return (int)$this->getOne($sSql) == 1;
+        return $this->query("UPDATE `sys_objects_menu` SET " . $this->arrayToSQL($aFields) . " WHERE `object`=:object", [
+            'object' => $sObject
+        ]);
     }
 
     function getSets($aParams, &$aItems, $bReturnCount = true)
     {
         $aMethod = array('name' => 'getAll', 'params' => array(0 => 'query'));
-        $sSelectClause = $sJoinClause = $sWhereClause = $sGroupClause = $sOrderClause = $sLimitClause = "";
+        $sSelectClause = "
+            `tms`.`set_name` AS `name`,
+            `tms`.`set_name` AS `set_name`,
+            `tms`.`module` AS `module`,
+            `tms`.`title` AS `title`,
+            `tms`.`deletable` AS `deletable`";
+        $sJoinClause = $sWhereClause = $sGroupClause = $sOrderClause = $sLimitClause = "";
 
         if(!isset($aParams['order']) || empty($aParams['order']))
            $sOrderClause = "ORDER BY `tms`.`title` ASC";
@@ -103,7 +128,7 @@ class BxDolStudioNavigationQuery extends BxDolDb
                 	'set_name' => $aParams['value']
                 );
 
-                $sSelectClause = ", COUNT(`tmi`.`id`) AS `items_count`";
+                $sSelectClause .= ", COUNT(`tmi`.`id`) AS `items_count`";
                 $sJoinClause = "LEFT JOIN `sys_menu_items` AS `tmi` ON `tms`.`set_name`=`tmi`.`set_name` AND `tmi`.`active`='1'";
                 $sWhereClause = " AND `tms`.`set_name`=:set_name ";
                 $sGroupClause = "GROUP BY `tms`.`set_name`";
@@ -121,36 +146,41 @@ class BxDolStudioNavigationQuery extends BxDolDb
                 $aMethod['name'] = 'getPairs';
                 $aMethod['params'][1] = 'module';
                 $aMethod['params'][2] = 'counter';
-                $sSelectClause = ", COUNT(*) AS `counter`";
+                $sSelectClause .= ", COUNT(*) AS `counter`";
                 $sGroupClause = "GROUP BY `tms`.`module`";
                 break;
 
             case 'dump_by_name':
                 $aMethod['name'] = 'getRow';
                 $aMethod['params'][1] = array(
-                	'set_name' => $aParams['value']
+                    'set_name' => $aParams['value']
                 );
 
                 $sWhereClause = " AND `tms`.`set_name`=:set_name ";
                 break;
 
+            case 'export_by_name':
+                $aMethod['name'] = 'getRow';
+                $aMethod['params'][1] = [
+                    'set_name' => $aParams['value']
+                ];
+
+                $sSelectClause = "`tms`.*";
+                $sWhereClause = " AND `tms`.`set_name`=:set_name ";
+                break;
+            
             case 'all':
                 if(isset($aParams['except'])) {
-                	$aMethod['params'][1] = array(
-	                	'set_name' => $aParams['except']
-	                );
+                    $aMethod['params'][1] = array(
+                        'set_name' => $aParams['except']
+                    );
 
                     $sWhereClause = " AND `tms`.`set_name`<>:set_name ";
                 }
                 break;
         }
 
-        $aMethod['params'][0] = "SELECT " . ($bReturnCount ? "SQL_CALC_FOUND_ROWS" : "") . "
-                `tms`.`set_name` AS `name`,
-                `tms`.`set_name` AS `set_name`,
-                `tms`.`module` AS `module`,
-                `tms`.`title` AS `title`,
-                `tms`.`deletable` AS `deletable`" . $sSelectClause . "
+        $aMethod['params'][0] = "SELECT " . ($bReturnCount ? "SQL_CALC_FOUND_ROWS" : "") . $sSelectClause . "
             FROM `sys_menu_sets` AS `tms` " . $sJoinClause . "
             WHERE 1 " . $sWhereClause . " " . $sGroupClause . " " . $sOrderClause . " " . $sLimitClause;
         $aItems = call_user_func_array(array($this, $aMethod['name']), $aMethod['params']);
@@ -161,6 +191,14 @@ class BxDolStudioNavigationQuery extends BxDolDb
         return (int)$this->getOne("SELECT FOUND_ROWS()");
     }
 
+    function isSetExists($sName)
+    {
+        $aSet = [];
+        $this->getSets(['type' => 'by_name', 'value' => $sName], $aSet, false);
+
+        return !empty($aSet) && is_array($aSet);
+    }
+
     function addSet($aFields)
     {
         $sSql = "INSERT INTO `sys_menu_sets` SET `" . implode("`=?, `", array_keys($aFields)) . "`=?";
@@ -214,7 +252,35 @@ class BxDolStudioNavigationQuery extends BxDolDb
     function getItems($aParams, &$aItems, $bReturnCount = true)
     {
         $aMethod = array('name' => 'getAll', 'params' => array(0 => 'query'));
-        $sSelectClause = $sJoinClause = $sWhereClause = $sGroupClause = $sOrderClause = $sLimitClause = "";
+        $sSelectClause = "
+            `tmi`.`id` AS `id`,
+            `tmi`.`parent_id` AS `parent_id`,
+            `tmi`.`set_name` AS `set_name`,
+            `tmi`.`module` AS `module`,
+            `tmi`.`name` AS `name`,
+            `tmi`.`title_system` AS `title_system`,
+            `tmi`.`title` AS `title`,
+            `tmi`.`link` AS `link`,
+            `tmi`.`onclick` AS `onclick`,
+            `tmi`.`target` AS `target`,
+            `tmi`.`icon` AS `icon`,
+            `tmi`.`addon` AS `addon`,
+            `tmi`.`submenu_object` AS `submenu_object`,
+            `tmi`.`submenu_popup` AS `submenu_popup`,
+            `tmi`.`visible_for_levels` AS `visible_for_levels`,
+            `tmi`.`visibility_custom` AS `visibility_custom`,
+            `tmi`.`primary` AS `primary`,
+            `tmi`.`collapsed` AS `collapsed`,
+            `tmi`.`active` AS `active`,
+            `tmi`.`active_api` AS `active_api`,
+            `tmi`.`copyable` AS `copyable`,
+            `tmi`.`editable` AS `editable`,
+            `tmi`.`hidden_on` AS `hidden_on`,
+            `tmi`.`hidden_on_cxt` AS `hidden_on_cxt`,
+            `tmi`.`hidden_on_pt` AS `hidden_on_pt`,
+            `tmi`.`hidden_on_col` AS `hidden_on_col`,
+            `tmi`.`order` AS `order`";
+        $sJoinClause = $sWhereClause = $sGroupClause = $sOrderClause = $sLimitClause = "";
 
         if(!isset($aParams['order']) || empty($aParams['order']))
            $sOrderClause = "ORDER BY `tmi`.`order` ASC";
@@ -229,6 +295,16 @@ class BxDolStudioNavigationQuery extends BxDolDb
                 $sWhereClause = " AND `tmi`.`id`=:id ";
                 break;
 
+            case 'by_set_and_name':
+                $aMethod['name'] = 'getRow';
+                $aMethod['params'][1] = array(
+                    'set_name' => $aParams['set_name'],
+                    'name' => $aParams['name'],
+                );
+
+                $sWhereClause = " AND `tmi`.`set_name`=:set_name AND `tmi`.`name`=:name ";
+                break;
+
             case 'by_parent_id':
                 $aMethod['params'][1] = array(
                     'parent_id' => $aParams['value']
@@ -245,11 +321,20 @@ class BxDolStudioNavigationQuery extends BxDolDb
                 $sWhereClause = " AND `tmi`.`set_name`=:set_name ";
                 break;
 
+            case 'export_by_set_name':
+                $aMethod['params'][1] = [
+                    'set_name' => $aParams['value']
+                ];
+
+                $sSelectClause = "`tmi`.*";
+                $sWhereClause = " AND `tmi`.`set_name`=:set_name ";
+                break;
+
             case 'counter_by_sets':
                 $aMethod['name'] = 'getPairs';
                 $aMethod['params'][1] = 'set_name';
                 $aMethod['params'][2] = 'counter';
-                $sSelectClause = ", COUNT(*) AS `counter`";
+                $sSelectClause .= ", COUNT(*) AS `counter`";
                 $sGroupClause = "GROUP BY `tmi`.`set_name`";
                 break;
 
@@ -257,7 +342,7 @@ class BxDolStudioNavigationQuery extends BxDolDb
                 $aMethod['name'] = 'getPairs';
                 $aMethod['params'][1] = 'module';
                 $aMethod['params'][2] = 'counter';
-                $sSelectClause = ", COUNT(*) AS `counter`";
+                $sSelectClause .= ", COUNT(*) AS `counter`";
                 $sGroupClause = "GROUP BY `tmi`.`module`";
                 break;
 
@@ -265,34 +350,7 @@ class BxDolStudioNavigationQuery extends BxDolDb
                 break;
         }
 
-        $aMethod['params'][0] = "SELECT " . ($bReturnCount ? "SQL_CALC_FOUND_ROWS" : "") . "
-                `tmi`.`id` AS `id`,
-                `tmi`.`parent_id` AS `parent_id`,
-                `tmi`.`set_name` AS `set_name`,
-                `tmi`.`module` AS `module`,
-                `tmi`.`name` AS `name`,
-                `tmi`.`title_system` AS `title_system`,
-                `tmi`.`title` AS `title`,
-                `tmi`.`link` AS `link`,
-                `tmi`.`onclick` AS `onclick`,
-                `tmi`.`target` AS `target`,
-                `tmi`.`icon` AS `icon`,
-                `tmi`.`addon` AS `addon`,
-                `tmi`.`submenu_object` AS `submenu_object`,
-                `tmi`.`submenu_popup` AS `submenu_popup`,
-                `tmi`.`visible_for_levels` AS `visible_for_levels`,
-                `tmi`.`visibility_custom` AS `visibility_custom`,
-                `tmi`.`primary` AS `primary`,
-                `tmi`.`collapsed` AS `collapsed`,
-                `tmi`.`active` AS `active`,
-                `tmi`.`active_api` AS `active_api`,
-                `tmi`.`copyable` AS `copyable`,
-                `tmi`.`editable` AS `editable`,
-                `tmi`.`hidden_on` AS `hidden_on`,
-                `tmi`.`hidden_on_cxt` AS `hidden_on_cxt`,
-                `tmi`.`hidden_on_pt` AS `hidden_on_pt`,
-                `tmi`.`hidden_on_col` AS `hidden_on_col`,
-                `tmi`.`order` AS `order`" . $sSelectClause . "
+        $aMethod['params'][0] = "SELECT " . ($bReturnCount ? "SQL_CALC_FOUND_ROWS" : "") . $sSelectClause . "
             FROM `sys_menu_items` AS `tmi` " . $sJoinClause . "
             WHERE 1 " . $sWhereClause . " " . $sGroupClause . " " . $sOrderClause . " " . $sLimitClause;
         $aItems = call_user_func_array(array($this, $aMethod['name']), $aMethod['params']);
@@ -303,6 +361,14 @@ class BxDolStudioNavigationQuery extends BxDolDb
         return (int)$this->getOne("SELECT FOUND_ROWS()");
     }
 
+    function isItemExists($sSetName, $sName)
+    {
+        $aItem = [];
+        $this->getItems(['type' => 'by_set_and_name', 'set_name' => $sSetName, 'name' => $sName], $aItem, false);
+
+        return !empty($aItem) && is_array($aItem);
+    }
+
     function deleteItemsBy($aParams)
     {
         $sWhereClause = $sLimitClause = "";
@@ -345,6 +411,14 @@ class BxDolStudioNavigationQuery extends BxDolDb
         return $this->query($sSql, ['id' => $iId]);
     }
 
+    function updateItemBySetAndName($sSetName, $sName, $aFields)
+    {
+        return $this->query("UPDATE `sys_menu_items` SET " . $this->arrayToSQL($aFields) . " WHERE `set_name`=:set_name AND `name`=:name", [
+            'set_name' => $sSetName,
+            'name' => $sName
+        ]);
+    }
+
     function getItemOrderMax($sSetName)
     {
         $sSql = $this->prepare("SELECT MAX(`order`) FROM `sys_menu_items` WHERE `set_name`=? LIMIT 1", $sSetName);

+ 5 - 0
studio/classes/BxDolStudioPage.php

@@ -76,6 +76,11 @@ class BxDolStudioPage extends BxDol
         }
     }
 
+    public function getDb()
+    {
+        return $this->oDb;
+    }
+
     public function getPageUrl()
     {
         if(empty($this->sPageUrl) && !empty($this->aPage['wid_url']))