AntonLV 12 anni fa
parent
commit
99c17fa645

+ 1 - 1
modules/boonex/developer/install/config.php

@@ -17,7 +17,7 @@ $aConfig = array(
     'name' => 'bx_developer',
     'name' => 'bx_developer',
     'title' => 'Developer',
     'title' => 'Developer',
     'note' => 'Developer tools...',
     'note' => 'Developer tools...',
-    'version' => '8.0.2.DEV',
+    'version' => '8.0.3.DEV',
     'vendor' => 'BoonEx',
     'vendor' => 'BoonEx',
 	'help_url' => 'http://feed.boonex.com/?section={module_name}',
 	'help_url' => 'http://feed.boonex.com/?section={module_name}',
 
 

+ 42 - 0
modules/boonex/developer/updates/8.0.1_8.0.2/install/config.php

@@ -0,0 +1,42 @@
+<?php
+/**
+ * Copyright (c) BoonEx Pty Limited - http://www.boonex.com/
+ * CC-BY License - http://creativecommons.org/licenses/by/3.0/
+ */
+
+$aConfig = array(
+    /**
+     * Main Section.
+     */
+    'title' => 'Developer',
+    'version_from' => '8.0.1',
+	'version_to' => '8.0.2',
+    'vendor' => 'BoonEx',
+
+    /**
+     * 'home_dir' and 'home_uri' - should be unique. Don't use spaces in 'home_uri' and the other special chars.
+     */
+    'home_dir' => 'boonex/developer/updates/update_8.0.1_8.0.2/',
+	'home_uri' => 'developer_update_801_802',
+
+	'module_dir' => 'boonex/developer/',
+	'module_uri' => 'developer',
+
+    'db_prefix' => 'bx_dev_',
+    'class_prefix' => 'BxDev',
+
+    /**
+     * Installation/Uninstallation Section.
+     */
+    'install' => array(
+		'execute_sql' => 0,
+        'update_files' => 1,
+        'update_languages' => 0,
+		'clear_db_cache' => 0,
+    ),
+
+	/**
+     * Category for language keys.
+     */
+    'language_category' => 'BoonEx Developer',
+);

+ 15 - 0
modules/boonex/developer/updates/8.0.1_8.0.2/install/installer.php

@@ -0,0 +1,15 @@
+<?php
+/**
+ * Copyright (c) BoonEx Pty Limited - http://www.boonex.com/
+ * CC-BY License - http://creativecommons.org/licenses/by/3.0/
+ */
+
+bx_import('BxDolStudioUpdater');
+
+class BxDevUpdater extends BxDolStudioUpdater
+{
+    function __construct($aConfig)
+	{
+        parent::__construct($aConfig);
+    }
+}

+ 425 - 0
modules/boonex/developer/updates/8.0.1_8.0.2/source/classes/BxDevBuilderPage.php

@@ -0,0 +1,425 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) BoonEx Pty Limited - http://www.boonex.com/
+ * CC-BY License - http://creativecommons.org/licenses/by/3.0/
+ *
+ * @defgroup    Developer Developer
+ * @ingroup     DolphinModules
+ *
+ * @{
+ */
+
+bx_import('BxTemplStudioBuilderPage');
+
+class BxDevBuilderPage extends BxTemplStudioBuilderPage
+{
+    protected $sActionPageExport = 'page_export';
+
+    protected $oModule;
+    protected $aParams;
+
+    function __construct($aParams)
+    {
+        parent::__construct(isset($aParams['type']) ? $aParams['type'] : '',  isset($aParams['page']) ? $aParams['page'] : '');
+
+        $this->aParams = $aParams;
+        $this->sBaseUrl = $this->aParams['url'];
+        $this->sTypeUrl = $this->sBaseUrl . '&bp_type=%s';
+        $this->sPageUrl = $this->sTypeUrl . '&bp_page=%s';
+
+        bx_import('BxDolModule');
+        $this->oModule = BxDolModule::getInstance('bx_developer');
+
+        $this->oModule->_oTemplate->addStudioCss(array('builder_page.css'));
+    }
+
+    function getBlockPanelTop($aParams = array())
+    {
+         return BxBaseStudioPage::getBlockPanelTop(
+            array('panel_top' => $this->oModule->_oTemplate->parseHtmlByName('bp_block_panel_top.html', $this->_getTmplVarsBlockPanelTop()))
+        );
+    }
+
+    protected function actionPageCreate()
+    {
+        bx_import('BxDolForm');
+        $oForm = BxDolForm::getObjectInstance('mod_dev_bp_page', 'mod_dev_bp_page_add');
+        $oForm->aFormAttrs['action'] = sprintf($this->sPageUrl, $this->sType, $this->sPage) . '&bp_action=' . $this->sActionPageCreate;
+        $oForm->aInputs['module']['values'] = array_merge(array('' => _t('_bx_dev_bp_txt_select_module')), BxDolStudioUtils::getModules());
+
+        $oForm->aInputs['layout_id']['values'] = array(
+            array('key' => '', 'value' => _t('_bx_dev_bp_txt_page_layout_id_select'))
+        );
+
+        $aLayouts = array();
+        $this->oDb->getLayouts(array('type' => 'all'), $aLayouts, false);
+        foreach($aLayouts as $aLayout)
+            $oForm->aInputs['layout_id']['values'][] = array('key' => $aLayout['id'], 'value' => _t($aLayout['title']));
+
+        $oForm->initChecker();
+        if($oForm->isSubmittedAndValid()) {
+            $sObject = $oForm->getCleanValue('object');
+            $sModule = $oForm->getCleanValue('module');
+
+            if(($iId = (int)$oForm->insert()) != 0)
+                return array('eval' => $this->getPageJsObject() . '.onCreatePage(\'' . $sModule . '\', \'' . $sObject . '\')');
+            else
+                return array('msg' => _t('_bx_dev_bp_err_page_create'));
+        }
+
+        bx_import('BxTemplStudioFunctions');
+        $sContent = BxTemplStudioFunctions::getInstance()->popupBox($this->aHtmlIds['add_popup_id'], _t('_bx_dev_bp_txt_page_create_popup'), $this->oModule->_oTemplate->parseHtmlByName('bp_add_page.html', array(
+            'form_id' => $oForm->aFormAttrs['id'],
+            'form' => $oForm->getCode(true)
+        )));
+
+        return array('popup' => $sContent);
+    }
+
+    protected function actionPageExport()
+    {
+        $sContentInsert = $sContentDelete = "";
+
+        $aPage = array();
+        $this->oDb->getPages(array('type' => 'by_object', 'value' => $this->sPage), $aPage, false);
+        if(empty($aPage) || !is_array($aPage))
+            return array();
+
+        $sContentInsert .= ($this->oModule->_oDb->getQueryInsert('sys_objects_page', array($aPage), "Dumping data for '" . $aPage['object'] . "' page"));
+        $sContentDelete .= ($this->oModule->_oDb->getQueryDelete('sys_objects_page', 'object', array($aPage), "Deleting data for '" . $aPage['object'] . "' page"));
+
+        $aBlocks = array();
+        $this->oDb->getBlocks(array('type' => 'by_object', 'value' => $aPage['object']), $aBlocks, false);
+        $sContentInsert .= $this->oModule->_oDb->getQueryInsert('sys_pages_blocks', $aBlocks, false, array('id', 'name'));
+        $sContentDelete .= $this->oModule->_oDb->getQueryDelete('sys_pages_blocks', 'object', array($aPage), false);
+
+        $aForm = array(
+            'form_attrs' => array(),
+            'inputs' => array (
+                'insert' => array(
+                    'type' => 'textarea',
+                    'name' => 'insert',
+                    'caption' => _t('_bx_dev_bp_txt_page_export_insert'),
+                    'value' => $sContentInsert,
+                ),
+                'delete' => array(
+                    'type' => 'textarea',
+                    'name' => 'delete',
+                    'caption' => _t('_bx_dev_bp_txt_page_export_delete'),
+                    'value' => $sContentDelete,
+                ),
+                'done' => array (
+                    'type' => 'button',
+                    'name' => 'done',
+                    'value' => _t('_bx_dev_bp_btn_page_done'),
+                    'attrs' => array(
+                        'onclick' => "$('.bx-popup-applied:visible').dolPopupHide()",
+                    ),
+                )
+            )
+        );
+        $oForm = new BxTemplStudioFormView($aForm);
+
+        bx_import('BxTemplStudioFunctions');
+        $sContent = BxTemplStudioFunctions::getInstance()->popupBox('bx-dev-bp-page-export-popup', _t('_bx_dev_bp_txt_page_export_popup', _t($aPage['title'])), $this->oModule->_oTemplate->parseHtmlByName('bp_export.html', array(
+            'content' => $oForm->getCode()
+        )));
+
+        return array('popup' => $sContent);
+    }
+
+    protected function actionBlockEdit()
+    {
+        $iId = (int)bx_get('id');
+        if(!$iId)
+            return array();
+
+        $aBlock = array();
+        $this->oDb->getBlocks(array('type' => 'by_id', 'value' => $iId), $aBlock, false);
+        if(empty($aBlock) || !is_array($aBlock))
+            return array('msg' => _t('_bx_dev_bp_err_block_not_found'));
+
+        bx_import('BxDolForm');
+        $oForm = BxDolForm::getObjectInstance('mod_dev_bp_block', 'mod_dev_bp_block_edit');
+
+        $this->onLoadBlock($oForm, $aBlock);
+
+        $oForm->initChecker($aBlock);
+        if($oForm->isSubmittedAndValid()) {
+            $this->onSaveBlock($oForm, $aBlock);
+
+            if($oForm->update($iId) !== false)
+                return array('eval' => $this->getPageJsObject() . '.onEditBlock(oData)');
+            else
+                return array('msg' => _t('_bx_dev_bp_err_block_edit'));
+        }
+
+        bx_import('BxTemplStudioFunctions');
+        $sContent = BxTemplStudioFunctions::getInstance()->popupBox($this->aHtmlIds['edit_block_popup_id'], _t('_bx_dev_bp_txt_block_edit_popup', _t($aBlock['title'])), $this->oModule->_oTemplate->parseHtmlByName('bp_add_block.html', array(
+            'form_id' => $oForm->aFormAttrs['id'],
+            'form' => $oForm->getCode(true)
+        )));
+
+        return array('popup' => $sContent);
+    }
+
+    protected function actionBlockDelete()
+    {
+        $sJsObject = $this->getPageJsObject();
+        $iId = (int)bx_get('id');
+
+        $aBlock = array();
+        $this->oDb->getBlocks(array('type' => 'by_id', 'value' => $iId), $aBlock, false);
+        if(empty($aBlock) || !is_array($aBlock))
+            return array('msg' => _t('_bx_dev_bp_err_block_not_found'));
+
+        if(!$this->oDb->deleteBlocks(array('type' => 'by_id', 'value' => $iId)))
+            return array('msg' => _t('_bx_dev_bp_err_block_delete'));
+
+        $this->onBlockDelete($aBlock);
+        return array('eval' => $sJsObject . '.onDeleteBlock(' . $iId . ', oData)');
+    }
+
+    protected function getSettingsOptions($aPage = array(), $bCreate = true, $bInputsOnly = false)
+    {
+        $aForm = array(
+            'form_attrs' => array(
+                'id' => 'adm-bp-settings-seo',
+            ),
+            'params' => array (
+                'remove_form' => '1',
+                'csrf' => array(
+                    'disable' => true
+                )
+            ),
+            'inputs' => array(
+                'object'  => array(
+                    'type' => 'text',
+                    'name' => 'object',
+                    'caption' => _t('_bx_dev_bp_txt_page_object'),
+                    'info' => '',
+                    'value' => $this->aPageRebuild['object'],
+                    'required' => '',
+                    'attrs' => array(
+                        'disabled' => 'disabled'
+                    ),
+                )
+            )
+        );
+
+        $aForm['inputs'] += parent::getSettingsOptions($aPage, $bCreate, true);
+
+        $aForm['inputs']['title_system']['type'] = 'text';
+        $aForm['inputs']['title_system']['caption'] = _t('_bx_dev_bp_txt_page_title_system');
+        $aForm['inputs']['title']['type'] = 'text';
+
+        $aUri = array(
+            'uri'  => array(
+                'type' => 'text',
+                'name' => 'uri',
+                'caption' => _t('_bx_dev_bp_txt_page_uri'),
+                'info' => '',
+                'value' => $this->aPageRebuild['uri'],
+                'required' => '',
+                'db' => array (
+                    'pass' => 'Xss',
+                ),
+            )
+        );
+        $aForm['inputs'] = bx_array_insert_before($aUri, $aForm['inputs'], 'url');
+
+        $aForm['inputs']['url']['caption'] = _t('_bx_dev_bp_txt_page_url');
+        $aForm['inputs']['url']['db'] = array (
+            'pass' => 'Xss',
+        );
+        unset($aForm['inputs']['url']['attrs']['disabled']);
+
+        $aForm['inputs']['deletable'] = array(
+            'type' => 'switcher',
+            'name' => 'deletable',
+            'caption' => _t('_bx_dev_bp_txt_page_deletable'),
+            'info' => '',
+            'value' => '1',
+            'checked' => (int)$this->aPageRebuild['deletable'] == 1,
+            'required' => '',
+            'db' => array (
+                'pass' => 'Int',
+            )
+        );
+        $aForm['inputs']['override_class_name'] = array(
+            'type' => 'text',
+            'name' => 'override_class_name',
+            'caption' => _t('_bx_dev_bp_txt_page_override_class_name'),
+            'info' => '',
+            'value' => $this->aPageRebuild['override_class_name'],
+            'required' => '0',
+            'db' => array (
+                'pass' => 'Xss',
+            )
+        );
+        $aForm['inputs']['override_class_file'] = array(
+            'type' => 'text',
+            'name' => 'override_class_file',
+            'caption' => _t('_bx_dev_bp_txt_page_override_class_file'),
+            'info' => '',
+            'value' => $this->aPageRebuild['override_class_file'],
+            'required' => '0',
+            'db' => array (
+                'pass' => 'Xss',
+            )
+        );
+
+        if($bInputsOnly)
+            return $aForm['inputs'];
+
+        $oForm = new BxTemplStudioFormView($aForm);
+        return $oForm->getCode();
+    }
+
+    protected function getSettingsCache($aPage = array(), $bCreate = true, $bInputsOnly = false)
+    {
+        $aForm = array(
+            'form_attrs' => array(
+                'id' => 'adm-bp-settings-cache',
+            ),
+            'params' => array (
+                'remove_form' => '1',
+                'csrf' => array(
+                    'disable' => true
+                )
+            ),
+            'inputs' => parent::getSettingsCache($aPage, $bCreate, true)
+        );
+
+        unset($aForm['inputs']['cache_lifetime']['attrs']);
+
+        $aForm['inputs']['cache_editable'] = array(
+            'type' => 'switcher',
+            'name' => 'cache_editable',
+            'caption' => _t('_bx_dev_bp_txt_page_cache_editable'),
+            'info' => '',
+            'value' => '1',
+            'checked' => (int)$this->aPageRebuild['cache_editable'] == 1,
+            'required' => '',
+            'db' => array (
+                'pass' => 'Int',
+            )
+        );
+
+        if($bInputsOnly)
+            return $aForm['inputs'];
+
+        $oForm = new BxTemplStudioFormView($aForm);
+        return $oForm->getCode();
+    }
+
+    protected function getBlockModule($aBlock)
+    {
+        return $this->aPageRebuild['module'];
+    }
+
+    protected function getBlockContent($aBlock)
+    {
+        $aFields = array();
+
+        switch($aBlock['type']) {
+            case BX_DOL_STUDIO_BP_BLOCK_SERVICE:
+                $aFields = array(
+                    'content' => array(
+                        'type' => 'textarea',
+                        'name' => 'content',
+                        'caption' => _t('_bx_dev_bp_txt_block_content_service'),
+                        'info' => '',
+                        'value' => $aBlock['content'],
+                        'required' => '0',
+                        'db' => array (
+                            'pass' => 'Xss',
+                        ),
+                    )
+                );
+                break;
+
+            default:
+                $aFields = parent::getBlockContent($aBlock);
+                break;
+        }
+
+        return $aFields;
+    }
+
+    protected function getBlocks($sModule)
+    {
+        $aBlocks = parent::getBlocks($sModule);
+
+        if($sModule == BX_DOL_STUDIO_BP_SKELETONS) {
+            $aBlock = array();
+            $this->oDb->getBlocks(array('type' => 'skeleton_by_type', 'value' => 'service'), $aBlock, false);
+            if(!empty($aBlock) && is_array($aBlock))
+                $aBlocks[] = $aBlock;
+        }
+
+        return $aBlocks;
+    }
+
+    protected function onLoadBlock(&$oForm, &$aBlock)
+    {
+        $oForm->aFormAttrs['action'] = sprintf($this->sPageUrl, $this->sType, $this->sPage) . '&bp_action=' . $this->sActionBlockEdit;
+        $oForm->aInputs['module']['values'] = array_merge(array('' => _t('_bx_dev_bp_txt_select_module')), BxDolStudioUtils::getModules());
+
+        $aDBoxes = array();
+        $this->oDb->getDesignBoxes(array('type' => 'ordered'), $aDBoxes, false);
+        foreach($aDBoxes as $aDBox)
+            $oForm->aInputs['designbox_id']['values'][] = array('key' => $this->sSelectKeyPrefix . $aDBox['id'], 'value' => _t($aDBox['title']));
+
+        $oForm->aInputs['visible_for']['value'] = $aBlock['visible_for_levels'] == BX_DOL_INT_MAX ? BX_DOL_STUDIO_VISIBLE_ALL : BX_DOL_STUDIO_VISIBLE_SELECTED;
+        $oForm->aInputs['visible_for']['values'] = array(
+            array('key' => BX_DOL_STUDIO_VISIBLE_ALL, 'value' => _t('_bx_dev_bp_txt_block_visible_for_all')),
+            array('key' => BX_DOL_STUDIO_VISIBLE_SELECTED, 'value' => _t('_bx_dev_bp_txt_block_visible_for_selected')),
+        );
+        $oForm->aInputs['visible_for']['attrs']['onchange'] = $this->getPageJsObject() . '.onChangeVisibleFor(this)';
+
+        $oForm->aInputs['visible_for_levels']['tr_attrs']['style'] = $aBlock['visible_for_levels'] == BX_DOL_INT_MAX ? 'display:none' : '';
+        BxDolStudioUtils::getVisibilityValues($aBlock['visible_for_levels'], $oForm->aInputs['visible_for_levels']['values'], $oForm->aInputs['visible_for_levels']['value']);
+        $aBlock['visible_for_levels'] = $oForm->aInputs['visible_for_levels']['value'];
+
+        $oForm->aInputs = $this->addInArray($oForm->aInputs, 'visible_for_levels', $this->getBlockContent($aBlock));
+
+        $oForm->aInputs['controls'][0]['value'] = _t('_bx_dev_bp_btn_block_save');
+        $oForm->aInputs['controls'][2]['attrs']['onclick'] = $this->getPageJsObject() . ".deleteBlock(" . $aBlock['id'] . ")";
+
+        if($aBlock['type'] == BX_DOL_STUDIO_BP_BLOCK_SERVICE)
+            $aBlock['content'] = BxDevFunctions::unserializeString($aBlock['content']);
+
+        if((int)$aBlock['designbox_id'] != 0)
+            $aBlock['designbox_id'] = $this->sSelectKeyPrefix . $aBlock['designbox_id'];
+    }
+
+    protected function onSaveBlock(&$oForm, &$aBlock)
+    {
+        parent::onSaveBlock($oForm, $aBlock);
+
+        if($aBlock['type'] == BX_DOL_STUDIO_BP_BLOCK_SERVICE && isset($oForm->aInputs['content'])) {
+            $sValue = $oForm->getCleanValue('content');
+            $sValue = BxDevFunctions::serializeString($sValue);
+            BxDolForm::setSubmittedValue('content', $sValue, $oForm->aFormAttrs['method']);
+        }
+    }
+
+    protected function _getTmplVarsBlockPanelTopActions()
+    {
+        $sJsObject = $this->getPageJsObject();
+
+        bx_import('BxDolPermalinks');
+        $oPermalinks = BxDolPermalinks::getInstance();
+
+        return array(
+            'js_object' => $sJsObject,
+            'url_view' => BX_DOL_URL_ROOT . $oPermalinks->permalink($this->aPageRebuild['url']),
+            'action_page_export' => $this->sActionPageExport,
+            'action_page_edit' => $this->sActionPageEdit,
+            'action_block_create' => $this->sActionBlockCreate,
+        );
+    }
+}
+
+/** @} */

+ 72 - 0
modules/boonex/developer/updates/8.0.1_8.0.2/source/classes/BxDevDb.php

@@ -0,0 +1,72 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) BoonEx Pty Limited - http://www.boonex.com/
+ * CC-BY License - http://creativecommons.org/licenses/by/3.0/
+ *
+ * @defgroup    Developer Developer
+ * @ingroup     DolphinModules
+ *
+ * @{
+ */
+
+bx_import('BxDolModuleDb');
+
+class BxDevDb extends BxDolModuleDb
+{
+    function __construct(&$oConfig)
+    {
+        parent::__construct($oConfig);
+    }
+
+    function getQueryInsert($sTable, $aItems, $mixedComment = false, $aExclude = array('id'))
+    {
+        $bFirst = true;
+        $sContent = $sComment = "";
+        foreach($aItems as $aItem) {
+            foreach($aExclude as $sKey)
+                if(isset($aItem[$sKey]))
+                    unset($aItem[$sKey]);
+
+            $aKeys = array_keys($aItem);
+            $aValues = array_values($aItem);
+            $iValues = count($aValues);
+
+            foreach ($aValues as $iKey => $sValue)
+                $aValues[$iKey] = BxDevFunctions::dbAddSlashes($sValue, true);
+
+            if($bFirst) {
+                $sContent .= "INSERT INTO `" . $sTable . "`(`" . implode("`, `", $aKeys) . "`) VALUES \n";
+                $bFirst = false;
+            }
+
+            $sSql = "(" . implode(", ", array_fill(0, $iValues, "?")) . "),\n";
+            $sSql = call_user_func_array(array($this, 'prepare'), array_merge(array($sSql), $aValues));
+
+            $sContent .= $sSql;
+        }
+        $sContent = substr($sContent, 0, -2) . ";\n\n";
+
+        if($mixedComment === true || (is_string($mixedComment) && $mixedComment != ''))
+            $sComment = "--\n-- " . ($mixedComment === true ? "Dumping data for table `" . $sTable . "`" : $mixedComment) . "\n--\n";
+
+        return $sComment . $sContent;
+    }
+
+    function getQueryDelete($sTable, $sKey, $aItems, $mixedComment = false)
+    {
+        $sContent = $sComment = "";
+        foreach($aItems as $aItem)
+            if(isset($aItem[$sKey])) {
+                $sSql = "DELETE FROM `" . $sTable . "` WHERE `" . $sKey . "`=?;\n";
+                $sContent .= call_user_func_array(array($this, 'prepare'), array($sSql, $aItem[$sKey]));
+            }
+        $sContent .= "\n";
+
+        if($mixedComment === true || (is_string($mixedComment) && $mixedComment != ''))
+            $sComment = "--\n-- " . ($mixedComment === true ? "Delete data from table `" . $sTable . "`" : $mixedComment) . "\n--\n";
+
+        return $sComment . $sContent;
+    }
+}
+
+/** @} */

+ 103 - 0
modules/boonex/developer/updates/8.0.1_8.0.2/source/classes/BxDevModule.php

@@ -0,0 +1,103 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) BoonEx Pty Limited - http://www.boonex.com/
+ * CC-BY License - http://creativecommons.org/licenses/by/3.0/
+ *
+ * @defgroup    Developer Developer
+ * @ingroup     DolphinModules
+ *
+ * @{
+ */
+
+bx_import('BxDolModule');
+
+require_once('BxDevFunctions.php');
+
+define('BX_DEV_TOOLS_SETTINGS', 'settings');
+define('BX_DEV_TOOLS_FORMS', 'forms');
+define('BX_DEV_TOOLS_PAGES', 'pages');
+define('BX_DEV_TOOLS_NAVIGATION', 'navigation');
+define('BX_DEV_TOOLS_POLYGLOT', 'polyglot');
+define('BX_DEV_TOOLS_PERMISSIONS', 'permissions');
+
+class BxDevModule extends BxDolModule
+{
+    public $aTools;
+
+    function __construct($aModule)
+    {
+        parent::__construct($aModule);
+
+        $this->aTools = array(
+            array('name' => BX_DEV_TOOLS_SETTINGS, 'title' => '', 'icon' => 'cogs'),
+            array('name' => BX_DEV_TOOLS_FORMS, 'title' => '', 'icon' => 'bx-dev-mi-forms.png'),
+            array('name' => BX_DEV_TOOLS_NAVIGATION, 'title' => '', 'icon' => 'bx-dev-mi-navigation.png'),
+            array('name' => BX_DEV_TOOLS_PAGES, 'title' => '', 'icon' => 'bx-dev-mi-pages.png'),
+            array('name' => BX_DEV_TOOLS_POLYGLOT, 'title' => '', 'icon' => 'bx-dev-mi-polyglot.png'),
+            //array('name' => BX_DEV_TOOLS_PERMISSIONS, 'title' => '', 'icon' => 'bx-dev-mi-permissions.png'),
+        );
+    }
+
+    function getToolsList()
+    {
+        return $this->aTools;
+    }
+
+    public function actionResetHash($sType) {
+    	$oDb = bx_instance('BxDolStudioInstallerQuery');
+
+    	$sResult = '';
+    	switch ($sType) {
+    		case 'system':
+    			$oHasher = bx_instance('BxDolInstallerHasher');
+
+    			$oDb->deleteModuleTrackFiles(BX_SYSTEM_MODULE_ID);
+
+    			$sResult = _t('_bx_dev_hash_' . ($oHasher->hashSystemFiles() ? 'msg' : 'err') . '_reset_hash_system');    			
+    			break;
+
+    		case 'modules':
+    			bx_import('BxDolInstallerUtils');
+
+				bx_import('BxDolModuleQuery');
+				$aModules = BxDolModuleQuery::getInstance()->getModules();
+
+				$aTmplVarsModules = array();
+				foreach($aModules as $aModule) {
+					if($aModule['name'] == 'system')
+						continue;
+
+					$aConfig = BxDolInstallerUtils::getModuleConfig($aModule);
+					$sPathInstaller = BX_DIRECTORY_PATH_MODULES . $aModule['path'] . 'install/installer.php';
+					if(empty($aConfig) || !file_exists($sPathInstaller))
+						continue;
+
+					require_once($sPathInstaller);
+
+					$sClassName = $aConfig['class_prefix'] . 'Installer';
+					$oInstaller = new $sClassName($aConfig);
+
+					$oDb->deleteModuleTrackFiles($aModule['id']);
+
+					$aFiles = array();
+				    $oInstaller->hashFiles(BX_DIRECTORY_PATH_ROOT . 'modules/' . $aModule['path'], $aFiles);
+					foreach($aFiles as $aFile)
+				    	$oDb->insertModuleTrack($aModule['id'], $aFile);
+
+					$aTmplVarsModules[] = array(
+						'module' => $aModule['title'],
+						'files' => count($aFiles)
+					);
+				}
+
+				$sResult = $this->_oTemplate->parseHtmlByName('hash_modules.html', array(
+					'bx_repeat:modules' => $aTmplVarsModules
+				));
+				break;
+    	}
+
+    	echo $sResult;
+    	exit;
+    }
+}
+/** @} */

+ 128 - 0
modules/boonex/developer/updates/8.0.1_8.0.2/source/classes/BxDevStudioPage.php

@@ -0,0 +1,128 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) BoonEx Pty Limited - http://www.boonex.com/
+ * CC-BY License - http://creativecommons.org/licenses/by/3.0/
+ *
+ * @defgroup    Developer Developer
+ * @ingroup     DolphinModules
+ *
+ * @{
+ */
+
+bx_import('BxTemplStudioModule');
+
+class BxDevStudioPage extends BxTemplStudioModule
+{
+    protected $oModule;
+    protected $sUrl;
+
+    function __construct($sModule = "", $sPage = "")
+    {
+        parent::__construct($sModule, $sPage);
+
+        bx_import('BxDolModule');
+        $this->oModule = BxDolModule::getInstance($this->sModule);
+
+        $this->sUrl = BX_DOL_URL_STUDIO . 'module.php?name=%s&page=%s';
+    }
+
+    function getPageMenu($aMenu = array(), $aMarkers = array())
+    {
+        $this->aMenuItems = array();
+        foreach($this->oModule->aTools as $aTool)
+            $this->aMenuItems[] = array(
+                'name' => $aTool['name'],
+                'icon' => $aTool['icon'],
+                'link' => sprintf($this->sUrl, $this->sModule, $aTool['name']),
+                'title' => $aTool['title'],
+                'selected' => $aTool['name'] == $this->sPage
+            );
+
+        bx_import('BxTemplStudioMenu');
+        $oMenu = new BxTemplStudioMenu(array('template' => 'menu_main.html', 'menu_items' => $this->aMenuItems), $this->oModule->_oTemplate);
+        return $oMenu->getCode();
+    }
+
+    protected function getSettings()
+    {
+        bx_import('BxTemplStudioSettings');
+        $oContent = new BxTemplStudioSettings($this->sModule);
+
+        return $this->oModule->_oTemplate->displayPageContent($this->sPage, $oContent);
+    }
+
+    protected function getForms()
+    {
+        $sPage = bx_get('form_page');
+        $sPage = $sPage !== false ? bx_process_input($sPage) : '';
+
+		bx_import('Forms', $this->aModule);
+        $oContent = new BxDevForms(array(
+            'page' => $sPage,
+            'url' => sprintf($this->sUrl, $this->sModule, BX_DEV_TOOLS_FORMS),
+        ));
+        return $this->oModule->_oTemplate->displayPageContent($this->sPage, $oContent);
+    }
+
+    protected function getNavigation()
+    {
+        $sPage = bx_get('nav_page');
+        $sPage = $sPage !== false ? bx_process_input($sPage) : '';
+
+        bx_import('Navigation', $this->aModule);
+        $oContent = new BxDevNavigation(array(
+            'page' => $sPage,
+            'url' => sprintf($this->sUrl, $this->sModule, BX_DEV_TOOLS_NAVIGATION),
+        ));
+        return $this->oModule->_oTemplate->displayPageContent($this->sPage, $oContent);
+    }
+
+    protected function getPages()
+    {
+        $sType = bx_get('bp_type');
+        $sType = $sType !== false ? bx_process_input($sType) : '';
+
+        $sPage = bx_get('bp_page');
+        $sPage = $sPage !== false ? bx_process_input($sPage) : '';
+
+        bx_import('BuilderPage', $this->aModule);
+        $oContent = new BxDevBuilderPage(array(
+            'type' => $sType,
+            'page' => $sPage,
+            'url' => sprintf($this->sUrl, $this->sModule, BX_DEV_TOOLS_PAGES),
+        ));
+        $oContent->init();
+        return $this->oModule->_oTemplate->displayPageContent($this->sPage, $oContent);
+    }
+
+    protected function getPolyglot()
+    {
+        $sType = bx_get('pgt_type');
+        $sType = $sType !== false ? bx_process_input($sType) : '';
+
+        $sPage = bx_get('pgt_page');
+        $sPage = $sPage !== false ? bx_process_input($sPage) : 'manager';
+
+        bx_import('Polyglot', $this->aModule);
+        $oContent = new BxDevPolyglot(array(
+            'page' => $sPage,
+            'url' => sprintf($this->sUrl, $this->sModule, BX_DEV_TOOLS_POLYGLOT),
+        ));
+        return $this->oModule->_oTemplate->displayPageContent($this->sPage, $oContent);
+    }
+
+    protected function getPermissions()
+    {
+        $sPage = bx_get('prm_page');
+        $sPage = $sPage !== false ? bx_process_input($sPage) : '';
+
+        bx_import('Permissions', $this->aModule);
+        $oContent = new BxDevPermissions(array(
+            'page' => $sPage,
+            'url' => sprintf($this->sUrl, $this->sModule, BX_DEV_TOOLS_PERMISSIONS),
+        ));
+        return $this->oModule->_oTemplate->displayPageContent($this->sPage, $oContent);
+    }
+}
+
+/** @} */

+ 80 - 0
modules/boonex/developer/updates/8.0.1_8.0.2/source/install/config.php

@@ -0,0 +1,80 @@
+<?php
+/**
+ * Copyright (c) BoonEx Pty Limited - http://www.boonex.com/
+ * CC-BY License - http://creativecommons.org/licenses/by/3.0/
+ *
+ * @defgroup    Developer Developer
+ * @ingroup     DolphinModules
+ *
+ * @{
+ */
+
+$aConfig = array(
+    /**
+     * Main Section.
+     */
+    'type' => BX_DOL_MODULE_TYPE_MODULE,
+    'name' => 'bx_developer',
+    'title' => 'Developer',
+    'note' => 'Developer tools...',
+    'version' => '8.0.2',
+    'vendor' => 'BoonEx',
+	'help_url' => 'http://feed.boonex.com/?section={module_name}',
+
+    'compatible_with' => array(
+        '8.0.x'
+    ),
+
+    /**
+     * 'home_dir' and 'home_uri' - should be unique. Don't use spaces in 'home_uri' and the other special chars.
+     */
+    'home_dir' => 'boonex/developer/',
+    'home_uri' => 'developer',
+
+    'db_prefix' => 'bx_dev_',
+    'class_prefix' => 'BxDev',
+    /**
+     * Installation/Uninstallation Section.
+     */
+    'install' => array(
+        'execute_sql' => 1,
+        'update_languages' => 1,
+        'recompile_global_paramaters' => 1,
+        'recompile_permalinks' => 1,
+        'clear_db_cache' => 1
+    ),
+    'uninstall' => array (
+        'execute_sql' => 1,
+        'update_languages' => 1,
+        'recompile_global_paramaters' => 1,
+        'recompile_permalinks' => 1,
+        'clear_db_cache' => 1
+    ),
+    'enable' => array(
+        'execute_sql' => 1,
+    ),
+    'disable' => array(
+        'execute_sql' => 1,
+    ),
+    /**
+     * Dependencies Section
+     */
+    'dependencies' => array(),
+    /**
+     * Category for language keys.
+     */
+    'language_category' => 'BoonEx Developer',
+    /**
+     * Introduction and Conclusion Section.
+     */
+    'install_info' => array(
+        'introduction' => 'inst_intro.html',
+        'conclusion' => 'inst_concl.html'
+    ),
+    'uninstall_info' => array(
+        'introduction' => 'uninst_intro.html',
+        'conclusion' => 'uninst_concl.html'
+    )
+);
+
+/** @} */