|
|
@@ -41,7 +41,8 @@ class BxDevModule extends BxDolModule
|
|
|
return $this->aTools;
|
|
|
}
|
|
|
|
|
|
- public function actionResetHash($sType, $sModule = '') {
|
|
|
+ public function actionResetHash($sType, $sModule = '')
|
|
|
+ {
|
|
|
$oDb = bx_instance('BxDolStudioInstallerQuery');
|
|
|
|
|
|
$sResult = '';
|
|
|
@@ -104,5 +105,384 @@ class BxDevModule extends BxDolModule
|
|
|
echo $sResult;
|
|
|
exit;
|
|
|
}
|
|
|
+
|
|
|
+ public function actionExport()
|
|
|
+ {
|
|
|
+ $sType = bx_process_input(bx_get('type'));
|
|
|
+ if(empty($sType))
|
|
|
+ return echoJson([]);
|
|
|
+
|
|
|
+ echoJson([
|
|
|
+ 'url' => BX_DOL_URL_ROOT . bx_append_url_params($this->_oConfig->getBaseUri() . 'download', [
|
|
|
+ 'type' => $sType,
|
|
|
+ ]),
|
|
|
+ 'eval' => $this->_oConfig->getJsObject('main') . '.onExport(oData);'
|
|
|
+ ]);
|
|
|
+ }
|
|
|
+
|
|
|
+ public function actionDownload()
|
|
|
+ {
|
|
|
+ $sType = bx_process_input(bx_get('type'));
|
|
|
+ if(empty($sType))
|
|
|
+ return;
|
|
|
+
|
|
|
+ $sMethod = '_eiExport' . bx_gen_method_name($sType);
|
|
|
+ if(!method_exists($this, $sMethod))
|
|
|
+ return;
|
|
|
+
|
|
|
+ $mixedFull = ($mixedFull = bx_get('full')) !== false ? (int)$mixedFull != 0 : false;
|
|
|
+
|
|
|
+ list($aMeta, $aData) = $this->$sMethod($mixedFull);
|
|
|
+
|
|
|
+ $iNow = time();
|
|
|
+ $sContent = json_encode([
|
|
|
+ 'meta' => array_merge([
|
|
|
+ 'version' => bx_get_ver(),
|
|
|
+ 'date' => date('D, d M Y H:i:s', $iNow),
|
|
|
+ 'full' => $mixedFull
|
|
|
+ ], $aMeta),
|
|
|
+ 'data' => $aData
|
|
|
+ ]);
|
|
|
+
|
|
|
+ header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
|
|
|
+ header("Content-type: application/json");
|
|
|
+ header("Content-Length: " . strlen($sContent));
|
|
|
+ header("Content-Disposition: attachment; filename=\"" . $sType . ($mixedFull ? "_f" : "") . "_". date('d_m_Y', $iNow) . ".json\"");
|
|
|
+
|
|
|
+ echo $sContent;
|
|
|
+ exit;
|
|
|
+ }
|
|
|
+
|
|
|
+ public function actionImport()
|
|
|
+ {
|
|
|
+ $sType = bx_process_input(bx_get('type'));
|
|
|
+ if(empty($sType))
|
|
|
+ return echoJson([]);
|
|
|
+
|
|
|
+ $aResult = $this->getPopupCodeImport([
|
|
|
+ 'form_name' => 'bx-dev-' . $sType . '-import-full',
|
|
|
+ 'form_action' => BX_DOL_URL_ROOT . $this->_oConfig->getBaseUri() . 'import?type=' . $sType
|
|
|
+ ]);
|
|
|
+
|
|
|
+ if(!isset($aResult['code']) || (int)$aResult['code'] != 0)
|
|
|
+ return echoJson($aResult);
|
|
|
+
|
|
|
+ $sMethod = '_eiImport' . bx_gen_method_name($sType);
|
|
|
+ if(!method_exists($this, $sMethod))
|
|
|
+ return echoJson([]);
|
|
|
+
|
|
|
+ echoJson($this->$sMethod($aResult['content']));
|
|
|
+ }
|
|
|
+
|
|
|
+ public function getPopupCodeImport($aParams)
|
|
|
+ {
|
|
|
+ $sJsObject = $this->_oConfig->getJsObject('main');
|
|
|
+
|
|
|
+ $sForm = $aParams['form_name'];
|
|
|
+ $aForm = [
|
|
|
+ 'form_attrs' => [
|
|
|
+ 'id' => $sForm,
|
|
|
+ 'name' => $sForm,
|
|
|
+ 'action' => $aParams['form_action'],
|
|
|
+ 'method' => 'post',
|
|
|
+ 'enctype' => 'multipart/form-data'
|
|
|
+ ],
|
|
|
+ 'params' => [
|
|
|
+ 'db' => [
|
|
|
+ 'submit_name' => 'save'
|
|
|
+ ],
|
|
|
+ ],
|
|
|
+ 'inputs' => [
|
|
|
+ 'file' => [
|
|
|
+ 'type' => 'file',
|
|
|
+ 'name' => 'file',
|
|
|
+ 'caption' => '',
|
|
|
+ 'value' => '',
|
|
|
+ ],
|
|
|
+ 'controls' => [
|
|
|
+ 'type' => 'input_set', [
|
|
|
+ 'type' => 'submit',
|
|
|
+ 'name' => 'save',
|
|
|
+ 'value' => _t('_bx_dev_btn_import_full'),
|
|
|
+ ], [
|
|
|
+ 'type' => 'button',
|
|
|
+ 'name' => 'cancel',
|
|
|
+ 'value' => _t('_bx_dev_btn_cancel'),
|
|
|
+ 'attrs' => [
|
|
|
+ 'class' => 'bx-def-margin-sec-left-auto',
|
|
|
+ 'onclick' => '$(".bx-popup-applied:visible").dolPopupHide()'
|
|
|
+ ]
|
|
|
+ ]
|
|
|
+ ]
|
|
|
+ ]
|
|
|
+ ];
|
|
|
+
|
|
|
+ $oForm = new BxTemplStudioFormView($aForm);
|
|
|
+ $oForm->initChecker();
|
|
|
+
|
|
|
+ if($oForm->isSubmittedAndValid()) {
|
|
|
+ $sError = _t('_bx_dev_err_cannot_perform');
|
|
|
+
|
|
|
+ if(empty($_FILES['file']) || empty($_FILES['file']['tmp_name']))
|
|
|
+ return ['code' => 1, 'msg' => $sError];
|
|
|
+
|
|
|
+ $aFile = $_FILES['file'];
|
|
|
+ $sFile = $aFile['tmp_name'];
|
|
|
+ $rHandle = @fopen($sFile, "r");
|
|
|
+ if(!$rHandle)
|
|
|
+ return ['code' => 2, 'message' => $sError];
|
|
|
+
|
|
|
+ $sContents = fread($rHandle, filesize($sFile));
|
|
|
+ fclose($rHandle);
|
|
|
+
|
|
|
+ $aContent = json_decode($sContents, true);
|
|
|
+ if(!is_array($aContent) || empty($aContent['meta']) || empty($aContent['data']))
|
|
|
+ return ['code' => 3, 'message' => $sError];
|
|
|
+
|
|
|
+ return ['code' => 0, 'content' => $aContent];
|
|
|
+ }
|
|
|
+
|
|
|
+ return [
|
|
|
+ 'popup' => BxTemplStudioFunctions::getInstance()->popupBox('bx-dev-import-popup', _t('_bx_dev_txt_import_full_popup'), $this->_oTemplate->parseHtmlByName('import_popup.html', [
|
|
|
+ 'js_object' => $sJsObject,
|
|
|
+ 'form_id' => $sForm,
|
|
|
+ 'form' => $oForm->getCode(true),
|
|
|
+ ]))
|
|
|
+ ];
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ *
|
|
|
+ * Methods for Export/Import feature.
|
|
|
+ *
|
|
|
+ */
|
|
|
+ protected function _eiExportForms($bModeFull = false)
|
|
|
+ {
|
|
|
+ $oGrid = BxDolGrid::getObjectInstance($this->_oConfig->getObject('grid_forms'));
|
|
|
+ if(!$oGrid)
|
|
|
+ return [];
|
|
|
+
|
|
|
+ $aForms = [];
|
|
|
+ $oGrid->oDb->getForms(['type' => 'export'], $aForms, false);
|
|
|
+ if(empty($aForms) || !is_array($aForms))
|
|
|
+ return [];
|
|
|
+
|
|
|
+ $aMeta = [
|
|
|
+ 'masks' => [
|
|
|
+ 'form' => ['object', 'active'],
|
|
|
+ 'display' => ['display_name'],
|
|
|
+ 'input' => ['object', 'name', 'privacy', 'checker_func', 'checker_params', 'checker_error', 'db_pass', 'db_params'],
|
|
|
+ 'display_input' => ['display_name', 'input_name', 'visible_for_levels', 'active', 'order']
|
|
|
+ ]
|
|
|
+ ];
|
|
|
+
|
|
|
+ if($bModeFull) {
|
|
|
+ $aMeta['masks'] = [
|
|
|
+ 'form' => ['object', 'module', 'title', 'action', 'form_attrs', 'submit_name', 'table', 'key', 'uri', 'uri_title', 'params', 'deletable', 'active', 'override_class_name', 'override_class_file'],
|
|
|
+ 'display' => ['display_name', 'module', 'object', 'title', 'view_mode'],
|
|
|
+ 'input' => ['object', 'module', 'name', 'value', 'values', 'checked', 'type', 'caption_system', 'caption', 'info', 'help', 'icon', 'required', 'unique', 'collapsed', 'html', 'privacy', 'rateable', 'attrs', 'attrs_tr', 'attrs_wrapper', 'checker_func', 'checker_params', 'checker_error', 'db_pass', 'db_params', 'editable', 'deletable'],
|
|
|
+ 'display_input' => ['display_name', 'input_name', 'visible_for_levels', 'active', 'order']
|
|
|
+ ];
|
|
|
+ }
|
|
|
+
|
|
|
+ $aMfForm = $aMfDisplay = $aMfInput = $aMfDisplayInput = false;
|
|
|
+ foreach($aMeta['masks'] as $sMask => $aMask)
|
|
|
+ ${'aMf' . bx_gen_method_name($sMask)} = array_flip($aMask);
|
|
|
+
|
|
|
+ $aData = [];
|
|
|
+ foreach($aForms as $aForm) {
|
|
|
+ $sObject = $aForm['object'];
|
|
|
+
|
|
|
+ $aDisplays = [];
|
|
|
+ $oGrid->oDb->getDisplays(['type' => 'export_by_object', 'value' => $sObject], $aDisplays, false);
|
|
|
+
|
|
|
+ $aListDisplays = [];
|
|
|
+ $aDataDisplays = [];
|
|
|
+ if(!empty($aDisplays) && is_array($aDisplays))
|
|
|
+ foreach($aDisplays as $aDisplay) {
|
|
|
+ $aListDisplays[] = $aDisplay['display_name'];
|
|
|
+ $aDataDisplays[] = $aMfDisplay !== false ? array_intersect_key($aDisplay, $aMfDisplay) : $aDisplay;
|
|
|
+ }
|
|
|
+
|
|
|
+ $aInputs = [];
|
|
|
+ $oGrid->oDb->getInputs(['type' => 'dump_inputs', 'value' => $sObject], $aInputs, false);
|
|
|
+
|
|
|
+ $aDataInputs = [];
|
|
|
+ if(!empty($aInputs) && is_array($aInputs))
|
|
|
+ foreach($aInputs as $aInput)
|
|
|
+ $aDataInputs[] = $aMfInput !== false ? array_intersect_key($aInput, $aMfInput) : $aInput;
|
|
|
+
|
|
|
+ $aDisplayInputs = [];
|
|
|
+ $oGrid->oDb->getInputs(['type' => 'dump_display_inputs', 'displays' => $aListDisplays], $aDisplayInputs, false);
|
|
|
+
|
|
|
+ $aDataDisplayInputs = [];
|
|
|
+ if(!empty($aDisplayInputs) && is_array($aDisplayInputs))
|
|
|
+ foreach($aDisplayInputs as $aDisplayInput)
|
|
|
+ $aDataDisplayInputs[] = $aMfDisplayInput !== false ? array_intersect_key($aDisplayInput, $aMfDisplayInput) : $aDisplayInput;
|
|
|
+
|
|
|
+ $aData[] = [
|
|
|
+ 'form' => $aMfForm !== false ? array_intersect_key($aForm, $aMfForm) : $aForm,
|
|
|
+ 'displays' => $aDataDisplays,
|
|
|
+ 'inputs' => $aDataInputs,
|
|
|
+ 'display_inputs' => $aDataDisplayInputs
|
|
|
+ ];
|
|
|
+ }
|
|
|
+
|
|
|
+ return [$aMeta, $aData];
|
|
|
+ }
|
|
|
+
|
|
|
+ protected function _eiExportMenus($bModeFull = false)
|
|
|
+ {
|
|
|
+ $oGrid = BxDolGrid::getObjectInstance($this->_oConfig->getObject('grid_nav_menus'));
|
|
|
+ if(!$oGrid)
|
|
|
+ return [];
|
|
|
+
|
|
|
+ $aMenus = [];
|
|
|
+ $oGrid->oDb->getMenus(['type' => 'export'], $aMenus, false);
|
|
|
+ if(empty($aMenus) || !is_array($aMenus))
|
|
|
+ return [];
|
|
|
+
|
|
|
+ $aMeta = [
|
|
|
+ 'masks' => [
|
|
|
+ 'menu' => ['object', 'active'],
|
|
|
+ 'set' => ['set_name'],
|
|
|
+ 'item' => ['set_name', 'name', 'visible_for_levels', 'visibility_custom', 'hidden_on', 'hidden_on_cxt', 'hidden_on_pt', 'hidden_on_col', 'active', 'active_api', 'order']
|
|
|
+ ]
|
|
|
+ ];
|
|
|
+
|
|
|
+ if($bModeFull) {
|
|
|
+ $aMeta['masks'] = [
|
|
|
+ 'menu' => ['object', 'title', 'set_name', 'module', 'template_id', 'deletable', 'active', 'override_class_name', 'override_class_file'],
|
|
|
+ 'set' => ['set_name', 'module', 'title', 'deletable'],
|
|
|
+ 'item' => ['parent_id', 'set_name', 'module', 'name', 'title_system', 'title', 'link', 'onclick', 'target', 'icon', 'addon', 'addon_cache', 'markers', 'submenu_object', 'submenu_popup', 'visible_for_levels', 'visibility_custom', 'hidden_on', 'hidden_on_cxt', 'hidden_on_pt', 'hidden_on_col', 'primary', 'collapsed', 'active', 'active_api', 'copyable', 'editable', 'order']
|
|
|
+ ];
|
|
|
+ }
|
|
|
+
|
|
|
+ $aMfMenu = $aMfSet = $aMfItem = false;
|
|
|
+ foreach($aMeta['masks'] as $sMask => $aMask)
|
|
|
+ ${'aMf' . bx_gen_method_name($sMask)} = array_flip($aMask);
|
|
|
+
|
|
|
+ $aData = [];
|
|
|
+ foreach($aMenus as $aMenu) {
|
|
|
+ $aSet = [];
|
|
|
+ $oGrid->oDb->getSets(['type' => 'export_by_name', 'value' => $aMenu['set_name']], $aSet, false);
|
|
|
+
|
|
|
+ $aDataItems = [];
|
|
|
+ if(!empty($aSet) && is_array($aSet)) {
|
|
|
+ $aItems = [];
|
|
|
+ $oGrid->oDb->getItems(['type' => 'export_by_set_name', 'value' => $aSet['set_name']], $aItems, false);
|
|
|
+
|
|
|
+ if(!empty($aItems) && is_array($aItems))
|
|
|
+ foreach($aItems as $aItem)
|
|
|
+ $aDataItems[] = $aMfItem !== false ? array_intersect_key($aItem, $aMfItem) : $aItem;
|
|
|
+ }
|
|
|
+
|
|
|
+ $aData[] = [
|
|
|
+ 'menu' => $aMfMenu !== false ? array_intersect_key($aMenu, $aMfMenu) : $aMenu,
|
|
|
+ 'set' => !empty($aSet) && $aMfSet !== false ? array_intersect_key($aSet, $aMfSet) : $aSet,
|
|
|
+ 'items' => $aDataItems,
|
|
|
+ ];
|
|
|
+ }
|
|
|
+
|
|
|
+ return [$aMeta, $aData];
|
|
|
+ }
|
|
|
+
|
|
|
+ protected function _eiExportPages($bModeFull = false)
|
|
|
+ {
|
|
|
+ bx_import('BuilderPage', $this->_aModule);
|
|
|
+ $oBuilderPage = new BxDevBuilderPage(['type' => '', 'page' => '', 'url' => '']);
|
|
|
+ if(!$oBuilderPage)
|
|
|
+ return [];
|
|
|
+
|
|
|
+ $oBpDb = $oBuilderPage->getDb();
|
|
|
+
|
|
|
+ $aPages = $oBpDb->getPages(['type' => 'export']);
|
|
|
+ if(empty($aPages) || !is_array($aPages))
|
|
|
+ return [];
|
|
|
+
|
|
|
+ $aMeta = [
|
|
|
+ 'masks' => [
|
|
|
+ 'page' => ['object', 'visible_for_levels'],
|
|
|
+ 'block' => ['object', 'cell_id', 'module', 'title_system', 'title', 'visible_for_levels', 'hidden_on', 'active', 'active_api', 'order']
|
|
|
+ ]
|
|
|
+ ];
|
|
|
+
|
|
|
+ if($bModeFull) {
|
|
|
+ $aMeta['masks'] = [
|
|
|
+ 'page' => ['author', 'added', 'object', 'uri', 'title_system', 'title', 'module', 'cover', 'cover_image', 'cover_title', 'type_id', 'layout_id', 'sticky_columns', 'submenu', 'visible_for_levels', 'visible_for_levels_editable', 'url', 'content_info', 'meta_description', 'meta_keywords', 'meta_robots', 'cache_lifetime', 'cache_editable', 'inj_head', 'inj_footer', 'deletable', 'override_class_name', 'override_class_file'],
|
|
|
+ 'block' => ['object', 'cell_id', 'module', 'title_system', 'title', 'designbox_id', 'class', 'submenu', 'tabs', 'async', 'visible_for_levels', 'hidden_on', 'type', 'content', 'content_empty', 'text', 'text_updated', 'help', 'cache_lifetime', 'deletable', 'copyable', 'active', 'active_api', 'order']
|
|
|
+ ];
|
|
|
+ }
|
|
|
+
|
|
|
+ $aMfPage = $aMfBlock = false;
|
|
|
+ foreach($aMeta['masks'] as $sMask => $aMask)
|
|
|
+ ${'aMf' . bx_gen_method_name($sMask)} = array_flip($aMask);
|
|
|
+
|
|
|
+ $aData = [];
|
|
|
+ foreach($aPages as $aPage) {
|
|
|
+ $aBlocks = [];
|
|
|
+ $oBpDb->getBlocks(['type' => 'export_by_object', 'value' => $aPage['object']], $aBlocks, false);
|
|
|
+
|
|
|
+ $aDataBlocks = [];
|
|
|
+ if(!empty($aBlocks) && is_array($aBlocks))
|
|
|
+ foreach($aBlocks as $aBlock)
|
|
|
+ $aDataBlocks[] = $aMfBlock !== false ? array_intersect_key($aBlock, $aMfBlock) : $aBlock;
|
|
|
+
|
|
|
+ $aData[] = [
|
|
|
+ 'page' => $aMfPage !== false ? array_intersect_key($aPage, $aMfPage) : $aPage,
|
|
|
+ 'blocks' => $aDataBlocks,
|
|
|
+ ];
|
|
|
+ }
|
|
|
+
|
|
|
+ return [$aMeta, $aData];
|
|
|
+ }
|
|
|
+
|
|
|
+ protected function _eiImportPages($aContent)
|
|
|
+ {
|
|
|
+ bx_import('BuilderPage', $this->_aModule);
|
|
|
+ $oBuilderPage = new BxDevBuilderPage(['type' => '', 'page' => '', 'url' => '']);
|
|
|
+ if(!$oBuilderPage)
|
|
|
+ return [];
|
|
|
+
|
|
|
+ $oBpDb = $oBuilderPage->getDb();
|
|
|
+
|
|
|
+ $bModeFull = isset($aContent['meta']['full']) && (bool)$aContent['meta']['full'] === true;
|
|
|
+
|
|
|
+ $aMfMenu = $aMfSet = $aMfItem = false;
|
|
|
+ foreach($aContent['meta']['masks'] as $sMask => $aMask)
|
|
|
+ ${'aMf' . bx_gen_method_name($sMask)} = array_flip($aMask);
|
|
|
+
|
|
|
+ $iData = 0;
|
|
|
+ foreach($aContent['data'] as $aData) {
|
|
|
+ $iData += 1;
|
|
|
+
|
|
|
+ $sObject = $aData['page']['object'];
|
|
|
+ if($bModeFull && !$oBpDb->isPageExists($sObject))
|
|
|
+ $oBpDb->addPage($aData['page']);
|
|
|
+ else
|
|
|
+ $oBpDb->updatePageByObject($sObject, $aData['page']);
|
|
|
+
|
|
|
+ foreach($aData['blocks'] as $aBlock) {
|
|
|
+ $aFields = [
|
|
|
+ 'object' => $aBlock['object'],
|
|
|
+ 'module' => $aBlock['module'],
|
|
|
+ 'title_system' => $aBlock['title_system'],
|
|
|
+ 'title' => $aBlock['title']
|
|
|
+ ];
|
|
|
+
|
|
|
+ if($bModeFull && !$oBpDb->isBlockExists($aFields))
|
|
|
+ $oBpDb->addBlock($aItem);
|
|
|
+ else
|
|
|
+ $oBpDb->updateBlockByFields($aFields, $aBlock);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ BxDolCacheUtilities::getInstance()->clear('db');
|
|
|
+
|
|
|
+ return [
|
|
|
+ 'msg' => _t('_bx_dev_msg_imported', $iData),
|
|
|
+ 'eval' => $this->_oConfig->getJsObject('main') . '.onImport(oData);'
|
|
|
+ ];
|
|
|
+ }
|
|
|
}
|
|
|
/** @} */
|