Kaynağa Gözat

Modules updates.

AntonLV 1 yıl önce
ebeveyn
işleme
a5f723bdcf
51 değiştirilmiş dosya ile 9527 ekleme ve 0 silme
  1. 51 0
      modules/boonex/ads/updates/14.0.5_14.0.6/install/config.php
  2. 13 0
      modules/boonex/ads/updates/14.0.5_14.0.6/install/installer.php
  3. 2773 0
      modules/boonex/ads/updates/14.0.5_14.0.6/source/classes/BxAdsModule.php
  4. 151 0
      modules/boonex/ads/updates/14.0.5_14.0.6/source/install/config.php
  5. 14 0
      modules/boonex/ads/updates/14.0.5_14.0.6/source/template/categories.html
  6. 51 0
      modules/boonex/albums/updates/14.0.5_14.0.6/install/config.php
  7. 13 0
      modules/boonex/albums/updates/14.0.5_14.0.6/install/installer.php
  8. 130 0
      modules/boonex/albums/updates/14.0.5_14.0.6/source/classes/BxAlbumsPageMedia.php
  9. 143 0
      modules/boonex/albums/updates/14.0.5_14.0.6/source/install/config.php
  10. 51 0
      modules/boonex/credits/updates/14.0.4_14.0.5/install/config.php
  11. 13 0
      modules/boonex/credits/updates/14.0.4_14.0.5/install/installer.php
  12. 2 0
      modules/boonex/credits/updates/14.0.4_14.0.5/install/sql/enable.sql
  13. 77 0
      modules/boonex/credits/updates/14.0.4_14.0.5/source/install/config.php
  14. 293 0
      modules/boonex/credits/updates/14.0.4_14.0.5/source/install/sql/enable.sql
  15. 51 0
      modules/boonex/developer/updates/14.0.4_14.0.5/install/config.php
  16. 13 0
      modules/boonex/developer/updates/14.0.4_14.0.5/install/installer.php
  17. 779 0
      modules/boonex/developer/updates/14.0.4_14.0.5/source/classes/BxDevFormsField.php
  18. 69 0
      modules/boonex/developer/updates/14.0.4_14.0.5/source/install/config.php
  19. 51 0
      modules/boonex/files/updates/14.0.4_14.0.5/install/config.php
  20. 13 0
      modules/boonex/files/updates/14.0.4_14.0.5/install/installer.php
  21. 142 0
      modules/boonex/files/updates/14.0.4_14.0.5/source/install/config.php
  22. 151 0
      modules/boonex/files/updates/14.0.4_14.0.5/source/template/css/main.css
  23. 19 0
      modules/boonex/files/updates/14.0.4_14.0.5/source/template/unit.html
  24. 51 0
      modules/boonex/forum/updates/14.0.4_14.0.5/install/config.php
  25. 13 0
      modules/boonex/forum/updates/14.0.4_14.0.5/install/installer.php
  26. 151 0
      modules/boonex/forum/updates/14.0.4_14.0.5/source/install/config.php
  27. 15 0
      modules/boonex/forum/updates/14.0.4_14.0.5/source/template/score_element_inline.html
  28. 51 0
      modules/boonex/market/updates/14.0.6_14.0.7/install/config.php
  29. 13 0
      modules/boonex/market/updates/14.0.6_14.0.7/install/installer.php
  30. 8 0
      modules/boonex/market/updates/14.0.6_14.0.7/install/langs/en.xml
  31. 4 0
      modules/boonex/market/updates/14.0.6_14.0.7/install/sql/install.sql
  32. 364 0
      modules/boonex/market/updates/14.0.6_14.0.7/source/classes/BxMarketFormEntry.php
  33. 140 0
      modules/boonex/market/updates/14.0.6_14.0.7/source/install/config.php
  34. 509 0
      modules/boonex/market/updates/14.0.6_14.0.7/source/install/langs/en.xml
  35. 663 0
      modules/boonex/market/updates/14.0.6_14.0.7/source/install/sql/install.sql
  36. 51 0
      modules/boonex/notifications/updates/14.0.6_14.0.7/install/config.php
  37. 13 0
      modules/boonex/notifications/updates/14.0.6_14.0.7/install/installer.php
  38. 855 0
      modules/boonex/notifications/updates/14.0.6_14.0.7/source/classes/BxNtfsModule.php
  39. 82 0
      modules/boonex/notifications/updates/14.0.6_14.0.7/source/install/config.php
  40. 16 0
      modules/boonex/notifications/updates/14.0.6_14.0.7/source/template/event.html
  41. 51 0
      modules/boonex/organizations/updates/14.0.7_14.0.8/install/config.php
  42. 13 0
      modules/boonex/organizations/updates/14.0.7_14.0.8/install/installer.php
  43. 335 0
      modules/boonex/organizations/updates/14.0.7_14.0.8/source/classes/BxOrgsConfig.php
  44. 152 0
      modules/boonex/organizations/updates/14.0.7_14.0.8/source/install/config.php
  45. 20 0
      modules/boonex/organizations/updates/14.0.7_14.0.8/source/js/main.js
  46. 51 0
      modules/boonex/payment/updates/14.0.7_14.0.8/install/config.php
  47. 13 0
      modules/boonex/payment/updates/14.0.7_14.0.8/install/installer.php
  48. 5 0
      modules/boonex/payment/updates/14.0.7_14.0.8/install/sql/install.sql
  49. 70 0
      modules/boonex/payment/updates/14.0.7_14.0.8/source/install/config.php
  50. 679 0
      modules/boonex/payment/updates/14.0.7_14.0.8/source/install/sql/install.sql
  51. 76 0
      modules/boonex/payment/updates/14.0.7_14.0.8/source/template/css/orders.css

+ 51 - 0
modules/boonex/ads/updates/14.0.5_14.0.6/install/config.php

@@ -0,0 +1,51 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ */
+
+$aConfig = array(
+    /**
+     * Main Section.
+     */
+    'title' => 'Ads',
+    'version_from' => '14.0.5',
+    'version_to' => '14.0.6',
+    'vendor' => 'UNA INC',
+
+    'compatible_with' => array(
+        '14.0.0-RC4'
+    ),
+
+    /**
+     * 'home_dir' and 'home_uri' - should be unique. Don't use spaces in 'home_uri' and the other special chars.
+     */
+    'home_dir' => 'boonex/ads/updates/update_14.0.5_14.0.6/',
+    'home_uri' => 'ads_update_1405_1406',
+
+    'module_dir' => 'boonex/ads/',
+    'module_uri' => 'ads',
+
+    'db_prefix' => 'bx_ads_',
+    'class_prefix' => 'BxAds',
+
+    /**
+     * Installation/Uninstallation Section.
+     */
+    'install' => array(
+        'execute_sql' => 0,
+        'update_files' => 1,
+        'update_languages' => 0,
+        'clear_db_cache' => 0,
+    ),
+
+    /**
+     * Category for language keys.
+     */
+    'language_category' => 'Ads',
+
+    /**
+     * Files Section
+     */
+    'delete_files' => array(),
+);

+ 13 - 0
modules/boonex/ads/updates/14.0.5_14.0.6/install/installer.php

@@ -0,0 +1,13 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ */
+
+class BxAdsUpdater extends BxDolStudioUpdater
+{
+    function __construct($aConfig)
+    {
+        parent::__construct($aConfig);
+    }
+}

+ 2773 - 0
modules/boonex/ads/updates/14.0.5_14.0.6/source/classes/BxAdsModule.php

@@ -0,0 +1,2773 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Ads Ads
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+define('BX_ADS_STATUS_OFFER', 'offer');
+define('BX_ADS_STATUS_SOLD', 'sold');
+
+define('BX_ADS_STATUS_ADMIN_UNPAID', 'unpaid');
+
+define('BX_ADS_COMMODITY_TYPE_PRODUCT', 'product');
+define('BX_ADS_COMMODITY_TYPE_PROMOTION', 'promotion');
+
+define('BX_ADS_OFFER_STATUS_ACCEPTED', 'accepted');
+define('BX_ADS_OFFER_STATUS_AWAITING', 'awaiting');
+define('BX_ADS_OFFER_STATUS_DECLINED', 'declined');
+define('BX_ADS_OFFER_STATUS_CANCELED', 'canceled');
+define('BX_ADS_OFFER_STATUS_PAID', 'paid');
+
+/**
+ * Ads module
+ */
+class BxAdsModule extends BxBaseModTextModule
+{
+    protected $_aOfferStatuses;
+
+    function __construct(&$aModule)
+    {
+        parent::__construct($aModule);
+
+        $this->_oConfig->init($this->_oDb);
+
+        $CNF = &$this->_oConfig->CNF;
+
+        $this->_aSearchableNamesExcept = array_merge($this->_aSearchableNamesExcept, array(
+            $CNF['FIELD_CATEGORY_VIEW'],
+            $CNF['FIELD_CATEGORY_SELECT']
+        ));
+
+        $this->_aOfferStatuses = array(
+            BX_ADS_OFFER_STATUS_ACCEPTED,
+            BX_ADS_OFFER_STATUS_AWAITING,
+            BX_ADS_OFFER_STATUS_DECLINED
+        );
+    }
+    
+    public function decodeDataApi ($aData, $bExtended = false)
+    {
+        $CNF = $this->_oConfig->CNF;
+        
+        $aResult = array_merge(parent::decodeDataApi($aData, $bExtended), [
+            $CNF['FIELD_PRICE'] => $aData[$CNF['FIELD_PRICE']],
+            $CNF['FIELD_QUANTITY'] => $aData[$CNF['FIELD_QUANTITY']],
+            $CNF['FIELD_NOTES_PURCHASED'] => $aData[$CNF['FIELD_NOTES_PURCHASED']]
+        ]);
+
+        if($this->_oConfig->isSources() && !empty($aData[$CNF['FIELD_URL']]))
+            $aResult[$CNF['FIELD_URL']] = $aData[$CNF['FIELD_URL']];
+
+        return $aResult;
+    }
+
+    public function actionGetSource()
+    {
+        $aEntries = $this->serviceGetSourceData();
+
+        header('Content-Type:text/javascript; charset=utf-8');
+        echo(json_encode($aEntries));
+    }
+    
+    public function serviceGetSourceData()
+    {
+        $sSourceType = bx_get('source_type');
+        if(empty($sSourceType)) {
+            $aSource = $this->serviceGetSource($this->_iProfileId);
+            if(!empty($aSource) && is_array($aSource))
+                $sSourceType = $aSource['name'];
+        }
+
+        $sTerm = bx_get('term');
+
+        $aEntries = $this->serviceLoadEntriesFromSourceByTerm($sSourceType, $sTerm);
+
+        return $aEntries;
+    }
+
+    public function actionLoadEntryFromSource()
+    {
+        $sSourceType = bx_process_url_param(bx_process_input(bx_get('source_type')));
+        $sSource = bx_process_url_param(bx_process_input(bx_get('source')));
+        if(empty($sSourceType) || empty($sSource))
+            return echoJson(['code' => 1]);
+
+        $aEntry = $this->serviceLoadEntryFromSource($sSourceType, $sSource);
+        if(empty($aEntry) || !is_array($aEntry))
+            return echoJson(['code' => 2]);
+
+        return echoJson([
+            'code' => 0,
+            'fields' => $aEntry
+        ]);
+    }
+
+    public function actionGetCategoryForm()
+    {
+        if(($iCategory = bx_get('category')) === false || (int)$iCategory == 0)
+            return echoJson(['msg' => _t('_bx_ads_form_entry_input_category_select_err')]);
+
+        return echoJson([
+            'eval' => $this->_oConfig->getJsObject('form') . '.onSelectCategory(oData)',
+            'content' => $this->serviceGetCreatePostForm([
+                'absolute_action_url' => true,
+                'dynamic_mode' => true,
+                'context_id' => ($iContextId = bx_get('context_id')) !== false ? (int)$iContextId : false
+            ])
+        ]);
+    }
+
+    public function actionCheckName()
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        $iId = (int)bx_get($CNF['FIELD_ID']);
+    	$sTitle = bx_process_input(bx_get($CNF['FIELD_TITLE']));
+
+    	echoJson($this->serviceCheckName($sTitle, $iId));
+    }
+
+    public function actionInterested()
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        $iContentId = bx_process_input(bx_get('id'), BX_DATA_INT);
+
+        $aContentInfo = $this->_oDb->getContentInfoById($iContentId);
+        if(empty($aContentInfo) || !is_array($aContentInfo))
+            return echoJson(array());
+
+        $iViewer = bx_get_logged_profile_id();        
+        $oViewer = BxDolProfile::getInstance($iViewer);
+        if(!$oViewer)
+            return echoJson(array());
+
+        $iContentAuthor = (int)$aContentInfo[$CNF['FIELD_AUTHOR']];
+        if($iContentAuthor == $iViewer)
+            return echoJson(array('msg' => _t('_bx_ads_txt_err_your_own')));
+
+        if($this->_oDb->isInterested($iContentId, $iViewer))
+            return echoJson(array('msg' => _t('_bx_ads_txt_err_duplicate')));
+
+        $iInterestId = $this->_oDb->insertInterested(array('entry_id' => $iContentId, 'profile_id' => $iViewer));
+        if(!$iInterestId)
+            return echoJson(array('msg' => _t('_bx_ads_txt_err_cannot_perform_action')));
+
+        /**
+         * @hooks
+         * @hookdef hook-bx_ads-doInterest 'bx_ads', 'doInterest' - hook after 'interested' action was performed
+         * - $unit_name - equals `bx_ads`
+         * - $action - equals `doInterest`
+         * - $object_id - content id
+         * - $sender_id - profile id who performed the action
+         * - $extra_params - array of additional params with the following array keys:
+         *      - `subobject_id` - [int] id of a database table record, created during the action
+         *      - `subobject_author_id` - [int] profile id who performed the action
+         *      - `object_author_id` - [int] content author profile id
+         * @hook @ref hook-bx_ads-doInterest
+         */
+        bx_alert($this->getName(), 'doInterest', $iContentId, $iViewer, [
+            'subobject_id' => $iInterestId, 
+            'subobject_author_id' => $iViewer, 
+
+            'object_author_id' => $iContentAuthor
+        ]);
+
+        if(getParam($CNF['PARAM_USE_IIN']) == 'on')
+            sendMailTemplate($CNF['ETEMPLATE_INTERESTED'], 0, $iContentAuthor, array(
+                'viewer_name' => $oViewer->getDisplayName(),
+                'viewer_url' => $oViewer->getUrl(),
+                'ad_name' => $aContentInfo[$CNF['FIELD_TITLE']],
+                'ad_url' => bx_absolute_url(BxDolPermalinks::getInstance()->permalink('page.php', array(
+                    'i' => $CNF['URI_VIEW_ENTRY'], 
+                    $CNF['FIELD_ID'] => $iContentId
+                )))
+            ));
+
+        return echoJson(array('msg' => _t('_bx_ads_txt_msg_author_notified')));
+    }
+
+    public function actionShow()
+    {
+        return echoJson($this->_actionChangeStatus(BX_BASE_MOD_TEXT_STATUS_ACTIVE));
+    }
+
+    public function actionHide()
+    {
+        return echoJson($this->_actionChangeStatus(BX_BASE_MOD_TEXT_STATUS_HIDDEN));
+    }
+
+    public function actionMakeOffer()
+    {
+        $CNF = &$this->_oConfig->CNF;
+        $sJsObject = $this->_oConfig->getJsObject('entry');
+
+        $iAuthorId = bx_get_logged_profile_id();
+        $iContentId = bx_process_input(bx_get('content_id'), BX_DATA_INT);
+
+        if(empty($iAuthorId))
+            return echoJson(['code' => 1, 'eval' => 'window.open("' . BxDolPermalinks::getInstance()->permalink('page.php?i=login') . '", "_self");']);
+
+        $aContentInfo = $this->_oDb->getContentInfoById($iContentId);
+        if(empty($aContentInfo) || !is_array($aContentInfo))
+            return echoJson([]);
+
+        if(($mixedCheck = $this->checkAllowedMakeOffer($aContentInfo)) !== CHECK_ACTION_RESULT_ALLOWED)
+            return echoJson(['code' => 2, 'msg' => $mixedCheck]);
+
+        $aOffer = $this->_oDb->getOffersBy([
+            'type' => 'content_and_author_ids', 
+            'content_id' => $iContentId, 
+            'author_id' => $iAuthorId, 
+            'status' => BX_ADS_OFFER_STATUS_AWAITING
+        ]);
+
+        if(!empty($aOffer) && is_array($aOffer))
+            return echoJson(['code' => 3, 'msg' => _t('_bx_ads_txt_err_duplicate')]);
+
+        $aOffer = $this->_oDb->getOffersBy([
+            'type' => 'content_and_author_ids', 
+            'content_id' => $iContentId, 
+            'author_id' => $iAuthorId, 
+            'status' => BX_ADS_OFFER_STATUS_ACCEPTED
+        ]);
+
+        if(!empty($aOffer) && is_array($aOffer))
+            return echoJson(['code' => 4, 'msg' => _t('_bx_ads_txt_err_offer_accepted')]);
+
+        $oForm = BxDolForm::getObjectInstance($CNF['OBJECT_FORM_OFFER'], $CNF['OBJECT_FORM_OFFER_DISPLAY_ADD']);
+        $oForm->aFormAttrs['action'] = BX_DOL_URL_ROOT . bx_append_url_params($this->_oConfig->getBaseUri() . 'make_offer', ['content_id' => $iContentId]);
+        $oForm->initChecker();
+        if($oForm->isSubmittedAndValid()) {
+            $iQuantity = (int)$oForm->getCleanValue($CNF['FIELD_OFR_QUANTITY']);
+            $iQuantityAvailable = $this->getAvailableQuantity($aContentInfo);
+            if($iQuantity > $iQuantityAvailable)
+                return echoJson(['code' => 5, 'msg' => _t('_bx_ads_txt_err_offer_wrong_quantity', $iQuantityAvailable)]);
+
+            $aValToAdd = ['content_id' => $iContentId, 'author_id' => $iAuthorId];
+
+            if(($iId = (int)$oForm->insert($aValToAdd)) != 0) {
+                $this->checkAllowedMakeOffer($aContentInfo, true);
+
+                $this->onOfferAdded($iId, $aResult);
+
+                $aResult = ['code' => 0, 'msg' => _t('_bx_ads_txt_msg_offer_added'), 'eval' => $sJsObject . '.onMakeOffer(oData);', 'id' => $iId];
+            }
+            else
+                $aResult = ['code' => 6, 'msg' => _t('_bx_ads_txt_err_cannot_perform_action')];
+
+            return echoJson($aResult);
+        }
+
+        $sContent = BxTemplFunctions::getInstance()->transBox($this->_oConfig->getHtmlIds('offer_popup'), $this->_oTemplate->parseHtmlByName('offer_popup.html', array(
+            'form_id' => $oForm->getId(),
+            'form' => $oForm->getCode(true)
+        )));
+
+        return echoJson(array('popup' => array('html' => $sContent, 'options' => array('closeOnOuterClick' => false, 'removeOnClose' => true))));
+    }
+
+    public function actionViewOffer()
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        $iAuthorId = bx_get_logged_profile_id();
+        $iOfferId = bx_process_input(bx_get('id'), BX_DATA_INT);
+
+        $aOffer = $this->_oDb->getOffersBy(array('type' => 'id', 'id' => $iOfferId));
+        if(empty($aOffer) || !is_array($aOffer))
+            return echoJson(array());
+        
+        $oForm = BxDolForm::getObjectInstance($CNF['OBJECT_FORM_OFFER'], $CNF['OBJECT_FORM_OFFER_DISPLAY_VIEW']);
+        $oForm->initChecker($aOffer);
+
+        $sContent = BxTemplFunctions::getInstance()->transBox($this->_oConfig->getHtmlIds('offer_popup'), $this->_oTemplate->parseHtmlByName('offer_popup.html', array(
+            'form_id' => $oForm->getId(),
+            'form' => $oForm->getCode(true)
+        )));
+
+        return echoJson(array('popup' => array('html' => $sContent, 'options' => array('closeOnOuterClick' => true, 'removeOnClose' => true))));
+    }
+
+    public function actionAcceptOffer()
+    {
+        $iId = bx_process_input(bx_get('id'), BX_DATA_INT);
+
+        if(($mixedResult = $this->offerAccept($iId)) !== true)
+            return echoJson(['msg' => $mixedResult !== false ? $mixedResult : _t('_bx_ads_txt_err_cannot_perform_action')]);
+
+        return echoJson(['msg' => _t('_bx_ads_txt_msg_offer_accepted'), 'reload' => 1]);
+    }
+
+    public function actionDeclineOffer()
+    {
+        $iId = bx_process_input(bx_get('id'), BX_DATA_INT);
+
+        if(!$this->offerDecline($iId))
+            return echoJson(array('msg' => _t('_bx_ads_txt_err_cannot_perform_action')));
+
+        return echoJson(array('msg' => _t('_bx_ads_txt_msg_offer_declined'), 'reload' => 1));
+    }
+
+    public function actionCancelOffer()
+    {
+        $iId = bx_process_input(bx_get('id'), BX_DATA_INT);
+
+        if(!$this->offerCancel($iId))
+            return echoJson(['msg' => _t('_bx_ads_txt_err_cannot_perform_action')]);
+
+        return echoJson(['msg' => _t('_bx_ads_txt_msg_offer_canceled'), 'reload' => 1]);
+    }
+
+    public function actionPayOffer()
+    {
+        $iId = bx_process_input(bx_get('id'), BX_DATA_INT);
+
+        if(($mixedResult = $this->offerPay($iId)) !== false)
+            return echoJson($mixedResult);
+
+        return echoJson(array('msg' => _t('_bx_ads_txt_err_cannot_perform_action')));     
+    }
+
+    public function actionShipped()
+    {
+        return echoJson($this->_actionMarkAs('shipped'));
+    }
+
+    public function actionReceived()
+    {
+        return echoJson($this->_actionMarkAs('received'));
+    }
+
+    public function actionRegisterImpression($iId)
+    {
+        echoJson($this->serviceRegisterImpression($iId));
+    }
+
+    public function actionRegisterClick($iId)
+    {
+        echoJson($this->serviceRegisterClick($iId));
+    }
+
+    public function serviceGetSafeServices()
+    {
+        return array_merge(parent::serviceGetSafeServices(), [
+            'IsSourcesAvaliable' => '',
+            'LoadEntryFromSource' => '',
+            'LoadEntriesFromSourceByTerm' => '',
+            'EntityReviews' => '',
+            'EntityReviewsRating' => '',
+            'CategoriesList' => '',
+            'BrowseCategory' => '',
+            'RegisterImpression' => '',
+            'RegisterClick' => '',
+            'BlockSourcesDetails' => '',
+            'GetSourceData' => '',
+        ]);
+    }
+
+    public function serviceRegisterImpression($iId)
+    {
+        return ['code' => $this->_oDb->updatePromotionTracker($iId, 'impressions') ? 0 : 1];
+    }
+    
+    public function serviceRegisterClick($iId)
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        if(!$this->_oDb->updatePromotionTracker($iId, 'clicks'))
+            return ['code' => 1];
+
+        $sUrl = '';
+        if($this->_oConfig->isSources())  {
+            $aEntry = $this->_oDb->getContentInfoById($iId);
+            if(!empty($aEntry) && is_array($aEntry) && !empty($aEntry[$CNF['FIELD_URL']]))
+                $sUrl = $aEntry[$CNF['FIELD_URL']];
+        }
+
+        return [
+            'code' => 0,
+            'redirect' => !empty($sUrl) ? $sUrl : $this->_oConfig->getViewEntryUrl($iId)
+        ];
+    }
+
+    public function serviceCheckName($sTitle, $iId = 0)
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+    	if(empty($sTitle))
+            return array();
+
+        $sName = '';
+        if(!empty($iId)) {
+            $aEntry = $this->_oDb->getContentInfoById($iId); 
+            if(strcmp($sTitle, $aEntry[$CNF['FIELD_NAME']]) == 0) 
+                $sName = $sTitle;
+        }
+
+        return array(
+            'title' => $sTitle,
+            'name' => !empty($sName) ? $sName : $this->_oConfig->getEntryName($sTitle, $iId)
+    	);
+    }
+
+    public function serviceUpdateCategoriesStats($mixedContentInfo = false)
+    {
+        $aContentInfo = [];
+        if(!empty($mixedContentInfo))
+            $aContentInfo = !is_array($mixedContentInfo) ? $this->_oDb->getContentInfoById((int)$mixedContentInfo) : $mixedContentInfo;
+
+        $iCategoryId = 0;
+        if($aContentInfo && !empty($aContentInfo['category']))
+            $iCategoryId = (int)$aContentInfo['category'];
+
+        return $this->serviceUpdateCategoriesStatsByCategory($iCategoryId);
+    }
+
+    public function serviceUpdateCategoriesStatsByCategory($iCategoryId = 0)
+    {
+        $aParams = ['type' => 'collect_stats'];
+        if($iCategoryId)
+            $aParams['category_id'] = (int)$iCategoryId;
+
+        $aStats = $this->_oDb->getCategories($aParams);
+        if(empty($aStats) || !is_array($aStats))
+            return true;
+
+        $iUpdated = 0;
+        foreach($aStats as $aStat)
+            if($this->_oDb->updateCategory(array('items' => $aStat['count']), array('id' => $aStat['id'])))
+                $iUpdated++;
+
+        return count($aStats) == $iUpdated;
+    }
+
+    public function serviceGetCategoryOptions($iParentId, $bPleaseSelect = false)
+    {
+        $aValues = array();
+        if($bPleaseSelect)
+            $aValues[] = array('key' => '', 'value' => _t('_sys_please_select'));
+
+        $this->_getCategoryOptions($iParentId, $aValues);
+
+        return $aValues;
+    }
+
+    public function serviceGetSearchableFields($aInputsAdd = array())
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        $aResult = parent::serviceGetSearchableFields(array_merge($aInputsAdd, $this->_getSearchableFields()));
+        unset($aResult[$CNF['FIELD_NOTES_PURCHASED']]);
+        unset($aResult[$CNF['FIELD_CATEGORY_VIEW']], $aResult[$CNF['FIELD_CATEGORY_SELECT']]);
+        unset($aResult[$CNF['FIELD_PRICE']], $aResult[$CNF['FIELD_YEAR']]);
+
+        return $aResult;
+    }
+
+    public function serviceGetSearchableFieldsExtended($aInputsAdd = array())
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        $aInputsAdd = array_merge($aInputsAdd, $this->_getSearchableFields());
+
+        if(isset($aInputsAdd[$CNF['FIELD_CATEGORY']])) {
+            $aInputsAdd[$CNF['FIELD_CATEGORY']]['type'] = 'select';
+            $aInputsAdd[$CNF['FIELD_CATEGORY']]['values_src'] = BxDolService::getSerializedService($this->_oConfig->getName(), 'get_category_options', array(0));
+        }
+
+        if(isset($aInputsAdd[$CNF['FIELD_PRICE']])) {
+            $aInputsAdd[$CNF['FIELD_PRICE']]['search_type'] = 'text_range';
+            $aInputsAdd[$CNF['FIELD_PRICE']]['search_operator'] = 'between';
+        }
+
+        if(isset($aInputsAdd[$CNF['FIELD_YEAR']])) {
+            $aInputsAdd[$CNF['FIELD_YEAR']]['search_type'] = 'text_range';
+            $aInputsAdd[$CNF['FIELD_YEAR']]['search_operator'] = 'between';
+        }
+
+        return parent::serviceGetSearchableFieldsExtended($aInputsAdd);
+    }
+
+    /**
+     * Mark an ad as shipped/received by seller/bauer accordingly.
+     * @param type $sAction - shipped/received action.
+     * @param type $iContentId - an ad the action will be performed with.
+     * @param integer $iProfileSrc - profile, who performed the action.
+     * @param integer $iProfileDst - profile, the action is pointed on.
+     * @return boolean - true or a string value with error message.
+     */
+    public function serviceMarkAs($sAction, $iContentId, $iProfileSrc = 0, $iProfileDst = 0)
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        if(!$iProfileSrc)
+            $iProfileSrc = bx_get_logged_profile_id();
+
+        $sTxtError = '_bx_ads_txt_err_cannot_perform_action';
+        $aContentInfo = $this->_oDb->getContentInfoById($iContentId);
+
+        $sMethodCheck = 'checkAllowedMark' . bx_gen_method_name($sAction) . 'ForProfile';
+        if(!method_exists($this, $sMethodCheck))
+            return _t($sTxtError);
+
+        if(($mixedCheckResult = $this->$sMethodCheck($aContentInfo, false, $iProfileSrc)) !== CHECK_ACTION_RESULT_ALLOWED)
+            return $mixedCheckResult;
+
+        if((int)$this->_oDb->updateEntriesBy(array($CNF['FIELD_' . strtoupper($sAction)] => time()), array($CNF['FIELD_ID'] => $iContentId)) == 0)
+            return _t($sTxtError);
+
+        $this->$sMethodCheck($aContentInfo, true, $iProfileSrc);
+
+        $sMethodOnResult = 'on' . bx_gen_method_name($sAction);
+        if(method_exists($this, $sMethodOnResult))
+            $this->$sMethodOnResult($aContentInfo, $iProfileSrc, $iProfileDst);        
+
+        return true;
+    }
+
+    public function serviceEntityCreate ($sParams = false)
+    {
+        $iCategory = is_numeric($sParams) ? (int)$sParams : 0;
+
+        if(($sDisplay = $this->getCategoryDisplay('add', $iCategory)) !== false) {
+            if(empty($sParams) || !is_array($sParams))
+                $sParams = array();
+
+            $sParams['display'] = $sDisplay;
+        }
+
+        if($iCategory)
+            BxDolSession::getInstance()->setValue($sDisplay . '_category', $iCategory);
+
+        return parent::serviceEntityCreate($sParams);
+    }
+    
+    public function serviceEntityEditBudget ($iContentId = 0, $sDisplay = false)
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        return parent::serviceEntityEdit($iContentId, $CNF['OBJECT_FORM_ENTRY_DISPLAY_EDIT_BUDGET']);
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_ads Ads 
+     * @subsection bx_ads-page_blocks Page Blocks
+     * @subsubsection bx_ads-entity_reviews entity_reviews
+     * 
+     * @code bx_srv('bx_ads', 'entity_reviews', [...]); @endcode
+     * 
+     * Get reviews for particular content
+     * @param $iContentId content ID
+     * 
+     * @see BxAdsModule::serviceEntityReviews
+     */
+    /** 
+     * @ref bx_ads-entity_reviews "entity_reviews"
+     */
+    public function serviceEntityReviews($iContentId = 0)
+    {
+        $CNF = &$this->_oConfig->CNF;
+        if(empty($CNF['OBJECT_REVIEWS']))
+            return false;
+
+        return $this->_entityComments($CNF['OBJECT_REVIEWS'], $iContentId);
+    }
+    
+    /**
+     * @page service Service Calls
+     * @section bx_ads Ads 
+     * @subsection bx_ads-page_blocks Page Blocks
+     * @subsubsection bx_ads-entity_reviews_rating entity_reviews_rating
+     * 
+     * @code bx_srv('bx_ads', 'entity_reviews_rating', [...]); @endcode
+     * 
+     * Get reviews rating for particular content
+     * @param $iContentId content ID
+     * 
+     * @see BxAdsModule::serviceEntityReviewsRating
+     */
+    /** 
+     * @ref bx_ads-entity_reviews_rating "entity_reviews_rating"
+     */
+    public function serviceEntityReviewsRating($iContentId = 0)
+    {
+        $CNF = &$this->_oConfig->CNF;
+        if(empty($CNF['OBJECT_REVIEWS']))
+            return false;
+
+        if(!$iContentId)
+            $iContentId = bx_process_input(bx_get('id'), BX_DATA_INT);
+
+        if(!$iContentId)
+            return false;
+
+        $oCmts = BxDolCmts::getObjectInstance($CNF['OBJECT_REVIEWS'], $iContentId);
+        if (!$oCmts || !$oCmts->isEnabled())
+            return false;
+
+        return $oCmts->getRatingBlock(array('in_designbox' => false));
+    }
+
+    public function serviceEntityPromotionGrowth($iContentId = 0)
+    {
+        return $this->_serviceTemplateFunc('entryPromotionGrowth', $iContentId);
+    }
+
+    public function serviceEntityPromotionSummary($iContentId = 0)
+    {
+        return $this->_serviceTemplateFunc('entryPromotionSummary', $iContentId);
+    }
+    
+    public function serviceEntityPromotionRoi($iContentId = 0)
+    {
+        return $this->_serviceTemplateFunc('entryPromotionRoi', $iContentId);
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_ads Ads 
+     * @subsection bx_ads-page_blocks Page Blocks
+     * @subsubsection bx_ads-categories_list categories_list
+     * 
+     * @code bx_srv('bx_ads', 'categories_list', [...]); @endcode
+     * 
+     * Get reviews rating for particular content
+     * @param $aParams additional params array, such as 'show_empty'
+     * 
+     * @see BxAdsModule::serviceCategoriesList
+     */
+    /** 
+     * @ref bx_ads-categories_list "categories_list"
+     */
+    public function serviceCategoriesList($aParams = array())
+    {
+        if(!isset($aParams['show_empty']))
+            $aParams['show_empty'] = true;
+
+        return $this->_oTemplate->categoriesList($aParams);
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_ads Ads 
+     * @subsection bx_ads-browse Browse
+     * @subsubsection bx_ads-browse_category browse_category
+     * 
+     * @code bx_srv('bx_ads', 'browse_category', [...]); @endcode
+     * 
+     * Get reviews rating for particular content
+     * @param $iCategoryId category ID
+     * @param $aParams additional params array, such as empty_message, ajax_paginate, etc
+     * 
+     * @see BxAdsModule::serviceBrowseCategory
+     */
+    /**
+     * @ref bx_ads-browse_category "browse_category"
+     */
+    public function serviceBrowseCategory($sUnitView = false, $bEmptyMessage = true, $bAjaxPaginate = true, $aParams = [])
+    {
+        $mixedResult = parent::serviceBrowseCategory($sUnitView, $bEmptyMessage, $bAjaxPaginate, $aParams);
+        if(empty($mixedResult['content']))
+            return $mixedResult;
+
+        $aCategory = $this->_oDb->getCategories([
+            'type' => 'id', 
+            'id' => !empty($aParams['category']) ? (int)$aParams['category'] : bx_process_input(bx_get('category'), BX_DATA_INT)
+        ]);
+
+        if(!empty($aCategory['title']))
+            $mixedResult['title'] = _t('_bx_ads_page_block_title_entries_by_category_mask', _t($aCategory['title']));
+
+        return $mixedResult;
+    }
+
+    public function serviceGetTimelinePost($aEvent, $aBrowseParams = [])
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        $mixedResult = parent::serviceGetTimelinePost($aEvent, $aBrowseParams);
+        if(!$mixedResult)
+            return $mixedResult;
+        
+        $aContentInfo = $this->_oDb->getContentInfoById($aEvent['object_id']);
+
+        if($this->_oConfig->isSources() && !empty($aContentInfo[$CNF['FIELD_URL']]))
+            $mixedResult['url'] = $aContentInfo[$CNF['FIELD_URL']];
+
+        return $mixedResult;
+    }
+
+    public function serviceGetNotificationsData()
+    {
+        $sModule = $this->_aModule['name'];
+
+        $sEventPrivacy = $sModule . '_allow_view_event_to';
+        if(BxDolPrivacy::getObjectInstance($sEventPrivacy) === false)
+            $sEventPrivacy = '';
+
+        $aResult = parent::serviceGetNotificationsData();
+        $aResult['handlers'] = array_merge($aResult['handlers'], array(
+            array('group' => $sModule . '_interest', 'type' => 'insert', 'alert_unit' => $sModule, 'alert_action' => 'doInterest', 'module_name' => $sModule, 'module_method' => 'get_notifications_interest', 'module_class' => 'Module', 'module_event_privacy' => $sEventPrivacy),
+            array('group' => $sModule . '_paid', 'type' => 'insert', 'alert_unit' => $sModule, 'alert_action' => 'license_register', 'module_name' => $sModule, 'module_method' => 'get_notifications_license_register', 'module_class' => 'Module', 'module_event_privacy' => $sEventPrivacy),
+            //---> To Buyer
+            array('group' => $sModule . '_shipped', 'type' => 'insert', 'alert_unit' => $sModule, 'alert_action' => 'shipped', 'module_name' => $sModule, 'module_method' => 'get_notifications_shipped', 'module_class' => 'Module', 'module_event_privacy' => $sEventPrivacy),
+            //<---
+            array('group' => $sModule . '_received', 'type' => 'insert', 'alert_unit' => $sModule, 'alert_action' => 'received', 'module_name' => $sModule, 'module_method' => 'get_notifications_received', 'module_class' => 'Module', 'module_event_privacy' => $sEventPrivacy),
+
+            array('group' => $sModule . '_offer_added', 'type' => 'insert', 'alert_unit' => $sModule, 'alert_action' => 'offer_added', 'module_name' => $sModule, 'module_method' => 'get_notifications_offer_added', 'module_class' => 'Module', 'module_event_privacy' => $sEventPrivacy),
+            //---> To Offerer
+            array('group' => $sModule . '_offer_accepted', 'type' => 'insert', 'alert_unit' => $sModule, 'alert_action' => 'offer_accepted', 'module_name' => $sModule, 'module_method' => 'get_notifications_offer_accepted', 'module_class' => 'Module', 'module_event_privacy' => $sEventPrivacy),
+            array('group' => $sModule . '_offer_declined', 'type' => 'insert', 'alert_unit' => $sModule, 'alert_action' => 'offer_declined', 'module_name' => $sModule, 'module_method' => 'get_notifications_offer_declined', 'module_class' => 'Module', 'module_event_privacy' => $sEventPrivacy),
+            //<---
+            array('group' => $sModule . '_offer_canceled', 'type' => 'insert', 'alert_unit' => $sModule, 'alert_action' => 'offer_canceled', 'module_name' => $sModule, 'module_method' => 'get_notifications_offer_canceled', 'module_class' => 'Module', 'module_event_privacy' => $sEventPrivacy)
+        ));
+
+        $aResult['settings'] = array_merge($aResult['settings'], array(
+            array('group' => 'interest', 'unit' => $sModule, 'action' => 'doInterest', 'types' => array('personal')),
+
+            array('group' => 'usage', 'unit' => $sModule, 'action' => 'license_register', 'types' => array('personal')),
+            array('group' => 'usage', 'unit' => $sModule, 'action' => 'shipped', 'types' => array('personal')),
+            array('group' => 'usage', 'unit' => $sModule, 'action' => 'received', 'types' => array('personal')),
+            array('group' => 'usage', 'unit' => $sModule, 'action' => 'offer_added', 'types' => array('personal')),
+            array('group' => 'usage', 'unit' => $sModule, 'action' => 'offer_accepted', 'types' => array('personal')),
+            array('group' => 'usage', 'unit' => $sModule, 'action' => 'offer_declined', 'types' => array('personal')),
+            array('group' => 'usage', 'unit' => $sModule, 'action' => 'offer_canceled', 'types' => array('personal')),
+        ));
+
+        $aResult['alerts'] = array_merge($aResult['alerts'], array(
+            array('unit' => $sModule, 'action' => 'doInterest'),
+            array('unit' => $sModule, 'action' => 'license_register'),
+            array('unit' => $sModule, 'action' => 'shipped'),
+            array('unit' => $sModule, 'action' => 'received'),
+            array('unit' => $sModule, 'action' => 'offer_added'),
+            array('unit' => $sModule, 'action' => 'offer_accepted'),
+            array('unit' => $sModule, 'action' => 'offer_declined'),
+            array('unit' => $sModule, 'action' => 'offer_canceled'),
+        ));
+
+        return $aResult; 
+    }
+
+    public function serviceGetNotificationsInsertData($oAlert, $aHandler, $aDataItems)
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        $aResult = [];
+        switch($oAlert->sAction) {
+            case 'license_register':
+                $aContentInfo = $this->_oDb->getContentInfoById($oAlert->aExtras['product_id']);
+                if(empty($aContentInfo) || !is_array($aContentInfo)) {
+                    $aResult = $aDataItems;
+                    break;
+                }
+
+                foreach($aDataItems as $aDataItem) {
+                    $aDataItem = array_merge($aDataItem, [
+                        'owner_id' => $oAlert->aExtras['profile_id'],
+                        'object_id' => $aContentInfo[$CNF['FIELD_ID']],
+                        'object_owner_id' => $aContentInfo[$CNF['FIELD_AUTHOR']],
+                        'object_privacy_view' => BX_DOL_PG_ALL
+                    ]);
+
+                    $aResult[] = $aDataItem;
+                }
+                break;
+
+            case 'shipped':
+                foreach($aDataItems as $aDataItem) {
+                    $aLicense = $this->_oDb->getLicense(['type' => 'entry_id', 'entry_id' => $aDataItem['object_id'], 'newest' => true]);
+                    if(!empty($aLicense) && is_array($aLicense))
+                        $aDataItem['object_owner_id'] = $aLicense['profile_id'];
+
+                    $aResult[] = $aDataItem;
+                }
+                break;
+
+            case 'offer_added':
+            case 'offer_canceled':
+                foreach($aDataItems as $aDataItem) {
+                    $aDataItem['object_owner_id'] = $oAlert->aExtras['object_author_id'];
+
+                    $aResult[] = $aDataItem;
+                }
+                break;
+
+            case 'offer_accepted':
+            case 'offer_declined':
+                foreach($aDataItems as $aDataItem) {
+                    $aDataItem['object_owner_id'] = $oAlert->aExtras['offer_author_id'];
+
+                    $aResult[] = $aDataItem;
+                }
+                break;
+
+            default:
+                $aResult = $aDataItems;
+        }
+
+        return $aResult;
+    }
+
+    public function serviceGetNotificationsInterest($aEvent)
+    {
+    	$CNF = &$this->_oConfig->CNF;
+
+    	$iContentId = (int)$aEvent['object_id'];
+    	$aContentInfo = $this->_oDb->getContentInfoById($iContentId);
+        if(empty($aContentInfo) || !is_array($aContentInfo))
+            return [];
+
+        $iInterestedId = (int)$aEvent['subobject_id'];
+        $aInterestedInfo = $this->_oDb->getInterested(['type' => 'id', 'id' => $iInterestedId]);
+        if(empty($aInterestedInfo) || !is_array($aInterestedInfo))
+            return [];
+
+        if(($oInterestedProfile = BxDolProfile::getInstance($aInterestedInfo['profile_id'])) !== false)
+            $sEntryUrl = $oInterestedProfile->getUrl();
+        else
+            $sEntryUrl = bx_absolute_url(BxDolPermalinks::getInstance()->permalink('page.php?i=' . $CNF['URI_VIEW_ENTRY'] . '&id=' . $iContentId), '{bx_url_root}');
+
+        return [
+            'entry_sample' => $CNF['T']['txt_sample_single'],
+            'entry_url' => $sEntryUrl,
+            'entry_caption' => $aContentInfo[$CNF['FIELD_TITLE']],
+            'entry_author' => $aContentInfo[$CNF['FIELD_AUTHOR']],
+            'subentry_sample' => $CNF['T']['txt_sample_interest_single'],
+            'subentry_url' => '',
+            'lang_key' => '_bx_ads_txt_ntfs_subobject_interested', //may be empty or not specified. In this case the default one from Notification module will be used.
+        ];
+    }
+
+    public function serviceGetNotificationsLicenseRegister($aEvent)
+    {
+        return $this->_serviceGetNotificationsByEntryAndAction($aEvent, 'license_register');
+    }
+
+    public function serviceGetNotificationsShipped($aEvent)
+    {
+        $aResult = $this->_serviceGetNotificationsByEntryAndAction($aEvent, 'shipped');
+        $aResult['entry_author'] = $aEvent['object_owner_id'];
+
+        return $aResult;
+    }
+
+    public function serviceGetNotificationsReceived($aEvent)
+    {
+        return $this->_serviceGetNotificationsByEntryAndAction($aEvent, 'received');
+    }
+
+    public function serviceGetNotificationsOfferAdded($aEvent)
+    {
+        return $this->_serviceGetNotificationsByOfferAndAction($aEvent, 'offer_added');
+    }
+
+    public function serviceGetNotificationsOfferAccepted($aEvent)
+    {
+        $aResult = $this->_serviceGetNotificationsByOfferAndAction($aEvent, 'offer_accepted');
+        $aResult['entry_author'] = $aEvent['object_owner_id'];
+
+        return $aResult;
+    }
+
+    public function serviceGetNotificationsOfferDeclined($aEvent)
+    {
+        $aResult = $this->_serviceGetNotificationsByOfferAndAction($aEvent, 'offer_declined');
+        $aResult['entry_author'] = $aEvent['object_owner_id'];
+
+        return $aResult;
+    }
+
+    public function serviceGetNotificationsOfferCanceled($aEvent)
+    {
+        return $this->_serviceGetNotificationsByOfferAndAction($aEvent, 'offer_canceled');
+    }
+
+    protected function _serviceGetNotificationsByEntryAndAction($aEvent, $sAction)
+    {
+    	$CNF = &$this->_oConfig->CNF;
+
+    	$iContentId = (int)$aEvent['object_id'];
+    	$aContentInfo = $this->_oDb->getContentInfoById($iContentId);
+        if(empty($aContentInfo) || !is_array($aContentInfo))
+            return array();
+
+        $sEntryUrl = bx_absolute_url(BxDolPermalinks::getInstance()->permalink('page.php?i=' . $CNF['URI_VIEW_ENTRY'] . '&id=' . $iContentId), '{bx_url_root}');
+
+        return array(
+            'entry_sample' => $CNF['T']['txt_sample_single'],
+            'entry_url' => $sEntryUrl,
+            'entry_caption' => $aContentInfo[$CNF['FIELD_TITLE']],
+            'entry_author' => $aContentInfo[$CNF['FIELD_AUTHOR']],
+            'subentry_sample' => '',
+            'subentry_url' => '',
+            'lang_key' => '_bx_ads_txt_ntfs_object_' . $sAction, //may be empty or not specified. In this case the default one from Notification module will be used.
+        );
+    }
+
+    protected function _serviceGetNotificationsByOfferAndAction($aEvent, $sAction)
+    {
+    	$CNF = &$this->_oConfig->CNF;
+
+    	$iOfferId = (int)$aEvent['object_id'];
+    	$aOfferInfo = $this->_oDb->getOffersBy(['type' => 'id', 'id' => $iOfferId]);
+        if(empty($aOfferInfo) || !is_array($aOfferInfo))
+            return array();
+
+        $iContentId = $aOfferInfo[$CNF['FIELD_OFR_CONTENT']];
+        $aContentInfo = $this->_oDb->getContentInfoById($iContentId);
+        if(empty($aContentInfo) || !is_array($aContentInfo))
+            return array();
+
+        $sEntryUrl = bx_absolute_url(BxDolPermalinks::getInstance()->permalink('page.php?i=' . $CNF['URI_VIEW_ENTRY'] . '&id=' . $iContentId), '{bx_url_root}');
+
+        return array(
+            'object_id' => $iContentId,
+            'entry_sample' => $CNF['T']['txt_sample_single'],
+            'entry_url' => $sEntryUrl,
+            'entry_caption' => $aContentInfo[$CNF['FIELD_TITLE']],
+            'entry_author' => $aContentInfo[$CNF['FIELD_AUTHOR']],
+            'subentry_sample' => '',
+            'subentry_url' => '',
+            'lang_key' => '_bx_ads_txt_ntfs_' . $sAction, //may be empty or not specified. In this case the default one from Notification module will be used.
+        );
+    }
+    
+    /**
+     * @page service Service Calls
+     * @section bx_ads Ads
+     * @subsection bx_ads-page_blocks Page Blocks
+     * @subsubsection bx_ads-block_licenses block_licenses
+     * 
+     * @code bx_srv('bx_ads', 'block_licenses', [...]); @endcode
+     * 
+     * Get page block with a list of licenses purchased by currently logged member.
+     *
+     * @return an array describing a block to display on the site or false if there is no enough input data. All necessary CSS and JS files are automatically added to the HEAD section of the site HTML.
+     * 
+     * @see BxAdsModule::serviceBlockLicenses
+     */
+    /** 
+     * @ref bx_ads-block_licenses "block_licenses"
+     */
+    public function serviceBlockLicenses() 
+    {
+        return $this->_getBlockLicenses();
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_ads Ads
+     * @subsection bx_ads-page_blocks Page Blocks
+     * @subsubsection bx_ads-block_licenses_administration block_licenses_administration
+     * 
+     * @code bx_srv('bx_ads', 'block_licenses_administration', [...]); @endcode
+     * 
+     * Get page block with a list of all licenses. It's needed for moderators/administrators.
+     *
+     * @return an array describing a block to display on the site or false if there is no enough input data. All necessary CSS and JS files are automatically added to the HEAD section of the site HTML.
+     * 
+     * @see BxAdsModule::serviceBlockLicensesAdministration
+     */
+    /** 
+     * @ref bx_ads-block_licenses "block_licenses"
+     */
+    public function serviceBlockLicensesAdministration() 
+    {
+        return $this->_getBlockLicenses('administration');
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_ads Ads
+     * @subsection bx_ads-page_blocks Page Blocks
+     * @subsubsection bx_ads-block_licenses_note block_licenses_note
+     * 
+     * @code bx_srv('bx_ads', 'block_licenses_note', [...]); @endcode
+     * 
+     * Get page block with a notice for licenses usage.
+     *
+     * @return HTML string with block content to display on the site.
+     * 
+     * @see BxAdsModule::serviceBlockLicensesNote
+     */
+    /** 
+     * @ref bx_ads-block_licenses_note "block_licenses_note"
+     */
+    public function serviceBlockLicensesNote()
+    {
+        return MsgBox(_t('_bx_ads_page_block_content_licenses_note'));
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_ads Ads
+     * @subsection bx_ads-payments Payments
+     * @subsubsection bx_ads-get_payment_data get_payment_data
+     * 
+     * @code bx_srv('bx_ads', 'get_payment_data', [...]); @endcode
+     * 
+     * Get an array with module's description. Is needed for payments processing module.
+     * 
+     * @return an array with module's description.
+     * 
+     * @see BxAdsModule::serviceGetPaymentData
+     */
+    /** 
+     * @ref bx_ads-get_payment_data "get_payment_data"
+     */
+    public function serviceGetPaymentData()
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        $oPermalink = BxDolPermalinks::getInstance();
+
+        $aResult = $this->_aModule;
+        $aResult['url_browse_order_common'] = bx_absolute_url($oPermalink->permalink($CNF['URL_LICENSES_COMMON'], array('filter' => '{order}')));
+        $aResult['url_browse_order_administration'] = bx_absolute_url($oPermalink->permalink($CNF['URL_LICENSES_ADMINISTRATION'], array('filter' => '{order}')));
+
+        return $aResult;
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_ads Ads
+     * @subsection bx_ads-payments Payments
+     * @subsubsection bx_ads-get_cart_item get_cart_item
+     * 
+     * @code bx_srv('bx_ads', 'get_cart_item', [...]); @endcode
+     * 
+     * Get an array with prodict's description. Is used in Shopping Cart in payments processing module.
+     * 
+     * @param $mixedItemId product's ID or Unique Name.
+     * @return an array with prodict's description. Empty array is returned if something is wrong.
+     * 
+     * @see BxAdsModule::serviceGetCartItem
+     */
+    /** 
+     * @ref bx_ads-get_cart_item "get_cart_item"
+     */
+    public function serviceGetCartItem($mixedItemId, $iClientId = 0)
+    {
+    	$CNF = &$this->_oConfig->CNF;
+
+        if(!$mixedItemId || !is_numeric($mixedItemId))
+            return [];
+
+        $aCommodity = $this->_oDb->getCommodity(['sample' => 'id_with_entry', 'id' => (int)$mixedItemId]);
+        if(empty($aCommodity) || !is_array($aCommodity))
+            return [];
+
+        $iItemId = (int)$aCommodity['id'];
+        $sItemType = $aCommodity['type'];
+
+        $iItemAuthor = 0;
+        $fItemPrice = 0;
+        switch($sItemType) {
+            case BX_ADS_COMMODITY_TYPE_PRODUCT:
+                $iItemAuthor = $aCommodity['entry_' . $CNF['FIELD_AUTHOR']];
+                $fItemPrice = (float)$aCommodity['entry_' . $CNF['FIELD_PRICE']];
+                if($this->_oConfig->isAuction() && (int)$aCommodity['entry_' . $CNF['FIELD_AUCTION']] != 0) {
+                    $aOffer = $this->_oDb->getOffersBy([
+                        'type' => 'content_and_author_ids', 
+                        'content_id' => $iItemId, 
+                        'author_id' => $iClientId,
+                        'status' => BX_ADS_OFFER_STATUS_ACCEPTED
+                    ]);
+
+                    if(!empty($aOffer) && is_array($aOffer))
+                        $fItemPrice = (float)$aOffer[$CNF['FIELD_OFR_AMOUNT']];
+                }
+                break;
+
+            case BX_ADS_COMMODITY_TYPE_PROMOTION:
+                $iItemAuthor = BxDolPayments::getInstance()->getOption('site_admin');
+                $fItemPrice = (float)$aCommodity['amount'];
+                break;
+        }
+
+        if(!$iClientId)
+            $iClientId = bx_get_logged_profile_id();
+
+        return [
+            'id' => $iItemId,
+            'author_id' => $iItemAuthor,
+            'name' => $aCommodity['entry_' . $CNF['FIELD_NAME']] . '-' . $sItemType,
+            'title' => $aCommodity['entry_' . $CNF['FIELD_TITLE']],
+            'description' => $sItemDescription = _t($CNF['T']['txt_cd_ct_' . $sItemType]),
+            'url' => bx_absolute_url(BxDolPermalinks::getInstance()->permalink('page.php?i=' . $CNF['URI_VIEW_ENTRY'], ['id' => $aCommodity['entry_' . $CNF['FIELD_ID']]])),
+            'price_single' => $fItemPrice,
+            'price_recurring' => '',
+            'period_recurring' => 0,
+            'period_unit_recurring' => '',
+            'trial_recurring' => ''
+        ];
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_ads Ads
+     * @subsection bx_ads-payments Payments
+     * @subsubsection bx_ads-get_cart_items get_cart_items
+     * 
+     * @code bx_srv('bx_ads', 'get_cart_items', [...]); @endcode
+     * 
+     * Get an array with prodicts' descriptions by seller. Is used in Manual Order Processing in payments processing module.
+     * 
+     * @param $iSellerId seller ID.
+     * @return an array with prodicts' descriptions. Empty array is returned if something is wrong or seller doesn't have any products.
+     * 
+     * @see BxAdsModule::serviceGetCartItems
+     */
+    /** 
+     * @ref bx_ads-get_cart_items "get_cart_items"
+     */
+    public function serviceGetCartItems($iSellerId)
+    {
+    	$CNF = &$this->_oConfig->CNF;
+
+        $iSellerId = (int)$iSellerId;
+        if(empty($iSellerId))
+            return [];
+
+        $aItems = $this->_oDb->getCommodity(['sample' => 'entry_author', 'author' => $iSellerId, 'type' => BX_ADS_COMMODITY_TYPE_PRODUCT]);
+
+        $aResult = [];
+        foreach($aItems as $aItem) {
+            $aItemInfo = $this->_oDb->getContentInfoById((int)$aItem['entry_id']);
+            if(empty($aItemInfo) || !is_array($aItemInfo) || $aItemInfo[$CNF['FIELD_STATUS']] != BX_BASE_MOD_TEXT_STATUS_ACTIVE || empty($aItemInfo[$CNF['FIELD_QUANTITY']]))
+                continue;
+
+            $aResult[] = $this->serviceGetCartItem($aItem['id']);
+        }
+
+        return $aResult;
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_ads Ads
+     * @subsection bx_ads-payments Payments
+     * @subsubsection bx_ads-authorize_cart_item authorize_cart_item
+     * 
+     * @code bx_srv('bx_ads', 'authorize_cart_item', [...]); @endcode
+     * 
+     * Authorize the order to process a single time payment inside the Ads module in future. Is called with payment processing module after the order was authorized there.
+     * 
+     * @param $iClientId client ID.
+     * @param $iSellerId seller ID
+     * @param $iItemId item ID.
+     * @param $iItemCount the number of purchased items.
+     * @param $sOrder order number received from payment provider (PayPal, Stripe, etc)
+     * @return an array with authorize prodict's description. Empty array is returned if something is wrong.
+     * 
+     * @see BxAdsModule::serviceAuthorizeCartItem
+     */
+    /** 
+     * @ref bx_ads-authorize_cart_item "authorize_cart_item"
+     */
+    public function serviceAuthorizeCartItem($iClientId, $iSellerId, $iItemId, $iItemCount, $sOrder)
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+    	$aItem = $this->serviceGetCartItem($iItemId);
+        if(empty($aItem) || !is_array($aItem))
+            return [];
+
+        $aCommodity = $this->_oDb->getCommodity(['sample' => 'id_with_entry', 'id' => (int)$iItemId]);
+        if(empty($aCommodity) || !is_array($aCommodity))
+            return [];
+
+        /**
+         * @hooks
+         * @hookdef hook-bx_ads-order_authorize 'bx_ads', 'order_authorize' - hook after the order was authorized with payment processing module
+         * - $unit_name - equals `bx_ads`
+         * - $action - equals `order_authorize`
+         * - $object_id - not used
+         * - $sender_id - not used
+         * - $extra_params - array of additional params with the following array keys:
+         *      - `id` - [int] commodity id 
+         *      - `type` - [string] commodity type, 'product' or 'promotion'
+         *      - `product_id` - [int] ad (entry) id the commodity is associated with
+         *      - `order` - [string] order number provided with payment processing module
+         *      - `count` - [int] number of items in order
+         * @hook @ref hook-bx_ads-order_authorize
+         */
+        bx_alert($this->getName(), 'order_authorize', 0, false, [
+            'id' => $aCommodity['id'],
+            'type' => $aCommodity['type'],
+            'product_id' => $aCommodity['entry_id'],
+            'profile_id' => $iClientId,
+            'order' => $sOrder,
+            'count' => $iItemCount
+        ]);
+
+        return $aItem;
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_ads Ads
+     * @subsection bx_ads-payments Payments
+     * @subsubsection bx_ads-register_cart_item register_cart_item
+     * 
+     * @code bx_srv('bx_ads', 'register_cart_item', [...]); @endcode
+     * 
+     * Register a processed single time payment inside the Ads module. Is called with payment processing module after the payment was registered there.
+     * 
+     * @param $iClientId client ID.
+     * @param $iSellerId seller ID
+     * @param $iItemId item ID.
+     * @param $iItemCount the number of purchased items.
+     * @param $sOrder order number received from payment provider (PayPal, Stripe, etc)
+     * @param $sLicense license number genereted with payment processing module for internal usage
+     * @return an array with purchased prodict's description. Empty array is returned if something is wrong.
+     * 
+     * @see BxAdsModule::serviceRegisterCartItem
+     */
+    /** 
+     * @ref bx_ads-register_cart_item "register_cart_item"
+     */
+    public function serviceRegisterCartItem($iClientId, $iSellerId, $iItemId, $iItemCount, $sOrder, $sLicense)
+    {
+        $aCommodity = $this->_oDb->getCommodity(['sample' => 'id', 'id' => (int)$iItemId]);
+        if(empty($aCommodity) || !is_array($aCommodity))
+            return [];
+        
+        $sMethod = '_registerCartItem' . bx_gen_method_name($aCommodity['type']);
+        if(!method_exists($this, $sMethod))
+            return [];
+
+        return $this->$sMethod($iClientId, $iSellerId, $aCommodity, $iItemCount, $sOrder, $sLicense);
+    }
+
+    protected function _registerCartItemProduct($iClientId, $iSellerId, $aCommodity, $iItemCount, $sOrder, $sLicense)
+    {
+        $CNF = &$this->_oConfig->CNF;
+        $sModule = $this->getName();
+
+    	$aItem = $this->serviceGetCartItem($aCommodity['id']);
+        if(empty($aItem) || !is_array($aItem))
+            return [];
+
+        $aEntry = $this->_oDb->getContentInfoById($aCommodity['entry_id']);
+        if(empty($aEntry) || !is_array($aEntry))
+            return [];
+
+        $iEntryId = (int)$aCommodity['entry_id'];
+        $iEntryQnt = (int)$aEntry[$CNF['FIELD_QUANTITY']];
+        if(($iEntryQnt - $iItemCount) < 0 || !$this->_oDb->registerLicense($iClientId, $iEntryId, $iItemCount, $sOrder, $sLicense))
+            return [];
+
+        $aOffer = $this->_oDb->getOffersBy([
+            'type' => 'content_and_author_ids', 
+            'content_id' => $iEntryId, 
+            'author_id' => $iClientId,
+            'status' => BX_ADS_OFFER_STATUS_ACCEPTED
+        ]);
+
+        if(!empty($aOffer) && is_array($aOffer))
+            $this->_oDb->updateOffer([$CNF['FIELD_OFR_STATUS'] => BX_ADS_OFFER_STATUS_PAID], [$CNF['FIELD_OFR_ID'] => $aOffer[$CNF['FIELD_OFR_ID']]]);
+
+        $iEntryQnt -= $iItemCount;
+        $bEntrySold = $iEntryQnt == 0;
+
+        $aUpdate = [
+            $CNF['FIELD_QUANTITY'] => $iEntryQnt
+        ];
+        if($bEntrySold)
+            $aUpdate = array_merge($aUpdate, [
+                $CNF['FIELD_STATUS'] =>  BX_ADS_STATUS_SOLD,
+                $CNF['FIELD_SOLD'] => time()
+            ]);
+
+        $this->_oDb->updateEntriesBy($aUpdate, [$CNF['FIELD_ID'] => $iEntryId]);
+
+        /**
+         * @hooks
+         * @hookdef hook-bx_ads-license_register 'bx_ads', 'license_register' - hook after the payment for an ad was processed with payment processing module
+         * - $unit_name - equals `bx_ads`
+         * - $action - equals `license_register`
+         * - $object_id - not used
+         * - $sender_id - not used
+         * - $extra_params - array of additional params with the following array keys:
+         *      - `id` - [int] commodity id 
+         *      - `type` - [string] commodity type, 'product' or 'promotion'
+         *      - `product_id` - [int] ad (entry) id the commodity is associated with
+         *      - `profile_id` - [int] client (buyer) profile id
+         *      - `order` - [string] order number provided with payment processing module
+         *      - `license` - [string] license number generated for the order
+         *      - `count` - [int] number of items in order
+         * @hook @ref hook-bx_ads-license_register
+         */
+        bx_alert($sModule, 'license_register', 0, false, [
+            'id' => $aCommodity['id'],
+            'type' => $aCommodity['type'],
+            'product_id' => $iEntryId,
+            'profile_id' => $iClientId,
+            'order' => $sOrder,
+            'license' => $sLicense,
+            'count' => $iItemCount
+        ]);
+
+        if($bEntrySold) {
+            $aParams = $this->_alertParams($aEntry);
+            
+            /**
+             * @hooks
+             * @hookdef hook-bx_ads-sold 'bx_ads', 'sold' - hook after the payment was processed with payment processing module and there is no the ad (entry) for selling anymore
+             * - $unit_name - equals `bx_ads`
+             * - $action - equals `sold`
+             * - $object_id - ad (entry) id
+             * - $sender_id - not used
+             * - $extra_params - array of additional params with the following array keys:
+             *      - `status` - [string] content status
+             *      - `status_admin` - [string] content admin status
+             *      - `privacy_view` - [int] or [string] privacy for view content action, @see BxDolPrivacy
+             *      - `cf` - [int] content's audience filter value
+             * @hook @ref hook-bx_ads-sold
+             */
+            bx_alert($sModule, 'sold', $iEntryId, false, $aParams);
+        }
+
+        $oAuthor = BxDolProfile::getInstanceMagic($aEntry[$CNF['FIELD_AUTHOR']]);
+        $oClient = BxDolProfile::getInstanceMagic($iClientId);
+        $oSeller = BxDolProfile::getInstanceMagic($iSellerId);
+        $sSellerUrl = $oSeller->getUrl();
+        $sSellerName = $oSeller->getDisplayName();
+
+        $sNote = $aEntry[$CNF['FIELD_NOTES_PURCHASED']];
+        if(empty($sNote))
+            $sNote = _t('_bx_ads_txt_purchased_note', $sSellerUrl, $sSellerName);
+
+        $sEmailTemplate = $CNF['ETEMPLATE_PURCHASED'];
+        $aEmailParams = [
+            'client_name' => $oClient->getDisplayName(),
+            'entry_name' => $aEntry[$CNF['FIELD_TITLE']],
+            'entry_url' => bx_absolute_url(BxDolPermalinks::getInstance()->permalink('page.php?i=' . $CNF['URI_VIEW_ENTRY'], ['id' => $iEntryId])),
+            'author_url' => $oAuthor->getUrl(),
+            'author_name' => $oAuthor->getDisplayName(),
+            'vendor_url' => $sSellerUrl,
+            'vendor_name' => $sSellerName,
+            'count' => (int)$iItemCount,
+            'license' => $sLicense,
+            'notes' => $sNote,
+        ];
+
+        $bCancel = false;
+        /**
+         * @hooks
+         * @hookdef hook-bx_ads-license_register_notif 'bx_ads', 'license_register_notif' - hook before sending a notification about new license. Allows to override a notification message or cancel the notification
+         * - $unit_name - equals `bx_ads`
+         * - $action - equals `license_register_notif`
+         * - $object_id - not used
+         * - $sender_id - not used
+         * - $extra_params - array of additional params with the following array keys:
+         *      - `entry_id` - [int] ad (entry) id
+         *      - `order` - [string] order number
+         *      - `recipient_id` - [int] by ref, client (buyer) profile id, can be overridden in hook processing
+         *      - `email_template` - [string] by ref, email template name, can be overridden in hook processing
+         *      - `email_params` - [array] by ref, email params array as key&value pairs, which will be parsed in email subject/body, can be overridden in hook processing
+         *      - `cancel` - [boolean] by ref, if email sending should be canceled or not, can be overridden in hook processing
+         * @hook @ref hook-bx_ads-license_register_notif
+         */
+        bx_alert($sModule, 'license_register_notif', 0, false, [
+            'entry_id' => $iEntryId,
+            'order' => $sOrder,
+            'recipient_id' => &$iClientId,
+            'email_template' => &$sEmailTemplate,
+            'email_params' => &$aEmailParams,
+            'cancel' => &$bCancel
+        ]);
+
+        if(!$bCancel)
+            sendMailTemplate($sEmailTemplate, 0, $iClientId, $aEmailParams);
+
+        return $aItem;
+    }
+    
+    protected function _registerCartItemPromotion($iClientId, $iSellerId, $aCommodity, $iItemCount, $sOrder, $sLicense)
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        $aItem = $this->serviceGetCartItem($aCommodity['id']);
+        if(empty($aItem) || !is_array($aItem))
+            return [];
+
+        $aEntry = $this->_oDb->getContentInfoById($aCommodity['entry_id']);
+        if(empty($aEntry) || !is_array($aEntry))
+            return [];
+
+        $iEntryId = (int)$aCommodity['entry_id'];
+        if(!$this->_oDb->registerPromotion($aEntry[$CNF['FIELD_AUTHOR']], $aCommodity['id'], $iEntryId, $aCommodity['amount'], $sOrder, $sLicense))
+            return [];
+
+        if($aEntry[$CNF['FIELD_STATUS_ADMIN']] == BX_ADS_STATUS_ADMIN_UNPAID) {
+            $aUpdate[$CNF['FIELD_STATUS_ADMIN']] = BX_BASE_MOD_GENERAL_STATUS_ACTIVE;
+            if(!$this->_isModerator() && !$this->_oConfig->isAutoApproveEnabled())
+                $aUpdate[$CNF['FIELD_STATUS_ADMIN']] = BX_BASE_MOD_GENERAL_STATUS_PENDING;
+            
+            $this->_oDb->updateEntriesBy($aUpdate, [$CNF['FIELD_ID'] => $iEntryId]);
+        }
+
+        /**
+         * @hooks
+         * @hookdef hook-bx_ads-promotion_register 'bx_ads', 'promotion_register' - hook after the payment for promotion was processed with payment processing module
+         * - $unit_name - equals `bx_ads`
+         * - $action - equals `promotion_register`
+         * - $object_id - not used
+         * - $sender_id - not used
+         * - $extra_params - array of additional params with the following array keys:
+         *      - `id` - [int] commodity id 
+         *      - `type` - [string] commodity type, 'product' or 'promotion'
+         *      - `product_id` - [int] ad (entry) id the commodity is associated with
+         *      - `profile_id` - [int] client (buyer) profile id
+         *      - `amount` - [float] amount paid for the promotion
+         *      - `order` - [string] order number provided with payment processing module
+         *      - `license` - [string] license number generated for the order
+         * @hook @ref hook-bx_ads-promotion_register
+         */
+        bx_alert($this->getName(), 'promotion_register', 0, false, [
+            'id' => $aCommodity['id'],
+            'type' => $aCommodity['type'],
+            'product_id' => $iEntryId,
+            'profile_id' => $iClientId,
+            'amount' => $aCommodity['amount'],
+            'order' => $sOrder,
+            'license' => $sLicense,
+        ]);
+
+        return $aItem;
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_ads Ads
+     * @subsection bx_ads-payments Payments
+     * @subsubsection bx_ads-authorize_subscription_item authorize_subscription_item
+     * 
+     * @code bx_srv('bx_ads', 'authorize_subscription_item', [...]); @endcode
+     * 
+     * Authorize the order to process a subscription (recurring payment) inside the Ads module in future. Is called with payment processing module after the order for subscription was authorized there.
+     * 
+     * @param $iClientId client ID.
+     * @param $iSellerId seller ID
+     * @param $iItemId item ID.
+     * @param $iItemCount the number of purchased items.
+     * @param $sOrder order number received from payment provider (PayPal, Stripe, etc)
+     * @return an array with authorize prodict's description. Empty array is returned if something is wrong.
+     * 
+     * @see BxAdsModule::serviceAuthorizeSubscriptionItem
+     */
+    /** 
+     * @ref bx_ads-authorize_subscription_item "authorize_subscription_item"
+     */
+    public function serviceAuthorizeSubscriptionItem($iClientId, $iSellerId, $iItemId, $iItemCount, $sOrder)
+    {
+        return [];
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_ads Ads
+     * @subsection bx_ads-payments Payments
+     * @subsubsection bx_ads-register_subscription_item register_subscription_item
+     * 
+     * @code bx_srv('bx_ads', 'register_subscription_item', [...]); @endcode
+     * 
+     * Register a processed subscription (recurring payment) inside the Ads module. Is called with payment processing module after the subscription was registered there.
+     * 
+     * @param $iClientId client ID.
+     * @param $iSellerId seller ID
+     * @param $iItemId item ID.
+     * @param $iItemCount the number of purchased items.
+     * @param $sOrder order number received from payment provider (PayPal, Stripe, etc)
+     * @param $sLicense license number genereted with payment processing module for internal usage
+     * @return an array with subscribed prodict's description. Empty array is returned if something is wrong.
+     * 
+     * @see BxAdsModule::serviceRegisterSubscriptionItem
+     */
+    /** 
+     * @ref bx_ads-register_subscription_item "register_subscription_item"
+     */
+    public function serviceRegisterSubscriptionItem($iClientId, $iSellerId, $iItemId, $iItemCount, $sOrder, $sLicense)
+    {
+        return [];
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_ads Ads
+     * @subsection bx_ads-payments Payments
+     * @subsubsection bx_ads-reregister_cart_item reregister_cart_item
+     * 
+     * @code bx_srv('bx_ads', 'reregister_cart_item', [...]); @endcode
+     * 
+     * Reregister a single time payment inside the Ads module. Is called with payment processing module after the payment was reregistered there.
+     * 
+     * @param $iClientId client ID.
+     * @param $iSellerId seller ID
+     * @param $iItemIdOld old item ID.
+     * @param $iItemIdNew new item ID.
+     * @param $sOrder order number received from payment provider (PayPal, Stripe, etc)
+     * @return an array with purchased prodict's description. Empty array is returned if something is wrong.
+     * 
+     * @see BxAdsModule::serviceReregisterCartItem
+     */
+    /** 
+     * @ref bx_ads-reregister_cart_item "reregister_cart_item"
+     */
+    public function serviceReregisterCartItem($iClientId, $iSellerId, $iItemIdOld, $iItemIdNew, $sOrder)
+    {
+        return [];
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_ads Ads
+     * @subsection bx_ads-payments Payments
+     * @subsubsection bx_ads-reregister_subscription_item reregister_subscription_item
+     * 
+     * @code bx_srv('bx_ads', 'reregister_subscription_item', [...]); @endcode
+     * 
+     * Reregister a subscription (recurring payment) inside the Ads module. Is called with payment processing module after the subscription was reregistered there.
+     * 
+     * @param $iClientId client ID.
+     * @param $iSellerId seller ID
+     * @param $iItemIdOld old item ID.
+     * @param $iItemIdNew new item ID.
+     * @param $sOrder order number received from payment provider (PayPal, Stripe, etc)
+     * @return an array with subscribed prodict's description. Empty array is returned if something is wrong.
+     * 
+     * @see BxAdsModule::serviceReregisterSubscriptionItem
+     */
+    /** 
+     * @ref bx_ads-reregister_subscription_item "reregister_subscription_item"
+     */
+    public function serviceReregisterSubscriptionItem($iClientId, $iSellerId, $iItemIdOld, $iItemIdNew, $sOrder)
+    {
+        return [];
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_ads Ads
+     * @subsection bx_ads-payments Payments
+     * @subsubsection bx_ads-unregister_cart_item unregister_cart_item
+     * 
+     * @code bx_srv('bx_ads', 'unregister_cart_item', [...]); @endcode
+     * 
+     * Unregister an earlier processed single time payment inside the Ads module. Is called with payment processing module after the payment was unregistered there.
+     * 
+     * @param $iClientId client ID.
+     * @param $iSellerId seller ID
+     * @param $iItemId item ID.
+     * @param $iItemCount the number of purchased items.
+     * @param $sOrder order number received from payment provider (PayPal, Stripe, etc)
+     * @param $sLicense license number genereted with payment processing module for internal usage
+     * @return boolean value determining where the payment was unregistered or not.
+     * 
+     * @see BxAdsModule::serviceUnregisterCartItem
+     */
+    /** 
+     * @ref bx_ads-unregister_cart_item "unregister_cart_item"
+     */
+    public function serviceUnregisterCartItem($iClientId, $iSellerId, $iItemId, $iItemCount, $sOrder, $sLicense)
+    {
+        $aCommodity = $this->_oDb->getCommodity(['sample' => 'id', 'id' => (int)$iItemId]);
+        if(empty($aCommodity) || !is_array($aCommodity))
+            return [];
+        
+        $sMethod = '_unregisterCartItem' . bx_gen_method_name($aCommodity['type']);
+        if(!method_exists($this, $sMethod))
+            return [];
+
+        return $this->$sMethod($iClientId, $iSellerId, $aCommodity, $iItemCount, $sOrder, $sLicense);
+    }
+    
+    protected function _unregisterCartItemProduct($iClientId, $iSellerId, $aCommodity, $iItemCount, $sOrder, $sLicense)
+    {
+        $iEntryId = (int)$aCommodity['entry_id'];
+
+        if(!$this->_oDb->unregisterLicense($iClientId, $iEntryId, $sOrder, $sLicense))
+            return false;
+
+        /**
+         * @hooks
+         * @hookdef hook-bx_ads-license_unregister 'bx_ads', 'license_unregister' - hook after the payment for ad was refunded with payment processing module
+         * It's equivalent to @ref hook-bx_ads-license_register
+         * @hook @ref hook-bx_ads-license_unregister
+         */
+        bx_alert($this->getName(), 'license_unregister', 0, false, [
+            'id' => $aCommodity['id'],
+            'type' => $aCommodity['type'],
+            'product_id' => $iEntryId,
+            'profile_id' => $iClientId,
+            'order' => $sOrder,
+            'license' => $sLicense,
+            'count' => $iItemCount
+        ]);
+
+    	return true;
+    }
+
+    protected function _unregisterCartItemPromotion($iClientId, $iSellerId, $aCommodity, $iItemCount, $sOrder, $sLicense)
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        $aEntry = $this->_oDb->getContentInfoById($aCommodity['entry_id']);
+        if(empty($aEntry) || !is_array($aEntry))
+            return false;
+
+        $iEntryId = (int)$aCommodity['entry_id'];
+
+        if(!$this->_oDb->unregisterPromotion($aEntry[$CNF['FIELD_AUTHOR']], $aCommodity['id'], $iEntryId, $sOrder, $sLicense))
+            return false;
+
+        /**
+         * @hooks
+         * @hookdef hook-bx_ads-promotion_unregister 'bx_ads', 'promotion_unregister' - hook after the payment for promotion was refunded with payment processing module
+         * It's equivalent to @ref hook-bx_ads-promotion_register
+         * @hook @ref hook-bx_ads-promotion_unregister
+         */
+        bx_alert($this->getName(), 'promotion_unregister', 0, false, [
+            'id' => $aCommodity['id'],
+            'type' => $aCommodity['type'],
+            'product_id' => $iEntryId,
+            'profile_id' => $iClientId,
+            'amount' => $aCommodity['amount'],
+            'order' => $sOrder,
+            'license' => $sLicense
+        ]);
+
+    	return true;
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_ads Ads
+     * @subsection bx_ads-payments Payments
+     * @subsubsection bx_ads-unregister_subscription_item unregister_subscription_item
+     * 
+     * @code bx_srv('bx_ads', 'unregister_subscription_item', [...]); @endcode
+     * 
+     * Unregister an earlier processed subscription (recurring payment) inside the Ads module. Is called with payment processing module after the subscription was unregistered there.
+     * 
+     * @param $iClientId client ID.
+     * @param $iSellerId seller ID
+     * @param $iItemId item ID.
+     * @param $iItemCount the number of purchased items.
+     * @param $sOrder order number received from payment provider (PayPal, Stripe, etc)
+     * @param $sLicense license number genereted with payment processing module for internal usage
+     * @return boolean value determining where the subscription was unregistered or not.
+     * 
+     * @see BxAdsModule::serviceUnregisterSubscriptionItem
+     */
+    /** 
+     * @ref bx_ads-unregister_subscription_item "unregister_subscription_item"
+     */
+    public function serviceUnregisterSubscriptionItem($iClientId, $iSellerId, $iItemId, $iItemCount, $sOrder, $sLicense)
+    {
+    	return true; 
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_ads Ads
+     * @subsection bx_ads-payments Payments
+     * @subsubsection bx_ads-cancel_subscription_item cancel_subscription_item
+     * 
+     * @code bx_srv('bx_ads', 'cancel_subscription_item', [...]); @endcode
+     * 
+     * Cancel an earlier processed subscription (recurring payment) inside the Ads module. Is called with payment processing module after the subscription was canceled there.
+     * 
+     * @param $iClientId client ID.
+     * @param $iSellerId seller ID
+     * @param $iItemId item ID.
+     * @param $iItemCount the number of purchased items.
+     * @param $sOrder order number received from payment provider (PayPal, Stripe, etc)
+     * @return boolean value determining where the subscription was canceled or not.
+     * 
+     * @see BxAdsModule::serviceCancelSubscriptionItem
+     */
+    /** 
+     * @ref bx_ads-cancel_subscription_item "cancel_subscription_item"
+     */
+    public function serviceCancelSubscriptionItem($iClientId, $iSellerId, $iItemId, $iItemCount, $sOrder)
+    {
+    	return true;
+    }
+
+    public function serviceGetOffersCount($sStatus = '')
+    {
+        if(!$this->_oConfig->isAuction())
+            return 0;
+
+        if(empty($sStatus) || !in_array($sStatus, $this->_aOfferStatuses))
+            $sStatus = BX_ADS_OFFER_STATUS_AWAITING;
+
+        $iUserId = bx_get_logged_profile_id();
+        return $this->_oDb->getOffersBy(array('type' => 'content_author_id', 'author_id' => $iUserId, 'status' => $sStatus, 'count' => true));
+    }
+
+    public function serviceGetLiveUpdates($sStatus, $aMenuItemParent, $aMenuItemChild, $iCount = 0)
+    {
+        if(!in_array($sStatus, $this->_aOfferStatuses))
+            return false;
+
+        $iUserId = bx_get_logged_profile_id();
+        $iCountNew = $this->_oDb->getOffersBy(array('type' => 'content_author_id', 'author_id' => $iUserId, 'status' => $sStatus, 'count' => true));
+        if($iCountNew == $iCount)
+            return false;
+
+        return array(
+            'count' => $iCountNew, // required
+            'method' => 'bx_menu_show_live_update(oData)', // required
+            'data' => array(
+                'code' => BxDolTemplate::getInstance()->parseHtmlByTemplateName('menu_item_addon', array(
+                    'content' => '{count}'
+                )),
+            'mi_parent' => $aMenuItemParent,
+            'mi_child' => $aMenuItemChild
+            ),  // optional, may have some additional data to be passed in JS method provided using 'method' param above.
+    	);
+    }
+
+    public function serviceOffers()       
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        if(!$this->_oConfig->isAuction())
+            return '';
+
+        $oGrid = BxDolGrid::getObjectInstance($CNF['OBJECT_GRID_OFFERS_ALL']);
+        if(!$oGrid)
+            return '';
+
+        return $oGrid->getCode();
+    }
+
+    public function serviceEntityOffers($iContentId = 0)
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        if(!$this->_oConfig->isAuction())
+            return '';
+
+        $oGrid = BxDolGrid::getObjectInstance($CNF['OBJECT_GRID_OFFERS']);
+        if(!$oGrid)
+            return '';
+
+        if(empty($iContentId) && ($_iContentId = bx_get('id')) !== false)
+            $iContentId = (int)$_iContentId;
+
+        $oGrid->setContentId($iContentId);
+        return $oGrid->getCode();
+    }
+
+    public function serviceEntityOfferAccepted($iContentId = 0)
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        if(!$this->_oConfig->isAuction())
+            return '';
+
+        $iUserId = bx_get_logged_profile_id();
+
+        if(empty($iContentId) && ($_iContentId = bx_get('id')) !== false)
+            $iContentId = (int)$_iContentId;
+
+        $aContent = $this->_oDb->getContentInfoById($iContentId);
+        if(empty($aContent) || !is_array($aContent) || $aContent[$CNF['FIELD_QUANTITY']] <= 0)
+            return '';
+
+        $aOffer = $this->_oDb->getOffersBy(array(
+            'type' => 'content_and_author_ids', 
+            'content_id' => $iContentId, 
+            'author_id' => $iUserId,
+            'status' => BX_ADS_OFFER_STATUS_ACCEPTED
+        ));
+
+        if(empty($aOffer) || !is_array($aOffer))
+            return '';
+
+        return $this->_oTemplate->entryOfferAccepted($iUserId, $aContent, $aOffer);
+    }
+
+    public function serviceIsSourcesAvaliable()
+    {
+        return $this->_oConfig->isSources();
+    }
+    
+    public function serviceGetSources($iAuthorId)
+    {
+        $aSources = $this->_oDb->getSources(['sample' => 'all']);
+        $aOptions = $this->_oDb->getSourcesOptions($iAuthorId);
+
+        $aResult = [];
+        foreach($aSources as $sSource => $aSource) {
+            if(!isset($aOptions[$aSource['option_prefix'] . 'active']) || (int)$aOptions[$aSource['option_prefix'] . 'active']['value'] != 1) 
+                continue;
+
+            foreach($aOptions as $sName => $aOption)
+                if(strpos($sName, $aSource['option_prefix']) !== false)
+                    $aSource['options'][$sName] = $aOption;
+            $aResult[$sSource] = $aSource;
+        }
+
+        return $aResult; 
+    }
+
+    public function serviceGetSource($iAuthorId, $sAuthorSource = '')
+    {
+    	$aSourcesOptions = $this->serviceGetSources($iAuthorId);
+        if(empty($aSourcesOptions) || !is_array($aSourcesOptions))
+            return false;
+
+        $mixedResult = false;
+        if(!empty($sAuthorSource)) {
+            if(!empty($aSourcesOptions[$sAuthorSource]) && is_array($aSourcesOptions[$sAuthorSource]))
+                $mixedResult = $aSourcesOptions[$sAuthorSource];
+        }
+        else 
+            $mixedResult = array_shift($aSourcesOptions);
+
+    	return $mixedResult;
+    }
+
+    public function serviceLoadEntriesFromSourceByTerm($sSourceType, $sTerm)
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        $oSource = $this->getObjectSource($sSourceType, $this->_iProfileId);
+        if(!$oSource)
+            return [];
+
+        $aEntries = $oSource->getEntries(['sample' => 'all_id_title_pairs']);
+        if(empty($aEntries) || !is_array($aEntries))
+            return [];
+
+        $aResults = []; 
+        foreach($aEntries as $aEntry) {
+            if(stripos($aEntry[$CNF['FIELD_TITLE']], $sTerm) === false)
+                continue;
+
+            $aResults[] = [
+                'label' => $aEntry[$CNF['FIELD_TITLE']], 
+                'value' => $aEntry[$CNF['FIELD_SOURCE']], 
+            ];
+        }
+
+        return $aResults; 
+    }
+
+    public function serviceLoadEntryFromSource($sSourceType, $sSource)
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        $aResult = [];
+        $oSource = $this->getObjectSource($sSourceType, $this->_iProfileId);
+        if(!$oSource)
+            return $aResult;
+
+        $aEntry = $oSource->getEntry($sSource);
+        if(empty($aEntry) || !is_array($aEntry))
+            return $aResult;
+
+        $aName = $this->serviceCheckName($aEntry[$CNF['FIELD_TITLE']]);
+        if(!empty($aName) && is_array($aName))
+            $aResult[$CNF['FIELD_NAME']] = ['type' => 'text', 'value' => $aName['name']];
+
+        $aKey2Type = [
+            $CNF['FIELD_TITLE'] => 'text',
+            $CNF['FIELD_URL'] => 'hidden',
+            $CNF['FIELD_TEXT'] => 'text_html',
+            $CNF['FIELD_TAGS'] => 'text',
+            $CNF['FIELD_PRICE'] => 'text', 
+            $CNF['FIELD_QUANTITY'] => 'text'
+        ];
+        foreach($aEntry as $sKey => $sValue)
+            if(isset($aKey2Type[$sKey]))
+                $aResult[$sKey] = ['type' => $aKey2Type[$sKey], 'value' => $sValue];
+
+        return $aResult;
+    }
+
+    public function serviceBlockSourcesDetails($iProfileId = 0)
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        if(!isLogged())
+             return bx_is_api() ? [bx_api_get_msg(_t('_Access denied'))] : ['content' => MsgBox(_t('_Access denied'))];
+
+        $iProfileId = !empty($iProfileId) ? $iProfileId : bx_get_logged_profile_id();
+
+        $oForm = BxTemplFormView::getObjectInstance($CNF['OBJECT_FORM_SOURCES_DETAILS'], $CNF['OBJECT_FORM_SOURCES_DETAILS_DISPLAY_EDIT']);
+        $oForm->setProfileId($iProfileId);
+        $oForm->initChecker();
+
+        if($oForm->isSubmitted()) {
+            if($oForm->isValid()) {
+                $aOptions = $this->_oDb->getSourcesOptions();
+                foreach($aOptions as $aOption) {
+                    $sValue = bx_get($aOption['name']) !== false ? bx_get($aOption['name']) : '';
+                    $this->_oDb->updateSourceOption($iProfileId, $aOption['id'], bx_process_input($sValue));
+                }
+                if (bx_is_api()){
+                    return [
+                        bx_api_get_block('form', $oForm->getCodeAPI(), ['ext' => ['name' => $this->getName(), 'request' => ['url' => '/api.php?r=' . $this->getName() . '/block_sources_details', 'immutable' => true]]]),
+                        bx_api_get_block('redirect', ['uri' => '/' . BxDolPermalinks::getInstance()->permalink($CNF['URL_SOURCES']), 'timeout' => 100])
+                        ];
+                }
+                else{
+                    header('Location: ' . bx_absolute_url(BxDolPermalinks::getInstance()->permalink($CNF['URL_SOURCES'])));
+                    return;
+                }
+            }
+            else
+                foreach($oForm->aInputs as $aInput)
+                    if(!empty($aInput['error']) && !empty($aInput['attrs']['bx-data-source'])) {
+                        $sSourceBlock = 'source_' . (int)$aInput['attrs']['bx-data-source'] . '_begin';
+                        if(!empty($oForm->aInputs[$sSourceBlock]))
+                            $oForm->aInputs[$sSourceBlock]['collapsed'] = false;
+                    }
+        }
+
+        return bx_is_api() ? [bx_api_get_block('form', $oForm->getCodeAPI(), ['ext' => ['name' => $this->getName(), 'request' => ['url' => '/api.php?r=' . $this->getName() . '/block_sources_details', 'immutable' => true]]])] : ['content' => $oForm->getCode()];
+        
+    }
+
+    public function isEntryActive($aContentInfo)
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        $iViewer = bx_get_logged_profile_id();
+        $bModerator = $this->_isModerator();
+
+        $mixedResult = null;
+        /**
+         * @hooks
+         * @hookdef hook-bx_ads-is_entry_active 'bx_ads', 'is_entry_active' - hook to override whether an ad (entry) active or not
+         * It's equivalent to @ref hook-bx_base_general-is_entry_active
+         * @hook @ref hook-bx_ads-is_entry_active
+         */
+        bx_alert($this->getName(), 'is_entry_active', 0, 0, [
+            'viewer_id' => $iViewer, 
+            'is_moderator' => $bModerator, 
+            'content_info' => $aContentInfo, 
+            'override_result' => &$mixedResult
+        ]);
+        if($mixedResult !== null)
+            return $mixedResult;
+
+        if($aContentInfo[$CNF['FIELD_AUTHOR']] == $iViewer || $bModerator)
+            return true;
+
+        if(isset($CNF['FIELD_STATUS']) && !in_array($aContentInfo[$CNF['FIELD_STATUS']], array(BX_BASE_MOD_TEXT_STATUS_ACTIVE, BX_ADS_STATUS_OFFER, BX_ADS_STATUS_SOLD)))
+            return false;
+
+        if(isset($CNF['FIELD_STATUS_ADMIN']) && $aContentInfo[$CNF['FIELD_STATUS_ADMIN']] != 'active')
+            return false;
+
+        return true;        
+    }
+
+    public function isAuction($aContentInfo)
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        return $this->_oConfig->isAuction() && (int)$aContentInfo[$CNF['FIELD_AUCTION']] != 0;
+    }
+
+    public function isAllowedMakeOffer($mixedContent, $isPerformAction = false)
+    {
+        return $this->checkAllowedMakeOffer($mixedContent, $isPerformAction) === CHECK_ACTION_RESULT_ALLOWED;
+    }
+
+    public function checkAllowedMakeOffer($mixedContent, $isPerformAction = false)
+    {
+        $CNF = &$this->_oConfig->CNF;
+        $sTxtError = '_sys_txt_access_denied';
+
+        $iProfileId = bx_get_logged_profile_id();
+
+        if(!is_array($mixedContent))
+            $mixedContent = $this->_oDb->getContentInfoById((int)$mixedContent);
+
+        if(empty($mixedContent) || !is_array($mixedContent))
+            return _t($sTxtError);
+
+        if(!$this->isAuction($mixedContent) || (int)$mixedContent[$CNF['FIELD_QUANTITY']] <= 0)
+            return _t($sTxtError);
+
+        if($mixedContent[$CNF['FIELD_AUTHOR']] == $iProfileId)
+            return _t($sTxtError);
+
+        $aCheck = checkActionModule($iProfileId, 'make offer', $this->getName(), $isPerformAction);
+        if($aCheck[CHECK_ACTION_RESULT] !== CHECK_ACTION_RESULT_ALLOWED)
+            return $aCheck[CHECK_ACTION_MESSAGE];
+
+        return CHECK_ACTION_RESULT_ALLOWED;
+    }
+
+    public function isAllowedViewOffers($mixedContent, $isPerformAction = false)
+    {
+        return $this->checkAllowedViewOffers($mixedContent, $isPerformAction) === CHECK_ACTION_RESULT_ALLOWED;
+    }
+
+    public function checkAllowedViewOffers($mixedContent, $isPerformAction = false)
+    {
+        $CNF = &$this->_oConfig->CNF;
+        $sTxtError = '_sys_txt_access_denied';
+
+        if(!is_array($mixedContent))
+            $mixedContent = $this->_oDb->getContentInfoById((int)$mixedContent);
+
+        if(empty($mixedContent) || !is_array($mixedContent))
+            return _t($sTxtError);
+
+        if(!$this->isAuction($mixedContent))
+            return _t($sTxtError);
+
+        if($this->_isModerator())
+            return CHECK_ACTION_RESULT_ALLOWED;
+
+        if($mixedContent[$CNF['FIELD_AUTHOR']] == bx_get_logged_profile_id())
+            return CHECK_ACTION_RESULT_ALLOWED;
+
+        return _t($sTxtError);
+    }
+
+    public function isAllowedMarkShipped($mixedContent, $isPerformAction = false)
+    {
+        return $this->checkAllowedMarkShipped($mixedContent, $isPerformAction) === CHECK_ACTION_RESULT_ALLOWED;
+    }
+
+    public function checkAllowedMarkShipped($mixedContent, $isPerformAction = false)
+    {
+        return $this->checkAllowedMarkShippedForProfile($mixedContent, $isPerformAction);
+    }
+
+    public function checkAllowedMarkShippedForProfile($mixedContent, $isPerformAction = false, $iProfileId = false)
+    {
+        $CNF = &$this->_oConfig->CNF;
+        $sTxtError = '_sys_txt_access_denied';
+
+        if(!$iProfileId)
+            $iProfileId = bx_get_logged_profile_id();
+                
+        if(!is_array($mixedContent))
+            $mixedContent = $this->_oDb->getContentInfoById((int)$mixedContent);
+
+        if(empty($mixedContent) || !is_array($mixedContent) || !$this->isSingle($mixedContent))
+            return _t($sTxtError);
+
+        if((int)$mixedContent[$CNF['FIELD_SHIPPED']] != 0 || $mixedContent[$CNF['FIELD_STATUS']] != BX_ADS_STATUS_SOLD || (!$this->isEntryAuthor($mixedContent, $iProfileId) && !$this->_isModerator() && !$this->_isAdministrator()))
+            return _t($sTxtError);
+
+        return CHECK_ACTION_RESULT_ALLOWED;
+    }
+
+    public function isAllowedMarkReceived($mixedContent, $isPerformAction = false)
+    {
+        return $this->checkAllowedMarkReceived($mixedContent, $isPerformAction) === CHECK_ACTION_RESULT_ALLOWED;
+    }
+
+    public function checkAllowedMarkReceived($mixedContent, $isPerformAction = false)
+    {
+        return $this->checkAllowedMarkReceivedForProfile($mixedContent, $isPerformAction);
+    }
+
+    public function checkAllowedMarkReceivedForProfile($mixedContent, $isPerformAction = false, $iProfileId = false)
+    {
+        $CNF = &$this->_oConfig->CNF;
+        $sTxtError = '_sys_txt_access_denied';
+
+        if(!$iProfileId)
+            $iProfileId = bx_get_logged_profile_id();
+
+        if(!is_array($mixedContent))
+            $mixedContent = $this->_oDb->getContentInfoById((int)$mixedContent);
+
+        if(empty($mixedContent) || !is_array($mixedContent) || !$this->isSingle($mixedContent))
+            return _t($sTxtError);
+
+        if((int)$mixedContent[$CNF['FIELD_RECEIVED']] != 0 || !$this->_oDb->hasLicense($iProfileId, $mixedContent[$CNF['FIELD_ID']]))
+            return _t($sTxtError);
+
+        return CHECK_ACTION_RESULT_ALLOWED;
+    }
+
+    public function onPublished($iContentId)
+    {
+        $this->serviceUpdateCategoriesStats($iContentId);
+
+        parent::onPublished($iContentId);
+    }
+
+    public function onOfferAdded($iOfferId, &$aResult)
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        $aOfferInfo = $this->_oDb->getOffersBy(array('type' => 'id', 'id' => $iOfferId));
+        if(empty($aOfferInfo) || !is_array($aOfferInfo))
+            return;
+
+        $iContentId = (int)$aOfferInfo[$CNF['FIELD_OFR_CONTENT']];
+        $aContentInfo = $this->_oDb->getContentInfoById($iContentId);
+        if(empty($aContentInfo) || !is_array($aContentInfo))
+            return;
+
+        $iViewer = bx_get_logged_profile_id();        
+        $oViewer = BxDolProfile::getInstanceMagic($iViewer);
+
+        if(getParam($CNF['PARAM_USE_IIN']) == 'on')
+            sendMailTemplate($CNF['ETEMPLATE_OFFER_ADDED'], 0, $aContentInfo[$CNF['FIELD_AUTHOR']], array(
+                'viewer_name' => $oViewer->getDisplayName(),
+                'viewer_url' => $oViewer->getUrl(),
+                'entry_name' => $aContentInfo[$CNF['FIELD_TITLE']],
+                'entry_url' => bx_absolute_url(BxDolPermalinks::getInstance()->permalink('page.php', array(
+                    'i' => $CNF['URI_VIEW_ENTRY'], 
+                    $CNF['FIELD_ID'] => $iContentId
+                )))
+            ));
+
+        $aParams = $this->_alertParamsOffer($aContentInfo, $aOfferInfo);
+        $aParams['override_result'] = &$aResult;
+
+        /**
+         * @hooks
+         * @hookdef hook-bx_ads-offer_added 'bx_ads', 'offer_added' - hook after an offer was added. Allows to override action results.
+         * - $unit_name - equals `bx_ads`
+         * - $action - equals `offer_added`
+         * - $object_id - offer id
+         * - $sender_id - offer author profile id
+         * - $extra_params - array of additional params with the following array keys:
+         *      - `object_id` - [int] content id
+         *      - `object_author_id` - [int] content author profile id
+         *      - `offer_id` - [int] offer id
+         *      - `offer_author_id` - [int] offer author profile id
+         *      - `privacy_view` - [int] privacy for view action, equals to BX_DOL_PG_ALL, @see BxDolPrivacy
+         *      - `override_result` - [array] by ref, results array as key&value pairs, can be overridden in hook processing
+         * @hook @ref hook-bx_ads-offer_added
+         */
+        bx_alert($this->getName(), 'offer_added', $iOfferId, $aOfferInfo[$CNF['FIELD_OFR_AUTHOR']], $aParams);
+    }
+
+    public function onOfferAccepted($iOfferId)
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        $aOfferInfo = $this->_oDb->getOffersBy(array('type' => 'id', 'id' => $iOfferId));
+        if(empty($aOfferInfo) || !is_array($aOfferInfo))
+            return;
+
+        $iContentId = (int)$aOfferInfo[$CNF['FIELD_OFR_CONTENT']];
+        $aContentInfo = $this->_oDb->getContentInfoById($iContentId);
+        if(empty($aContentInfo) || !is_array($aContentInfo))
+            return;
+
+        if($aContentInfo[$CNF['FIELD_STATUS']] != BX_ADS_STATUS_OFFER && ($this->isSingle($aContentInfo) || $this->getAvailableQuantity($aContentInfo) <= 0))
+            if(!$this->_oDb->updateEntriesBy([$CNF['FIELD_STATUS'] => BX_ADS_STATUS_OFFER], [$CNF['FIELD_ID'] => $iContentId]))
+                return;
+
+        $this->serviceUpdateCategoriesStats($iContentId);
+
+        $iOfferer = (int)$aOfferInfo[$CNF['FIELD_OFR_AUTHOR']];
+        $oOfferer = BxDolProfile::getInstanceMagic($iOfferer);
+
+        if(getParam($CNF['PARAM_USE_IIN']) == 'on')
+            sendMailTemplate($CNF['ETEMPLATE_OFFER_ACCEPTED'], 0, $iOfferer, array(
+                'offerer_name' => $oOfferer->getDisplayName(),
+                'offerer_url' => $oOfferer->getUrl(),
+                'entry_name' => $aContentInfo[$CNF['FIELD_TITLE']],
+                'entry_url' => bx_absolute_url(BxDolPermalinks::getInstance()->permalink('page.php', array(
+                    'i' => $CNF['URI_VIEW_ENTRY'], 
+                    $CNF['FIELD_ID'] => $iContentId
+                )))
+            ));
+
+        $aParams = $this->_alertParamsOffer($aContentInfo, $aOfferInfo);
+        
+        /**
+         * @hooks
+         * @hookdef hook-bx_ads-offer_accepted 'bx_ads', 'offer_accepted' - hook after an offer was accepted.
+         * It's equivalent to @ref hook-bx_ads-offer_added
+         * except content author profile id is passed to $sender_id and
+         * `override_result` parameter in $extra_params is missing
+         * @hook @ref hook-bx_ads-offer_accepted
+         */
+        bx_alert($this->getName(), 'offer_accepted', $iOfferId, $aContentInfo[$CNF['FIELD_AUTHOR']], $aParams);
+    }
+
+    public function onOfferDeclined($iOfferId)
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        $aOfferInfo = $this->_oDb->getOffersBy(array('type' => 'id', 'id' => $iOfferId));
+        if(empty($aOfferInfo) || !is_array($aOfferInfo))
+            return;
+
+        $iContentId = (int)$aOfferInfo[$CNF['FIELD_OFR_CONTENT']];
+        $aContentInfo = $this->_oDb->getContentInfoById($iContentId);
+        if(empty($aContentInfo) || !is_array($aContentInfo))
+            return;
+
+        $iOfferer = (int)$aOfferInfo[$CNF['FIELD_OFR_AUTHOR']];
+        $oOfferer = BxDolProfile::getInstanceMagic($iOfferer);
+
+        if(getParam($CNF['PARAM_USE_IIN']) == 'on')
+            sendMailTemplate($CNF['ETEMPLATE_OFFER_DECLINED'], 0, $iOfferer, array(
+                'offerer_name' => $oOfferer->getDisplayName(),
+                'offerer_url' => $oOfferer->getUrl(),
+                'entry_name' => $aContentInfo[$CNF['FIELD_TITLE']],
+                'entry_url' => bx_absolute_url(BxDolPermalinks::getInstance()->permalink('page.php', array(
+                    'i' => $CNF['URI_VIEW_ENTRY'], 
+                    $CNF['FIELD_ID'] => $iContentId
+                )))
+            ));
+
+        $aParams = $this->_alertParamsOffer($aContentInfo, $aOfferInfo);
+        
+        /**
+         * @hooks
+         * @hookdef hook-bx_ads-offer_declined 'bx_ads', 'offer_declined' - hook after an offer was declined.
+         * It's equivalent to @ref hook-bx_ads-offer_accepted
+         * @hook @ref hook-bx_ads-offer_declined
+         */
+        bx_alert($this->getName(), 'offer_declined', $iOfferId, $aContentInfo[$CNF['FIELD_AUTHOR']], $aParams);
+    }
+
+    public function onOfferCanceled($iOfferId)
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        $aOfferInfo = $this->_oDb->getOffersBy(['type' => 'id', 'id' => $iOfferId]);
+        if(empty($aOfferInfo) || !is_array($aOfferInfo))
+            return;
+
+        $iContentId = (int)$aOfferInfo[$CNF['FIELD_OFR_CONTENT']];
+        $aContentInfo = $this->_oDb->getContentInfoById($iContentId);
+        if(empty($aContentInfo) || !is_array($aContentInfo))
+            return;
+
+        if(!$this->_oDb->updateEntriesBy([$CNF['FIELD_STATUS'] => BX_BASE_MOD_TEXT_STATUS_ACTIVE], [$CNF['FIELD_ID'] => $iContentId]))
+            return;
+
+        $this->serviceUpdateCategoriesStats($iContentId);
+
+        $iOfferer = (int)$aOfferInfo[$CNF['FIELD_OFR_AUTHOR']];
+        $oOfferer = BxDolProfile::getInstanceMagic($iOfferer);
+
+        if(getParam($CNF['PARAM_USE_IIN']) == 'on')
+            sendMailTemplate($CNF['ETEMPLATE_OFFER_CANCELED'], 0, (int)$aContentInfo[$CNF['FIELD_AUTHOR']], [
+                'offerer_name' => $oOfferer->getDisplayName(),
+                'offerer_url' => $oOfferer->getUrl(),
+                'entry_name' => $aContentInfo[$CNF['FIELD_TITLE']],
+                'entry_url' => bx_absolute_url(BxDolPermalinks::getInstance()->permalink('page.php', [
+                    'i' => $CNF['URI_VIEW_ENTRY'], 
+                    $CNF['FIELD_ID'] => $iContentId
+                ]))
+            ]);
+
+        $aParams = $this->_alertParamsOffer($aContentInfo, $aOfferInfo);
+        
+        /**
+         * @hooks
+         * @hookdef hook-bx_ads-offer_canceled 'bx_ads', 'offer_canceled' - hook after an offer was declined.
+         * It's equivalent to @ref hook-bx_ads-offer_added
+         * except `override_result` parameter in $extra_params is missing
+         * @hook @ref hook-bx_ads-offer_canceled
+         */
+        bx_alert($this->getName(), 'offer_canceled', $iOfferId, $aOfferInfo[$CNF['FIELD_OFR_AUTHOR']], $aParams);
+    }
+
+    /**
+     * Common methods.
+     */
+    public function onShipped($mixedContent, $iProfileSrc = 0, $iProfileDst = 0)
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        if(!is_array($mixedContent))
+            $mixedContent = $this->_oDb->getContentInfoById((int)$mixedContent);
+        $iContentId = (int)$mixedContent[$CNF['FIELD_ID']];
+
+        if(empty($iProfileSrc))
+            $iProfileSrc = (int)$mixedContent[$CNF['FIELD_AUTHOR']];
+
+        $oProfileSrc = BxDolProfile::getInstanceMagic($iProfileSrc);
+
+        $aOffer = $this->_oDb->getOffersBy(array('type' => 'accepted', 'content_id' => $iContentId));
+        $bOffer = !empty($aOffer) && is_array($aOffer);
+
+        if(empty($iProfileDst) && $bOffer)
+            $iProfileDst = (int)$aOffer[$CNF['FIELD_OFR_AUTHOR']];        
+
+        if(!empty($oProfileSrc) && !empty($iProfileDst) && getParam($CNF['PARAM_USE_IIN']) == 'on')
+            sendMailTemplate($CNF['ETEMPLATE_SHIPPED'], 0, $iProfileDst, array(
+                'vendor_name' => $oProfileSrc->getDisplayName(),
+                'vendor_url' => $oProfileSrc->getUrl(),
+                'entry_name' => $mixedContent[$CNF['FIELD_TITLE']],
+                'entry_url' => bx_absolute_url(BxDolPermalinks::getInstance()->permalink('page.php', array(
+                    'i' => $CNF['URI_VIEW_ENTRY'], 
+                    $CNF['FIELD_ID'] => $iContentId
+                )))
+            ));
+
+        $aParams = $this->_alertParams($mixedContent);
+        $aParams = array_merge($aParams, [
+            'profile_src' => $iProfileSrc,
+            'profile_dst' => $iProfileDst,
+            'offer_id' => $bOffer ? (int)$aOffer[$CNF['FIELD_OFR_ID']] : 0,
+        ]);
+
+        /**
+         * @hooks
+         * @hookdef hook-bx_ads-shipped 'bx_ads', 'shipped' - hook after the ad (entry) was marked as shipped
+         * - $unit_name - equals `bx_ads`
+         * - $action - equals `shipped`
+         * - $object_id - ad (entry) id
+         * - $sender_id - not used
+         * - $extra_params - array of additional params with the following array keys:
+         *      - `status` - [string] content status
+         *      - `status_admin` - [string] content admin status
+         *      - `privacy_view` - [int] or [string] privacy for view content action, @see BxDolPrivacy
+         *      - `cf` - [int] content's audience filter value
+         *      - `profile_src` - [int] sender profile id
+         *      - `profile_dst` - [int] recipient profile id
+         *      - `offer_id` - [int] offer id if the ad was sold by offer
+         * @hook @ref hook-bx_ads-shipped
+         */
+        bx_alert($this->getName(), 'shipped', $iContentId, false, $aParams);
+    }
+
+    public function onReceived($mixedContent, $iProfileSrc = 0, $iProfileDst = 0)
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        if(!is_array($mixedContent))
+            $mixedContent = $this->_oDb->getContentInfoById((int)$mixedContent);
+        $iContentId = (int)$mixedContent[$CNF['FIELD_ID']];
+
+        if(empty($iProfileDst))
+            $iProfileDst = (int)$mixedContent[$CNF['FIELD_AUTHOR']];
+
+        $aOffer = $this->_oDb->getOffersBy(array('type' => 'accepted', 'content_id' => $iContentId));
+        $bOffer = !empty($aOffer) && is_array($aOffer);
+
+        if(empty($iProfileSrc) && $bOffer)
+            $iProfileSrc = (int)$aOffer[$CNF['FIELD_OFR_AUTHOR']];
+        $oProfileSrc = BxDolProfile::getInstanceMagic($iProfileSrc);
+
+        if(!empty($iProfileSrc) && !empty($iProfileDst) && getParam($CNF['PARAM_USE_IIN']) == 'on')
+            sendMailTemplate($CNF['ETEMPLATE_RECEIVED'], 0, $iProfileDst, array(
+                'client_name' => $oProfileSrc->getDisplayName(),
+                'client_url' => $oProfileSrc->getUrl(),
+                'entry_name' => $mixedContent[$CNF['FIELD_TITLE']],
+                'entry_url' => bx_absolute_url(BxDolPermalinks::getInstance()->permalink('page.php', array(
+                    'i' => $CNF['URI_VIEW_ENTRY'], 
+                    $CNF['FIELD_ID'] => $iContentId
+                )))
+            ));
+
+        $aParams = $this->_alertParams($mixedContent);
+        $aParams = array_merge($aParams, [
+            'profile_src' => $iProfileSrc,
+            'profile_dst' => $iProfileDst,
+            'offer_id' => $bOffer ? (int)$aOffer[$CNF['FIELD_OFR_ID']] : 0,
+        ]);
+
+        /**
+         * @hooks
+         * @hookdef hook-bx_ads-received 'bx_ads', 'received' - hook after the ad (entry) was marked as received
+         * It's equivalent to @ref hook-bx_ads-shipped
+         * @hook @ref hook-bx_ads-received
+         */
+        bx_alert($this->getName(), 'received', $iContentId, false, $aParams);
+    }
+
+    public function getObjectSource($sSource, $iProfileId = 0)
+    {
+        $aSource = $this->_oDb->getSources(array('sample' => 'by_name', 'name' => $sSource));
+        if(empty($aSource) || !is_array($aSource) || empty($aSource['class_name']))
+            return false;
+
+        if(!empty($iProfileId)) {
+            $aSource['author'] = (int)$iProfileId;
+            $aSource['options'] = $this->_oDb->getSourcesOptions((int)$iProfileId, $aSource['id']);
+        }
+
+        $sClassPath = !empty($aSource['class_file']) ? BX_DIRECTORY_PATH_ROOT . $aSource['class_file'] : $this->_oConfig->getClassPath() . $aSource['class_name'] . '.php';
+        if(!file_exists($sClassPath))
+            return false;
+
+        require_once($sClassPath);
+        return new $aSource['class_name']($this->_iProfileId, $aSource, $this);
+    }
+
+    public function offerAccept($iId) 
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        $aOfferInfo = $this->_oDb->getOffersBy(['type' => 'id', 'id' => $iId]);
+        if(empty($aOfferInfo) || !is_array($aOfferInfo))
+            return false;
+
+        $iContentId = (int)$aOfferInfo[$CNF['FIELD_OFR_CONTENT']];
+        $aContentInfo = $this->_oDb->getContentInfoById($iContentId);
+        if(empty($aContentInfo) || !is_array($aContentInfo))
+            return false;
+
+        $iQuantity = (int)$aOfferInfo[$CNF['FIELD_OFR_QUANTITY']];
+        $iQuantityAvailable = $this->getAvailableQuantity($aContentInfo);
+        if($iQuantity > $iQuantityAvailable)
+            return _t('_bx_ads_txt_err_offer_wrong_quantity', $iQuantityAvailable);
+
+        if(!$this->_oDb->updateOffer([$CNF['FIELD_OFR_STATUS'] => BX_ADS_OFFER_STATUS_ACCEPTED], [$CNF['FIELD_OFR_ID'] => $iId]))
+            return false;
+
+        $this->onOfferAccepted($iId);
+        return true;
+    }
+
+    public function offerDecline($iId) 
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        if(!$this->_oDb->updateOffer([$CNF['FIELD_OFR_STATUS'] => BX_ADS_OFFER_STATUS_DECLINED], [$CNF['FIELD_OFR_ID'] => $iId]))
+            return false;
+
+        $this->onOfferDeclined($iId);
+        return true;        
+    }
+
+    public function offerCancel($iId)
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        if(!$this->_oDb->updateOffer([$CNF['FIELD_OFR_STATUS'] => BX_ADS_OFFER_STATUS_CANCELED], [$CNF['FIELD_OFR_ID'] => $iId]))
+            return false;
+
+        $this->onOfferCanceled($iId);
+        return true;
+    }
+    
+    public function offerPay($iId)
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        $aOffer = $this->_oDb->getOffersBy(array('type' => 'id', 'id' => $iId));
+        if(empty($aOffer) || !is_array($aOffer))
+            return false;
+
+        $iContent = (int)$aOffer[$CNF['FIELD_OFR_CONTENT']];
+        $aContent = $this->_oDb->getContentInfoById($iContent);
+        $iContentAuthor = (int)$aContent[$CNF['FIELD_AUTHOR']];
+
+        $aReturn = array(
+            'redirect' => bx_absolute_url(BxDolPermalinks::getInstance()->permalink('page.php', array(
+                'i' => $CNF['URI_VIEW_ENTRY'], 
+                $CNF['FIELD_ID'] => $aOffer[$CNF['FIELD_OFR_CONTENT']]
+            )))
+        );
+
+        $oPayments = BxDolPayments::getInstance();
+        $aResult = $oPayments->addToCart($iContentAuthor, $this->getName(), $iContent, $aOffer[$CNF['FIELD_OFR_QUANTITY']]);
+        if(!empty($aResult) && is_array($aResult)) {
+            if(!empty($aResult['message']))
+                $aReturn['msg'] = $aResult['message'];
+
+            if(isset($aResult['code']) && (int)$aResult['code'] == 0)
+                $aReturn['redirect'] = $oPayments->getCartUrl($iContentAuthor);
+        }
+
+        return $aReturn;
+    }
+
+    public function processMetasAdd($iContentId)
+    {
+        if(!parent::processMetasAdd($iContentId))
+            return false;
+
+        $CNF = &$this->_oConfig->CNF;
+
+        $oMetatags = BxDolMetatags::getObjectInstance($CNF['OBJECT_METATAGS']);
+        $aContentInfo = $this->_oDb->getContentInfoById($iContentId);
+
+        $aCategoryTypes = $this->_oDb->getCategoryTypes(array('type' => 'all'));
+        foreach($aCategoryTypes as $aCategoryType)
+            $oMetatags->metaAddAuto($iContentId, $aContentInfo, $CNF, $aCategoryType['display_add']);
+
+        return true;
+    }
+
+    public function processMetasEdit($iContentId, $oForm)
+    {
+        if(!parent::processMetasEdit($iContentId, $oForm))
+            return false;
+        
+        $CNF = &$this->_oConfig->CNF;
+
+        $oMetatags = BxDolMetatags::getObjectInstance($CNF['OBJECT_METATAGS']);
+        $aContentInfo = $this->_oDb->getContentInfoById($iContentId);
+        
+        $aCategoryTypes = $this->_oDb->getCategoryTypes(array('type' => 'all'));
+        foreach($aCategoryTypes as $aCategoryType)
+            $oMetatags->metaAddAuto($iContentId, $aContentInfo, $CNF, $aCategoryType['display_edit']);
+
+        return true;
+    }
+
+    public function getCategoryDisplay($sDisplayType, $iCategory = 0)
+    {
+        if(empty($iCategory) && bx_get('category') !== false)
+            $iCategory = (int)bx_get('category');
+
+        if(empty($iCategory))
+            return false;
+
+        $aCategory = $this->_oDb->getCategories(array('type' => 'id_full', 'id' => $iCategory));
+
+        $sKey = 'type_display_' . $sDisplayType;
+        if(empty($aCategory[$sKey]))
+            return false;
+
+        return $aCategory[$sKey];
+    }
+
+    public function isSingle($mixedContent)
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        if(!is_array($mixedContent))
+            $mixedContent = $this->_oDb->getContentInfoById((int)$mixedContent);
+
+        return (int)$mixedContent[$CNF['FIELD_SINGLE']] == 1;
+    }
+
+    public function getAvailableQuantity($mixedContent)
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        if(!is_array($mixedContent))
+            $mixedContent = $this->_oDb->getContentInfoById((int)$mixedContent);
+
+        if(!$this->_oConfig->isAuction() || (int)$mixedContent[$CNF['FIELD_AUCTION']] == 0)
+            return (int)$mixedContent[$CNF['FIELD_QUANTITY']];
+
+        $iQuantity = (int)$this->_oDb->getOffersBy([
+            'type' => 'quantity_reserved', 
+            'content_id' => $mixedContent[$CNF['FIELD_ID']], 
+            'status' => BX_ADS_OFFER_STATUS_ACCEPTED
+        ]);
+
+        return (int)$mixedContent[$CNF['FIELD_QUANTITY']] - $iQuantity;
+    }
+
+
+    /**
+     * Internal methods.
+     */
+    protected function _actionMarkAs($sAction)
+    {
+        $iContentId = bx_process_input(bx_get('id'), BX_DATA_INT);
+
+        if(($mixedResult = $this->serviceMarkAs($sAction, $iContentId)) !== true)
+            return array('msg' => $mixedResult); 
+
+        return array(
+            'reload' => 1
+        );
+    }
+
+    protected function _actionChangeStatus($sStatus)
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        $iContentId = bx_process_input(bx_get('id'), BX_DATA_INT);
+        $aContentInfo = $this->_oDb->getContentInfoById($iContentId);
+
+        if(($mixedResult = $this->checkAllowedEdit($aContentInfo)) !== CHECK_ACTION_RESULT_ALLOWED)
+            return array('msg' => $mixedResult);
+
+        if(!$this->_oDb->updateEntriesBy(array($CNF['FIELD_STATUS'] => $sStatus), array($CNF['FIELD_ID'] => $iContentId)))
+            return array('msg' => _t('_bx_ads_txt_err_cannot_perform_action'));
+
+        $this->serviceUpdateCategoriesStats($aContentInfo);
+
+        return array(
+            'reload' => 1
+        );
+    }
+
+    protected function _serviceEntityForm ($sFormMethod, $iContentId = 0, $sDisplay = false, $sCheckFunction = false, $bErrorMsg = true)
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        $mixedContent = $this->_getContent($iContentId, true);
+        if($mixedContent === false)
+            return false;
+
+        list($iContentId, $aContentInfo) = $mixedContent;
+
+        $sDisplayType = false;
+        switch($sFormMethod) {
+            case 'editDataForm':
+                if($sDisplay === false)
+                    $sDisplayType = 'edit';
+                break;
+            case 'viewDataForm':
+            case 'viewDataEntry':
+                $sDisplayType = 'view';
+                break;
+        }
+
+        if($sDisplayType !== false && ($sDisplayNew = $this->getCategoryDisplay($sDisplayType, $aContentInfo[$CNF['FIELD_CATEGORY']])) !== false)
+            $sDisplay = $sDisplayNew;
+
+        return parent::_serviceEntityForm ($sFormMethod, $iContentId, $sDisplay, $sCheckFunction, $bErrorMsg);
+    }
+
+    protected function _getCategoryOptions($iParentId, &$aValues)
+    {
+        $aCategories = $this->_oDb->getCategories(array('type' => 'parent_id', 'parent_id' => $iParentId, 'active' => true));
+        foreach($aCategories as $aCategory) {
+            $aValues[] = array('key' => $aCategory['id'], 'value' => str_repeat('--', (int)$aCategory['level']) . ' ' . _t($aCategory['title']));
+
+            $this->_getCategoryOptions($aCategory['id'], $aValues);
+        }
+    }
+
+    protected function _getSearchableFields($mixedDisplayType = '')
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        if(empty($mixedDisplayType))
+            $mixedDisplayType = array('add', 'edit');
+
+        $aResult = array();
+        $aDisplays = $this->_oDb->getDisplays($this->_oConfig->getName() . '_entry', $mixedDisplayType);
+        foreach($aDisplays as $aDisplay) {
+            if($aDisplay['display_name'] == $CNF['OBJECT_FORM_ENTRY_DISPLAY_ADD'])
+                continue;
+
+            $oForm = BxDolForm::getObjectInstance($CNF['OBJECT_FORM_ENTRY'], $aDisplay['display_name'], $this->_oTemplate);
+            if(!$oForm)
+                continue;
+
+            $aResult = array_merge($aResult, $oForm->aInputs);
+        }
+
+        return $aResult;
+    }
+    
+    protected function _getContentForTimelinePost($aEvent, $aContentInfo, $aBrowseParams = array())
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        $bDynamic = isset($aBrowseParams['dynamic_mode']) && (bool)$aBrowseParams['dynamic_mode'] === true;
+
+        $sCategory = '';
+        if(!empty($CNF['FIELD_CATEGORY']) && !empty($aContentInfo[$CNF['FIELD_CATEGORY']])) {
+            $iCategory = (int)$aContentInfo[$CNF['FIELD_CATEGORY']];
+            $aCategory = $this->_oDb->getCategories(array('type' => 'id', 'id' => $iCategory));
+            $sCategory = _t($aCategory['title']);
+            $sCategoryLink = bx_absolute_url(BxDolPermalinks::getInstance()->permalink($CNF['URL_CATEGORIES'], array($CNF['GET_PARAM_CATEGORY'] => $iCategory)));
+        }
+
+        $sPrice = _t('_bx_ads_txt_free');
+        if(!empty($CNF['FIELD_PRICE']) && !empty($aContentInfo[$CNF['FIELD_PRICE']]))
+            $sPrice = _t_format_currency_ext((float)$aContentInfo[$CNF['FIELD_PRICE']], [
+                'sign' => BxDolPayments::getInstance()->getCurrencySign((int)$aContentInfo[$CNF['FIELD_AUTHOR']])
+            ]);
+
+        $aResult = parent::_getContentForTimelinePost($aEvent, $aContentInfo, $aBrowseParams);
+
+        if(!$this->_bIsApi) {
+            if(empty($aResult['raw']))
+                $aResult['raw'] = '';
+
+            $aResult['text'] = $this->_oTemplate->parseHtmlByName('timeline_post_text.html', [
+                'category_link' => $sCategoryLink,
+                'category_title' => $sCategory,
+                'category_title_attr' => bx_html_attribute($sCategory),
+                'price' => $sPrice,
+                'text' => $aResult['text']
+            ]);
+        }
+        else
+            $aResult = array_merge($aResult, [
+                'price' => $sPrice,
+                'category_title' => $sCategory,
+                'register_click' => $this->_oConfig->isPromotion() ? 'bx_ads/register_click&params[]=' . $aContentInfo[$CNF['FIELD_ID']] : false,
+                'register_impression' => $this->_oConfig->isPromotion() ? 'bx_ads/register_impression&params[]=' . $aContentInfo[$CNF['FIELD_ID']] : false,
+            ]);
+
+        if($this->_oConfig->isSources() && !empty($aContentInfo[$CNF['FIELD_URL']]))
+            $aResult['url'] = $aContentInfo[$CNF['FIELD_URL']];
+
+        if($this->_bIsApi)
+            return $aResult;
+
+        if($this->_oConfig->isPromotion()) {
+            $sJsObject = $this->_oConfig->getJsObject('main');
+            $sHtmlId = $this->_oConfig->getHtmlIds('unit') . $aContentInfo[$CNF['FIELD_ID']] . '-' . time() . '-' . mt_rand(0, 100);
+
+            $aResult['onclick'] = 'return ' . $sJsObject . '.registerClick(this, ' . $aContentInfo[$CNF['FIELD_ID']] . ')';
+            $aResult['raw'] .= $this->_oTemplate->parseHtmlByName('timeline_post_promotion.html', [
+                'html_id' => $sHtmlId,
+                'js_code' => $this->_oTemplate->_wrapInTagJsCode($sJsObject . '.registerTrakerForTimeline(' . $aContentInfo[$CNF['FIELD_ID']] . ', \'' . $sHtmlId . '\');')
+            ]);
+        }
+
+        $sInclude = $this->_oTemplate->addCss(['timeline.css'], $bDynamic);
+        if($bDynamic)
+            $aResult['raw'] .= $sInclude;
+
+        return $aResult;
+    }
+
+    protected function _getBlockLicenses($sType = '') 
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        $sGrid = $CNF['OBJECT_GRID_LICENSES' . (!empty($sType) ? '_' . strtoupper($sType) : '')];
+        $oGrid = BxDolGrid::getObjectInstance($sGrid);
+        if(!$oGrid)
+            return '';
+
+        $this->_oDb->updateLicense(array('new' => 0), array('profile_id' => bx_get_logged_profile_id(), 'new' => 1));
+
+        $this->_oTemplate->addJs(array('licenses.js'));
+        return array(
+            'content' => $this->_oTemplate->getJsCode('licenses', array('sObjNameGrid' => $sGrid)) . $oGrid->getCode(),
+            'menu' => $CNF['OBJECT_MENU_LICENSES']
+        );
+    }
+
+    protected function _alertParamsOffer($aContentInfo, $aOfferInfo)
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        $aParams = array(
+            'object_id' => (int)$aContentInfo[$CNF['FIELD_ID']],
+            'object_author_id' => (int)$aContentInfo[$CNF['FIELD_AUTHOR']],
+
+            'offer_id' => (int)$aOfferInfo[$CNF['FIELD_OFR_ID']],
+            'offer_author_id' => (int)$aOfferInfo[$CNF['FIELD_OFR_AUTHOR']],
+        );
+        if(isset($aContentInfo[$CNF['FIELD_ALLOW_VIEW_TO']]))
+            $aParams['privacy_view'] = $aContentInfo[$CNF['FIELD_ALLOW_VIEW_TO']];
+
+        return $aParams;
+    }
+}
+
+/** @} */

+ 151 - 0
modules/boonex/ads/updates/14.0.5_14.0.6/source/install/config.php

@@ -0,0 +1,151 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Ads Ads
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+$aConfig = array(
+
+    /**
+     * Main Section.
+     */
+    'type' => BX_DOL_MODULE_TYPE_MODULE,
+    'name' => 'bx_ads',
+    'title' => 'Ads',
+    'note' => 'Ads module.',
+    'version' => '14.0.6',
+    'vendor' => 'UNA INC',
+    'help_url' => 'http://feed.una.io/?section={module_name}',
+
+    'compatible_with' => array(
+        '14.0.0-RC4'
+    ),
+
+    /**
+     * 'home_dir' and 'home_uri' - should be unique. Don't use spaces in 'home_uri' and the other special chars.
+     */
+    'home_dir' => 'boonex/ads/',
+    'home_uri' => 'ads',
+
+    'db_prefix' => 'bx_ads_',
+    'class_prefix' => 'BxAds',
+
+    /**
+     * Category for language keys.
+     */
+    'language_category' => 'Ads',
+
+    /**
+     * List of page triggers.
+     */
+    'page_triggers' => array (
+    	'trigger_page_profile_view_entry',
+    ),
+    
+    /**
+     * Menu triggers.
+     */
+    'menu_triggers' => array(
+        'trigger_profile_view_submenu',
+        'trigger_group_view_submenu',
+    ),
+
+    /**
+     * Storage objects to automatically delete files from upon module uninstallation.
+     * Note. Don't add storage objects used in transcoder objects.
+     */
+    'storages' => array(
+        'bx_ads_covers',
+    	'bx_ads_photos',
+        'bx_ads_videos',
+        'bx_ads_files'
+    ),
+
+    /**
+     * Transcoders.
+     */
+    'transcoders' => array(
+        'bx_ads_preview',
+        'bx_ads_gallery',
+        'bx_ads_cover',
+
+        'bx_ads_preview_photos',
+        'bx_ads_gallery_photos',
+        'bx_ads_view_photos',
+
+        'bx_ads_videos_poster',
+        'bx_ads_videos_poster_preview',
+        'bx_ads_videos_mp4',
+        'bx_ads_videos_mp4_hd',
+
+        'bx_ads_preview_files',
+        'bx_ads_gallery_files'
+    ),
+
+    /**
+     * Extended Search Forms.
+     */
+    'esearches' => array(
+        'bx_ads',
+    	'bx_ads_cmts'
+    ),
+
+    /**
+     * Installation/Uninstallation Section.
+     */
+    'install' => array(
+        'execute_sql' => 1,
+        'update_languages' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'uninstall' => array (
+    	'process_esearches' => 1,
+        'execute_sql' => 1,
+        'update_languages' => 1,
+        'update_relations' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'enable' => array(
+        'execute_sql' => 1,
+        'update_relations' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'enable_success' => array(
+        'process_menu_triggers' => 1,
+        'process_page_triggers' => 1,
+    	'process_esearches' => 1,
+        'register_transcoders' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'disable' => array (
+        'execute_sql' => 1,
+        'update_relations' => 1,
+        'unregister_transcoders' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'disable_failed' => array (
+        'register_transcoders' => 1,
+        'clear_db_cache' => 1,
+    ),
+
+    /**
+     * Dependencies Section
+     */
+    'dependencies' => array(),
+
+    /**
+     * Relations Section
+     */
+    'relations' => array(
+    	'bx_timeline',
+    	'bx_notifications'
+    ),
+
+);
+
+/** @} */

+ 14 - 0
modules/boonex/ads/updates/14.0.5_14.0.6/source/template/categories.html

@@ -0,0 +1,14 @@
+<div class="bx-ads-categories">
+    <div class="bx-ads-categories-cnt">
+        <bx_repeat:categories>
+            <div class="bx-ads-category bx-def-padding-thd-topbottom">
+                <bx_if:show_icon><span class="ltr:pr-2 rtl:pl-2"><i class="sys-icon __icon__"></i></span></bx_if:show_icon>
+                <a href="__url__">__title__</a>
+                <bx_if:show_counter><span class="pl-2">(__items__)</span></bx_if:show_counter>
+            </div>
+            <bx_if:show_subcategories>
+                <div class="bx-ads-subcategories ltr:ml-4 ltr:pl-2 rtl:mr-4 rtl:pr-2">__subcategories__</div>
+            </bx_if:show_subcategories>
+        </bx_repeat:categories>
+    </div>
+</div>

+ 51 - 0
modules/boonex/albums/updates/14.0.5_14.0.6/install/config.php

@@ -0,0 +1,51 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ */
+
+$aConfig = array(
+    /**
+     * Main Section.
+     */
+    'title' => 'Albums',
+    'version_from' => '14.0.5',
+    'version_to' => '14.0.6',
+    'vendor' => 'UNA INC',
+
+    'compatible_with' => array(
+        '14.0.0-RC4'
+    ),
+
+    /**
+     * 'home_dir' and 'home_uri' - should be unique. Don't use spaces in 'home_uri' and the other special chars.
+     */
+    'home_dir' => 'boonex/albums/updates/update_14.0.5_14.0.6/',
+    'home_uri' => 'albums_update_1405_1406',
+
+    'module_dir' => 'boonex/albums/',
+    'module_uri' => 'albums',
+
+    'db_prefix' => 'bx_albums_',
+    'class_prefix' => 'BxAlbums',
+
+    /**
+     * Installation/Uninstallation Section.
+     */
+    'install' => array(
+        'execute_sql' => 0,
+        'update_files' => 1,
+        'update_languages' => 0,
+        'clear_db_cache' => 0,
+    ),
+
+    /**
+     * Category for language keys.
+     */
+    'language_category' => 'Albums',
+
+    /**
+     * Files Section
+     */
+    'delete_files' => array(),
+);

+ 13 - 0
modules/boonex/albums/updates/14.0.5_14.0.6/install/installer.php

@@ -0,0 +1,13 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ */
+
+class BxAlbumsUpdater extends BxDolStudioUpdater
+{
+    function __construct($aConfig)
+    {
+        parent::__construct($aConfig);
+    }
+}

+ 130 - 0
modules/boonex/albums/updates/14.0.5_14.0.6/source/classes/BxAlbumsPageMedia.php

@@ -0,0 +1,130 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Albums Albums
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+bx_import('BxDolAcl');
+
+/**
+ * Entry create/edit pages
+ */
+class BxAlbumsPageMedia extends BxTemplPage
+{
+    protected $MODULE;
+    protected $_oModule;
+    protected $_aAlbumInfo = false;
+    protected $_aMediaInfo = false;
+    protected $_mixedContext = false;
+
+    public function __construct($aObject, $oTemplate = false)
+    {        
+        parent::__construct($aObject, $oTemplate);
+        $this->MODULE = 'bx_albums';
+        $this->_oModule = BxDolModule::getInstance($this->MODULE);
+        $CNF = &$this->_oModule->_oConfig->CNF;
+
+        $iMediaId = bx_process_input(bx_get('id'), BX_DATA_INT);
+        if ($iMediaId)
+            $this->_aMediaInfo = $this->_oModule->_oDb->getMediaInfoById($iMediaId);
+
+        if ($this->_aMediaInfo)
+            $this->_aAlbumInfo = $this->_oModule->_oDb->getContentInfoById($this->_aMediaInfo['content_id']);
+
+        if ($this->_aAlbumInfo) {
+            $this->addMarkers(array_merge($this->_aAlbumInfo, $this->_aMediaInfo)); // every field can be used as marker
+            $this->addMarkers(array(
+                'title' => !empty($this->_aMediaInfo['title']) ? $this->_aMediaInfo['title'] : _t('_bx_albums_txt_media_title_alt', $this->_aAlbumInfo[$CNF['FIELD_TITLE']]),
+            ));
+
+            $sTitle = isset($this->_aAlbumInfo[$CNF['FIELD_TITLE']]) ? $this->_aAlbumInfo[$CNF['FIELD_TITLE']] : strmaxtextlen($this->_aAlbumInfo[$CNF['FIELD_TEXT']], 20, '...');
+            $sUrl = bx_absolute_url(BxDolPermalinks::getInstance()->permalink('page.php?i=' . $CNF['URI_VIEW_ENTRY'] . '&id=' . $this->_aAlbumInfo[$CNF['FIELD_ID']]));
+
+            // select view entry submenu
+            $oMenuSubmenu = BxDolMenu::getObjectInstance('sys_site_submenu');
+            if($oMenuSubmenu)
+                $oMenuSubmenu->setObjectSubmenu($CNF['OBJECT_MENU_SUBMENU_VIEW_ENTRY'], array (
+                    'title' => '',
+                    'link' => '',
+                    'icon' => '',
+                ));
+        }
+    }
+
+    public function isAlbumActive()
+    {
+        $CNF = &$this->_oModule->_oConfig->CNF;
+
+        $oPageEntry = BxDolPage::getObjectInstance($this->MODULE . '_view_entry');
+        $oPageEntry->setContentId($this->_aAlbumInfo[$CNF['FIELD_ID']]);
+        return $oPageEntry->isPage();
+    }
+
+    public function getCode ()
+    {
+        // check if content exists
+        if (!$this->_aAlbumInfo || !$this->isAlbumActive() || !$this->_aMediaInfo) { // if entry is not found - display standard "404 page not found" page
+            $this->_oTemplate->displayPageNotFound();
+            exit;
+        }
+
+        // permissions check 
+        if (CHECK_ACTION_RESULT_ALLOWED !== ($sMsg = $this->_oModule->checkAllowedView($this->_aAlbumInfo))) {
+            $this->_oTemplate->displayAccessDenied($sMsg);
+            exit;
+        }
+        $this->_oModule->checkAllowedView($this->_aAlbumInfo, true);
+
+        // count views
+        $CNF = &$this->_oModule->_oConfig->CNF;
+        if (!empty($CNF['OBJECT_VIEWS_MEDIA']))
+            BxDolView::getObjectInstance($CNF['OBJECT_VIEWS_MEDIA'], $this->_aMediaInfo['id'])->doView();
+
+        // add content metatags
+        if(!empty($CNF['OBJECT_METATAGS_MEDIA'])) {
+            $oMetatags = BxDolMetatags::getObjectInstance($CNF['OBJECT_METATAGS_MEDIA']);
+            if($oMetatags)
+                $oMetatags->addPageMetaInfo($this->_aMediaInfo['id'], $this->_getThumbForMetaObject());
+        }
+
+        $aVars = array();
+        $this->_oTemplate->addInjection ('injection_footer', 'text', $this->_oModule->_oTemplate->parseHtmlByName('photoswipe.html', $aVars));
+
+        return parent::getCode ();
+    }
+
+    protected function _getThumbForMetaObject ()
+    {
+        $CNF = &$this->_oModule->_oConfig->CNF;        
+        
+        if(empty($this->_aMediaInfo['file_id']) || empty($CNF['OBJECT_TRANSCODER_COVER']))
+            return false;
+
+        return array('id' => $this->_aMediaInfo['file_id'], 'transcoder' => $CNF['OBJECT_TRANSCODER_COVER']);
+    }
+    
+    protected function _addJsCss()
+    {
+        parent::_addJsCss();
+
+        $this->_oModule->_oTemplate->addCss([
+            BX_DIRECTORY_PATH_PLUGINS_PUBLIC . 'photo-swipe/|photoswipe.css',
+            BX_DIRECTORY_PATH_PLUGINS_PUBLIC . 'photo-swipe/default-skin/|default-skin.css',
+        ]);
+
+        $this->_oModule->_oTemplate->addJs([
+            'history.js',
+            'history.adapter.jquery.js',
+            'photo-swipe/photoswipe.min.js',
+            'photo-swipe/photoswipe-ui-default.min.js',
+            'media_view.js',
+        ]);
+    }
+}
+
+/** @} */

+ 143 - 0
modules/boonex/albums/updates/14.0.5_14.0.6/source/install/config.php

@@ -0,0 +1,143 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Albums Albums
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+$aConfig = array(
+
+    /**
+     * Main Section.
+     */
+    'type' => BX_DOL_MODULE_TYPE_MODULE,
+    'name' => 'bx_albums',
+    'title' => 'Albums',
+    'note' => 'Photos & videos',
+    'version' => '14.0.6',
+    'vendor' => 'UNA INC',
+    'help_url' => 'http://feed.una.io/?section={module_name}',
+
+    'compatible_with' => array(
+        '14.0.0-RC4'
+    ),
+
+    /**
+     * 'home_dir' and 'home_uri' - should be unique. Don't use spaces in 'home_uri' and the other special chars.
+     */
+    'home_dir' => 'boonex/albums/',
+    'home_uri' => 'albums',
+
+    'db_prefix' => 'bx_albums_',
+    'class_prefix' => 'BxAlbums',
+
+    /**
+     * Category for language keys.
+     */
+    'language_category' => 'Albums',
+
+    /**
+     * List of page triggers.
+     */
+    'page_triggers' => array (
+    	'trigger_page_profile_view_entry',
+    ),
+
+    /**
+     * Menu triggers.
+     */
+    'menu_triggers' => array(
+    	'trigger_profile_view_submenu',
+        'trigger_group_view_submenu',
+    ),
+
+	/**
+     * Storage objects to automatically delete files from upon module uninstallation.
+     * Note. Don't add storage objects used in transcoder objects.
+     */
+    'storages' => array(
+    	'bx_albums_files'
+    ),
+
+    /**
+     * Transcoders.
+     */
+    'transcoders' => array(
+        'bx_albums_preview',
+        'bx_albums_browse',
+        'bx_albums_big',
+        'bx_albums_video_poster_browse',
+        'bx_albums_video_poster_preview',
+        'bx_albums_video_poster_big',
+        'bx_albums_video_mp4',
+        'bx_albums_video_mp4_hd',
+    ),
+
+    /**
+     * Extended Search Forms.
+     */
+    'esearches' => array(
+        'bx_albums',
+    	'bx_albums_media',
+    	'bx_albums_cmts',
+        'bx_albums_media_cmts'
+    ),
+
+    /**
+     * Installation/Uninstallation Section.
+     */
+    'install' => array(
+        'execute_sql' => 1,
+        'update_languages' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'uninstall' => array (
+    	'process_esearches' => 1,
+        'execute_sql' => 1,
+        'update_languages' => 1,
+    	'update_relations' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'enable' => array(
+        'execute_sql' => 1,
+    	'update_relations' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'enable_success' => array(
+        'process_menu_triggers' => 1,
+        'process_page_triggers' => 1,
+    	'process_esearches' => 1,
+    	'register_transcoders' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'disable' => array (
+        'execute_sql' => 1,
+    	'update_relations' => 1,
+    	'unregister_transcoders' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'disable_failed' => array (
+    	'register_transcoders' => 1,
+    	'clear_db_cache' => 1,
+    ),
+
+    /**
+     * Dependencies Section
+     */
+    'dependencies' => array(),
+
+    /**
+     * Connections Section
+     */
+    'relations' => array(
+    	'bx_timeline',
+    	'bx_notifications'
+    ),
+
+);
+
+/** @} */

+ 51 - 0
modules/boonex/credits/updates/14.0.4_14.0.5/install/config.php

@@ -0,0 +1,51 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ */
+
+$aConfig = array(
+    /**
+     * Main Section.
+     */
+    'title' => 'Credits',
+    'version_from' => '14.0.4',
+    'version_to' => '14.0.5',
+    'vendor' => 'BoonEx',
+
+    'compatible_with' => array(
+        '14.0.0-RC4'
+    ),
+
+    /**
+     * 'home_dir' and 'home_uri' - should be unique. Don't use spaces in 'home_uri' and the other special chars.
+     */
+    'home_dir' => 'boonex/credits/updates/update_14.0.4_14.0.5/',
+    'home_uri' => 'credits_update_1404_1405',
+
+    'module_dir' => 'boonex/credits/',
+    'module_uri' => 'credits',
+
+    'db_prefix' => 'bx_credits_',
+    'class_prefix' => 'BxCredits',
+
+    /**
+     * Installation/Uninstallation Section.
+     */
+    'install' => array(
+        'execute_sql' => 1,
+        'update_files' => 1,
+        'update_languages' => 0,
+        'clear_db_cache' => 1,
+    ),
+
+    /**
+     * Category for language keys.
+     */
+    'language_category' => 'Credits',
+
+    /**
+     * Files Section
+     */
+    'delete_files' => array(),
+);

+ 13 - 0
modules/boonex/credits/updates/14.0.4_14.0.5/install/installer.php

@@ -0,0 +1,13 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ */
+
+class BxCreditsUpdater extends BxDolStudioUpdater
+{
+    function __construct($aConfig)
+    {
+        parent::__construct($aConfig);
+    }
+}

+ 2 - 0
modules/boonex/credits/updates/14.0.4_14.0.5/install/sql/enable.sql

@@ -0,0 +1,2 @@
+-- MENUS
+UPDATE `sys_menu_items` SET `icon`='copyright col-green3' WHERE `set_name`='sys_toolbar_member' AND `name`='credits-history' AND `icon`='';

+ 77 - 0
modules/boonex/credits/updates/14.0.4_14.0.5/source/install/config.php

@@ -0,0 +1,77 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Credits Credits
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+$aConfig = array(
+
+    /**
+     * Main Section.
+     */
+    'type' => BX_DOL_MODULE_TYPE_MODULE,
+    'name' => 'bx_credits',
+    'title' => 'Credits',
+    'note' => 'Credits module.',
+    'version' => '14.0.5',
+    'vendor' => 'UNA INC',
+    'help_url' => 'http://feed.una.io/?section={module_name}',
+
+    'compatible_with' => array(
+        '14.0.0-RC4'
+    ),
+
+    /**
+     * 'home_dir' and 'home_uri' - should be unique. Don't use spaces in 'home_uri' and the other special chars.
+     */
+    'home_dir' => 'boonex/credits/',
+    'home_uri' => 'credits',
+
+    'db_prefix' => 'bx_credits_',
+    'class_prefix' => 'BxCredits',
+
+    /**
+     * Category for language keys.
+     */
+    'language_category' => 'Credits',
+
+    /**
+     * Installation/Uninstallation Section.
+     */
+    'install' => array(
+        'execute_sql' => 1,
+        'update_languages' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'uninstall' => array (
+        'execute_sql' => 1,
+        'update_languages' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'enable' => array(
+        'execute_sql' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'disable' => array (
+        'execute_sql' => 1,
+        'clear_db_cache' => 1,
+    ),
+
+    /**
+     * Dependencies Section
+     */
+    'dependencies' => array(),
+
+    /**
+     * Relations Section
+     */
+    'relations' => array(),
+
+);
+
+/** @} */

+ 293 - 0
modules/boonex/credits/updates/14.0.4_14.0.5/source/install/sql/enable.sql

@@ -0,0 +1,293 @@
+
+-- SETTINGS
+SET @iTypeOrder = (SELECT MAX(`order`) FROM `sys_options_types` WHERE `group` = 'modules');
+INSERT INTO `sys_options_types`(`group`, `name`, `caption`, `icon`, `order`) VALUES 
+('modules', 'bx_credits', '_bx_credits', 'bx_credits@modules/boonex/credits/|std-icon.svg', IF(ISNULL(@iTypeOrder), 1, @iTypeOrder + 1));
+SET @iTypeId = LAST_INSERT_ID();
+
+INSERT INTO `sys_options_categories` (`type_id`, `name`, `caption`, `order`)
+VALUES (@iTypeId, 'bx_credits', '_bx_credits', 1);
+SET @iCategId = LAST_INSERT_ID();
+
+INSERT INTO `sys_options` (`name`, `value`, `category_id`, `caption`, `type`, `check`, `check_error`, `extra`, `order`) VALUES
+('bx_credits_enable_withdraw', '', @iCategId, '_bx_credits_option_enable_withdraw', 'checkbox', '', '', '', 1),
+('bx_credits_withdraw_email', '', @iCategId, '_bx_credits_option_withdraw_email', 'digit', '', '', '', 2),
+('bx_credits_withdraw_clearing', '30', @iCategId, '_bx_credits_option_withdraw_clearing', 'digit', '', '', '', 3),
+('bx_credits_withdraw_minimum', '500', @iCategId, '_bx_credits_option_withdraw_minimum', 'digit', '', '', '', 4),
+('bx_credits_withdraw_remaining', '100', @iCategId, '_bx_credits_option_withdraw_remaining', 'digit', '', '', '', 5),
+
+('bx_credits_precision', '2', @iCategId, '_bx_credits_option_precision', 'digit', '', '', '', 10),
+('bx_credits_conversion_rate_use', '1.0', @iCategId, '_bx_credits_option_conversion_rate_use', 'digit', '', '', '', 11),
+('bx_credits_conversion_rate_withdraw', '1.0', @iCategId, '_bx_credits_option_conversion_rate_withdraw', 'digit', '', '', '', 12),
+
+('bx_credits_code', '', @iCategId, '_bx_credits_option_code', 'digit', '', '', '', 20),
+('bx_credits_icon', 'copyright', @iCategId, '_bx_credits_option_icon', 'digit', '', '', '', 21),
+
+('bx_credits_enable_provider', '', @iCategId, '_bx_credits_enable_provider', 'checkbox', '', '', '', 30);
+
+
+-- PAGE: module home
+INSERT INTO `sys_objects_page`(`object`, `uri`, `title_system`, `title`, `module`, `layout_id`, `visible_for_levels`, `visible_for_levels_editable`, `url`, `meta_description`, `meta_keywords`, `meta_robots`, `cache_lifetime`, `cache_editable`, `deletable`, `override_class_name`, `override_class_file`) VALUES 
+('bx_credits_home', 'credits-home', '_bx_credits_page_title_sys_home', '_bx_credits_page_title_home', 'bx_credits', 5, 2147483647, 1, 'page.php?i=credits-home', '', '', '', 0, 1, 0, 'BxCreditsPageBrowse', 'modules/boonex/credits/classes/BxCreditsPageBrowse.php');
+
+INSERT INTO `sys_pages_blocks`(`object`, `cell_id`, `module`, `title_system`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `active`, `order`) VALUES 
+('bx_credits_home', 1, 'bx_credits', '_bx_credits_page_block_title_sys_bundles', '_bx_credits_page_block_title_bundles', 13, 2147483647, 'service', 'a:2:{s:6:"module";s:10:"bx_credits";s:6:"method";s:17:"get_block_bundles";}', 0, 1, 1, 0);
+
+-- PAGE: checkout
+INSERT INTO `sys_objects_page`(`object`, `uri`, `title_system`, `title`, `module`, `type_id`, `layout_id`, `visible_for_levels`, `visible_for_levels_editable`, `url`, `meta_description`, `meta_keywords`, `meta_robots`, `cache_lifetime`, `cache_editable`, `deletable`, `override_class_name`, `override_class_file`) VALUES 
+('bx_credits_checkout', 'credits-checkout', '_bx_credits_page_title_sys_checkout', '_bx_credits_page_title_checkout', 'bx_credits', 2, 5, 2147483647, 1, 'page.php?i=credits-checkout', '', '', '', 0, 1, 0, 'BxCreditsPageBrowse', 'modules/boonex/credits/classes/BxCreditsPageBrowse.php');
+
+INSERT INTO `sys_pages_blocks`(`object`, `cell_id`, `module`, `title_system`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `active`, `order`) VALUES 
+('bx_credits_checkout', 1, 'bx_credits', '_bx_credits_page_block_title_sys_checkout', '_bx_credits_page_block_title_checkout', 0, 2147483647, 'service', 'a:2:{s:6:"module";s:10:"bx_credits";s:6:"method";s:18:"get_block_checkout";}', 0, 0, 1, 0);
+
+-- PAGE: profile's orders
+INSERT INTO `sys_objects_page`(`object`, `title_system`, `title`, `module`, `layout_id`, `visible_for_levels`, `visible_for_levels_editable`, `uri`, `url`, `meta_description`, `meta_keywords`, `meta_robots`, `cache_lifetime`, `cache_editable`, `deletable`, `override_class_name`, `override_class_file`) VALUES 
+('bx_credits_orders_common', '_bx_credits_page_title_sys_orders_common', '_bx_credits_page_title_orders_common', 'bx_credits', 5, 2147483647, 1, 'credits-orders-common', '', '', '', '', 0, 1, 0, 'BxCreditsPageOrders', 'modules/boonex/credits/classes/BxCreditsPageOrders.php');
+
+INSERT INTO `sys_pages_blocks`(`object`, `cell_id`, `module`, `title_system`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `active`, `order`) VALUES 
+('bx_credits_orders_common', 1, 'bx_credits', '_bx_credits_page_block_title_sys_orders_common_note', '_bx_credits_page_block_title_orders_common_note', 13, 2147483647, 'service', 'a:2:{s:6:"module";s:10:"bx_credits";s:6:"method";s:21:"get_block_orders_note";}', 0, 0, 1, 0),
+('bx_credits_orders_common', 1, 'bx_credits', '_bx_credits_page_block_title_sys_orders_common', '_bx_credits_page_block_title_orders_common', 11, 2147483647, 'service', 'a:2:{s:6:"module";s:10:"bx_credits";s:6:"method";s:16:"get_block_orders";}', 0, 0, 1, 1);
+
+-- PAGE: orders administration
+INSERT INTO `sys_objects_page`(`object`, `title_system`, `title`, `module`, `layout_id`, `visible_for_levels`, `visible_for_levels_editable`, `uri`, `url`, `meta_description`, `meta_keywords`, `meta_robots`, `cache_lifetime`, `cache_editable`, `deletable`, `override_class_name`, `override_class_file`) VALUES 
+('bx_credits_orders_administration', '_bx_credits_page_title_sys_orders_administration', '_bx_credits_page_title_orders_administration', 'bx_credits', 5, 192, 1, 'credits-orders-administration', '', '', '', '', 0, 1, 0, 'BxCreditsPageOrders', 'modules/boonex/credits/classes/BxCreditsPageOrders.php');
+
+INSERT INTO `sys_pages_blocks`(`object`, `cell_id`, `module`, `title_system`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `active`, `order`) VALUES 
+('bx_credits_orders_administration', 1, 'bx_credits', '_bx_credits_page_block_title_sys_orders_administration', '_bx_credits_page_block_title_orders_administration', 11, 192, 'service', 'a:3:{s:6:"module";s:10:"bx_credits";s:6:"method";s:16:"get_block_orders";s:6:"params";a:1:{i:0;s:14:"administration";}}', 0, 0, 1, 0);
+
+-- PAGE: profile's history
+INSERT INTO `sys_objects_page`(`object`, `title_system`, `title`, `module`, `layout_id`, `visible_for_levels`, `visible_for_levels_editable`, `uri`, `url`, `meta_description`, `meta_keywords`, `meta_robots`, `cache_lifetime`, `cache_editable`, `deletable`, `override_class_name`, `override_class_file`) VALUES 
+('bx_credits_history_common', '_bx_credits_page_title_sys_history_common', '_bx_credits_page_title_history_common', 'bx_credits', 5, 2147483647, 1, 'credits-history-common', 'page.php?i=credits-history-common', '', '', '', 0, 1, 0, 'BxCreditsPageHistory', 'modules/boonex/credits/classes/BxCreditsPageHistory.php');
+
+INSERT INTO `sys_pages_blocks`(`object`, `cell_id`, `module`, `title_system`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `order`) VALUES 
+('bx_credits_history_common', 1, 'bx_credits', '_bx_credits_page_block_title_sys_history_common', '_bx_credits_page_block_title_history_common', 11, 2147483647, 'service', 'a:2:{s:6:"module";s:10:"bx_credits";s:6:"method";s:17:"get_block_history";}}', 0, 1, 0);
+
+-- PAGE: history administration
+INSERT INTO `sys_objects_page`(`object`, `title_system`, `title`, `module`, `layout_id`, `visible_for_levels`, `visible_for_levels_editable`, `uri`, `url`, `meta_description`, `meta_keywords`, `meta_robots`, `cache_lifetime`, `cache_editable`, `deletable`, `override_class_name`, `override_class_file`) VALUES 
+('bx_credits_history_administration', '_bx_credits_page_title_sys_history_administration', '_bx_credits_page_title_history_administration', 'bx_credits', 5, 192, 1, 'credits-history-administration', 'page.php?i=credits-history-administration', '', '', '', 0, 1, 0, 'BxCreditsPageHistory', 'modules/boonex/credits/classes/BxCreditsPageHistory.php');
+
+INSERT INTO `sys_pages_blocks`(`object`, `cell_id`, `module`, `title_system`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `order`) VALUES 
+('bx_credits_history_administration', 1, 'bx_credits', '_bx_credits_page_block_title_sys_history_administration', '_bx_credits_page_block_title_history_administration', 11, 192, 'service', 'a:3:{s:6:"module";s:10:"bx_credits";s:6:"method";s:17:"get_block_history";s:6:"params";a:1:{i:0;s:14:"administration";}}', 0, 1, 0);
+
+-- PAGE: profile's withdrawals
+INSERT INTO `sys_objects_page`(`object`, `title_system`, `title`, `module`, `layout_id`, `visible_for_levels`, `visible_for_levels_editable`, `uri`, `url`, `meta_description`, `meta_keywords`, `meta_robots`, `cache_lifetime`, `cache_editable`, `deletable`, `override_class_name`, `override_class_file`) VALUES 
+('bx_credits_withdrawals_common', '_bx_credits_page_title_sys_withdrawals_common', '_bx_credits_page_title_withdrawals_common', 'bx_credits', 5, 2147483647, 1, 'credits-withdrawals-common', 'page.php?i=credits-withdrawals-common', '', '', '', 0, 1, 0, 'BxCreditsPageWithdrawals', 'modules/boonex/credits/classes/BxCreditsPageWithdrawals.php');
+
+INSERT INTO `sys_pages_blocks`(`object`, `cell_id`, `module`, `title_system`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `order`) VALUES 
+('bx_credits_withdrawals_common', 1, 'bx_credits', '_bx_credits_page_block_title_sys_withdrawals_common', '_bx_credits_page_block_title_withdrawals_common', 11, 2147483647, 'service', 'a:2:{s:6:"module";s:10:"bx_credits";s:6:"method";s:21:"get_block_withdrawals";}}', 0, 1, 0);
+
+-- PAGE: withdrawals administration
+INSERT INTO `sys_objects_page`(`object`, `title_system`, `title`, `module`, `layout_id`, `visible_for_levels`, `visible_for_levels_editable`, `uri`, `url`, `meta_description`, `meta_keywords`, `meta_robots`, `cache_lifetime`, `cache_editable`, `deletable`, `override_class_name`, `override_class_file`) VALUES 
+('bx_credits_withdrawals_administration', '_bx_credits_page_title_sys_withdrawals_administration', '_bx_credits_page_title_withdrawals_administration', 'bx_credits', 5, 192, 1, 'credits-withdrawals-administration', 'page.php?i=credits-withdrawals-administration', '', '', '', 0, 1, 0, 'BxCreditsPageWithdrawals', 'modules/boonex/credits/classes/BxCreditsPageWithdrawals.php');
+
+INSERT INTO `sys_pages_blocks`(`object`, `cell_id`, `module`, `title_system`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `order`) VALUES 
+('bx_credits_withdrawals_administration', 1, 'bx_credits', '_bx_credits_page_block_title_sys_withdrawals_administration', '_bx_credits_page_block_title_withdrawals_administration', 11, 192, 'service', 'a:3:{s:6:"module";s:10:"bx_credits";s:6:"method";s:21:"get_block_withdrawals";s:6:"params";a:1:{i:0;s:14:"administration";}}', 0, 1, 0);
+
+-- PAGE: profiles administration
+INSERT INTO `sys_objects_page`(`object`, `title_system`, `title`, `module`, `layout_id`, `visible_for_levels`, `visible_for_levels_editable`, `uri`, `url`, `meta_description`, `meta_keywords`, `meta_robots`, `cache_lifetime`, `cache_editable`, `deletable`, `override_class_name`, `override_class_file`) VALUES 
+('bx_credits_profiles_administration', '_bx_credits_page_title_sys_profiles_administration', '_bx_credits_page_title_profiles_administration', 'bx_credits', 5, 192, 1, 'credits-profiles-administration', 'page.php?i=credits-profiles-administration', '', '', '', 0, 1, 0, 'BxCreditsPageProfiles', 'modules/boonex/credits/classes/BxCreditsPageProfiles.php');
+
+INSERT INTO `sys_pages_blocks`(`object`, `cell_id`, `module`, `title_system`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `order`) VALUES 
+('bx_credits_profiles_administration', 1, 'bx_credits', '_bx_credits_page_block_title_sys_profiles_administration', '_bx_credits_page_block_title_profiles_administration', 11, 192, 'service', 'a:3:{s:6:"module";s:10:"bx_credits";s:6:"method";s:18:"get_block_profiles";s:6:"params";a:1:{i:0;s:14:"administration";}}', 0, 1, 0);
+
+
+-- MENU: add to site menu
+SET @iSiteMenuOrder = (SELECT `order` FROM `sys_menu_items` WHERE `set_name` = 'sys_site' AND `active` = 1 AND `order` < 9999 ORDER BY `order` DESC LIMIT 1);
+INSERT INTO `sys_menu_items` (`set_name`, `module`, `name`, `title_system`, `title`, `link`, `onclick`, `target`, `icon`, `submenu_object`, `visible_for_levels`, `active`, `copyable`, `order`) VALUES 
+('sys_site', 'bx_credits', 'credits-home', '_bx_credits_menu_item_title_system_credits', '_bx_credits_menu_item_title_credits', 'page.php?i=credits-home', '', '', 'copyright col-green3', 'bx_credits_submenu', 2147483647, 1, 1, IFNULL(@iSiteMenuOrder, 0) + 1);
+
+-- MENU: add to homepage menu
+SET @iHomepageMenuOrder = (SELECT `order` FROM `sys_menu_items` WHERE `set_name` = 'sys_homepage' AND `active` = 1 ORDER BY `order` DESC LIMIT 1);
+INSERT INTO `sys_menu_items` (`set_name`, `module`, `name`, `title_system`, `title`, `link`, `onclick`, `target`, `icon`, `submenu_object`, `visible_for_levels`, `active`, `copyable`, `order`) VALUES 
+('sys_homepage', 'bx_credits', 'credits-home', '_bx_credits_menu_item_title_system_credits', '_bx_credits_menu_item_title_credits', 'page.php?i=credits-home', '', '', 'copyright col-green3', 'bx_credits_submenu', 2147483647, 1, 1, IFNULL(@iHomepageMenuOrder, 0) + 1);
+
+-- MENU: member toolbar
+SET @iMenuToolbarMenuOrder = (SELECT IFNULL(MAX(`order`), 0) FROM `sys_menu_items` WHERE `set_name`='sys_toolbar_member' LIMIT 1);
+INSERT INTO `sys_menu_items`(`set_name`, `module`, `name`, `title_system`, `title`, `link`, `onclick`, `target`, `icon`, `addon`, `markers`, `submenu_object`, `submenu_popup`, `visible_for_levels`, `active`, `copyable`, `order`) VALUES 
+('sys_toolbar_member', 'bx_credits', 'credits-history', '_bx_credits_menu_item_title_system_history', '_bx_credits_menu_item_title_history', 'page.php?i=credits-history-common', '', '', 'copyright col-green3', '', 'a:2:{s:6:"module";s:10:"bx_credits";s:6:"method";s:26:"get_menu_item_addon_amount";}', '', 0, 2147483646, 0, 1, 0);
+
+-- MENU: Notifications
+SET @iAccountNotificationsMenuOrder = (SELECT IFNULL(MAX(`order`), 0) FROM `sys_menu_items` WHERE `set_name` = 'sys_account_notifications' AND `order` < 9999);
+INSERT INTO `sys_menu_items` (`set_name`, `module`, `name`, `title_system`, `title`, `link`, `onclick`, `target`, `icon`, `addon`, `markers`, `submenu_object`, `submenu_popup`, `visible_for_levels`, `active`, `copyable`, `order`) VALUES
+('sys_account_notifications', 'bx_credits', 'notifications-credits', '_bx_credits_menu_item_title_system_notifications', '_bx_credits_menu_item_title_notifications', 'page.php?i=credits-history-common', '', '', 'copyright col-green3', '', 'a:2:{s:6:"module";s:10:"bx_credits";s:6:"method";s:26:"get_menu_item_addon_amount";}', '', '0', 2147483646, 1, 1, @iAccountNotificationsMenuOrder + 1);
+
+-- MENU: account dashboard
+SET @iAccountDashboardMenuOrder = (SELECT IFNULL(MAX(`order`), 0) FROM `sys_menu_items` WHERE `set_name`='sys_account_dashboard' LIMIT 1);
+INSERT INTO `sys_menu_items` (`set_name`, `module`, `name`, `title_system`, `title`, `link`, `onclick`, `target`, `icon`, `addon`, `submenu_object`, `visible_for_levels`, `active`, `copyable`, `editable`, `order`) VALUES
+('sys_account_dashboard', 'bx_credits', 'credits-manage', '_bx_credits_menu_item_title_system_manage', '_bx_credits_menu_item_title_manage', 'page.php?i=credits-history-common', '', '', 'copyright col-green3', '', '', 2147483646, 1, 0, 1, @iAccountDashboardMenuOrder + 1);
+
+-- MENU: module sub-menu
+INSERT INTO `sys_objects_menu`(`object`, `title`, `set_name`, `module`, `template_id`, `deletable`, `active`, `override_class_name`, `override_class_file`) VALUES 
+('bx_credits_submenu', '_bx_credits_menu_title_submenu', 'bx_credits_submenu', 'bx_credits', 8, 0, 1, '', '');
+
+INSERT INTO `sys_menu_sets`(`set_name`, `module`, `title`, `deletable`) VALUES 
+('bx_credits_submenu', 'bx_credits', '_bx_credits_menu_set_title_submenu', 0);
+
+INSERT INTO `sys_menu_items`(`set_name`, `module`, `name`, `title_system`, `title`, `link`, `onclick`, `target`, `icon`, `submenu_object`, `visible_for_levels`, `active`, `copyable`, `order`) VALUES 
+('bx_credits_submenu', 'bx_credits', 'credits-home', '_bx_credits_menu_item_title_system_home', '_bx_credits_menu_item_title_home', 'page.php?i=credits-home', '', '', '', '', 2147483647, 0, 1, 1);
+
+-- MENU: manage submenu
+INSERT INTO `sys_objects_menu`(`object`, `title`, `set_name`, `module`, `template_id`, `deletable`, `active`, `override_class_name`, `override_class_file`) VALUES 
+('bx_credits_manage_submenu', '_bx_credits_menu_title_manage_submenu', 'bx_credits_manage_submenu', 'bx_credits', 6, 0, 1, 'BxCreditsMenuManage', 'modules/boonex/credits/classes/BxCreditsMenuManage.php');
+
+INSERT INTO `sys_menu_sets`(`set_name`, `module`, `title`, `deletable`) VALUES 
+('bx_credits_manage_submenu', 'bx_credits', '_bx_credits_menu_set_title_manage_submenu', 0);
+
+INSERT INTO `sys_menu_items`(`set_name`, `module`, `name`, `title_system`, `title`, `link`, `onclick`, `target`, `icon`, `addon`, `submenu_object`, `visible_for_levels`, `active`, `copyable`, `editable`, `order`) VALUES 
+('bx_credits_manage_submenu', 'bx_credits', 'credits-history-common', '_bx_credits_menu_item_title_system_history_common', '_bx_credits_menu_item_title_history_common', 'page.php?i=credits-history-common', '', '_self', '', '', '', 2147483646, 1, 0, 1, 1),
+('bx_credits_manage_submenu', 'bx_credits', 'credits-history-administration', '_bx_credits_menu_item_title_system_history_administration', '_bx_credits_menu_item_title_history_administration', 'page.php?i=credits-history-administration', '', '_self', '', '', '', 192, 1, 0, 1, 2),
+('bx_credits_manage_submenu', 'bx_credits', 'credits-orders-common', '_bx_credits_menu_item_title_system_orders_common', '_bx_credits_menu_item_title_orders_common', 'page.php?i=credits-orders-common', '', '_self', '', '', '', 2147483646, 1, 0, 1, 3),
+('bx_credits_manage_submenu', 'bx_credits', 'credits-orders-administration', '_bx_credits_menu_item_title_system_orders_administration', '_bx_credits_menu_item_title_orders_administration', 'page.php?i=credits-orders-administration', '', '_self', '', '', '', 192, 1, 0, 1, 4),
+('bx_credits_manage_submenu', 'bx_credits', 'credits-withdrawals-common', '_bx_credits_menu_item_title_system_withdrawals_common', '_bx_credits_menu_item_title_withdrawals_common', 'page.php?i=credits-withdrawals-common', '', '_self', '', '', '', 2147483646, 1, 0, 1, 5),
+('bx_credits_manage_submenu', 'bx_credits', 'credits-withdrawals-administration', '_bx_credits_menu_item_title_system_withdrawals_administration', '_bx_credits_menu_item_title_withdrawals_administration', 'page.php?i=credits-withdrawals-administration', '', '_self', '', '', '', 192, 1, 0, 1, 6),
+('bx_credits_manage_submenu', 'bx_credits', 'credits-profiles-administration', '_bx_credits_menu_item_title_system_profiles_administration', '_bx_credits_menu_item_title_profiles_administration', 'page.php?i=credits-profiles-administration', '', '_self', '', '', '', 192, 1, 0, 1, 7);
+
+-- MENU: dashboard manage tools
+SET @iManageMenuOrder = (SELECT IFNULL(MAX(`order`), 0) FROM `sys_menu_items` WHERE `set_name`='sys_account_dashboard_manage_tools' LIMIT 1);
+INSERT INTO `sys_menu_items`(`set_name`, `module`, `name`, `title_system`, `title`, `link`, `onclick`, `target`, `icon`, `addon`, `submenu_object`, `visible_for_levels`, `active`, `copyable`, `order`) VALUES 
+('sys_account_dashboard_manage_tools', 'bx_credits', 'credits-history-administration', '_bx_credits_menu_item_title_system_admt_credits', '_bx_credits_menu_item_title_admt_credits', 'page.php?i=credits-history-administration', '', '_self', 'copyright', 'a:2:{s:6:"module";s:10:"bx_credits";s:6:"method";s:27:"get_menu_addon_manage_tools";}', '', 192, 1, 0, @iManageMenuOrder + 1);
+
+
+-- GRIDS: bundles
+INSERT INTO `sys_objects_grid` (`object`, `source_type`, `source`, `table`, `field_id`, `field_order`, `field_active`, `paginate_url`, `paginate_per_page`, `paginate_simple`, `paginate_get_start`, `paginate_get_per_page`, `filter_fields`, `filter_fields_translatable`, `filter_mode`, `sorting_fields`, `sorting_fields_translatable`, `visible_for_levels`, `override_class_name`, `override_class_file`) VALUES
+('bx_credits_bundles', 'Sql', 'SELECT * FROM `bx_credits_bundles` WHERE 1 ', 'bx_credits_bundles', 'id', 'order', 'active', '', 100, NULL, 'start', '', 'period,period_unit,price', '', 'like', '', '', 192, 'BxCreditsGridBundles', 'modules/boonex/credits/classes/BxCreditsGridBundles.php');
+
+INSERT INTO `sys_grid_fields` (`object`, `name`, `title`, `width`, `translatable`, `chars_limit`, `params`, `order`) VALUES
+('bx_credits_bundles', 'checkbox', '_sys_select', '1%', 0, '', '', 1),
+('bx_credits_bundles', 'order', '', '1%', 0, '', '', 2),
+('bx_credits_bundles', 'name', '_bx_credits_grid_column_title_name', '23%', 0, 32, '', 3),
+('bx_credits_bundles', 'title', '_bx_credits_grid_column_title_title', '30%', 1, 16, '', 4),
+('bx_credits_bundles', 'amount', '_bx_credits_grid_column_title_amount', '10%', 0, 16, '', 5),
+('bx_credits_bundles', 'bonus', '_bx_credits_grid_column_title_bonus', '5%', 0, 16, '', 6),
+('bx_credits_bundles', 'price', '_bx_credits_grid_column_title_price', '10%', 0, 16, '', 7),
+('bx_credits_bundles', 'actions', '', '20%', 0, '', '', 8);
+
+INSERT INTO `sys_grid_actions` (`object`, `type`, `name`, `title`, `icon`, `icon_only`, `confirm`, `order`) VALUES
+('bx_credits_bundles', 'independent', 'add', '_bx_credits_grid_action_title_add', '', 0, 0, 1),
+('bx_credits_bundles', 'single', 'edit', '_bx_credits_grid_action_title_edit', 'pencil-alt', 1, 0, 1),
+('bx_credits_bundles', 'single', 'delete', '_bx_credits_grid_action_title_delete', 'remove', 1, 1, 2),
+('bx_credits_bundles', 'bulk', 'delete', '_bx_credits_grid_action_title_delete', '', 0, 1, 1);
+
+-- GRIDS: orders
+INSERT INTO `sys_objects_grid` (`object`, `source_type`, `source`, `table`, `field_id`, `field_order`, `field_active`, `paginate_url`, `paginate_per_page`, `paginate_simple`, `paginate_get_start`, `paginate_get_per_page`, `filter_fields`, `filter_fields_translatable`, `filter_mode`, `sorting_fields`, `sorting_fields_translatable`, `visible_for_levels`, `override_class_name`, `override_class_file`) VALUES
+('bx_credits_orders_administration', 'Sql', 'SELECT `to`.`id` AS `id`, `to`.`profile_id` AS `profile_id`, `to`.`bundle_id` AS `bundle_id`, `tb`.`title` AS `bundle`, `to`.`order` AS `transaction`, `to`.`license` AS `license`, `to`.`type` AS `type`, `to`.`added` AS `added`, `to`.`expired` AS `expired` FROM `bx_credits_orders` AS `to` LEFT JOIN `bx_credits_bundles` AS `tb` ON `to`.`bundle_id`=`tb`.`id` WHERE 1 ', 'bx_credits_orders', 'id', 'added', '', '', 20, NULL, 'start', '', 'tb`.`title,to`.`order,to`.`license,to`.`type', '', 'like', '', '', 192, 'BxCreditsGridOrdersAdministration', 'modules/boonex/credits/classes/BxCreditsGridOrdersAdministration.php'),
+('bx_credits_orders_common', 'Sql', 'SELECT `to`.`id` AS `id`, `to`.`profile_id` AS `profile_id`, `to`.`bundle_id` AS `bundle_id`, `tb`.`title` AS `bundle`, `to`.`order` AS `transaction`, `to`.`license` AS `license`, `to`.`type` AS `type`, `to`.`added` AS `added`, `to`.`expired` AS `expired` FROM `bx_credits_orders` AS `to` LEFT JOIN `bx_credits_bundles` AS `tb` ON `to`.`bundle_id`=`tb`.`id` WHERE 1 ', 'bx_credits_orders', 'id', 'added', '', '', 20, NULL, 'start', '', 'tb`.`title,to`.`order,to`.`license,to`.`type', '', 'like', '', '', 2147483647, 'BxCreditsGridOrdersCommon', 'modules/boonex/credits/classes/BxCreditsGridOrdersCommon.php');
+
+INSERT INTO `sys_grid_fields` (`object`, `name`, `title`, `width`, `translatable`, `chars_limit`, `params`, `order`) VALUES
+('bx_credits_orders_administration', 'profile_id', '_bx_credits_grid_column_title_ord_profile_id', '10%', 0, '28', '', 1),
+('bx_credits_orders_administration', 'bundle', '_bx_credits_grid_column_title_ord_bundle', '20%', 1, '28', '', 2),
+('bx_credits_orders_administration', 'transaction', '_bx_credits_grid_column_title_ord_transaction', '10%', 0, '32', '', 3),
+('bx_credits_orders_administration', 'type', '_bx_credits_grid_column_title_ord_type', '5%', 1, '12', '', 4),
+('bx_credits_orders_administration', 'added', '_bx_credits_grid_column_title_ord_added', '10%', 1, '25', '', 5),
+('bx_credits_orders_administration', 'expired', '_bx_credits_grid_column_title_ord_expired', '10%', 1, '25', '', 6),
+
+('bx_credits_orders_common', 'bundle', '_bx_credits_grid_column_title_ord_bundle', '20%', 1, '28', '', 1),
+('bx_credits_orders_common', 'transaction', '_bx_credits_grid_column_title_ord_transaction', '10%', 0, '32', '', 2),
+('bx_credits_orders_common', 'type', '_bx_credits_grid_column_title_ord_type', '10%', 1, '12', '', 3),
+('bx_credits_orders_common', 'added', '_bx_credits_grid_column_title_ord_added', '10%', 1, '25', '', 4),
+('bx_credits_orders_common', 'expired', '_bx_credits_grid_column_title_ord_expired', '10%', 1, '25', '', 5);
+
+-- GRIDS: history
+INSERT INTO `sys_objects_grid` (`object`, `source_type`, `source`, `table`, `field_id`, `field_order`, `field_active`, `paginate_url`, `paginate_per_page`, `paginate_simple`, `paginate_get_start`, `paginate_get_per_page`, `filter_fields`, `filter_fields_translatable`, `filter_mode`, `sorting_fields`, `sorting_fields_translatable`, `visible_for_levels`, `override_class_name`, `override_class_file`) VALUES
+('bx_credits_history_administration', 'Sql', 'SELECT `th`.*, `tp`.`wdw_clearing` FROM `bx_credits_history` AS `th` LEFT JOIN `bx_credits_profiles` AS `tp` ON `th`.`first_pid`=`tp`.`id` WHERE 1 ', 'bx_credits_history', 'id', 'date', '', '', 20, NULL, 'start', '', 'th`.`direction,th`.`order,th`.`info', '', 'like', '', '', 192, 'BxCreditsGridHistoryAdministration', 'modules/boonex/credits/classes/BxCreditsGridHistoryAdministration.php'),
+('bx_credits_history_common', 'Sql', 'SELECT `th`.*, `tp`.`wdw_clearing` FROM `bx_credits_history` AS `th` LEFT JOIN `bx_credits_profiles` AS `tp` ON `th`.`first_pid`=`tp`.`id` WHERE 1 ', 'bx_credits_history', 'id', 'date', '', '', 20, NULL, 'start', '', 'th`.`direction,th`.`order,th`.`info', '', 'like', '', '', 2147483647, 'BxCreditsGridHistoryCommon', 'modules/boonex/credits/classes/BxCreditsGridHistoryCommon.php');
+
+INSERT INTO `sys_grid_fields` (`object`, `name`, `title`, `width`, `translatable`, `chars_limit`, `params`, `order`) VALUES
+('bx_credits_history_administration', 'first_pid', '_bx_credits_grid_column_title_htr_first_pid', '15%', 0, '', '', 1),
+('bx_credits_history_administration', 'direction', '_bx_credits_grid_column_title_htr_direction', '10%', 0, '', '', 2),
+('bx_credits_history_administration', 'second_pid', '_bx_credits_grid_column_title_htr_second_pid', '15%', 0, '', '', 3),
+('bx_credits_history_administration', 'amount', '_bx_credits_grid_column_title_htr_amount', '10%', 1, '', '', 4),
+('bx_credits_history_administration', 'order', '_bx_credits_grid_column_title_htr_order', '15%', 0, '16', '', 5),
+('bx_credits_history_administration', 'info', '_bx_credits_grid_column_title_htr_info', '15%', 1, '24', '', 6),
+('bx_credits_history_administration', 'date', '_bx_credits_grid_column_title_htr_date', '10%', 0, '', '', 7),
+('bx_credits_history_administration', 'cleared', '_bx_credits_grid_column_title_htr_cleared', '10%', 0, '', '', 8),
+
+('bx_credits_history_common', 'direction', '_bx_credits_grid_column_title_htr_direction', '10%', 0, '', '', 1),
+('bx_credits_history_common', 'second_pid', '_bx_credits_grid_column_title_htr_pid', '25%', 0, '', '', 2),
+('bx_credits_history_common', 'amount', '_bx_credits_grid_column_title_htr_amount', '15%', 1, '', '', 3),
+('bx_credits_history_common', 'order', '_bx_credits_grid_column_title_htr_order', '15%', 0, '16', '', 4),
+('bx_credits_history_common', 'info', '_bx_credits_grid_column_title_htr_info', '15%', 1, '32', '', 5),
+('bx_credits_history_common', 'date', '_bx_credits_grid_column_title_htr_date', '10%', 0, '', '', 6),
+('bx_credits_history_common', 'cleared', '_bx_credits_grid_column_title_htr_cleared', '10%', 0, '', '', 7);
+
+INSERT INTO `sys_grid_actions` (`object`, `type`, `name`, `title`, `icon`, `icon_only`, `confirm`, `order`) VALUES
+('bx_credits_history_administration', 'independent', 'grant', '_bx_credits_grid_action_title_htr_grant', '', 0, 0, 1),
+
+('bx_credits_history_common', 'independent', 'send', '_bx_credits_grid_action_title_htr_send', '', 0, 0, 1);
+
+-- GRIDS: withdrawals
+INSERT INTO `sys_objects_grid` (`object`, `source_type`, `source`, `table`, `field_id`, `field_order`, `field_active`, `paginate_url`, `paginate_per_page`, `paginate_simple`, `paginate_get_start`, `paginate_get_per_page`, `filter_fields`, `filter_fields_translatable`, `filter_mode`, `sorting_fields`, `sorting_fields_translatable`, `visible_for_levels`, `override_class_name`, `override_class_file`) VALUES
+('bx_credits_withdrawals_administration', 'Sql', 'SELECT * FROM `bx_credits_withdrawals` WHERE 1 ', 'bx_credits_withdrawals', 'id', 'added', '', '', 20, NULL, 'start', '', 'message,order', '', 'like', '', '', 192, 'BxCreditsGridWithdrawalsAdministration', 'modules/boonex/credits/classes/BxCreditsGridWithdrawalsAdministration.php'),
+('bx_credits_withdrawals_common', 'Sql', 'SELECT * FROM `bx_credits_withdrawals` WHERE 1 ', 'bx_credits_withdrawals', 'id', 'added', '', '', 20, NULL, 'start', '', 'message,order', '', 'like', '', '', 2147483647, 'BxCreditsGridWithdrawalsCommon', 'modules/boonex/credits/classes/BxCreditsGridWithdrawalsCommon.php');
+
+INSERT INTO `sys_grid_fields` (`object`, `name`, `title`, `width`, `translatable`, `chars_limit`, `params`, `order`) VALUES
+('bx_credits_withdrawals_administration', 'profile_id', '_bx_credits_grid_column_title_wdw_profile_id', '15%', 0, 0, '', 1),
+('bx_credits_withdrawals_administration', 'amount', '_bx_credits_grid_column_title_wdw_amount', '5%', 0, 0, '', 2),
+('bx_credits_withdrawals_administration', 'rate', '_bx_credits_grid_column_title_wdw_rate', '5%', 0, 0, '', 3),
+('bx_credits_withdrawals_administration', 'message', '_bx_credits_grid_column_title_wdw_message', '10%', 0, 16, '', 4),
+('bx_credits_withdrawals_administration', 'added', '_bx_credits_grid_column_title_wdw_added', '5%', 0, 0, '', 5),
+('bx_credits_withdrawals_administration', 'performer_id', '_bx_credits_grid_column_title_wdw_performer_id', '15%', 0, 0, '', 6),
+('bx_credits_withdrawals_administration', 'order', '_bx_credits_grid_column_title_wdw_order', '15%', 0, 16, '', 7),
+('bx_credits_withdrawals_administration', 'confirmed', '_bx_credits_grid_column_title_wdw_confirmed', '5%', 0, 0, '', 8),
+('bx_credits_withdrawals_administration', 'status', '_bx_credits_grid_column_title_wdw_status', '5%', 0, 0, '', 9),
+('bx_credits_withdrawals_administration', 'actions', '', '20%', 0, 0, '', 10),
+
+('bx_credits_withdrawals_common', 'amount', '_bx_credits_grid_column_title_wdw_amount', '10%', 0, 0, '', 1),
+('bx_credits_withdrawals_common', 'rate', '_bx_credits_grid_column_title_wdw_rate', '10%', 0, 0, '', 2),
+('bx_credits_withdrawals_common', 'message', '_bx_credits_grid_column_title_wdw_message', '15%', 0, 16, '', 3),
+('bx_credits_withdrawals_common', 'added', '_bx_credits_grid_column_title_wdw_added', '10%', 0, 0, '', 4),
+('bx_credits_withdrawals_common', 'order', '_bx_credits_grid_column_title_wdw_order', '15%', 0, 16, '', 5),
+('bx_credits_withdrawals_common', 'confirmed', '_bx_credits_grid_column_title_wdw_confirmed', '10%', 0, 0, '', 6),
+('bx_credits_withdrawals_common', 'status', '_bx_credits_grid_column_title_wdw_status', '10%', 0, 0, '', 7),
+('bx_credits_withdrawals_common', 'actions', '', '20%', 0, 0, '', 8);
+
+INSERT INTO `sys_grid_actions` (`object`, `type`, `name`, `title`, `icon`, `icon_only`, `confirm`, `order`) VALUES
+('bx_credits_withdrawals_administration', 'single', 'withdraw_confirm', '_bx_credits_grid_action_title_wdw_withdraw_confirm', 'check', 1, 1, 1),
+
+('bx_credits_withdrawals_common', 'independent', 'withdraw_request', '_bx_credits_grid_action_title_wdw_withdraw_request', '', 0, 0, 1),
+('bx_credits_withdrawals_common', 'single', 'withdraw_cancel', '_bx_credits_grid_action_title_wdw_withdraw_cancel', 'times', 1, 1, 1);
+
+
+-- GRIDS: profiles
+INSERT INTO `sys_objects_grid` (`object`, `source_type`, `source`, `table`, `field_id`, `field_order`, `field_active`, `paginate_url`, `paginate_per_page`, `paginate_simple`, `paginate_get_start`, `paginate_get_per_page`, `filter_fields`, `filter_fields_translatable`, `filter_mode`, `sorting_fields`, `sorting_fields_translatable`, `visible_for_levels`, `override_class_name`, `override_class_file`) VALUES
+('bx_credits_profiles_administration', 'Sql', 'SELECT * FROM `bx_credits_profiles` WHERE 1 ', 'bx_credits_profiles', 'id', '', '', '', 20, NULL, 'start', '', '', '', 'like', '', '', 192, 'BxCreditsGridProfilesAdministration', 'modules/boonex/credits/classes/BxCreditsGridProfilesAdministration.php');
+
+INSERT INTO `sys_grid_fields` (`object`, `name`, `title`, `width`, `translatable`, `chars_limit`, `params`, `order`) VALUES
+('bx_credits_profiles_administration', 'id', '_bx_credits_grid_column_title_pfl_id', '40%', 0, '', '', 1),
+('bx_credits_profiles_administration', 'wdw_clearing', '_bx_credits_grid_column_title_pfl_wdw_clearing', '10%', 0, '', '', 2),
+('bx_credits_profiles_administration', 'wdw_minimum', '_bx_credits_grid_column_title_pfl_wdw_minimum', '10%', 0, '', '', 3),
+('bx_credits_profiles_administration', 'wdw_remaining', '_bx_credits_grid_column_title_pfl_wdw_remaining', '10%', 0, '', '', 4),
+('bx_credits_profiles_administration', 'balance', '_bx_credits_grid_column_title_pfl_balance', '15%', 0, '', '', 5),
+('bx_credits_profiles_administration', 'balance_cleared', '_bx_credits_grid_column_title_pfl_balance_cleared', '15%', 0, '', '', 6),
+('bx_credits_profiles_administration', 'actions', '', '20%', 0, '', '', 7);
+
+INSERT INTO `sys_grid_actions` (`object`, `type`, `name`, `title`, `icon`, `icon_only`, `confirm`, `order`) VALUES
+('bx_credits_profiles_administration', 'single', 'edit', '_bx_credits_grid_action_title_pfl_edit', 'pencil-alt', 1, 0, 1);
+
+
+-- ALERTS
+INSERT INTO `sys_alerts_handlers` (`name`, `class`, `file`, `service_call`) VALUES 
+('bx_credits', 'BxCreditsAlertsResponse', 'modules/boonex/credits/classes/BxCreditsAlertsResponse.php', '');
+SET @iHandler := LAST_INSERT_ID();
+
+INSERT INTO `sys_alerts` (`unit`, `action`, `handler_id`) VALUES
+('system', 'save_setting', @iHandler),
+('profile', 'add', @iHandler),
+('profile', 'delete', @iHandler);
+
+
+-- EMAIL TEMPLATES
+INSERT INTO `sys_email_templates` (`Module`, `NameSystem`, `Name`, `Subject`, `Body`) VALUES 
+('bx_credits', '_bx_credits_et_txt_name_granted', 'bx_credits_granted', '_bx_credits_et_txt_subject_granted', '_bx_credits_et_txt_body_granted'),
+('bx_credits', '_bx_credits_et_txt_name_received', 'bx_credits_received', '_bx_credits_et_txt_subject_received', '_bx_credits_et_txt_body_received'),
+('bx_credits', '_bx_credits_et_txt_name_purchased', 'bx_credits_purchased', '_bx_credits_et_txt_subject_purchased', '_bx_credits_et_txt_body_purchased'),
+('bx_credits', '_bx_credits_et_txt_name_in', 'bx_credits_in', '_bx_credits_et_txt_subject_in', '_bx_credits_et_txt_body_in'),
+('bx_credits', '_bx_credits_et_txt_name_out', 'bx_credits_out', '_bx_credits_et_txt_subject_out', '_bx_credits_et_txt_body_out'),
+('bx_credits', '_bx_credits_et_txt_name_withdraw_requested', 'bx_credits_withdraw_requested', '_bx_credits_et_txt_subject_withdraw_requested', '_bx_credits_et_txt_body_withdraw_requested'),
+('bx_credits', '_bx_credits_et_txt_name_withdraw_canceled', 'bx_credits_withdraw_canceled', '_bx_credits_et_txt_subject_withdraw_canceled', '_bx_credits_et_txt_body_withdraw_canceled'),
+('bx_credits', '_bx_credits_et_txt_name_withdraw_sent', 'bx_credits_withdraw_sent', '_bx_credits_et_txt_subject_withdraw_sent', '_bx_credits_et_txt_body_withdraw_sent');
+
+
+-- CRON
+INSERT INTO `sys_cron_jobs` (`name`, `time`, `class`, `file`, `service_call`) VALUES
+('bx_credits_clearing', '0 0 * * *', 'BxCreditsCronClearing', 'modules/boonex/credits/classes/BxCreditsCronClearing.php', '');

+ 51 - 0
modules/boonex/developer/updates/14.0.4_14.0.5/install/config.php

@@ -0,0 +1,51 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ */
+
+$aConfig = array(
+    /**
+     * Main Section.
+     */
+    'title' => 'Developer',
+    'version_from' => '14.0.4',
+    'version_to' => '14.0.5',
+    'vendor' => 'BoonEx',
+
+    'compatible_with' => array(
+        '14.0.0-RC4'
+    ),
+
+    /**
+     * '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_14.0.4_14.0.5/',
+    'home_uri' => 'developer_update_1404_1405',
+
+    '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',
+
+    /**
+     * Files Section
+     */
+    'delete_files' => array(),
+);

+ 13 - 0
modules/boonex/developer/updates/14.0.4_14.0.5/install/installer.php

@@ -0,0 +1,13 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ */
+
+class BxDevUpdater extends BxDolStudioUpdater
+{
+    function __construct($aConfig)
+    {
+        parent::__construct($aConfig);
+    }
+}

+ 779 - 0
modules/boonex/developer/updates/14.0.4_14.0.5/source/classes/BxDevFormsField.php

@@ -0,0 +1,779 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Developer Developer
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+require_once('BxDevFunctions.php');
+
+class BxDevFormsField extends BxTemplStudioFormsField
+{
+    function __construct($aParams = array(), $aField = array())
+    {
+        parent::__construct($aParams, $aField);
+
+        $this->aTypes = array_merge($this->aTypes, array(
+        	'captcha' => array('add' => 1),
+        	'location' => array('add' => 1), 
+        	'custom' => array('add' => 1)
+        ));
+    }
+}
+
+class BxDevFormsFieldBlockHeader extends BxTemplStudioFormsFieldBlockHeader
+{
+    public function init()
+    {
+        parent::init();
+
+        BxDevFunctions::changeFormField($this->aParams, $this->aForm['inputs'], $this->oDb);
+    }
+
+    protected function getFormAdd($sAction, $sObject)
+    {
+        $aForm = parent::getFormAdd($sAction, $sObject);
+        BxDevFunctions::changeForm($sAction, $aForm, $this);
+        return $aForm;
+    }
+
+    protected function getFormEdit($sAction, $sObject)
+    {
+        $aForm = parent::getFormEdit($sAction, $sObject);
+        BxDevFunctions::changeForm($sAction, $aForm, $this);
+        return $aForm;
+    }
+}
+
+class BxDevFormsFieldBlockEnd extends BxTemplStudioFormsFieldBlockEnd
+{
+    public function init()
+    {
+        parent::init();
+
+        BxDevFunctions::changeFormField($this->aParams, $this->aForm['inputs'], $this->oDb);
+    }
+
+    protected function getFormAdd($sAction, $sObject)
+    {
+        $aForm = parent::getFormAdd($sAction, $sObject);
+        BxDevFunctions::changeForm($sAction, $aForm, $this);
+        return $aForm;
+    }
+
+    protected function getFormEdit($sAction, $sObject)
+    {
+        $aForm = parent::getFormEdit($sAction, $sObject);
+        BxDevFunctions::changeForm($sAction, $aForm, $this);
+        return $aForm;
+    }
+}
+
+class BxDevFormsFieldValue extends BxTemplStudioFormsFieldValue
+{
+    public function init()
+    {
+        parent::init();
+
+        BxDevFunctions::changeFormField($this->aParams, $this->aForm['inputs'], $this->oDb);
+    }
+
+    protected function getFormAdd($sAction, $sObject)
+    {
+        $aForm = parent::getFormAdd($sAction, $sObject);
+        BxDevFunctions::changeForm($sAction, $aForm, $this);
+        return $aForm;
+    }
+
+    protected function getFormEdit($sAction, $sObject)
+    {
+        $aForm = parent::getFormEdit($sAction, $sObject);
+        BxDevFunctions::changeForm($sAction, $aForm, $this);
+        return $aForm;
+    }
+}
+
+class BxDevFormsFieldText extends BxTemplStudioFormsFieldText
+{
+    public function init()
+    {
+        parent::init();
+
+        BxDevFunctions::changeFormField($this->aParams, $this->aForm['inputs'], $this->oDb);
+    }
+
+    protected function getFormAdd($sAction, $sObject)
+    {
+        $aForm = parent::getFormAdd($sAction, $sObject);
+        BxDevFunctions::changeForm($sAction, $aForm, $this);
+        return $aForm;
+    }
+
+    protected function getFormEdit($sAction, $sObject)
+    {
+        $aForm = parent::getFormEdit($sAction, $sObject);
+        BxDevFunctions::changeForm($sAction, $aForm, $this);
+        return $aForm;
+    }
+}
+
+class BxDevFormsFieldPassword extends BxTemplStudioFormsFieldPassword
+{
+    public function init()
+    {
+        parent::init();
+
+        BxDevFunctions::changeFormField($this->aParams, $this->aForm['inputs'], $this->oDb);
+    }
+
+    protected function getFormAdd($sAction, $sObject)
+    {
+        $aForm = parent::getFormAdd($sAction, $sObject);
+        BxDevFunctions::changeForm($sAction, $aForm, $this);
+        return $aForm;
+    }
+
+    protected function getFormEdit($sAction, $sObject)
+    {
+        $aForm = parent::getFormEdit($sAction, $sObject);
+        BxDevFunctions::changeForm($sAction, $aForm, $this);
+        return $aForm;
+    }
+}
+
+class BxDevFormsFieldTextarea extends BxTemplStudioFormsFieldTextarea
+{
+    public function init()
+    {
+        parent::init();
+
+        BxDevFunctions::changeFormField($this->aParams, $this->aForm['inputs'], $this->oDb);
+
+        $this->aForm['inputs'] = $this->addInArray($this->aForm['inputs'], 'required', array(
+            'unique' => $this->aFieldUnique
+        ));
+    }
+
+    protected function getFormAdd($sAction, $sObject)
+    {
+        $aForm = parent::getFormAdd($sAction, $sObject);
+        BxDevFunctions::changeForm($sAction, $aForm, $this);
+        return $aForm;
+    }
+
+    protected function getFormEdit($sAction, $sObject)
+    {
+        $aForm = parent::getFormEdit($sAction, $sObject);
+        BxDevFunctions::changeForm($sAction, $aForm, $this);
+        return $aForm;
+    }
+}
+
+class BxDevFormsFieldNumber extends BxTemplStudioFormsFieldNumber
+{
+    public function init()
+    {
+        parent::init();
+
+        BxDevFunctions::changeFormField($this->aParams, $this->aForm['inputs'], $this->oDb);
+    }
+
+    protected function getFormAdd($sAction, $sObject)
+    {
+        $aForm = parent::getFormAdd($sAction, $sObject);
+        BxDevFunctions::changeForm($sAction, $aForm, $this);
+        return $aForm;
+    }
+
+    protected function getFormEdit($sAction, $sObject)
+    {
+        $aForm = parent::getFormEdit($sAction, $sObject);
+        BxDevFunctions::changeForm($sAction, $aForm, $this);
+        return $aForm;
+    }
+}
+
+class BxDevFormsFieldPrice extends BxTemplStudioFormsFieldPrice
+{
+    public function init()
+    {
+        parent::init();
+
+        BxDevFunctions::changeFormField($this->aParams, $this->aForm['inputs'], $this->oDb);
+    }
+
+    protected function getFormAdd($sAction, $sObject)
+    {
+        $aForm = parent::getFormAdd($sAction, $sObject);
+        BxDevFunctions::changeForm($sAction, $aForm, $this);
+        return $aForm;
+    }
+
+    protected function getFormEdit($sAction, $sObject)
+    {
+        $aForm = parent::getFormEdit($sAction, $sObject);
+        BxDevFunctions::changeForm($sAction, $aForm, $this);
+        return $aForm;
+    }
+}
+
+class BxDevFormsFieldDatepicker extends BxTemplStudioFormsFieldDatepicker
+{
+    public function init()
+    {
+        parent::init();
+
+        BxDevFunctions::changeFormField($this->aParams, $this->aForm['inputs'], $this->oDb);
+    }
+
+    protected function getFormAdd($sAction, $sObject)
+    {
+        $aForm = parent::getFormAdd($sAction, $sObject);
+        BxDevFunctions::changeForm($sAction, $aForm, $this);
+        return $aForm;
+    }
+
+    protected function getFormEdit($sAction, $sObject)
+    {
+        $aForm = parent::getFormEdit($sAction, $sObject);
+        BxDevFunctions::changeForm($sAction, $aForm, $this);
+        return $aForm;
+    }
+}
+
+class BxDevFormsFieldDateselect extends BxTemplStudioFormsFieldDateselect
+{
+    public function init()
+    {
+        parent::init();
+
+        BxDevFunctions::changeFormField($this->aParams, $this->aForm['inputs'], $this->oDb);
+    }
+
+    protected function getFormAdd($sAction, $sObject)
+    {
+        $aForm = parent::getFormAdd($sAction, $sObject);
+        BxDevFunctions::changeForm($sAction, $aForm, $this);
+        return $aForm;
+    }
+
+    protected function getFormEdit($sAction, $sObject)
+    {
+        $aForm = parent::getFormEdit($sAction, $sObject);
+        BxDevFunctions::changeForm($sAction, $aForm, $this);
+        return $aForm;
+    }
+}
+
+class BxDevFormsFieldDatetime extends BxTemplStudioFormsFieldDatetime
+{
+    public function init()
+    {
+        parent::init();
+
+        BxDevFunctions::changeFormField($this->aParams, $this->aForm['inputs'], $this->oDb);
+    }
+
+    protected function getFormAdd($sAction, $sObject)
+    {
+        $aForm = parent::getFormAdd($sAction, $sObject);
+        BxDevFunctions::changeForm($sAction, $aForm, $this);
+        return $aForm;
+    }
+
+    protected function getFormEdit($sAction, $sObject)
+    {
+        $aForm = parent::getFormEdit($sAction, $sObject);
+        BxDevFunctions::changeForm($sAction, $aForm, $this);
+        return $aForm;
+    }
+}
+
+class BxDevFormsFieldCheckbox extends BxTemplStudioFormsFieldCheckbox
+{
+    public function init()
+    {
+        parent::init();
+
+        BxDevFunctions::changeFormField($this->aParams, $this->aForm['inputs'], $this->oDb);
+
+        $this->aForm['inputs']['value']['type'] = 'text';
+    }
+
+    protected function getFormAdd($sAction, $sObject)
+    {
+        $aForm = parent::getFormAdd($sAction, $sObject);
+        BxDevFunctions::changeForm($sAction, $aForm, $this);
+        return $aForm;
+    }
+
+    protected function getFormEdit($sAction, $sObject)
+    {
+        $aForm = parent::getFormEdit($sAction, $sObject);
+        BxDevFunctions::changeForm($sAction, $aForm, $this);
+        return $aForm;
+    }
+}
+
+class BxDevFormsFieldSwitcher extends BxTemplStudioFormsFieldSwitcher
+{
+    public function init()
+    {
+        parent::init();
+
+        BxDevFunctions::changeFormField($this->aParams, $this->aForm['inputs'], $this->oDb);
+
+        $this->aForm['inputs']['value']['type'] = 'text';
+    }
+
+    protected function getFormAdd($sAction, $sObject)
+    {
+        $aForm = parent::getFormAdd($sAction, $sObject);
+        BxDevFunctions::changeForm($sAction, $aForm, $this);
+        return $aForm;
+    }
+
+    protected function getFormEdit($sAction, $sObject)
+    {
+        $aForm = parent::getFormEdit($sAction, $sObject);
+        BxDevFunctions::changeForm($sAction, $aForm, $this);
+        return $aForm;
+    }
+}
+
+class BxDevFormsFieldFile extends BxTemplStudioFormsFieldFile
+{
+    public function init()
+    {
+        parent::init();
+
+        BxDevFunctions::changeFormField($this->aParams, $this->aForm['inputs'], $this->oDb);
+    }
+
+    protected function getFormAdd($sAction, $sObject)
+    {
+        $aForm = parent::getFormAdd($sAction, $sObject);
+        BxDevFunctions::changeForm($sAction, $aForm, $this);
+        return $aForm;
+    }
+
+    protected function getFormEdit($sAction, $sObject)
+    {
+        $aForm = parent::getFormEdit($sAction, $sObject);
+        BxDevFunctions::changeForm($sAction, $aForm, $this);
+        return $aForm;
+    }
+}
+
+class BxDevFormsFieldFiles extends BxTemplStudioFormsFieldFiles
+{
+    public function init()
+    {
+        parent::init();
+
+        BxDevFunctions::changeFormField($this->aParams, $this->aForm['inputs'], $this->oDb);
+    }
+
+    protected function getFormAdd($sAction, $sObject)
+    {
+        $aForm = parent::getFormAdd($sAction, $sObject);
+        BxDevFunctions::changeForm($sAction, $aForm, $this);
+        return $aForm;
+    }
+
+    protected function getFormEdit($sAction, $sObject)
+    {
+        $aForm = parent::getFormEdit($sAction, $sObject);
+        BxDevFunctions::changeForm($sAction, $aForm, $this);
+        return $aForm;
+    }
+}
+
+class BxDevFormsFieldSlider extends BxTemplStudioFormsFieldSlider
+{
+    public function init()
+    {
+        parent::init();
+
+        BxDevFunctions::changeFormField($this->aParams, $this->aForm['inputs'], $this->oDb);
+
+        $this->aForm['inputs'] = $this->addInArray($this->aForm['inputs'], 'required', array(
+            'unique' => $this->aFieldUnique
+        ));
+    }
+
+    protected function getFormAdd($sAction, $sObject)
+    {
+        $aForm = parent::getFormAdd($sAction, $sObject);
+        BxDevFunctions::changeForm($sAction, $aForm, $this);
+        return $aForm;
+    }
+
+    protected function getFormEdit($sAction, $sObject)
+    {
+        $aForm = parent::getFormEdit($sAction, $sObject);
+        BxDevFunctions::changeForm($sAction, $aForm, $this);
+        return $aForm;
+    }
+}
+
+class BxDevFormsFieldDoublerange extends BxTemplStudioFormsFieldDoublerange
+{
+    public function init()
+    {
+        parent::init();
+
+        BxDevFunctions::changeFormField($this->aParams, $this->aForm['inputs'], $this->oDb);
+
+        $this->aForm['inputs'] = $this->addInArray($this->aForm['inputs'], 'required', array(
+            'unique' => $this->aFieldUnique
+        ));
+    }
+
+    protected function getFormAdd($sAction, $sObject)
+    {
+        $aForm = parent::getFormAdd($sAction, $sObject);
+        BxDevFunctions::changeForm($sAction, $aForm, $this);
+        return $aForm;
+    }
+
+    protected function getFormEdit($sAction, $sObject)
+    {
+        $aForm = parent::getFormEdit($sAction, $sObject);
+        BxDevFunctions::changeForm($sAction, $aForm, $this);
+        return $aForm;
+    }
+}
+
+class BxDevFormsFieldHidden extends BxTemplStudioFormsFieldHidden
+{
+    public function init()
+    {
+        parent::init();
+
+        BxDevFunctions::changeFormField($this->aParams, $this->aForm['inputs'], $this->oDb);
+    }
+
+    protected function getFormAdd($sAction, $sObject)
+    {
+        $aForm = parent::getFormAdd($sAction, $sObject);
+        BxDevFunctions::changeForm($sAction, $aForm, $this);
+        return $aForm;
+    }
+
+    protected function getFormEdit($sAction, $sObject)
+    {
+        $aForm = parent::getFormEdit($sAction, $sObject);
+        BxDevFunctions::changeForm($sAction, $aForm, $this);
+        return $aForm;
+    }
+}
+
+class BxDevFormsFieldButton extends BxTemplStudioFormsFieldButton
+{
+    public function init()
+    {
+        parent::init();
+
+        BxDevFunctions::changeFormField($this->aParams, $this->aForm['inputs'], $this->oDb);
+    }
+
+    protected function getFormAdd($sAction, $sObject)
+    {
+        $aForm = parent::getFormAdd($sAction, $sObject);
+        BxDevFunctions::changeForm($sAction, $aForm, $this);
+        return $aForm;
+    }
+
+    protected function getFormEdit($sAction, $sObject)
+    {
+        $aForm = parent::getFormEdit($sAction, $sObject);
+        BxDevFunctions::changeForm($sAction, $aForm, $this);
+        return $aForm;
+    }
+}
+
+class BxDevFormsFieldReset extends BxTemplStudioFormsFieldReset
+{
+    public function init()
+    {
+        parent::init();
+
+        BxDevFunctions::changeFormField($this->aParams, $this->aForm['inputs'], $this->oDb);
+    }
+
+    protected function getFormAdd($sAction, $sObject)
+    {
+        $aForm = parent::getFormAdd($sAction, $sObject);
+        BxDevFunctions::changeForm($sAction, $aForm, $this);
+        return $aForm;
+    }
+
+    protected function getFormEdit($sAction, $sObject)
+    {
+        $aForm = parent::getFormEdit($sAction, $sObject);
+        BxDevFunctions::changeForm($sAction, $aForm, $this);
+        return $aForm;
+    }
+}
+
+class BxDevFormsFieldSubmit extends BxTemplStudioFormsFieldSubmit
+{
+    public function init()
+    {
+        parent::init();
+
+        BxDevFunctions::changeFormField($this->aParams, $this->aForm['inputs'], $this->oDb);
+    }
+
+    protected function getFormAdd($sAction, $sObject)
+    {
+        $aForm = parent::getFormAdd($sAction, $sObject);
+        BxDevFunctions::changeForm($sAction, $aForm, $this);
+        return $aForm;
+    }
+
+    protected function getFormEdit($sAction, $sObject)
+    {
+        $aForm = parent::getFormEdit($sAction, $sObject);
+        BxDevFunctions::changeForm($sAction, $aForm, $this);
+        return $aForm;
+    }
+}
+
+class BxDevFormsFieldImage extends BxTemplStudioFormsFieldImage
+{
+    public function init()
+    {
+        parent::init();
+
+        BxDevFunctions::changeFormField($this->aParams, $this->aForm['inputs'], $this->oDb);
+    }
+
+    protected function getFormAdd($sAction, $sObject)
+    {
+        $aForm = parent::getFormAdd($sAction, $sObject);
+        BxDevFunctions::changeForm($sAction, $aForm, $this);
+        return $aForm;
+    }
+
+    protected function getFormEdit($sAction, $sObject)
+    {
+        $aForm = parent::getFormEdit($sAction, $sObject);
+        BxDevFunctions::changeForm($sAction, $aForm, $this);
+        return $aForm;
+    }
+}
+
+class BxDevFormsFieldSelect extends BxTemplStudioFormsFieldSelect
+{
+    public function init()
+    {
+        parent::init();
+
+        BxDevFunctions::changeFormField($this->aParams, $this->aForm['inputs'], $this->oDb);
+
+        $this->aForm['inputs'] = $this->addInArray($this->aForm['inputs'], 'required', array(
+            'unique' => $this->aFieldUnique
+        ));
+    }
+
+    protected function getFormAdd($sAction, $sObject)
+    {
+        $aForm = parent::getFormAdd($sAction, $sObject);
+        BxDevFunctions::changeForm($sAction, $aForm, $this);
+        return $aForm;
+    }
+
+    protected function getFormEdit($sAction, $sObject)
+    {
+        $aForm = parent::getFormEdit($sAction, $sObject);
+        BxDevFunctions::changeForm($sAction, $aForm, $this);
+        return $aForm;
+    }
+}
+
+class BxDevFormsFieldSelectMultiple extends BxTemplStudioFormsFieldSelectMultiple
+{
+    public function init()
+    {
+        parent::init();
+
+        BxDevFunctions::changeFormField($this->aParams, $this->aForm['inputs'], $this->oDb);
+
+        $this->aForm['inputs'] = $this->addInArray($this->aForm['inputs'], 'required', array(
+            'unique' => $this->aFieldUnique
+        ));
+    }
+
+    protected function getFormAdd($sAction, $sObject)
+    {
+        $aForm = parent::getFormAdd($sAction, $sObject);
+        BxDevFunctions::changeForm($sAction, $aForm, $this);
+        return $aForm;
+    }
+
+    protected function getFormEdit($sAction, $sObject)
+    {
+        $aForm = parent::getFormEdit($sAction, $sObject);
+        BxDevFunctions::changeForm($sAction, $aForm, $this);
+        return $aForm;
+    }
+}
+
+class BxDevFormsFieldCheckboxSet extends BxTemplStudioFormsFieldCheckboxSet
+{
+    public function init()
+    {
+        parent::init();
+
+        BxDevFunctions::changeFormField($this->aParams, $this->aForm['inputs'], $this->oDb);
+
+        $this->aForm['inputs'] = $this->addInArray($this->aForm['inputs'], 'required', array(
+            'unique' => $this->aFieldUnique
+        ));
+    }
+
+    protected function getFormAdd($sAction, $sObject)
+    {
+        $aForm = parent::getFormAdd($sAction, $sObject);
+        BxDevFunctions::changeForm($sAction, $aForm, $this);
+        return $aForm;
+    }
+
+    protected function getFormEdit($sAction, $sObject)
+    {
+        $aForm = parent::getFormEdit($sAction, $sObject);
+        BxDevFunctions::changeForm($sAction, $aForm, $this);
+        return $aForm;
+    }
+}
+
+class BxDevFormsFieldRadioSet extends BxTemplStudioFormsFieldRadioSet
+{
+    public function init()
+    {
+        parent::init();
+
+        BxDevFunctions::changeFormField($this->aParams, $this->aForm['inputs'], $this->oDb);
+
+        $this->aForm['inputs'] = $this->addInArray($this->aForm['inputs'], 'required', array(
+            'unique' => $this->aFieldUnique
+        ));
+    }
+
+    protected function getFormAdd($sAction, $sObject)
+    {
+        $aForm = parent::getFormAdd($sAction, $sObject);
+        BxDevFunctions::changeForm($sAction, $aForm, $this);
+        return $aForm;
+    }
+
+    protected function getFormEdit($sAction, $sObject)
+    {
+        $aForm = parent::getFormEdit($sAction, $sObject);
+        BxDevFunctions::changeForm($sAction, $aForm, $this);
+        return $aForm;
+    }
+}
+
+class BxDevFormsFieldCustom extends BxTemplStudioFormsFieldCustom
+{
+    public function init()
+    {
+        parent::init();
+
+        BxDevFunctions::changeFormField($this->aParams, $this->aForm['inputs'], $this->oDb);
+    }
+
+    protected function getFormAdd($sAction, $sObject)
+    {
+        $aForm = parent::getFormAdd($sAction, $sObject);
+        BxDevFunctions::changeForm($sAction, $aForm, $this);
+        return $aForm;
+    }
+
+    protected function getFormEdit($sAction, $sObject)
+    {
+        $aForm = parent::getFormEdit($sAction, $sObject);
+        BxDevFunctions::changeForm($sAction, $aForm, $this);
+        return $aForm;
+    }
+}
+
+class BxDevFormsFieldInputSet extends BxTemplStudioFormsFieldInputSet
+{
+    public function init()
+    {
+        parent::init();
+
+        BxDevFunctions::changeFormField($this->aParams, $this->aForm['inputs'], $this->oDb);
+    }
+
+    protected function getFormAdd($sAction, $sObject)
+    {
+        $aForm = parent::getFormAdd($sAction, $sObject);
+        BxDevFunctions::changeForm($sAction, $aForm, $this);
+        return $aForm;
+    }
+
+    protected function getFormEdit($sAction, $sObject)
+    {
+        $aForm = parent::getFormEdit($sAction, $sObject);
+        BxDevFunctions::changeForm($sAction, $aForm, $this);
+        return $aForm;
+    }
+}
+
+class BxDevFormsFieldCaptcha extends BxTemplStudioFormsFieldCaptcha
+{
+    public function init()
+    {
+        parent::init();
+
+        BxDevFunctions::changeFormField($this->aParams, $this->aForm['inputs'], $this->oDb);
+    }
+
+    protected function getFormAdd($sAction, $sObject)
+    {
+        $aForm = parent::getFormAdd($sAction, $sObject);
+        BxDevFunctions::changeForm($sAction, $aForm, $this);
+        return $aForm;
+    }
+
+    protected function getFormEdit($sAction, $sObject)
+    {
+        $aForm = parent::getFormEdit($sAction, $sObject);
+        BxDevFunctions::changeForm($sAction, $aForm, $this);
+        return $aForm;
+    }
+}
+
+class BxDevFormsFieldLocation extends BxTemplStudioFormsFieldLocation
+{
+    public function init()
+    {
+        parent::init();
+
+        BxDevFunctions::changeFormField($this->aParams, $this->aForm['inputs'], $this->oDb);
+    }
+
+    protected function getFormAdd($sAction, $sObject)
+    {
+        $aForm = parent::getFormAdd($sAction, $sObject);
+        BxDevFunctions::changeForm($sAction, $aForm, $this);
+        return $aForm;
+    }
+
+    protected function getFormEdit($sAction, $sObject)
+    {
+        $aForm = parent::getFormEdit($sAction, $sObject);
+        BxDevFunctions::changeForm($sAction, $aForm, $this);
+        return $aForm;
+    }
+}
+/** @} */

+ 69 - 0
modules/boonex/developer/updates/14.0.4_14.0.5/source/install/config.php

@@ -0,0 +1,69 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Developer Developer
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+$aConfig = array(
+    /**
+     * Main Section.
+     */
+    'type' => BX_DOL_MODULE_TYPE_MODULE,
+    'name' => 'bx_developer',
+    'title' => 'Developer',
+    'note' => 'Developer tools...',
+    'version' => '14.0.5',
+    'vendor' => 'UNA INC',
+    'help_url' => 'http://feed.una.io/?section={module_name}',
+
+    'compatible_with' => array(
+        '14.0.0-RC4'
+    ),
+
+    /**
+     * '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',
+
+	/**
+     * Category for language keys.
+     */
+    'language_category' => 'BoonEx Developer',
+
+    /**
+     * Installation/Uninstallation Section.
+     */
+    'install' => array(
+        'execute_sql' => 1,
+        'update_languages' => 1,
+        'clear_db_cache' => 1
+    ),
+    'uninstall' => array (
+        'execute_sql' => 1,
+        'update_languages' => 1,
+        'clear_db_cache' => 1
+    ),
+    'enable' => array(
+        'execute_sql' => 1,
+    ),
+    'disable' => array(
+        'execute_sql' => 1,
+    ),
+
+    /**
+     * Dependencies Section
+     */
+    'dependencies' => array(),
+
+);
+
+/** @} */

+ 51 - 0
modules/boonex/files/updates/14.0.4_14.0.5/install/config.php

@@ -0,0 +1,51 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ */
+
+$aConfig = array(
+    /**
+     * Main Section.
+     */
+    'title' => 'Files',
+    'version_from' => '14.0.4',
+    'version_to' => '14.0.5',
+    'vendor' => 'BoonEx',
+
+    'compatible_with' => array(
+        '14.0.0-RC4'
+    ),
+
+    /**
+     * 'home_dir' and 'home_uri' - should be unique. Don't use spaces in 'home_uri' and the other special chars.
+     */
+    'home_dir' => 'boonex/files/updates/update_14.0.4_14.0.5/',
+    'home_uri' => 'files_update_1404_1405',
+
+    'module_dir' => 'boonex/files/',
+    'module_uri' => 'files',
+
+    'db_prefix' => 'bx_files_',
+    'class_prefix' => 'BxFiles',
+
+    /**
+     * Installation/Uninstallation Section.
+     */
+    'install' => array(
+        'execute_sql' => 0,
+        'update_files' => 1,
+        'update_languages' => 0,
+        'clear_db_cache' => 0,
+    ),
+
+    /**
+     * Category for language keys.
+     */
+    'language_category' => 'Files',
+
+    /**
+     * Files Section
+     */
+    'delete_files' => array(),
+);

+ 13 - 0
modules/boonex/files/updates/14.0.4_14.0.5/install/installer.php

@@ -0,0 +1,13 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ */
+
+class BxFilesUpdater extends BxDolStudioUpdater
+{
+    function __construct($aConfig)
+    {
+        parent::__construct($aConfig);
+    }
+}

+ 142 - 0
modules/boonex/files/updates/14.0.4_14.0.5/source/install/config.php

@@ -0,0 +1,142 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Files Files
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+$aConfig = array(
+
+    /**
+     * Main Section.
+     */
+    'type' => BX_DOL_MODULE_TYPE_MODULE,
+    'name' => 'bx_files',
+    'title' => 'Files',
+    'note' => 'Basic blogging module.',
+    'version' => '14.0.5',
+    'vendor' => 'UNA INC',
+    'help_url' => 'http://feed.una.io/?section={module_name}',
+
+    'compatible_with' => array(
+        '14.0.0-RC4'
+    ),
+
+    /**
+     * 'home_dir' and 'home_uri' - should be unique. Don't use spaces in 'home_uri' and the other special chars.
+     */
+    'home_dir' => 'boonex/files/',
+    'home_uri' => 'files',
+
+    'db_prefix' => 'bx_files_',
+    'class_prefix' => 'BxFiles',
+
+    /**
+     * Category for language keys.
+     */
+    'language_category' => 'Files',
+
+    /**
+     * List of page triggers.
+     */
+    'page_triggers' => array (
+    	'trigger_page_profile_view_entry',
+    ),
+    
+    /**
+     * Menu triggers.
+     */
+    'menu_triggers' => array(
+    	'trigger_profile_view_submenu',
+    	'trigger_group_view_submenu',
+    ),
+
+	/**
+     * Storage objects to automatically delete files from upon module uninstallation.
+     * Note. Don't add storage objects used in transcoder objects.
+     */
+    'storages' => array(
+    	'bx_files_files'
+    ),
+
+    /**
+     * Transcoders.
+     */
+    'transcoders' => array(
+        'bx_files_preview',
+        'bx_files_gallery',
+
+        'bx_files_sounds_mp3',
+
+        'bx_files_videos_poster',
+        'bx_files_videos_poster_preview',
+        'bx_files_videos_mp4',
+        'bx_files_videos_mp4_hd'
+    ),
+
+	/**
+     * Extended Search Forms.
+     */
+    'esearches' => array(
+        'bx_files',
+    	'bx_files_cmts',
+    ),
+
+    /**
+     * Installation/Uninstallation Section.
+     */
+    'install' => array(
+        'execute_sql' => 1,
+        'update_languages' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'uninstall' => array (
+    	'process_esearches' => 1,
+        'execute_sql' => 1,
+        'update_languages' => 1,
+    	'update_relations' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'enable' => array(
+        'execute_sql' => 1,
+    	'update_relations' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'enable_success' => array(
+        'process_menu_triggers' => 1,
+        'process_page_triggers' => 1,
+    	'process_esearches' => 1,
+    	'register_transcoders' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'disable' => array (
+        'execute_sql' => 1,
+    	'update_relations' => 1,
+    	'unregister_transcoders' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'disable_failed' => array (
+    	'register_transcoders' => 1,
+    	'clear_db_cache' => 1,
+    ),
+
+    /**
+     * Dependencies Section
+     */
+    'dependencies' => array(),
+
+    /**
+     * Relations Section
+     */
+    'relations' => array(
+    	'bx_timeline',
+    	'bx_notifications',
+    ),
+
+);
+
+/** @} */

+ 151 - 0
modules/boonex/files/updates/14.0.4_14.0.5/source/template/css/main.css

@@ -0,0 +1,151 @@
+.bx-files-text-unit-gallery .bx-base-text-unit-no-thumb {
+    position:relative;
+}
+
+.bx-files-text-unit-gallery .bx-base-text-unit-no-thumb .sys-icon {
+    left:0;
+    top:0;
+    width:100%;
+    position:absolute;
+    font-size:10rem;
+    line-height:12.25rem;
+    text-align:center;
+    overflow:hidden;
+}
+
+.bx-files-text-unit-gallery .bx-files-filename,
+.bx-files-text-unit-simple-row .bx-files-filename{
+    overflow: hidden;
+    text-overflow: ellipsis;
+    line-height: 2rem;
+    margin: 0px;
+    font-weight: bold;
+    white-space: nowrap;
+}
+
+.bx-files-text-unit-gallery .bx-base-general-unit-meta ul.bx-menu-custom.bx-menu-custom-hor {
+    align-items: center;
+    -webkit-align-items: center;
+    justify-content: center;
+    -webkit-justify-content: center;
+}
+
+.bx-files-text-unit-gallery .bx-files-inline-menu ul.bx-menu-object-bx_files_view_inline li.bx-menu-item span.bx-base-general-entity-action {
+    margin: 0px;
+    vertical-align: top;
+}
+.bx-files-inline-menu ul.bx-menu-object-bx_files_view_inline > li.bx-menu-item {
+    white-space: nowrap;
+}
+.bx-files-text-unit-gallery .bx-menu-custom.bx-menu-custom-hor.bx-menu-more-auto {
+    justify-content: center;
+}
+.bx-files-text-unit-gallery {
+    overflow: visible!important;
+}
+.bx-files-text-unit-gallery .bx-base-text-unit-thumb,
+.bx-files-text-unit-gallery .bx-base-text-unit-no-thumb,
+.bx-files-text-unit-gallery .bx-base-text-unit-text {
+    overflow: hidden;
+}
+.bx-media-phone .bx-files-text-unit-gallery,
+.bx-media-desktop .bx-layout-column-thin .bx-files-text-unit-gallery {
+    max-width: 100%;
+}
+.bx-media-tablet2 .bx-files-text-unit-gallery,
+.bx-media-desktop .bx-layout-column-half .bx-files-text-unit-gallery {
+    max-width: 49.8%;
+}
+.bx-media-desktop .bx-files-text-unit-gallery {
+    max-width: 33.25%;
+}
+
+.bx-files-text-unit .bx-base-text-unit-text .sys-icon {
+    line-height: normal;
+    font-size: 3.2rem;
+}
+
+/*--- View page ---*/
+.bx-files-entity-preview {
+    overflow: hidden;
+}
+.bx-files-entity-preview .bx-msg-box-container {
+    margin: 0;
+    padding: 0;
+}
+
+/*--- Files Browser Table layout ---*/
+.bx-files-text-unit-simple-row {
+    text-align: left;
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+}
+.bx-files-text-unit-simple-row .bx-files-fileinfo {
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+    display: flex;
+    align-items: center;
+    -webkit-align-items: center;
+}
+.bx-files-text-unit-simple-row .bx-files-fileinfo-text {
+    display: inline-block;
+    overflow: hidden;
+}
+.bx-files-text-unit-simple-row .bx-files-inline-menu ul.bx-menu-object-bx_files_view_inline {
+    float: right;
+}
+.bx-files-text-unit-simple-row .bx-files-inline-menu ul.bx-menu-object-bx_files_view_inline li.bx-menu-item span.bx-base-general-entity-action {
+    margin: 0px;
+    vertical-align: top;
+}
+.bx-files-text-unit-simple-row .bx-files-fileinfo i {
+    font-size: 2.3rem;
+    line-height: 2.3rem;
+}
+.bx-files-text-unit-simple-row .bx-base-general-unit-meta ul {
+    margin: 0px!important;
+    margin-top: 0.2rem;
+}
+.bx-files-text-unit-simple-row .bx-files-filename {
+    line-height: unset;
+}
+
+
+/*--- Toolbar ---*/
+.bx-files-browser-toolbar {
+    width: 100%;
+    box-sizing: border-box;
+    text-align: left;
+    padding-top: 0px;
+}
+.bx-files-browser-toolbar .bx-form-element-wrapper {
+    display: inline-block;
+    margin: 0px;
+}
+.bx-files-browser-toolbar .bx-btn {
+    float: none;
+    display: inline-block;
+    vertical-align: top;
+}
+.bx-files-toolbar-controls-group {
+    display: inline-block;
+    margin-right: 10px;
+    white-space: nowrap;
+    margin-bottom: 1rem;
+    vertical-align: middle;
+}
+.bx-files-toolbar-spacer {
+    width: 100%;
+    margin-bottom: 0.5rem;
+}
+.bx-files-folder-path i:last-child {
+    display: none;
+}
+.bx-files-bulk-actions {
+    display: none;
+}
+.bx-files-input-checkbox-select-all {
+    display: inline-block!important;
+}

+ 19 - 0
modules/boonex/files/updates/14.0.4_14.0.5/source/template/unit.html

@@ -0,0 +1,19 @@
+<div class="bx-files-text-unit bx-base-text-unit bx-base-text-unit-ext bx-def-box bx-def-round-corners bx-def-color-bg-box bx-def-margin-bottom">
+    <bx_if:thumb>
+        <div class="bx-base-text-unit-cover">
+            <img class="bx-base-text-unit-cover bx-def-round-corners aspect-video object-cover bg-cover" alt="__title__" src="__thumb_url__" />
+        </div>
+    </bx_if:thumb>
+    <div class="bx-base-text-unit-text bx-def-padding bx-def-box-sizing flex flex-row flex-wrap">
+        <div class="flex-none">
+            <i class="sys-icon __icon__"></i>
+        </div>
+        <div class="flex-1 ltr:ml-4 rtl:mr-4">
+            <h2><a href="__content_url__">__title__</a></h2>
+            <div class="bx-base-text-unit-info bx-def-margin-sec-top bx-def-font-small">
+                <bx_if:meta><div class="bx-base-general-unit-meta">__meta__</div></bx_if:meta>
+            </div>
+        </div>
+        <div class="bx-base-text-unit-summary bx-def-margin-sec-top w-full">__summary__</div> 
+    </div>
+</div>

+ 51 - 0
modules/boonex/forum/updates/14.0.4_14.0.5/install/config.php

@@ -0,0 +1,51 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ */
+
+$aConfig = array(
+    /**
+     * Main Section.
+     */
+    'title' => 'Discussions',
+    'version_from' => '14.0.4',
+    'version_to' => '14.0.5',
+    'vendor' => 'BoonEx',
+
+    'compatible_with' => array(
+        '14.0.0-RC4'
+    ),
+
+    /**
+     * 'home_dir' and 'home_uri' - should be unique. Don't use spaces in 'home_uri' and the other special chars.
+     */
+    'home_dir' => 'boonex/forum/updates/update_14.0.4_14.0.5/',
+    'home_uri' => 'forum_update_1404_1405',
+
+    'module_dir' => 'boonex/forum/',
+    'module_uri' => 'forum',
+
+    'db_prefix' => 'bx_forum_',
+    'class_prefix' => 'BxForum',
+
+    /**
+     * Installation/Uninstallation Section.
+     */
+    'install' => array(
+        'execute_sql' => 0,
+        'update_files' => 1,
+        'update_languages' => 0,
+        'clear_db_cache' => 0,
+    ),
+
+    /**
+     * Category for language keys.
+     */
+    'language_category' => 'Discussions',
+
+    /**
+     * Files Section
+     */
+    'delete_files' => array(),
+);

+ 13 - 0
modules/boonex/forum/updates/14.0.4_14.0.5/install/installer.php

@@ -0,0 +1,13 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ */
+
+class BxForumUpdater extends BxDolStudioUpdater
+{
+    function __construct($aConfig)
+    {
+        parent::__construct($aConfig);
+    }
+}

+ 151 - 0
modules/boonex/forum/updates/14.0.4_14.0.5/source/install/config.php

@@ -0,0 +1,151 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Forum Forum
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+$aConfig = array(
+
+    /**
+     * Main Section.
+     */
+    'type' => BX_DOL_MODULE_TYPE_MODULE,
+    'name' => 'bx_forum',
+    'title' => 'Discussions',
+    'note' => 'Discussions module.',
+    'version' => '14.0.5',
+    'vendor' => 'UNA INC',
+    'help_url' => 'http://feed.una.io/?section={module_name}',
+
+    'compatible_with' => array(
+        '14.0.0-RC4'
+    ),
+
+    /**
+     * 'home_dir' and 'home_uri' - should be unique. Don't use spaces in 'home_uri' and the other special chars.
+     */
+    'home_dir' => 'boonex/forum/',
+    'home_uri' => 'forum',
+
+    'db_prefix' => 'bx_forum_',
+    'class_prefix' => 'BxForum',
+
+    /**
+     * Category for language keys.
+     */
+    'language_category' => 'Discussions',
+    
+    /**
+     * List of page triggers.
+     */
+    'page_triggers' => array (
+    	'trigger_page_profile_view_entry',
+    ),
+    
+    /**
+     * Menu triggers.
+     */
+    'menu_triggers' => array(
+    	'trigger_profile_view_submenu',
+        'trigger_group_view_submenu'
+    ),
+
+	/**
+     * Storage objects to automatically delete files from upon module uninstallation.
+     * Note. Don't add storage objects used in transcoder objects.
+     */
+    'storages' => array(
+    	'bx_forum_files'
+    ),
+
+    /**
+     * Transcoders.
+     */
+    'transcoders' => array(
+        'bx_forum_preview',
+        'bx_forum_miniature', 
+        'bx_forum_gallery',
+        'bx_forum_cover',
+
+        'bx_forum_preview_photos',
+        'bx_forum_miniature_photos', 
+        'bx_forum_gallery_photos',
+        'bx_forum_view_photos',
+
+        'bx_forum_videos_poster',
+        'bx_forum_videos_poster_preview',
+        'bx_forum_videos_mp4',
+        'bx_forum_videos_mp4_hd',
+
+        'bx_forum_preview_files',
+        'bx_forum_gallery_files',
+
+        'bx_forum_preview_cmts',
+    ),
+
+    /**
+     * Extended Search Forms.
+     */
+    'esearches' => array(
+        'bx_forum',
+    	'bx_forum_cmts',
+    ),
+
+    /**
+     * Installation/Uninstallation Section.
+     */
+    'install' => array(
+        'execute_sql' => 1,
+        'update_languages' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'uninstall' => array (
+    	'process_esearches' => 1,
+        'execute_sql' => 1,
+        'update_languages' => 1,
+    	'update_relations' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'enable' => array(
+        'execute_sql' => 1,
+    	'update_relations' => 1,
+        'clear_db_cache' => 1,
+    ),
+	'enable_success' => array(
+    	'process_menu_triggers' => 1,
+        'process_page_triggers' => 1,
+    	'process_esearches' => 1,
+    	'register_transcoders' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'disable' => array (
+        'execute_sql' => 1,
+    	'update_relations' => 1,
+    	'unregister_transcoders' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'disable_failed' => array (
+    	'register_transcoders' => 1,
+    	'clear_db_cache' => 1,
+    ),
+
+    /**
+     * Dependencies Section
+     */
+    'dependencies' => array(),
+
+    /**
+     * Relations Section
+     */
+    'relations' => array(
+    	'bx_timeline',
+    	'bx_notifications'
+    ),
+);
+
+/** @} */

+ 15 - 0
modules/boonex/forum/updates/14.0.4_14.0.5/source/template/score_element_inline.html

@@ -0,0 +1,15 @@
+<span id="__html_id__" class="sys-action __style_prefix__ __class__ inline-flex items-center whitespace-nowrap" bx_score_data_score="__score__" bx_score_data_cup="__cup__" bx_score_data_cdown="__cdown__">
+    <span class="sys-action-cnt __style_prefix__-cnt relative z-0 inline-flex shadow-sm rounded-md">
+        <bx_if:show_do_vote_up>
+            <span class="sys-action-element-holder __style_prefix__-element-holder __style_prefix__-eh-__style__ -mr-px border relative inline-flex items-center px-1.5 py-1 ltr:rounded-l-md rtl:rounded-r-md shadow-sm hover:shadow active:shadow-none font-medium text-xs bg-gray-100 text-gray-600 hover:text-gray-900 active:text-gray-900 border-gray-300  active:bg-gray-300  active:border-gray-400 hover:bg-white dark:bg-gray-700 dark:border-gray-600 dark:hover:bg-gray-700/50  dark:active:bg-gray-800 dark:active:border-gray-700  dark:text-gray-300 dark:hover:text-white dark:active:text-gray-200">__do_vote__</span>
+            <bx_if:show_counter_up><span class="sys-action-counter-holder __style_prefix__-counter-holder __style_prefix__-ch-__style__ -mr-px border relative inline-flex items-center px-1.5 py-1 shadow-sm hover:shadow active:shadow-none font-medium text-xs bg-gray-100 text-gray-600 hover:text-gray-900 active:text-gray-900 border-gray-300  active:bg-gray-300  active:border-gray-400 hover:bg-white dark:bg-gray-700 dark:border-gray-600 dark:hover:bg-gray-700/50  dark:active:bg-gray-800 dark:active:border-gray-700 dark:text-gray-300 dark:hover:text-white dark:active:text-gray-200"<bx_if:show_cup_hidden> style="display:none"</bx_if:show_cup_hidden>>__counter__</span></bx_if:show_counter_up>
+        </bx_if:show_do_vote_up>
+        <bx_if:show_counter>
+            <span class="sys-action-counter-holder __style_prefix__-counter-holder __style_prefix__-ch-__style__ border relative inline-flex items-center px-1.5 py-1 shadow-sm hover:shadow active:shadow-none font-medium text-xs bg-gray-100 text-gray-600 hover:text-gray-900 active:text-gray-900 border-gray-300  active:bg-gray-300  active:border-gray-400 hover:bg-white dark:bg-gray-700 dark:border-gray-600 dark:hover:bg-gray-700/50  dark:active:bg-gray-800 dark:active:border-gray-700  dark:text-gray-300 dark:hover:text-white dark:active:text-gray-200"<bx_if:show_hidden> style="display:none"</bx_if:show_hidden>>__counter__</span>
+        </bx_if:show_counter>
+        <bx_if:show_do_vote_down>
+            <bx_if:show_counter_down><span class="sys-action-counter-holder __style_prefix__-counter-holder __style_prefix__-ch-__style__ -mr-px border relative inline-flex items-center px-1.5 py-1 shadow-sm hover:shadow active:shadow-none font-medium text-xs bg-gray-100 text-gray-600 hover:text-gray-900 active:text-gray-900 border-gray-300  active:bg-gray-300  active:border-gray-400 hover:bg-white dark:bg-gray-700 dark:border-gray-600 dark:hover:bg-gray-700/50  dark:active:bg-gray-800 dark:active:border-gray-700 dark:text-gray-300 dark:hover:text-white dark:active:text-gray-200"<bx_if:show_cdown_hidden> style="display:none"</bx_if:show_cdown_hidden>>__counter__</span></bx_if:show_counter_down>
+            <span class="sys-action-element-holder __style_prefix__-element-holder __style_prefix__-eh-__style__ -ml-px border relative inline-flex items-center px-1.5 py-1 ltr:rounded-r-md rtl:rounded-l-md shadow-sm hover:shadow active:shadow-none font-medium text-xs bg-gray-100 text-gray-600 hover:text-gray-900 active:text-gray-900 border-gray-300  active:bg-gray-300  active:border-gray-400 hover:bg-white dark:bg-gray-700 dark:border-gray-600 dark:hover:bg-gray-700/50  dark:active:bg-gray-800 dark:active:border-gray-700  dark:text-gray-300 dark:hover:text-white dark:active:text-gray-200">__do_vote__</span>
+        </bx_if:show_do_vote_down>
+    </span>__script__
+</span>

+ 51 - 0
modules/boonex/market/updates/14.0.6_14.0.7/install/config.php

@@ -0,0 +1,51 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ */
+
+$aConfig = array(
+    /**
+     * Main Section.
+     */
+    'title' => 'Market',
+    'version_from' => '14.0.6',
+    'version_to' => '14.0.7',
+    'vendor' => 'UNA INC',
+
+    'compatible_with' => array(
+        '14.0.0-RC4'
+    ),
+
+    /**
+     * 'home_dir' and 'home_uri' - should be unique. Don't use spaces in 'home_uri' and the other special chars.
+     */
+    'home_dir' => 'boonex/market/updates/update_14.0.6_14.0.7/',
+    'home_uri' => 'market_update_1406_1407',
+
+    'module_dir' => 'boonex/market/',
+    'module_uri' => 'market',
+
+    'db_prefix' => 'bx_market_',
+    'class_prefix' => 'BxMarket',
+
+    /**
+     * Installation/Uninstallation Section.
+     */
+    'install' => array(
+        'execute_sql' => 1,
+        'update_files' => 1,
+        'update_languages' => 1,
+        'clear_db_cache' => 1,
+    ),
+
+    /**
+     * Category for language keys.
+     */
+    'language_category' => 'Market',
+
+    /**
+     * Files Section
+     */
+    'delete_files' => array(),
+);

+ 13 - 0
modules/boonex/market/updates/14.0.6_14.0.7/install/installer.php

@@ -0,0 +1,13 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ */
+
+class BxMarketUpdater extends BxDolStudioUpdater
+{
+    public function __construct($aConfig)
+    {
+        parent::__construct($aConfig);
+    }
+}

+ 8 - 0
modules/boonex/market/updates/14.0.6_14.0.7/install/langs/en.xml

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources name="en" flag="gb" title="English">
+	<string_add name="_bx_market_form_entry_input_name_inf"><![CDATA[Unique name for payment identification.]]></string_add>
+
+	<string_upd name="_bx_market_form_entry_input_sys_name"><![CDATA[Identifier]]></string_upd>
+	<string_upd name="_bx_market_form_entry_input_name"><![CDATA[Identifier]]></string_upd>
+	<string_upd name="_bx_market_form_entry_input_name_err"><![CDATA[Identifier should be unique and is needed for internal usage. Please, fill in this field]]></string_upd>
+</resources>

+ 4 - 0
modules/boonex/market/updates/14.0.6_14.0.7/install/sql/install.sql

@@ -0,0 +1,4 @@
+SET @sName = 'bx_market';
+
+-- FORMS
+UPDATE `sys_form_inputs` SET `info`='_bx_market_form_entry_input_name_inf', `checker_func`='', `checker_error`='' WHERE `object`=@sName AND `name`='name';

+ 364 - 0
modules/boonex/market/updates/14.0.6_14.0.7/source/classes/BxMarketFormEntry.php

@@ -0,0 +1,364 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Market Market
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+/**
+ * Create/Edit entry form
+ */
+class BxMarketFormEntry extends BxBaseModTextFormEntry
+{
+    protected $_bPhotoGhostCheckboxes;
+
+    public function __construct($aInfo, $oTemplate = false)
+    {
+        $this->MODULE = 'bx_market';
+        parent::__construct($aInfo, $oTemplate);
+
+        $CNF = &$this->_oModule->_oConfig->CNF;
+
+        /*
+         * Disabled since Header Image and Icon uploaders were moved on view product page.
+         */
+        $this->_bPhotoGhostCheckboxes = false;
+
+        $iProfileId = bx_get_logged_profile_id();
+
+        if(isset($this->aInputs[$CNF['FIELD_TITLE']], $this->aInputs[$CNF['FIELD_NAME']])) {
+            $sJsObject = $this->_oModule->_oConfig->getJsObject('form');
+
+            $aMask = array('mask' => "javascript:%s.checkName(this, '%s', '%s');", $sJsObject, $CNF['FIELD_TITLE'], $CNF['FIELD_NAME']);
+            if($this->aParams['display'] == $CNF['OBJECT_FORM_ENTRY_DISPLAY_EDIT'] && bx_get('id') !== false) {
+                $aMask['mask'] = "javascript:%s.checkName(this, '%s', '%s', %d);";
+                $aMask[] = (int)bx_get('id');
+            }
+
+            $sOnBlur = call_user_func_array('sprintf', array_values($aMask)); 
+            $this->aInputs[$CNF['FIELD_TITLE']]['attrs']['onblur'] = $sOnBlur;
+            $this->aInputs[$CNF['FIELD_NAME']]['attrs']['onblur'] = $sOnBlur;
+        }
+
+        if(isset($this->aInputs[$CNF['FIELD_COVER_RAW']]))
+            $this->aInputs[$CNF['FIELD_COVER_RAW']]['code'] = 1;
+
+        if(isset($this->aInputs[$CNF['FIELD_FILE']])) {
+            $this->aInputs[$CNF['FIELD_FILE']]['storage_object'] = $CNF['OBJECT_STORAGE_FILES'];
+            $this->aInputs[$CNF['FIELD_FILE']]['uploaders'] =  !empty($this->aInputs[$CNF['FIELD_FILE']]['value']) ? unserialize($this->aInputs[$CNF['FIELD_FILE']]['value']) : $CNF['OBJECT_UPLOADERS'];
+            $this->aInputs[$CNF['FIELD_FILE']]['images_transcoder'] = '';
+            $this->aInputs[$CNF['FIELD_FILE']]['storage_private'] = 1;
+            $this->aInputs[$CNF['FIELD_FILE']]['multiple'] = true;
+            $this->aInputs[$CNF['FIELD_FILE']]['content_id'] = 0;
+            $this->aInputs[$CNF['FIELD_FILE']]['ghost_template'] = '';
+        }
+
+        $bRecurring = $this->_oModule->_oDb->getParam($CNF['OPTION_ENABLE_RECURRING']) == 'on';
+        if(!$bRecurring) {
+            $this->aInputs[$CNF['FIELD_DURATION_RECURRING']]['type'] = 'hidden';
+            $this->aInputs[$CNF['FIELD_PRICE_RECURRING']]['type'] = 'hidden';
+            $this->aInputs[$CNF['FIELD_PRICE_RECURRING']]['value'] = 0;
+
+            unset($this->aInputs[$CNF['FIELD_HEADER_BEG_RECURRING']]);
+            unset($this->aInputs[$CNF['FIELD_HEADER_END_RECURRING']]);
+        }
+
+        $oPayment = BxDolPayments::getInstance();
+        $bNoPayments = $this->_oModule->_oDb->getParam($CNF['PARAM_NO_PAYMENTS']) == 'on';
+
+        if(isset($this->aInputs[$CNF['FIELD_WARNING_SINGLE']])) {
+            if(!$bNoPayments && !$oPayment->isAcceptingPayments($iProfileId, BX_PAYMENT_TYPE_SINGLE)) 
+                $this->aInputs[$CNF['FIELD_WARNING_SINGLE']]['value'] = MsgBox(_t($this->aInputs[$CNF['FIELD_WARNING_SINGLE']]['value'], $oPayment->getDetailsUrl()));
+            else 
+                unset($this->aInputs[$CNF['FIELD_WARNING_SINGLE']]);
+        }
+
+        if(isset($this->aInputs[$CNF['FIELD_WARNING_RECURRING']])) {
+            if(!$bNoPayments && $bRecurring && !$oPayment->isAcceptingPayments($iProfileId, BX_PAYMENT_TYPE_RECURRING))
+                $this->aInputs[$CNF['FIELD_WARNING_RECURRING']]['value'] = MsgBox(_t($this->aInputs[$CNF['FIELD_WARNING_RECURRING']]['value'], $oPayment->getDetailsUrl()));
+            else 
+                unset($this->aInputs[$CNF['FIELD_WARNING_RECURRING']]);
+        }
+
+        if(isset($this->aInputs[$CNF['FIELD_ALLOW_PURCHASE_TO']]))
+            $this->aInputs[$CNF['FIELD_ALLOW_PURCHASE_TO']] = BxDolPrivacy::getGroupChooser($CNF['OBJECT_PRIVACY_PURCHASE']);
+
+        $aDynamicGroups = array(
+            array ('key' => '', 'value' => '----'),
+            array ('key' => 'c', 'value' => _t('_bx_market_privacy_group_customers'))
+        );
+
+        if(isset($this->aInputs[$CNF['FIELD_ALLOW_COMMENT_TO']])) {
+            $this->aInputs[$CNF['FIELD_ALLOW_COMMENT_TO']] = BxDolPrivacy::getGroupChooser($CNF['OBJECT_PRIVACY_COMMENT'], $iProfileId, array('dynamic_groups' => $aDynamicGroups));
+            $this->aInputs[$CNF['FIELD_ALLOW_COMMENT_TO']]['db']['pass'] = 'Xss';
+        }
+
+        if(isset($this->aInputs[$CNF['FIELD_ALLOW_VOTE_TO']])) {
+            $this->aInputs[$CNF['FIELD_ALLOW_VOTE_TO']] = BxDolPrivacy::getGroupChooser($CNF['OBJECT_PRIVACY_VOTE'], $iProfileId, array('dynamic_groups' => $aDynamicGroups));
+            $this->aInputs[$CNF['FIELD_ALLOW_VOTE_TO']]['db']['pass'] = 'Xss';
+        }
+
+        if(isset($this->aInputs[$CNF['FIELD_SUBENTRIES']]) && $this->_oModule->checkAllowedSetSubentries() !== CHECK_ACTION_RESULT_ALLOWED)
+            unset($this->aInputs[$CNF['FIELD_SUBENTRIES']]);
+    }
+
+    function getCode($bDynamicMode = false)
+    {
+        $sCss = $this->_oModule->_oTemplate->addCss([BX_DIRECTORY_PATH_PLUGINS_PUBLIC . 'codemirror/|codemirror.css'], $bDynamicMode);
+    	$sJs = $this->_oModule->_oTemplate->addJs([
+            'codemirror/codemirror.min.js',
+            'form.js'
+        ], $bDynamicMode);
+
+        $sCode = '';
+        if($bDynamicMode)
+            $sCode .= $sCss . $sJs;
+
+        $sCode .= $this->_oModule->_oTemplate->getJsCode('form');
+        $sCode .= parent::getCode($bDynamicMode);
+
+        return $sCode;
+    }
+
+    function initChecker ($aValues = array (), $aSpecificValues = array())
+    {
+        $CNF = &$this->_oModule->_oConfig->CNF;
+
+        if(isset($this->aInputs[$CNF['FIELD_SUBENTRIES']]) && !empty($aValues[$CNF['FIELD_ID']])) {
+            $oConnection = BxDolConnection::getObjectInstance($CNF['OBJECT_CONNECTION_SUBENTRIES']);
+            if($oConnection)
+                $this->aInputs[$CNF['FIELD_SUBENTRIES']]['value'] = $oConnection->getConnectedContent((int)$aValues[$CNF['FIELD_ID']]);
+        }
+
+        return parent::initChecker($aValues, $aSpecificValues);
+    }
+
+    public function insert ($aValsToAdd = [], $isIgnore = false)
+    {
+        $CNF = &$this->_oModule->_oConfig->CNF;
+
+        if(isset($this->aInputs[$CNF['FIELD_NAME']])) {
+            $sName = BxDolForm::getSubmittedValue($CNF['FIELD_NAME'], $this->aFormAttrs['method'], $this->_aSpecificValues);
+            if(!$sName && isset($this->aInputs[$CNF['FIELD_TITLE']]))
+                $sName = BxDolForm::getSubmittedValue($CNF['FIELD_TITLE'], $this->aFormAttrs['method'], $this->_aSpecificValues);
+
+            $sName = $this->_oModule->_oConfig->getEntryName($sName);
+
+            BxDolForm::setSubmittedValue($CNF['FIELD_NAME'], $sName, $this->aFormAttrs['method'], $this->_aSpecificValues);
+        }
+
+        if($this->_oModule->checkAllowedSetCover() === CHECK_ACTION_RESULT_ALLOWED) {
+            $aCover = isset($_POST[$CNF['FIELD_COVER']]) ? bx_process_input ($_POST[$CNF['FIELD_COVER']], BX_DATA_INT) : false;
+
+            $aValsToAdd[$CNF['FIELD_COVER']] = 0;
+            if(!empty($aCover) && is_array($aCover) && ($iFileCover = array_pop($aCover)))
+                $aValsToAdd[$CNF['FIELD_COVER']] = $iFileCover;
+        }
+
+        $aPackage = bx_process_input(bx_get($CNF['FIELD_PACKAGE']), BX_DATA_INT);
+        $aValsToAdd[$CNF['FIELD_PACKAGE']] = 0;
+        if(!empty($aPackage) && is_array($aPackage) && ($iFilePackage = array_pop($aPackage)))
+            $aValsToAdd[$CNF['FIELD_PACKAGE']] = $iFilePackage;
+
+        $iContentId = parent::insert ($aValsToAdd, $isIgnore);
+        if(!empty($iContentId))
+            $this->processFiles($CNF['FIELD_FILE'], $iContentId, true, $CNF['OBJECT_STORAGE_FILES']);
+
+        return $iContentId;
+    }
+
+    function update ($iContentId, $aValsToAdd = array(), &$aTrackTextFieldsChanges = null)
+    {
+        $CNF = &$this->_oModule->_oConfig->CNF;
+
+        if(($sNameKey = $CNF['FIELD_NAME']) && isset($this->aInputs[$sNameKey])) {
+            $aContentInfo = $this->_oModule->_oDb->getContentInfoById($iContentId);
+            $bContentInfo = !empty($aContentInfo) && is_array($aContentInfo);
+
+            $sName = $this->getCleanValue($sNameKey);
+            if(!$sName) {
+                if($bContentInfo && !empty($aContentInfo[$sNameKey])) {
+                    $sName = $aContentInfo[$sNameKey];
+                    BxDolForm::setSubmittedValue($sNameKey, $sName, $this->aFormAttrs['method'], $this->_aSpecificValues);
+                }
+                else if(($sTitleKey = $CNF['FIELD_TITLE']) && isset($this->aInputs[$sTitleKey]))
+                    $sName = $this->getCleanValue($sTitleKey);
+                else
+                    $sName = 'ID' . time();
+            }
+
+            if($aContentInfo[$sNameKey] != $sName) {
+                $sName = $this->_oModule->_oConfig->getEntryName($sName);
+                BxDolForm::setSubmittedValue($sNameKey, $sName, $this->aFormAttrs['method'], $this->_aSpecificValues);
+            }
+        }
+
+        //TODO: Continue from here. Do the same for Thumb.
+        if(($aCover = bx_get($CNF['FIELD_COVER'])) !== false && $this->_oModule->checkAllowedSetCover() === CHECK_ACTION_RESULT_ALLOWED) {
+            $aCover = bx_process_input($aCover, BX_DATA_INT);
+
+            $aValsToAdd[$CNF['FIELD_COVER']] = 0;
+            if(!empty($aCover) && is_array($aCover) && ($iFileCover = array_pop($aCover)))
+                $aValsToAdd[$CNF['FIELD_COVER']] = $iFileCover;
+        }
+
+        $aPackage = bx_process_input(bx_get($CNF['FIELD_PACKAGE']), BX_DATA_INT);
+        $aValsToAdd[$CNF['FIELD_PACKAGE']] = 0;
+        if(!empty($aPackage) && is_array($aPackage) && ($iFilePackage = array_pop($aPackage)))
+            $aValsToAdd[$CNF['FIELD_PACKAGE']] = $iFilePackage;
+
+        $iResult = parent::update ($iContentId, $aValsToAdd, $aTrackTextFieldsChanges);
+
+        $this->processFiles($CNF['FIELD_FILE'], $iContentId, false, $CNF['OBJECT_STORAGE_FILES']);
+
+        return $iResult;
+    }
+
+	function delete ($iContentId, $aContentInfo = array())
+    {
+        $CNF = &$this->_oModule->_oConfig->CNF;
+
+        $bResult = parent::delete($iContentId, $aContentInfo);
+        if(!$bResult)
+            return $bResult;
+
+        // delete associated files
+        if (!empty($CNF['OBJECT_STORAGE_FILES'])) {
+            $oStorage = BxDolStorage::getObjectInstance($CNF['OBJECT_STORAGE_FILES']);
+            if($oStorage)
+                $oStorage->queueFilesForDeletionFromGhosts($aContentInfo[$CNF['FIELD_AUTHOR']], $iContentId);
+        }
+
+        // delete associations
+        $bResult &= $this->_oModule->_oDb->deassociatePhotoWithContent($iContentId, 0);
+        $bResult &= $this->_oModule->_oDb->deassociateFileWithContent($iContentId, 0);
+
+        return $bResult;
+    }
+
+    protected function _associalFileWithContent($oStorage, $iFileId, $iProfileId, $iContentId, $sPictureField = '')
+    {
+        parent::_associalFileWithContent($oStorage, $iFileId, $iProfileId, $iContentId, $sPictureField);
+
+        $sStorage = $oStorage->getObject();
+        switch($sStorage) {
+        	case $this->_oModule->_oConfig->CNF['OBJECT_STORAGE']:
+        		$this->_oModule->_oDb->associatePhotoWithContent($iContentId, $iFileId, $this->getCleanValue('title-' . $iFileId));
+        		break;
+
+        	case $this->_oModule->_oConfig->CNF['OBJECT_STORAGE_FILES']:
+        		$aParams = array(
+        			'type' => $this->getCleanValue('type-' . $iFileId)        			
+        		);
+
+        		switch ($aParams['type']) {
+        			case BX_MARKET_FILE_TYPE_VERSION:
+        				$aParams = array_merge($aParams, array(
+        					'version' => $this->getCleanValue('version-' . $iFileId),
+        				));
+        				break;
+        				
+        			case BX_MARKET_FILE_TYPE_UPDATE:
+        				$aParams = array_merge($aParams, array(
+        					'version' => $this->getCleanValue('version-from-' . $iFileId),
+        					'version_to' => $this->getCleanValue('version-to-' . $iFileId),
+        				));
+        				break;
+        		}
+
+        		$this->_oModule->_oDb->associateFileWithContent($iContentId, $iFileId, $aParams);
+        		break;
+        }
+    }
+
+    protected function _getPhotoGhostTmplVars($aContentInfo = [])
+    {
+        $CNF = &$this->_oModule->_oConfig->CNF;
+
+        $aResult = parent::_getPhotoGhostTmplVars($aContentInfo);
+
+        if(!empty($aResult['bx_if:set_thumb']))
+            $aResult['bx_if:set_thumb']['condition'] = $this->_bPhotoGhostCheckboxes && $aResult['bx_if:set_thumb']['condition'];
+
+        return array_merge($aResult, [
+            'cover_id' => isset($aContentInfo[$CNF['FIELD_COVER']]) ? $aContentInfo[$CNF['FIELD_COVER']] : 0,
+            'bx_if:set_cover' => [
+                'condition' => $this->_bPhotoGhostCheckboxes && $this->_oModule->checkAllowedSetCover() === CHECK_ACTION_RESULT_ALLOWED,
+                'content' => [
+                    'name_cover' => $CNF['FIELD_COVER'],
+                ]
+            ]
+        ]);
+    }
+
+    protected function _getFileGhostTmplVars($aContentInfo = array())
+    {
+    	$CNF = &$this->_oModule->_oConfig->CNF;
+
+        $aResult = parent::_getFileGhostTmplVars($aContentInfo);
+        $aResult = array_merge($aResult, array(
+            'thumb_id' => isset($aContentInfo[$CNF['FIELD_PACKAGE']]) ? $aContentInfo[$CNF['FIELD_PACKAGE']] : 0,
+            'bx_if:set_thumb' => array (
+                'condition' => true,
+                'content' => array(
+                    'name_thumb' => $CNF['FIELD_PACKAGE'],
+                ),
+            ),
+        ));
+
+    	return $aResult;
+    }
+
+    function genInputPrice(&$aInput)
+    {
+        $CNF = &$this->_oModule->_oConfig->CNF;
+
+        if(!isset($aInput['value_currency'])) {
+            $iAuthorId = 0;
+            if(!empty($this->_iContentId)) {
+                $aContentInfo = $this->_oModule->_oDb->getContentInfoById($this->_iContentId);
+                if(!empty($aContentInfo) || is_array($aContentInfo))
+                    $iAuthorId = $aContentInfo[$CNF['FIELD_AUTHOR']];
+            }
+            else
+                $iAuthorId = bx_get_logged_profile_id();
+
+            $aInput['value_currency'] = BxDolPayments::getInstance()->getCurrencyCode($iAuthorId);
+        }
+
+        return parent::genInputPrice($aInput);
+    }
+
+    protected function genCustomInputSubentries ($aInput)
+    {
+        $CNF = &$this->_oModule->_oConfig->CNF;
+
+        $aInput['ajax_get_suggestions'] = BX_DOL_URL_ROOT . $this->_oModule->_oConfig->getBaseUri() . 'get_subentries';
+        $aInput['placeholder'] = _t('_bx_market_form_entry_input_subentries_placeholder');
+
+        $sVals = '';
+        if(!empty($aInput['value']) && is_array($aInput['value'])) {
+            foreach($aInput['value'] as $iValue) {
+                $iValue = (int)$iValue;
+                if(!$iValue)
+                    continue;
+
+                $aContentInfo = $this->_oModule->_oDb->getContentInfoById($iValue);
+                if(empty($aContentInfo) || !is_array($aContentInfo))
+                    continue;
+                
+               $sVals .= '<b class="val bx-def-color-bg-hl bx-def-round-corners">' . $aContentInfo[$CNF['FIELD_TITLE']] . '<input type="hidden" name="' . $aInput['name'] . '[]" value="' . $iValue . '" /></b>';
+            }
+            $sVals = trim($sVals, ',');
+        }
+        $aInput['value'] = $sVals;
+
+        return $this->genCustomInputUsernamesSuggestions($aInput);
+    }
+}
+
+/** @} */

+ 140 - 0
modules/boonex/market/updates/14.0.6_14.0.7/source/install/config.php

@@ -0,0 +1,140 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Market Market
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+$aConfig = array(
+
+    /**
+     * Main Section.
+     */
+    'type' => BX_DOL_MODULE_TYPE_MODULE,
+    'name' => 'bx_market',
+    'title' => 'Market',
+    'note' => 'Market module.',
+    'version' => '14.0.7',
+    'vendor' => 'UNA INC',
+    'help_url' => 'http://feed.una.io/?section={module_name}',
+
+    'compatible_with' => array(
+        '14.0.0-RC4'
+    ),
+
+    /**
+     * 'home_dir' and 'home_uri' - should be unique. Don't use spaces in 'home_uri' and the other special chars.
+     */
+    'home_dir' => 'boonex/market/',
+    'home_uri' => 'market',
+
+    'db_prefix' => 'bx_market_',
+    'class_prefix' => 'BxMarket',
+
+    /**
+     * Category for language keys.
+     */
+    'language_category' => 'Market',
+
+	/**
+     * List of page triggers.
+     */
+    'page_triggers' => array (
+    	'trigger_page_profile_view_entry',
+    ),
+
+    /**
+     * Menu triggers.
+     */
+    'menu_triggers' => array(
+    	'trigger_profile_view_submenu',
+        'trigger_group_view_submenu'
+    ),
+
+	/**
+     * Storage objects to automatically delete files from upon module uninstallation.
+     * Note. Don't add storage objects used in transcoder objects.
+     */
+    'storages' => array(
+    	'bx_market_files',
+        'bx_market_photos'
+    ),
+
+    /**
+     * Transcoders.
+     */
+    'transcoders' => array(
+        'bx_market_icon',
+        'bx_market_thumb',
+        'bx_market_cover',
+        'bx_market_screenshot',
+		'bx_market_preview',
+        'bx_market_gallery',
+    ),
+
+    /**
+     * Extended Search Forms.
+     */
+    'esearches' => array(
+        'bx_market',
+    	'bx_market_cmts',
+    ),
+
+    /**
+     * Installation/Uninstallation Section.
+     */
+    'install' => array(
+        'execute_sql' => 1,
+        'update_languages' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'uninstall' => array (
+    	'process_esearches' => 1,
+        'execute_sql' => 1,
+        'update_languages' => 1,
+    	'update_relations' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'enable' => array(
+        'execute_sql' => 1,
+    	'update_relations' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'enable_success' => array(
+    	'process_page_triggers' => 1,
+    	'process_menu_triggers' => 1,
+    	'process_esearches' => 1,
+    	'register_transcoders' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'disable' => array (
+        'execute_sql' => 1,
+    	'update_relations' => 1,
+    	'unregister_transcoders' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'disable_failed' => array (
+    	'register_transcoders' => 1,
+    	'clear_db_cache' => 1,
+    ),
+
+    /**
+     * Dependencies Section
+     */
+    'dependencies' => array(),
+
+    /**
+     * Connections Section
+     */
+    'relations' => array(
+    	'bx_timeline',
+    	'bx_notifications'
+    ),
+
+);
+
+/** @} */

+ 509 - 0
modules/boonex/market/updates/14.0.6_14.0.7/source/install/langs/en.xml

@@ -0,0 +1,509 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources name="en" flag="gb" title="English">
+    <string name="_bx_market"><![CDATA[Market]]></string>
+    <string name="_bx_market_cmts"><![CDATA[Market's Reviews]]></string>
+    <string name="_bx_market_reactions"><![CDATA[Market's Reactions]]></string>
+
+    <string name="_bx_market_option_enable_auto_approve"><![CDATA[Auto approve a product after creation]]></string>
+    <string name="_bx_market_option_enable_no_payments"><![CDATA[Allow to work without payments]]></string>
+    <string name="_bx_market_option_enable_recurring"><![CDATA[Allow to sell subscriptions]]></string>
+    <string name="_bx_market_option_recurring_reserve"><![CDATA[Reserve (in days) to accept and process recurring payment notification]]></string>
+    <string name="_bx_market_option_summary_chars"><![CDATA[Number of characters in auto-cropped product summary]]></string>
+    <string name="_bx_market_option_plain_summary_chars"><![CDATA[Number of characters in plain product description when product hasn't thumb]]></string>
+    <string name="_bx_market_option_per_page_browse"><![CDATA[Number of items per page]]></string>
+    <string name="_bx_market_option_per_page_profile"><![CDATA[Number of items on profile page]]></string>
+    <string name="_bx_market_option_rss_num"><![CDATA[Number of items in RSS feed]]></string>
+    <string name="_bx_market_option_searchable_fields"><![CDATA[Searchable fields for keyword search]]></string>
+    <string name="_bx_market_option_per_page_for_favorites_lists"><![CDATA[Number of favorite lists per page]]></string>
+    <string name="_bx_market_option_enable_icon"><![CDATA[Enable product icon]]></string>
+    
+
+    <string name="_bx_market_form_entry"><![CDATA[Product]]></string>
+    <string name="_bx_market_form_entry_display_add"><![CDATA[Add Product]]></string>
+    <string name="_bx_market_form_entry_display_edit"><![CDATA[Edit Product]]></string>
+    <string name="_bx_market_form_entry_display_delete"><![CDATA[Delete Product]]></string>
+    <string name="_bx_market_form_entry_display_view"><![CDATA[View Product]]></string>
+    <string name="_bx_market_form_entry_display_view_full"><![CDATA[Full View Product]]></string>
+    <string name="_bx_market_form_entry_input_author"><![CDATA[Author]]></string>
+    <string name="_bx_market_form_entry_input_sys_do_submit"><![CDATA[Submit]]></string>
+    <string name="_bx_market_form_entry_input_do_submit"><![CDATA[Submit]]></string>
+    <string name="_bx_market_form_entry_input_sys_do_publish"><![CDATA[Publish]]></string>
+    <string name="_bx_market_form_entry_input_do_publish"><![CDATA[Publish]]></string>
+    <string name="_bx_market_form_entry_input_sys_title"><![CDATA[Title]]></string>
+    <string name="_bx_market_form_entry_input_title"><![CDATA[Title]]></string>
+    <string name="_bx_market_form_entry_input_title_err"><![CDATA[Title is essential. Please, fill in this field]]></string>
+    <string name="_bx_market_form_entry_input_sys_name"><![CDATA[Identifier]]></string>
+    <string name="_bx_market_form_entry_input_name"><![CDATA[Identifier]]></string>
+    <string name="_bx_market_form_entry_input_name_inf"><![CDATA[Unique name for payment identification.]]></string>
+    <string name="_bx_market_form_entry_input_name_err"><![CDATA[Identifier should be unique and is needed for internal usage. Please, fill in this field]]></string>
+    <string name="_bx_market_form_entry_input_sys_cat"><![CDATA[Category]]></string>
+    <string name="_bx_market_form_entry_input_cat"><![CDATA[Category]]></string>
+    <string name="_bx_market_form_entry_input_cat_err"><![CDATA[Please select category]]></string>
+    <string name="_bx_market_form_entry_input_sys_price_single"><![CDATA[Price]]></string>
+    <string name="_bx_market_form_entry_input_price_single"><![CDATA[Price]]></string>
+    <string name="_bx_market_form_entry_input_price_single_inf"><![CDATA[Leave empty to make the product free.]]></string>
+    <string name="_bx_market_form_entry_input_sys_price_recurring"><![CDATA[Recurring price]]></string>
+    <string name="_bx_market_form_entry_input_price_recurring"><![CDATA[Price]]></string>
+    <string name="_bx_market_form_entry_input_price_recurring_inf"><![CDATA[Leave empty to make the product free.]]></string>
+    <string name="_bx_market_form_entry_input_sys_duration_recurring"><![CDATA[Billing period]]></string>
+    <string name="_bx_market_form_entry_input_duration_recurring"><![CDATA[Billing period]]></string>
+    <string name="_bx_market_form_entry_input_sys_trial_recurring"><![CDATA[Recurring trial]]></string>
+    <string name="_bx_market_form_entry_input_trial_recurring"><![CDATA[Trial period]]></string>
+    <string name="_bx_market_form_entry_input_trial_recurring_inf"><![CDATA[The number of days new customers should receive a free trial. Leave empty to disable trial period.]]></string>
+    <string name="_bx_market_form_entry_input_sys_header_beg_single"><![CDATA[One-time payment: begin]]></string>
+    <string name="_bx_market_form_entry_input_header_beg_single"><![CDATA[One-time payment]]></string>
+    <string name="_bx_market_form_entry_input_sys_header_beg_recurring"><![CDATA[Recurring payment: begin]]></string>
+    <string name="_bx_market_form_entry_input_header_beg_recurring"><![CDATA[Recurring payment]]></string>
+    <string name="_bx_market_form_entry_input_sys_header_beg_privacy"><![CDATA[Privacy: begin]]></string>
+    <string name="_bx_market_form_entry_input_header_beg_privacy"><![CDATA[Privacy]]></string>
+    <string name="_bx_market_form_entry_input_sys_header_beg_notes"><![CDATA[Notes: begin]]></string>
+    <string name="_bx_market_form_entry_input_header_beg_notes"><![CDATA[Notes]]></string>
+    <string name="_bx_market_form_entry_input_sys_header_beg_other"><![CDATA[Other: begin]]></string>
+    <string name="_bx_market_form_entry_input_header_beg_other"><![CDATA[Other]]></string>
+    <string name="_bx_market_form_entry_input_sys_header_end_single"><![CDATA[One-time payment: end]]></string>
+    <string name="_bx_market_form_entry_input_sys_header_end_recurring"><![CDATA[Recurring payment: end]]></string>
+    <string name="_bx_market_form_entry_input_sys_header_end_privacy"><![CDATA[Privacy: end]]></string>
+    <string name="_bx_market_form_entry_input_sys_header_end_notes"><![CDATA[Notes: end]]></string>
+    <string name="_bx_market_form_entry_input_sys_header_end_other"><![CDATA[Other: end]]></string>
+    <string name="_bx_market_form_entry_input_sys_text"><![CDATA[Text]]></string>
+    <string name="_bx_market_form_entry_input_text"><![CDATA[Text]]></string>
+    <string name="_bx_market_form_entry_input_text_err"><![CDATA[Text field can't be empty]]></string>
+    <string name="_bx_market_form_entry_input_sys_notes"><![CDATA[Notes]]></string>
+    <string name="_bx_market_form_entry_input_notes"><![CDATA[Notes]]></string>
+    <string name="_bx_market_form_entry_input_notes_inf"><![CDATA[Will be shown on product's info page.]]></string>
+    <string name="_bx_market_form_entry_input_sys_notes_purchased"><![CDATA[After purchase notes]]></string>
+    <string name="_bx_market_form_entry_input_notes_purchased"><![CDATA[After purchase notes]]></string>
+    <string name="_bx_market_form_entry_input_notes_purchased_inf"><![CDATA[Will be attached to email message which is sent to buyer after purchase.]]></string>
+    <string name="_bx_market_form_entry_input_sys_delete_confirm"><![CDATA[Delete confirmation]]></string>
+    <string name="_bx_market_form_entry_input_delete_confirm"><![CDATA[I am sure I want to delete this product]]></string>
+    <string name="_bx_market_form_entry_input_delete_confirm_info"><![CDATA[This action can not be undone]]></string>
+    <string name="_bx_market_form_entry_input_delete_confirm_error"><![CDATA[Please check this checkbox if you really want to delete the product]]></string>
+    <string name="_bx_market_form_entry_input_sys_cover_raw"><![CDATA[Header Image RAW]]></string>
+    <string name="_bx_market_form_entry_input_cover_raw"><![CDATA[Header Image RAW]]></string>
+    <string name="_bx_market_form_entry_input_cover_raw_inf"><![CDATA[If provided, it'll be used instead of image based variant.]]></string>
+    <string name="_bx_market_form_entry_input_sys_pictures"><![CDATA[Pictures]]></string>
+    <string name="_bx_market_form_entry_input_pictures"><![CDATA[Pictures]]></string>
+    <string name="_bx_market_form_entry_input_pictures_title"><![CDATA[Title]]></string>
+    <string name="_bx_market_form_entry_input_pictures_use_as_thumb"><![CDATA[Icon]]></string>
+    <string name="_bx_market_form_entry_input_pictures_use_as_cover"><![CDATA[Header Image]]></string>
+    <string name="_bx_market_form_entry_input_sys_files"><![CDATA[Files]]></string>
+    <string name="_bx_market_form_entry_input_files"><![CDATA[Files]]></string>
+    <string name="_bx_market_form_entry_input_files_use_as_main"><![CDATA[Use as Main]]></string>
+    <string name="_bx_market_form_entry_input_files_name"><![CDATA[Name:]]></string>
+    <string name="_bx_market_form_entry_input_files_version"><![CDATA[Version:]]></string>
+    <string name="_bx_market_form_entry_input_files_type"><![CDATA[Type:]]></string>
+    <string name="_bx_market_form_entry_input_files_type_version"><![CDATA[version]]></string>
+    <string name="_bx_market_form_entry_input_files_type_update"><![CDATA[update]]></string>
+    <string name="_bx_market_form_entry_input_files_version_from"><![CDATA[Version from:]]></string>
+    <string name="_bx_market_form_entry_input_files_version_to"><![CDATA[Version to:]]></string>
+    <string name="_bx_market_form_entry_input_files_version_from_x_to_y"><![CDATA[{0} to {1}]]></string>
+    <string name="_bx_market_form_entry_input_sys_allow_view_to"><![CDATA[Who can view]]></string>
+    <string name="_bx_market_form_entry_input_allow_view_to"><![CDATA[Who can view]]></string>
+    <string name="_bx_market_form_entry_input_allow_view_favorite_list"><![CDATA[Visibility]]></string>
+    <string name="_bx_market_form_entry_input_sys_allow_purchase_to"><![CDATA[Who can purchase]]></string>
+    <string name="_bx_market_form_entry_input_allow_purchase_to"><![CDATA[Who can purchase]]></string>
+    <string name="_bx_market_form_entry_input_sys_allow_comment_to"><![CDATA[Who can review]]></string>
+    <string name="_bx_market_form_entry_input_allow_comment_to"><![CDATA[Who can review]]></string>
+    <string name="_bx_market_form_entry_input_sys_allow_vote_to"><![CDATA[Who can vote]]></string>
+    <string name="_bx_market_form_entry_input_allow_vote_to"><![CDATA[Who can vote]]></string>
+    <string name="_bx_market_form_entry_input_sys_added"><![CDATA[Created]]></string>
+    <string name="_bx_market_form_entry_input_added"><![CDATA[Created]]></string>
+    <string name="_bx_market_form_entry_input_sys_changed"><![CDATA[Updated]]></string>
+    <string name="_bx_market_form_entry_input_changed"><![CDATA[Updated]]></string>
+    <string name="_bx_market_form_entry_input_sys_warning_single"><![CDATA[Warning for single payments]]></string>
+    <string name="_bx_market_form_entry_input_sys_warning_recurring"><![CDATA[Warning for recurring payments]]></string>
+    <string name="_bx_market_form_entry_input_sys_subentries"><![CDATA[Subproducts]]></string>
+    <string name="_bx_market_form_entry_input_subentries"><![CDATA[Subproducts]]></string>
+    <string name="_bx_market_form_entry_input_subentries_inf"><![CDATA[Leave empty if you don't want to create association.]]></string>
+    <string name="_bx_market_form_entry_input_subentries_placeholder"><![CDATA[Type product name here...]]></string>
+    <string name="_bx_market_form_entry_input_files_version_caption_latest"><![CDATA[Latest version]]></string>
+    <string name="_bx_market_form_entry_input_files_version_caption_version"><![CDATA[Older versions]]></string>
+    <string name="_bx_market_form_entry_input_files_version_caption_update"><![CDATA[Updates]]></string>
+
+    <string name="_bx_market_form_license"><![CDATA[License]]></string>
+    <string name="_bx_market_form_license_display_edit"><![CDATA[Edit License]]></string>
+    <string name="_bx_market_form_license_input_sys_order"><![CDATA[Order]]></string>
+    <string name="_bx_market_form_license_input_order"><![CDATA[Order]]></string>
+    <string name="_bx_market_form_license_input_order_err"><![CDATA[Order is essential. Please, fill in this field.]]></string>
+    <string name="_bx_market_form_license_input_sys_license"><![CDATA[License]]></string>
+    <string name="_bx_market_form_license_input_license"><![CDATA[License]]></string>
+    <string name="_bx_market_form_license_input_license_err"><![CDATA[License should be unique and is needed for internal usage. Please, fill in this field.]]></string>
+    <string name="_bx_market_form_license_input_sys_domain"><![CDATA[Domain]]></string>
+    <string name="_bx_market_form_license_input_domain"><![CDATA[Domain]]></string>
+    <string name="_bx_market_form_license_input_sys_added"><![CDATA[Added]]></string>
+    <string name="_bx_market_form_license_input_added"><![CDATA[Added]]></string>
+    <string name="_bx_market_form_license_input_sys_expired"><![CDATA[Expired]]></string>
+    <string name="_bx_market_form_license_input_expired"><![CDATA[Expired]]></string>
+    <string name="_bx_market_form_license_input_sys_controls"><![CDATA[Controls]]></string>
+    <string name="_bx_market_form_license_input_sys_do_submit"><![CDATA[Submit]]></string>
+    <string name="_bx_market_form_license_input_do_submit"><![CDATA[Submit]]></string>
+    <string name="_bx_market_form_license_input_sys_do_cancel"><![CDATA[Cancel]]></string>
+    <string name="_bx_market_form_license_input_do_cancel"><![CDATA[Cancel]]></string>
+
+    <string name="_bx_market_acl_action_create_entry"><![CDATA[Create Product]]></string>
+    <string name="_bx_market_acl_action_delete_entry"><![CDATA[Delete Product]]></string>
+    <string name="_bx_market_acl_action_download_entry"><![CDATA[Download Product]]></string>
+    <string name="_bx_market_acl_action_view_entry"><![CDATA[View Product]]></string>
+    <string name="_bx_market_acl_action_set_cover"><![CDATA[Set Product Cover]]></string>
+    <string name="_bx_market_acl_action_set_subentries"><![CDATA[Set Product Subproducts]]></string>
+    <string name="_bx_market_acl_action_set_thumb"><![CDATA[Set Product Thumbnail]]></string>
+    <string name="_bx_market_acl_action_edit_any_entry"><![CDATA[Edit Any Product]]></string>
+    <string name="_bx_market_acl_action_delete_any_entry"><![CDATA[Delete Any Product]]></string>
+
+    <string name="_bx_market_privacy_group_customers"><![CDATA[Customers]]></string>
+
+    <string name="_bx_market_page_title_sys_create_entry"><![CDATA[New Product]]></string>
+    <string name="_bx_market_page_title_create_entry"><![CDATA[New Product]]></string>
+    <string name="_bx_market_page_block_title_create_entry"><![CDATA[New Product]]></string>
+    <string name="_bx_market_page_title_sys_edit_entry"><![CDATA[Edit Product]]></string>
+    <string name="_bx_market_page_title_edit_entry"><![CDATA[Edit Product]]></string>
+    <string name="_bx_market_page_block_title_edit_entry"><![CDATA[Edit Product]]></string>
+    <string name="_bx_market_page_title_sys_delete_entry"><![CDATA[Delete Product]]></string>
+    <string name="_bx_market_page_title_delete_entry"><![CDATA[Delete Product]]></string>
+    <string name="_bx_market_page_block_title_delete_entry"><![CDATA[Delete Product]]></string>
+    <string name="_bx_market_page_title_sys_download_entry"><![CDATA[Download Product]]></string>
+    <string name="_bx_market_page_title_download_entry"><![CDATA[Download Product]]></string>
+    <string name="_bx_market_page_block_title_download_entry"><![CDATA[Download Product]]></string>
+    <string name="_bx_market_page_title_sys_view_entry"><![CDATA[View Product]]></string>
+    <string name="_bx_market_page_title_view_entry"><![CDATA[{title}]]></string>
+    <string name="_bx_market_page_block_title_entry_text"><![CDATA[Product Overview]]></string>
+    <string name="_bx_market_page_title_browse"><![CDATA[Products]]></string>
+    <string name="_bx_market_page_title_search_results"><![CDATA[Products matching "{0}"]]></string>
+    <string name="_bx_market_page_title_browse_by_author"><![CDATA[Products of {display_name}]]></string>
+    <string name="_bx_market_page_title_browse_by_context"><![CDATA[Products in {display_name}]]></string>
+    <string name="_bx_market_page_title_browse_featured"><![CDATA[Featured Products]]></string>
+    <string name="_bx_market_page_title_browse_latest"><![CDATA[Latest Products]]></string>
+    <string name="_bx_market_page_title_browse_popular"><![CDATA[Popular Products]]></string>
+    <string name="_bx_market_page_title_browse_top"><![CDATA[Top Products]]></string>
+    <string name="_bx_market_page_title_browse_updated"><![CDATA[Updated Products]]></string>
+    <string name="_bx_market_page_title_browse_category"><![CDATA[Products by category: {0}]]></string>
+    <string name="_bx_market_page_title_browse_keyword"><![CDATA[Products by hashtag: {0}]]></string>
+    <string name="_bx_market_page_title_sys_home"><![CDATA[Market Home]]></string>
+    <string name="_bx_market_page_title_home"><![CDATA[Market]]></string>
+    <string name="_bx_market_page_title_sys_entries_by_category"><![CDATA[Products in category]]></string>
+    <string name="_bx_market_page_title_entries_by_category"><![CDATA[Products in {category_name}]]></string>
+    <string name="_bx_market_page_block_title_sys_entries_by_category"><![CDATA[Products in category]]></string>
+    <string name="_bx_market_page_block_title_entries_by_category"><![CDATA[{category_name}]]></string>
+    <string name="_bx_market_page_block_title_featured_entries"><![CDATA[Featured Products]]></string>
+    <string name="_bx_market_page_block_title_featured_entries_view_extended"><![CDATA[Featured Products (Extended View)]]></string>
+    <string name="_bx_market_page_block_title_featured_entries_view_full"><![CDATA[Featured Products (Full View)]]></string>
+    <string name="_bx_market_page_block_title_latest_entries"><![CDATA[Latest Products]]></string>
+    <string name="_bx_market_page_block_title_latest_entries_view_extended"><![CDATA[Latest Products (Extended View)]]></string>
+    <string name="_bx_market_page_block_title_latest_entries_view_full"><![CDATA[Latest Products (Full View)]]></string>
+    <string name="_bx_market_page_block_title_entry_social_sharing"><![CDATA[Share]]></string>
+    <string name="_bx_market_page_block_title_entry_author"><![CDATA[Vendor]]></string>
+    <string name="_bx_market_page_block_title_entry_author_entries"><![CDATA[More Products From {0}]]></string>
+    <string name="_bx_market_page_block_title_entry_actions"><![CDATA[Actions]]></string>
+    <string name="_bx_market_page_block_title_entry_breadcrumb"><![CDATA[Breadcrumb]]></string>
+    <string name="_bx_market_page_block_title_entry_comments"><![CDATA[Reviews]]></string>
+	<string name="_bx_market_page_block_title_entry_reports"><![CDATA[Reports]]></string>
+    <string name="_bx_market_page_block_title_entry_comments_link"><![CDATA[Reviews to <a href="{entry_link}">{title}</a>]]></string>
+    <string name="_bx_market_page_block_title_entry_comments_n"><![CDATA[Reviews ({0})]]></string>
+    <string name="_bx_market_page_block_title_entry_info"><![CDATA[Info]]></string>
+    <string name="_bx_market_page_block_title_entry_info_link"><![CDATA[<a href="{entry_link}">{title}</a> Info]]></string>
+    <string name="_bx_market_page_block_title_entry_location"><![CDATA[Location]]></string>
+    <string name="_bx_market_page_block_title_entry_attachments"><![CDATA[Attachments]]></string>
+    <string name="_bx_market_page_block_title_entry_all_actions"><![CDATA[All Actions]]></string>
+    <string name="_bx_market_page_block_title_entry_rating"><![CDATA[Rating]]></string>
+    <string name="_bx_market_page_title_sys_entries_latest"><![CDATA[Latest Products]]></string>
+    <string name="_bx_market_page_title_entries_latest"><![CDATA[Latest Products]]></string>
+    <string name="_bx_market_page_title_sys_entries_featured"><![CDATA[Featured Products]]></string>
+    <string name="_bx_market_page_title_entries_featured"><![CDATA[Featured Products]]></string>
+    <string name="_bx_market_page_title_sys_entries_popular"><![CDATA[Popular Products]]></string>
+    <string name="_bx_market_page_title_entries_popular"><![CDATA[Popular Products]]></string>
+    <string name="_bx_market_page_title_sys_entries_top"><![CDATA[Top Products]]></string>
+    <string name="_bx_market_page_title_entries_top"><![CDATA[Top Products]]></string>
+    <string name="_bx_market_page_title_sys_entries_updated"><![CDATA[Updated Products]]></string>
+    <string name="_bx_market_page_title_entries_updated"><![CDATA[Updated Products]]></string>
+    <string name="_bx_market_page_block_title_popular_entries"><![CDATA[Popular Products]]></string>
+    <string name="_bx_market_page_block_title_popular_entries_view_extended"><![CDATA[Popular Products (Extended View)]]></string>
+    <string name="_bx_market_page_block_title_popular_entries_view_full"><![CDATA[Popular Products (Full View)]]></string>
+    <string name="_bx_market_page_block_title_top_entries"><![CDATA[Top Products]]></string>
+    <string name="_bx_market_page_block_title_updated_entries"><![CDATA[Updated Products]]></string>
+    <string name="_bx_market_page_block_title_updated_entries_view_extended"><![CDATA[Updated Products (Extended View)]]></string>
+    <string name="_bx_market_page_block_title_updated_entries_view_full"><![CDATA[Updated Products (Full View)]]></string>
+    <string name="_bx_market_page_block_title_favorites_entries"><![CDATA["{title}" List]]></string>
+    <string name="_bx_market_page_block_title_favorites_entries_info"><![CDATA[Info]]></string>
+	<string name="_bx_market_page_block_title_sys_entry_context"><![CDATA[Posted in]]></string>
+    <string name="_bx_market_page_block_title_entry_context"><![CDATA[Posted in]]></string>
+	
+    <string name="_bx_market_page_title_sys_view_entry_comments"><![CDATA[Product Reviews]]></string>
+    <string name="_bx_market_page_title_view_entry_comments"><![CDATA[Reviews to {title}]]></string>
+    <string name="_bx_market_page_title_sys_view_entry_info"><![CDATA[Product Info]]></string>
+    <string name="_bx_market_page_title_view_entry_info"><![CDATA[{title} Info]]></string>
+    <string name="_bx_market_page_title_sys_entries_of_author"><![CDATA[Products of author]]></string>
+    <string name="_bx_market_page_title_entries_of_author"><![CDATA[Products by {display_name}]]></string>
+    <string name="_bx_market_page_title_sys_entries_in_context"><![CDATA[Products in context]]></string>
+    <string name="_bx_market_page_title_entries_in_context"><![CDATA[Products in {display_name}]]></string>
+    <string name="_bx_market_page_block_title_favorites_of_author"><![CDATA[Favorites by <a href="{profile_link}">{display_name}</a>]]></string>
+    <string name="_bx_market_page_block_title_sys_favorites_of_author"><![CDATA[Favorites of author]]></string>
+    <string name="_bx_market_page_block_title_entries_of_author"><![CDATA[Products by <a href="{profile_link}">{display_name}</a>]]></string>
+    <string name="_bx_market_page_block_title_sys_entries_of_author"><![CDATA[Products of author]]></string>
+    <string name="_bx_market_page_block_title_entries_in_context"><![CDATA[Products in <a href="{profile_link}">{display_name}</a>]]></string>
+    <string name="_bx_market_page_block_title_sys_entries_in_context"><![CDATA[Products in context]]></string>
+    <string name="_bx_market_page_block_title_entries_actions"><![CDATA[Products actions]]></string>
+    <string name="_bx_market_page_block_title_browse_cmts"><![CDATA[Products' Reviews]]></string>
+	<string name="_bx_market_page_title_sys_manage"><![CDATA[Manage Own Products]]></string>
+	<string name="_bx_market_page_title_sys_manage_administration"><![CDATA[Manage All Products]]></string>
+	<string name="_bx_market_page_title_manage"><![CDATA[Manage Products]]></string>
+	<string name="_bx_market_page_block_title_system_manage"><![CDATA[Manage Own Products]]></string>
+	<string name="_bx_market_page_block_title_system_manage_administration"><![CDATA[Manage All Products]]></string>
+	<string name="_bx_market_page_block_title_manage"><![CDATA[Manage Products]]></string>    
+	<string name="_bx_market_page_block_title_popular_keywords"><![CDATA[Popular Hashtags]]></string>
+	<string name="_bx_market_page_block_title_cats"><![CDATA[Products Categories]]></string>
+	<string name="_bx_market_page_title_sys_entries_categories"><![CDATA[Categories]]></string>
+    <string name="_bx_market_page_title_entries_categories"><![CDATA[Categories]]></string>
+    <string name="_bx_market_page_block_title_categories_entries"><![CDATA[Products]]></string>
+    
+    <string name="_bx_market_page_title_sys_licenses_administration"><![CDATA[Licenses]]></string>
+    <string name="_bx_market_page_title_licenses_administration"><![CDATA[Licenses]]></string>
+    <string name="_bx_market_page_block_title_licenses_administration"><![CDATA[Licenses]]></string>
+    <string name="_bx_market_page_title_sys_licenses"><![CDATA[Licenses]]></string>
+    <string name="_bx_market_page_title_licenses"><![CDATA[Licenses]]></string>
+    <string name="_bx_market_page_block_title_licenses"><![CDATA[Licenses]]></string>
+    <string name="_bx_market_page_block_title_licenses_note"><![CDATA[Note]]></string>
+    <string name="_bx_market_page_block_content_licenses_note"><![CDATA[The licenses are for reference only. There is no need to "register" them, as you can simply download and install licensed UNA apps directly from your site Studio Apps store.]]></string>
+    <string name="_bx_market_page_block_title_sys_view_profile"><![CDATA[User Products]]></string>
+    <string name="_bx_market_page_block_title_view_profile"><![CDATA[{display_name} Products]]></string>
+    <string name="_bx_market_page_title_sys_entries_search"><![CDATA[Search]]></string>
+    <string name="_bx_market_page_title_entries_search"><![CDATA[Search]]></string>
+    <string name="_bx_market_page_title_sys_entries_favorites"><![CDATA[Favorites Products]]></string>
+    <string name="_bx_market_page_title_entries_favorites"><![CDATA[Favorites Products]]></string>
+    <string name="_bx_market_page_block_title_search_form"><![CDATA[Search Form]]></string>
+    <string name="_bx_market_page_block_title_search_results"><![CDATA[Search Results]]></string>
+    <string name="_bx_market_page_block_title_search_form_cmts"><![CDATA[Comments Search Form]]></string>
+    <string name="_bx_market_page_block_title_search_results_cmts"><![CDATA[Comments Search Results]]></string>
+    <string name="_bx_market_page_block_title_sys_recent_entries_view_showcase"><![CDATA[Latest Products (Showcase View)]]></string>
+    <string name="_bx_market_page_block_title_recent_entries_view_showcase"><![CDATA[Latest Products]]></string>
+    <string name="_bx_market_page_block_title_sys_popular_entries_view_showcase"><![CDATA[Popular Products (Showcase View)]]></string>
+    <string name="_bx_market_page_block_title_popular_entries_view_showcase"><![CDATA[Popular Products]]></string>
+    <string name="_bx_market_page_block_title_sys_featured_entries_view_showcase"><![CDATA[Featured Products (Showcase View)]]></string>
+    <string name="_bx_market_page_block_title_featured_entries_view_showcase"><![CDATA[Featured Products]]></string>
+
+    <string name="_bx_market_menu_set_title_view_entry"><![CDATA[Product Actions]]></string>
+    <string name="_bx_market_menu_title_view_entry"><![CDATA[Product Actions]]></string>
+    <string name="_bx_market_menu_set_title_view_entry_more"><![CDATA[Product More Actions]]></string>
+    <string name="_bx_market_menu_title_view_entry_more"><![CDATA[Product More Actions]]></string>
+    <string name="_bx_market_menu_title_submenu"><![CDATA[Market Submenu]]></string>
+    <string name="_bx_market_menu_set_title_submenu"><![CDATA[Market Submenu]]></string>
+    <string name="_bx_market_menu_item_title_system_create_entry"><![CDATA[Product]]></string>
+    <string name="_bx_market_menu_item_title_create_entry"><![CDATA[Product]]></string>
+    <string name="_bx_market_menu_item_title_system_edit_entry"><![CDATA[Edit Product]]></string>
+    <string name="_bx_market_menu_item_title_edit_entry"><![CDATA[Edit]]></string>
+    <string name="_bx_market_menu_item_title_system_delete_entry"><![CDATA[Delete Product]]></string>
+    <string name="_bx_market_menu_item_title_delete_entry"><![CDATA[Delete]]></string>
+    <string name="_bx_market_menu_item_title_system_add_to_cart"><![CDATA[Add to Cart]]></string>
+    <string name="_bx_market_menu_item_title_add_to_cart"><![CDATA[Buy for {0}{1}]]></string>
+    <string name="_bx_market_menu_item_title_system_subscribe"><![CDATA[Subscribe]]></string>
+    <string name="_bx_market_menu_item_title_subscribe"><![CDATA[Subscribe for {0}{1}/{2}]]></string>
+    <string name="_bx_market_menu_item_title_system_download"><![CDATA[Download Product]]></string>
+    <string name="_bx_market_menu_item_title_download"><![CDATA[Download]]></string>
+    <string name="_bx_market_menu_item_title_system_product_more"><![CDATA[More Actions]]></string>
+    <string name="_bx_market_menu_item_title_product_more"><![CDATA[]]></string>
+    <string name="_bx_market_menu_item_title_system_unhide_entry"><![CDATA[Unhide Product]]></string>
+    <string name="_bx_market_menu_item_title_unhide_entry"><![CDATA[Publish]]></string>
+    <string name="_bx_market_menu_item_title_system_hide_entry"><![CDATA[Hide Product]]></string>
+    <string name="_bx_market_menu_item_title_hide_entry"><![CDATA[Hide]]></string>
+    <string name="_bx_market_menu_item_title_system_entries_home"><![CDATA[Market]]></string>
+    <string name="_bx_market_menu_item_title_entries_home"><![CDATA[Market]]></string>
+    <string name="_bx_market_menu_item_title_system_entries_categories"><![CDATA[Categories]]></string>
+    <string name="_bx_market_menu_item_title_entries_categories"><![CDATA[Categories]]></string>
+    <string name="_bx_market_menu_item_title_system_entries_public"><![CDATA[Storefront]]></string>
+    <string name="_bx_market_menu_item_title_entries_public"><![CDATA[Storefront]]></string>
+    <string name="_bx_market_menu_item_title_system_entries_search"><![CDATA[Search]]></string>
+    <string name="_bx_market_menu_item_title_entries_search"><![CDATA[Search]]></string>
+    <string name="_bx_market_menu_item_title_system_entries_manage"><![CDATA[Manage Products]]></string>
+    <string name="_bx_market_menu_item_title_entries_manage"><![CDATA[Manage]]></string>
+    <string name="_bx_market_menu_item_title_system_entries_latest"><![CDATA[Latest Products]]></string>
+    <string name="_bx_market_menu_item_title_entries_latest"><![CDATA[Latest]]></string>
+    <string name="_bx_market_menu_item_title_system_entries_featured"><![CDATA[Featured Products]]></string>
+    <string name="_bx_market_menu_item_title_entries_featured"><![CDATA[Featured]]></string>
+    <string name="_bx_market_menu_item_title_system_entries_popular"><![CDATA[Popular Products]]></string>
+    <string name="_bx_market_menu_item_title_entries_popular"><![CDATA[Popular]]></string>
+    <string name="_bx_market_menu_item_title_system_entries_top"><![CDATA[Top Products]]></string>
+    <string name="_bx_market_menu_item_title_entries_top"><![CDATA[Top]]></string>
+    <string name="_bx_market_menu_item_title_system_entries_updated"><![CDATA[Updated Products]]></string>
+    <string name="_bx_market_menu_item_title_entries_updated"><![CDATA[Updated]]></string>
+    <string name="_bx_market_menu_item_title_system_more_auto"><![CDATA[More]]></string>
+    <string name="_bx_market_menu_item_title_more_auto"><![CDATA[More]]></string>
+    <string name="_bx_market_menu_title_view_entry_submenu"><![CDATA[View Product Submenu]]></string>
+    <string name="_bx_market_menu_set_title_view_entry_submenu"><![CDATA[View Product Submenu]]></string>
+    <string name="_bx_market_menu_item_title_system_view_entry_submenu_entry"><![CDATA[Overview]]></string>
+    <string name="_bx_market_menu_item_title_view_entry_submenu_entry"><![CDATA[Overview]]></string>
+    <string name="_bx_market_menu_item_title_system_view_entry_submenu_comments"><![CDATA[Reviews]]></string>
+    <string name="_bx_market_menu_item_title_view_entry_submenu_comments"><![CDATA[Reviews]]></string>
+    <string name="_bx_market_menu_item_title_system_view_entry_submenu_info"><![CDATA[Info]]></string>
+    <string name="_bx_market_menu_item_title_view_entry_submenu_info"><![CDATA[Info]]></string>
+    <string name="_bx_market_menu_item_title_system_view_entries_author"><![CDATA[Products]]></string>
+    <string name="_bx_market_menu_item_title_view_entries_author"><![CDATA[Products]]></string>
+    <string name="_bx_market_menu_item_title_system_view_entries_in_context"><![CDATA[Products]]></string>
+    <string name="_bx_market_menu_item_title_view_entries_in_context"><![CDATA[Products]]></string>
+    <string name="_bx_market_menu_title_entries_my"><![CDATA[My Products Action Menu]]></string>
+    <string name="_bx_market_menu_set_title_entries_my"><![CDATA[My Products Menu]]></string>
+    <string name="_bx_market_menu_item_title_system_manage_my_products"><![CDATA[My products]]></string>
+    <string name="_bx_market_menu_item_title_manage_my_products"><![CDATA[Products]]></string>
+    <string name="_bx_market_menu_set_title_manage_tools"><![CDATA[Manage Tools Submenu]]></string>
+    <string name="_bx_market_menu_title_manage_tools"><![CDATA[Manage Tools Submenu]]></string>
+    <string name="_bx_market_menu_item_title_system_manage_account"><![CDATA[Manage account]]></string>
+    <string name="_bx_market_menu_item_title_manage_account"><![CDATA[Manage account]]></string>
+    <string name="_bx_market_menu_item_title_system_admt_products"><![CDATA[Products]]></string>
+    <string name="_bx_market_menu_item_title_admt_products"><![CDATA[Products]]></string>
+    <string name="_bx_market_menu_item_title_manage_my"><![CDATA[My Products]]></string>
+    <string name="_bx_market_menu_item_title_manage_all"><![CDATA[All Products]]></string>
+    <string name="_bx_market_menu_item_title_system_licenses"><![CDATA[Licenses]]></string>
+    <string name="_bx_market_menu_item_title_licenses"><![CDATA[Licenses]]></string>
+    <string name="_bx_market_menu_title_snippet"><![CDATA[Snippet Actions]]></string>
+    <string name="_bx_market_menu_set_title_snippet"><![CDATA[Snippet Actions]]></string>
+    <string name="_bx_market_menu_item_title_system_snippet_more"><![CDATA[More Actions]]></string>
+    <string name="_bx_market_menu_item_title_snippet_more"><![CDATA[More Actions]]></string>
+    <string name="_bx_market_menu_title_snippet_more"><![CDATA[Snippet More Actions]]></string>
+    <string name="_bx_market_menu_set_title_snippet_more"><![CDATA[Snippet More Actions]]></string>
+    <string name="_bx_market_menu_item_title_downloads_more"><![CDATA[Show More]]></string>
+    <string name="_bx_market_menu_title_licenses_submenu"><![CDATA[Licenses Submenu]]></string>
+    <string name="_bx_market_menu_set_title_licenses_submenu"><![CDATA[Licenses Submenu]]></string>
+    <string name="_bx_market_menu_item_title_system_products_licenses_administration"><![CDATA[All Licenses]]></string>
+    <string name="_bx_market_menu_item_title_products_licenses_administration"><![CDATA[All Licenses]]></string>
+    <string name="_bx_market_menu_item_title_system_products_licenses"><![CDATA[My Licenses]]></string>
+    <string name="_bx_market_menu_item_title_products_licenses"><![CDATA[My Licenses]]></string>
+    
+
+    <string name="_bx_market_grid_filter_item_title_adm_select_one_filter1"><![CDATA[All Statuses]]></string>
+    <string name="_bx_market_grid_filter_item_title_adm_select_one_filter2"><![CDATA[Any Audience]]></string>
+    <string name="_bx_market_grid_filter_item_title_adm_active"><![CDATA[Active]]></string>
+    <string name="_bx_market_grid_filter_item_title_adm_hidden"><![CDATA[Hidden]]></string>
+    <string name="_bx_market_grid_filter_item_title_adm_pending"><![CDATA[Pending]]></string>
+    <string name="_bx_market_grid_column_title_adm_active"><![CDATA[Active]]></string>
+    <string name="_bx_market_grid_column_title_adm_title"><![CDATA[Title]]></string>
+    <string name="_bx_market_grid_column_title_adm_added"><![CDATA[Added]]></string>
+    <string name="_bx_market_grid_column_title_adm_author"><![CDATA[Author]]></string>
+    <string name="_bx_market_grid_action_title_adm_edit"><![CDATA[Edit]]></string>
+    <string name="_bx_market_grid_action_title_adm_delete"><![CDATA[Delete]]></string>
+    <string name="_bx_market_grid_action_title_adm_more_actions"><![CDATA[More Actions]]></string>
+    <string name="_bx_market_grid_action_title_adm_audit_content"><![CDATA[Audit actions]]></string>
+    <string name="_bx_market_grid_action_title_adm_clear_reports"><![CDATA[Clear reports]]></string>
+    <string name="_bx_market_grid_column_title_adm_status_admin"><![CDATA[Moderation]]></string>
+    <string name="_bx_market_grid_action_err_delete"><![CDATA[Cannot delete the selected product(s).]]></string>
+    <string name="_bx_market_grid_txt_account_manager"><![CDATA[Redirect to manage account.]]></string>
+
+
+    <string name="_bx_market_grid_column_title_lcs_profile_id"><![CDATA[Owner]]></string>
+    <string name="_bx_market_grid_column_title_lcs_transaction"><![CDATA[Order]]></string>
+    <string name="_bx_market_grid_column_title_lcs_product"><![CDATA[Product]]></string>
+    <string name="_bx_market_grid_column_title_lcs_license"><![CDATA[License]]></string>
+    <string name="_bx_market_grid_column_title_lcs_type"><![CDATA[Type]]></string>
+    <string name="_bx_market_grid_column_title_lcs_domain"><![CDATA[Domain]]></string>
+    <string name="_bx_market_grid_column_title_lcs_added"><![CDATA[Begin]]></string>
+    <string name="_bx_market_grid_column_title_lcs_expired"><![CDATA[Expire]]></string>
+    <string name="_bx_market_grid_action_title_lcs_edit"><![CDATA[Edit]]></string>
+    <string name="_bx_market_grid_action_title_lcs_reset"><![CDATA[Reset]]></string>
+    <string name="_bx_market_grid_action_title_lcs_delete"><![CDATA[Delete]]></string>
+    <string name="_bx_market_grid_action_err_cannot_perform"><![CDATA[Cannot perform the action. Please report.]]></string>
+    <string name="_bx_market_grid_txt_lcs_type_single"><![CDATA[one-time]]></string>
+    <string name="_bx_market_grid_txt_lcs_type_recurring"><![CDATA[recurring]]></string>
+    <string name="_bx_market_grid_txt_lcs_never"><![CDATA[never]]></string>
+    <string name="_bx_market_popup_title_lcs_edit"><![CDATA[Edit License]]></string>
+
+    <string name="_bx_market_chart_growth"><![CDATA[Market: Growth]]></string>
+    <string name="_bx_market_chart_growth_speed"><![CDATA[Market: Growth Speed]]></string>
+
+    <string name="_bx_market_search_extended"><![CDATA[Market Search]]></string>
+    <string name="_bx_market_search_extended_cmts"><![CDATA[Market Comments Search]]></string>
+
+    <string name="_bx_market_pre_lists_cats"><![CDATA[Product categories]]></string>
+    <string name="_bx_market_cat_administration"><![CDATA[Administration]]></string>
+    <string name="_bx_market_cat_adult"><![CDATA[Adult]]></string>
+    <string name="_bx_market_cat_advertisement"><![CDATA[Advertisement]]></string>
+    <string name="_bx_market_cat_affiliates"><![CDATA[Affiliates]]></string>
+    <string name="_bx_market_cat_authentication"><![CDATA[Authentication]]></string>
+    <string name="_bx_market_cat_calendars"><![CDATA[Calendars]]></string>
+    <string name="_bx_market_cat_communication"><![CDATA[Communication]]></string>
+    <string name="_bx_market_cat_content"><![CDATA[Content]]></string>
+    <string name="_bx_market_cat_conversion"><![CDATA[Conversion]]></string>
+    <string name="_bx_market_cat_core_changes"><![CDATA[Core Changes]]></string>
+    <string name="_bx_market_cat_dating"><![CDATA[Dating]]></string>
+    <string name="_bx_market_cat_documentation"><![CDATA[Documentation]]></string>
+    <string name="_bx_market_cat_ecommerce"><![CDATA[eCommerce]]></string>
+    <string name="_bx_market_cat_events"><![CDATA[Events]]></string>
+    <string name="_bx_market_cat_feedback"><![CDATA[Feedback]]></string>
+    <string name="_bx_market_cat_flash"><![CDATA[Flash]]></string>
+    <string name="_bx_market_cat_games"><![CDATA[Games]]></string>
+    <string name="_bx_market_cat_graphics"><![CDATA[Graphics]]></string>
+    <string name="_bx_market_cat_hosting"><![CDATA[Hosting]]></string>
+    <string name="_bx_market_cat_integrations"><![CDATA[Integrations]]></string>
+    <string name="_bx_market_cat_location"><![CDATA[Location]]></string>
+    <string name="_bx_market_cat_management"><![CDATA[Management]]></string>
+    <string name="_bx_market_cat_mobile"><![CDATA[Mobile]]></string>
+    <string name="_bx_market_cat_multimedia"><![CDATA[Multimedia]]></string>
+    <string name="_bx_market_cat_music"><![CDATA[Music]]></string>
+    <string name="_bx_market_cat_navigation"><![CDATA[Navigation]]></string>
+    <string name="_bx_market_cat_other"><![CDATA[Other]]></string>
+    <string name="_bx_market_cat_performance"><![CDATA[Performance]]></string>
+    <string name="_bx_market_cat_photos"><![CDATA[Photos]]></string>
+    <string name="_bx_market_cat_search"><![CDATA[Search]]></string>
+    <string name="_bx_market_cat_security"><![CDATA[Security]]></string>
+    <string name="_bx_market_cat_services"><![CDATA[Services]]></string>
+    <string name="_bx_market_cat_social"><![CDATA[Social]]></string>
+    <string name="_bx_market_cat_spam_prevention"><![CDATA[Spam Prevention]]></string>
+    <string name="_bx_market_cat_statistics"><![CDATA[Statistics]]></string>
+    <string name="_bx_market_cat_templates"><![CDATA[Templates]]></string>
+    <string name="_bx_market_cat_tools"><![CDATA[Tools]]></string>
+    <string name="_bx_market_cat_translations"><![CDATA[Translations]]></string>
+    <string name="_bx_market_cat_video"><![CDATA[Video]]></string>
+
+    <string name="_bx_market_pre_lists_durations"><![CDATA[Product durations]]></string>
+    <string name="_bx_market_cat_duration_day"><![CDATA[daily]]></string>
+    <string name="_bx_market_cat_duration_week"><![CDATA[weekly]]></string>
+    <string name="_bx_market_cat_duration_month"><![CDATA[monthly]]></string>
+    <string name="_bx_market_cat_duration_year"><![CDATA[yearly]]></string>
+
+    <string name="_bx_market_vote_counter"><![CDATA[{0} ratings]]></string>
+
+    <string name="_bx_market_txt_msg_status_hidden"><![CDATA[This product was hidden.]]></string>
+    <string name="_bx_market_txt_msg_status_pending"><![CDATA[This product is pending approval.]]></string>
+    <string name="_bx_market_err_access_denied"><![CDATA[Access denied.]]></string>
+    <string name="_bx_market_err_no_payments"><![CDATA[There is no installed payment processing module.]]></string>
+    <string name="_bx_market_err_not_accept_payments"><![CDATA[You need to activate at least one payment provider. You may do it via My Account menu -> Settings page -> <a href="{0}">Payments</a> tab.]]></string>
+    <string name="_bx_market_err_not_accept_payments_single"><![CDATA[You need to activate at least one payment provider, which is working with Shopping Cart. You may do it via My Account menu -> Settings page -> <a href="{0}">Payments</a> tab.]]></string>
+    <string name="_bx_market_err_not_accept_payments_recurring"><![CDATA[You need to activate at least one payment provider, which is working with Subscriptions. You may do it via My Account menu -> Settings page -> <a href="{0}">Payments</a> tab.]]></string>
+
+    <string name="_bx_market_txt_all_entries_by"><![CDATA[{0} products]]></string>
+    <string name="_bx_market_txt_all_entries_in"><![CDATA[<a href="{0}">All Products in {1} ({2})</a>]]></string>
+    <string name="_bx_market_txt_category"><![CDATA[Category:]]></string>
+    <string name="_bx_market_txt_most_current_version"><![CDATA[The most current version]]></string>
+    <string name="_bx_market_txt_sample_single"><![CDATA[product]]></string>
+    <string name="_bx_market_txt_sample_single_with_article"><![CDATA[a product]]></string>
+    <string name="_bx_market_txt_sample_comment_single"><![CDATA[comment to product]]></string>
+    <string name="_bx_market_txt_sample_vote_single"><![CDATA[vote to product]]></string>
+    <string name="_bx_market_txt_sample_reaction_single"><![CDATA['{0}' reaction to product]]></string>
+    <string name="_bx_market_txt_sample_score_up_single"><![CDATA[score up vote to product]]></string>
+    <string name="_bx_market_txt_sample_score_down_single"><![CDATA[score down vote to product]]></string>
+    <string name="_bx_market_txt_author_added_product"><![CDATA[{0} {1}]]></string>
+    <string name="_bx_market_txt_joined"><![CDATA[Joined:]]></string>
+    <string name="_bx_market_txt_last_active"><![CDATA[Last Active:]]></string>
+    <string name="_bx_market_txt_price_single"><![CDATA[Buy for {0}{1}]]></string>
+    <string name="_bx_market_txt_price_single_short"><![CDATA[{0}{1}]]></string>
+    <string name="_bx_market_txt_price_recurring"><![CDATA[Subscribe for {0}{1}/{2}]]></string>
+    <string name="_bx_market_txt_price_recurring_short"><![CDATA[{0}{1}/{2}]]></string>
+    <string name="_bx_market_txt_price_free"><![CDATA[Free]]></string>
+    <string name="_bx_market_txt_per_hour"><![CDATA[hour]]></string>
+    <string name="_bx_market_txt_per_hour_short"><![CDATA[hour]]></string>
+    <string name="_bx_market_txt_per_day"><![CDATA[day]]></string>
+    <string name="_bx_market_txt_per_day_short"><![CDATA[day]]></string>
+    <string name="_bx_market_txt_per_week"><![CDATA[week]]></string>
+    <string name="_bx_market_txt_per_week_short"><![CDATA[week]]></string>
+    <string name="_bx_market_txt_per_month"><![CDATA[month]]></string>
+    <string name="_bx_market_txt_per_month_short"><![CDATA[month]]></string>
+    <string name="_bx_market_txt_per_year"><![CDATA[year]]></string>
+    <string name="_bx_market_txt_per_year_short"><![CDATA[year]]></string>
+    <string name="_bx_market_txt_get_for_free"><![CDATA[Download for Free]]></string>
+    <string name="_bx_market_txt_purchased_note"><![CDATA[Contact <a href="{0}">{1}</a> if you have any questions or need support.]]></string>
+
+    <!-- EMAIL TEMPLATES -->
+    <string name="_bx_market_et_txt_name_purchased"><![CDATA[Product purchased.]]></string>
+    <string name="_bx_market_et_txt_subject_purchased"><![CDATA[You've purchased {product_name} product.]]></string>
+    <string name="_bx_market_et_txt_body_purchased"><![CDATA[{email_header}
+<p>Hello, {client_name}.</p>
+<p>You've purchased <a href="{product_url}">{product_name}</a> product from <a href="{vendor_url}">{vendor_name}</a>.<br />Your license is <b>{license}</b>.</p>
+<p>{notes}</p>
+{email_footer}]]></string>
+</resources>

+ 663 - 0
modules/boonex/market/updates/14.0.6_14.0.7/source/install/sql/install.sql

@@ -0,0 +1,663 @@
+
+SET @sStorageEngine = (SELECT `value` FROM `sys_options` WHERE `name` = 'sys_storage_default');
+
+-- TABLE: entries
+CREATE TABLE IF NOT EXISTS `bx_market_products` (
+  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
+  `author` int(11) unsigned NOT NULL default '0',
+  `added` int(11) NOT NULL default '0',
+  `changed` int(11) NOT NULL default '0',
+  `thumb` int(11) NOT NULL default '0',
+  `cover` int(11) NOT NULL default '0',
+  `cover_data` varchar(64) NOT NULL default '',
+  `cover_raw` longtext NOT NULL,
+  `package` int(11) NOT NULL default '0',
+  `name` varchar(255) NOT NULL,
+  `title` varchar(255) NOT NULL,
+  `text` text NOT NULL,
+  `notes` text NOT NULL,
+  `notes_purchased` text NOT NULL,
+  `cat` int(11) NOT NULL,
+  `price_single` float NOT NULL default '0',
+  `price_recurring` float NOT NULL default '0',
+  `duration_recurring` varchar(16) NOT NULL default 'month',
+  `trial_recurring` int(11) NOT NULL default '0',
+  `labels` text NOT NULL,
+  `location` text NOT NULL,
+  `views` int(11) NOT NULL default '0',
+  `rate` float NOT NULL default '0',
+  `votes` int(11) NOT NULL default '0',
+  `rrate` float NOT NULL default '0',
+  `rvotes` int(11) NOT NULL default '0',
+  `score` int(11) NOT NULL default '0',
+  `sc_up` int(11) NOT NULL default '0',
+  `sc_down` int(11) NOT NULL default '0',
+  `favorites` int(11) NOT NULL default '0',
+  `comments` int(11) NOT NULL default '0',
+  `reports` int(11) NOT NULL default '0',
+  `featured` int(11) NOT NULL default '0',
+  `cf` int(11) NOT NULL default '1',
+  `allow_view_to` varchar(32) NOT NULL DEFAULT '3',
+  `allow_purchase_to` varchar(32) NOT NULL DEFAULT '3',
+  `allow_comment_to` varchar(32) NOT NULL DEFAULT 'c',
+  `allow_vote_to` varchar(32) NOT NULL DEFAULT 'c',
+  `status` enum('active','hidden') NOT NULL DEFAULT 'active',
+  `status_admin` enum('active','hidden','pending') NOT NULL DEFAULT 'active',
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `name` (`name`(191)),
+  FULLTEXT KEY `title_text` (`title`,`text`)
+);
+
+-- TABLE: subentries
+CREATE TABLE IF NOT EXISTS `bx_market_subproducts` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `initiator` int(11) NOT NULL,
+  `content` int(11) NOT NULL,
+  `added` int(10) unsigned NOT NULL,
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `initiator` (`initiator`,`content`),
+  KEY `content` (`content`)
+);
+
+-- TABLE: licenses
+CREATE TABLE IF NOT EXISTS `bx_market_licenses` (
+  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
+  `profile_id` int(11) unsigned NOT NULL default '0',
+  `product_id` int(11) unsigned NOT NULL default '0',
+  `count` int(11) unsigned NOT NULL default '0',
+  `order` varchar(32) NOT NULL default '',
+  `license` varchar(32) NOT NULL default '',
+  `type` varchar(16) NOT NULL default '',
+  `domain` varchar(128) NOT NULL default '',
+  `added` int(11) unsigned NOT NULL default '0',
+  `expired` int(11) unsigned NOT NULL default '0',
+  `expired_notif` int(11) unsigned NOT NULL default '0',
+  `new` tinyint(1) NOT NULL default '1',
+  PRIMARY KEY (`id`),
+  KEY `product_id` (`product_id`, `profile_id`),
+  KEY `license` (`license`)
+);
+
+CREATE TABLE IF NOT EXISTS `bx_market_licenses_deleted` (
+  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
+  `profile_id` int(11) unsigned NOT NULL default '0',
+  `product_id` int(11) unsigned NOT NULL default '0',
+  `count` int(11) unsigned NOT NULL default '0',
+  `order` varchar(32) NOT NULL default '',
+  `license` varchar(32) NOT NULL default '',
+  `type` varchar(16) NOT NULL default '',
+  `domain` varchar(128) NOT NULL default '',
+  `added` int(11) unsigned NOT NULL default '0',
+  `expired` int(11) unsigned NOT NULL default '0',
+  `expired_notif` int(11) unsigned NOT NULL default '0',
+  `new` tinyint(1) NOT NULL default '1',
+  `reason` varchar(16) NOT NULL default '',
+  `deleted` int(11) unsigned NOT NULL default '0',
+  PRIMARY KEY (`id`),
+  KEY `product_id` (`product_id`,`profile_id`),
+  KEY `license` (`license`)
+);
+
+-- TABLE: storages & transcoders
+CREATE TABLE IF NOT EXISTS `bx_market_files` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `profile_id` int(10) unsigned NOT NULL,
+  `remote_id` varchar(128) NOT NULL,
+  `path` varchar(255) NOT NULL,
+  `file_name` varchar(255) NOT NULL,
+  `mime_type` varchar(128) NOT NULL,
+  `ext` varchar(32) NOT NULL,
+  `size` bigint(20) NOT NULL,
+  `added` int(11) NOT NULL,
+  `modified` int(11) NOT NULL,
+  `private` int(11) NOT NULL,
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `remote_id` (`remote_id`)
+);
+
+CREATE TABLE IF NOT EXISTS `bx_market_files2products` (
+  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
+  `content_id` int(11) unsigned NOT NULL,
+  `file_id` int(11) NOT NULL,
+  `type` enum('version','update') NOT NULL DEFAULT 'version',
+  `version` varchar(255) NOT NULL,
+  `version_to` varchar(255) NOT NULL,
+  `downloads` int(11) NOT NULL,
+  `order` int(11) NOT NULL,
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `file_content` (`file_id`,`content_id`),
+  KEY `content_id` (`content_id`)
+);
+
+CREATE TABLE IF NOT EXISTS `bx_market_downloads_track` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `file_id` int(11) NOT NULL default '0',
+  `profile_id` int(11) NOT NULL default '0',
+  `profile_nip` int(11) unsigned NOT NULL default '0',
+  `date` int(11) NOT NULL default '0',
+  PRIMARY KEY (`id`)
+);
+
+CREATE TABLE IF NOT EXISTS `bx_market_photos` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `profile_id` int(10) unsigned NOT NULL,
+  `remote_id` varchar(128) NOT NULL,
+  `path` varchar(255) NOT NULL,
+  `file_name` varchar(255) NOT NULL,
+  `mime_type` varchar(128) NOT NULL,
+  `ext` varchar(32) NOT NULL,
+  `size` bigint(20) NOT NULL,
+  `added` int(11) NOT NULL,
+  `modified` int(11) NOT NULL,
+  `private` int(11) NOT NULL,
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `remote_id` (`remote_id`)
+);
+
+CREATE TABLE IF NOT EXISTS `bx_market_photos2products` (
+  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
+  `content_id` int(11) unsigned NOT NULL,
+  `file_id` int(11) NOT NULL,
+  `title` varchar(255) NOT NULL,
+  `order` int(11) NOT NULL,
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `file_content` (`file_id`,`content_id`),
+  KEY `content_id` (`content_id`)
+);
+
+CREATE TABLE IF NOT EXISTS `bx_market_photos_resized` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `profile_id` int(10) unsigned NOT NULL,
+  `remote_id` varchar(128) NOT NULL,
+  `path` varchar(255) NOT NULL,
+  `file_name` varchar(255) NOT NULL,
+  `mime_type` varchar(128) NOT NULL,
+  `ext` varchar(32) NOT NULL,
+  `size` bigint(20) NOT NULL,
+  `added` int(11) NOT NULL,
+  `modified` int(11) NOT NULL,
+  `private` int(11) NOT NULL,
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `remote_id` (`remote_id`)
+);
+
+-- TABLE: comments
+CREATE TABLE IF NOT EXISTS `bx_market_cmts` (
+  `cmt_id` int(11) NOT NULL AUTO_INCREMENT,
+  `cmt_parent_id` int(11) NOT NULL DEFAULT '0',
+  `cmt_vparent_id` int(11) NOT NULL DEFAULT '0',
+  `cmt_object_id` int(11) NOT NULL DEFAULT '0',
+  `cmt_author_id` int(11) NOT NULL DEFAULT '0',
+  `cmt_level` int(11) NOT NULL DEFAULT '0',
+  `cmt_text` text NOT NULL,
+  `cmt_mood` tinyint(4) NOT NULL DEFAULT '0',
+  `cmt_rate` int(11) NOT NULL DEFAULT '0',
+  `cmt_rate_count` int(11) NOT NULL DEFAULT '0',
+  `cmt_time` int(11) unsigned NOT NULL DEFAULT '0',
+  `cmt_replies` int(11) NOT NULL DEFAULT '0',
+  `cmt_pinned` int(11) NOT NULL default '0',
+  `cmt_cf` int(11) NOT NULL default '1',
+  PRIMARY KEY (`cmt_id`),
+  KEY `cmt_object_id` (`cmt_object_id`,`cmt_parent_id`),
+  FULLTEXT KEY `search_fields` (`cmt_text`)
+);
+
+CREATE TABLE IF NOT EXISTS `bx_market_cmts_notes` (
+  `cmt_id` int(11) NOT NULL AUTO_INCREMENT,
+  `cmt_parent_id` int(11) NOT NULL DEFAULT '0',
+  `cmt_vparent_id` int(11) NOT NULL DEFAULT '0',
+  `cmt_object_id` int(11) NOT NULL DEFAULT '0',
+  `cmt_author_id` int(11) NOT NULL DEFAULT '0',
+  `cmt_level` int(11) NOT NULL DEFAULT '0',
+  `cmt_text` text NOT NULL,
+  `cmt_mood` tinyint(4) NOT NULL DEFAULT '0',
+  `cmt_rate` int(11) NOT NULL DEFAULT '0',
+  `cmt_rate_count` int(11) NOT NULL DEFAULT '0',
+  `cmt_time` int(11) unsigned NOT NULL DEFAULT '0',
+  `cmt_replies` int(11) NOT NULL DEFAULT '0',
+  `cmt_pinned` int(11) NOT NULL default '0',
+  PRIMARY KEY (`cmt_id`),
+  KEY `cmt_object_id` (`cmt_object_id`,`cmt_parent_id`),
+  FULLTEXT KEY `search_fields` (`cmt_text`)
+);
+
+-- TABLE: votes
+CREATE TABLE IF NOT EXISTS `bx_market_votes` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `object_id` int(11) NOT NULL default '0',
+  `count` int(11) NOT NULL default '0',
+  `sum` int(11) NOT NULL default '0',
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `object_id` (`object_id`)
+);
+
+CREATE TABLE IF NOT EXISTS `bx_market_votes_track` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `object_id` int(11) NOT NULL default '0',
+  `author_id` int(11) NOT NULL default '0',
+  `author_nip` int(11) unsigned NOT NULL default '0',
+  `value` tinyint(4) NOT NULL default '0',
+  `date` int(11) NOT NULL default '0',
+  PRIMARY KEY (`id`),
+  KEY `vote` (`object_id`, `author_nip`)
+);
+
+CREATE TABLE IF NOT EXISTS `bx_market_reactions` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `object_id` int(11) NOT NULL default '0',
+  `reaction` varchar(32) NOT NULL default '',
+  `count` int(11) NOT NULL default '0',
+  `sum` int(11) NOT NULL default '0',
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `reaction` (`object_id`, `reaction`)
+);
+
+CREATE TABLE IF NOT EXISTS `bx_market_reactions_track` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `object_id` int(11) NOT NULL default '0',
+  `author_id` int(11) NOT NULL default '0',
+  `author_nip` int(11) unsigned NOT NULL default '0',
+  `reaction` varchar(32) NOT NULL default '',
+  `value` tinyint(4) NOT NULL default '0',
+  `date` int(11) NOT NULL default '0',
+  PRIMARY KEY (`id`),
+  KEY `vote` (`object_id`, `author_nip`)
+);
+
+-- TABLE: views
+CREATE TABLE `bx_market_views_track` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `object_id` int(11) NOT NULL default '0',
+  `viewer_id` int(11) NOT NULL default '0',
+  `viewer_nip` int(11) unsigned NOT NULL default '0',
+  `date` int(11) NOT NULL default '0',
+  PRIMARY KEY (`id`),
+  KEY `id` (`object_id`,`viewer_id`,`viewer_nip`)
+);
+
+-- TABLE: metas
+CREATE TABLE `bx_market_meta_keywords` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `object_id` int(10) unsigned NOT NULL,
+  `keyword` varchar(255) NOT NULL,
+  PRIMARY KEY (`id`),
+  KEY `object_id` (`object_id`),
+  KEY `keyword` (`keyword`)
+);
+
+CREATE TABLE `bx_market_meta_locations` (
+  `object_id` int(10) unsigned NOT NULL,
+  `lat` double NOT NULL,
+  `lng` double NOT NULL,
+  `country` varchar(2) NOT NULL,
+  `state` varchar(255) NOT NULL,
+  `city` varchar(255) NOT NULL,
+  `zip` varchar(255) NOT NULL,
+  `street` varchar(255) NOT NULL,
+  `street_number` varchar(255) NOT NULL,
+  PRIMARY KEY (`object_id`),
+  KEY `country_state_city` (`country`,`state`(8),`city`(8))
+);
+
+CREATE TABLE `bx_market_meta_mentions` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `object_id` int(10) unsigned NOT NULL,
+  `profile_id` int(10) unsigned NOT NULL,
+  PRIMARY KEY (`id`),
+  KEY `object_id` (`object_id`),
+  KEY `profile_id` (`profile_id`)
+);
+
+-- TABLE: reports
+CREATE TABLE IF NOT EXISTS `bx_market_reports` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `object_id` int(11) NOT NULL default '0',
+  `count` int(11) NOT NULL default '0',
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `object_id` (`object_id`)
+);
+
+CREATE TABLE IF NOT EXISTS `bx_market_reports_track` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `object_id` int(11) NOT NULL default '0',
+  `author_id` int(11) NOT NULL default '0',
+  `author_nip` int(11) unsigned NOT NULL default '0',
+  `type` varchar(32) NOT NULL default '',
+  `text` text NOT NULL default '',
+  `date` int(11) NOT NULL default '0',
+  `checked_by` int(11) NOT NULL default '0',
+  `status` tinyint(11) NOT NULL default '0',
+  PRIMARY KEY (`id`),
+  KEY `report` (`object_id`, `author_nip`)
+);
+
+-- TABLE: favorites
+CREATE TABLE `bx_market_favorites_track` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `object_id` int(11) NOT NULL default '0',
+  `author_id` int(11) NOT NULL default '0',
+  `list_id` int(11) NOT NULL default '0',
+  `date` int(11) NOT NULL default '0',
+  PRIMARY KEY (`id`),
+  KEY `id` (`object_id`,`author_id`)
+);
+
+CREATE TABLE `bx_market_favorites_lists` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `title` varchar(255) NOT NULL,
+  `author_id` int(11) NOT NULL default '0',
+  `date` int(11) NOT NULL default '0',
+  `allow_view_favorite_list_to` varchar(16) NOT NULL DEFAULT '3',
+   PRIMARY KEY (`id`)
+);
+
+-- TABLE: scores
+CREATE TABLE IF NOT EXISTS `bx_market_scores` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `object_id` int(11) NOT NULL default '0',
+  `count_up` int(11) NOT NULL default '0',
+  `count_down` int(11) NOT NULL default '0',
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `object_id` (`object_id`)
+);
+
+CREATE TABLE IF NOT EXISTS `bx_market_scores_track` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `object_id` int(11) NOT NULL default '0',
+  `author_id` int(11) NOT NULL default '0',
+  `author_nip` int(11) unsigned NOT NULL default '0',
+  `type` varchar(8) NOT NULL default '',
+  `date` int(11) NOT NULL default '0',
+  PRIMARY KEY (`id`),
+  KEY `vote` (`object_id`, `author_nip`)
+);
+
+
+-- STORAGES & TRANSCODERS
+INSERT INTO `sys_objects_storage` (`object`, `engine`, `params`, `token_life`, `cache_control`, `levels`, `table_files`, `ext_mode`, `ext_allow`, `ext_deny`, `quota_size`, `current_size`, `quota_number`, `current_number`, `max_file_size`, `ts`) VALUES
+('bx_market_files', @sStorageEngine, '', 360, 2592000, 3, 'bx_market_files', 'allow-deny', 'zip', '', 0, 0, 0, 0, 0, 0),
+('bx_market_photos', @sStorageEngine, '', 360, 2592000, 3, 'bx_market_photos', 'allow-deny', '{image}', '', 0, 0, 0, 0, 0, 0),
+('bx_market_photos_resized', @sStorageEngine, '', 360, 2592000, 3, 'bx_market_photos_resized', 'allow-deny', '{image}', '', 0, 0, 0, 0, 0, 0);
+
+INSERT INTO `sys_objects_transcoder` (`object`, `storage_object`, `source_type`, `source_params`, `private`, `atime_tracking`, `atime_pruning`, `ts`) VALUES 
+('bx_market_preview', 'bx_market_photos_resized', 'Storage', 'a:1:{s:6:"object";s:16:"bx_market_photos";}', 'no', '1', '2592000', '0'),
+('bx_market_icon', 'bx_market_photos_resized', 'Storage', 'a:1:{s:6:"object";s:16:"bx_market_photos";}', 'no', '1', '2592000', '0'),
+('bx_market_thumb', 'bx_market_photos_resized', 'Storage', 'a:1:{s:6:"object";s:16:"bx_market_photos";}', 'no', '1', '2592000', '0'),
+('bx_market_cover', 'bx_market_photos_resized', 'Storage', 'a:1:{s:6:"object";s:16:"bx_market_photos";}', 'no', '1', '2592000', '0'),
+('bx_market_screenshot', 'bx_market_photos_resized', 'Storage', 'a:1:{s:6:"object";s:16:"bx_market_photos";}', 'no', '1', '2592000', '0'),
+('bx_market_gallery', 'bx_market_photos_resized', 'Storage', 'a:1:{s:6:"object";s:16:"bx_market_photos";}', 'no', '1', '2592000', '0');
+
+INSERT INTO `sys_transcoder_filters` (`transcoder_object`, `filter`, `filter_params`, `order`) VALUES 
+('bx_market_preview', 'Resize', 'a:3:{s:1:"w";s:3:"300";s:1:"h";s:3:"200";s:11:"crop_resize";s:1:"1";}', '0'),
+('bx_market_gallery', 'Resize', 'a:1:{s:1:"w";s:3:"500";}', '0'),
+('bx_market_icon', 'Resize', 'a:3:{s:1:"w";s:2:"50";s:1:"h";s:2:"50";s:13:"square_resize";s:1:"1";}', '0'),
+('bx_market_thumb', 'Resize', 'a:3:{s:1:"w";s:3:"100";s:1:"h";s:3:"100";s:13:"square_resize";s:1:"1";}', '0'),
+('bx_market_cover', 'Resize', 'a:1:{s:1:"w";s:4:"1200";}', '0'),
+('bx_market_screenshot', 'Resize', 'a:3:{s:1:"w";s:3:"200";s:1:"h";s:3:"120";s:11:"crop_resize";s:1:"1";}', '0');
+
+-- FORMS
+INSERT INTO `sys_objects_form`(`object`, `module`, `title`, `action`, `form_attrs`, `table`, `key`, `uri`, `uri_title`, `submit_name`, `params`, `deletable`, `active`, `override_class_name`, `override_class_file`) VALUES 
+('bx_market', 'bx_market', '_bx_market_form_entry', '', 'a:1:{s:7:"enctype";s:19:"multipart/form-data";}', 'bx_market_products', 'id', '', '', 'a:2:{i:0;s:9:"do_submit";i:1;s:10:"do_publish";}', '', 0, 1, 'BxMarketFormEntry', 'modules/boonex/market/classes/BxMarketFormEntry.php');
+
+INSERT INTO `sys_form_displays`(`object`, `display_name`, `module`, `view_mode`, `title`) VALUES 
+('bx_market', 'bx_market_entry_add', 'bx_market', 0, '_bx_market_form_entry_display_add'),
+('bx_market', 'bx_market_entry_delete', 'bx_market', 0, '_bx_market_form_entry_display_delete'),
+('bx_market', 'bx_market_entry_edit', 'bx_market', 0, '_bx_market_form_entry_display_edit'),
+('bx_market', 'bx_market_entry_view', 'bx_market', 1, '_bx_market_form_entry_display_view'),
+('bx_market', 'bx_market_entry_view_full', 'bx_market', 1, '_bx_market_form_entry_display_view_full');
+
+INSERT INTO `sys_form_inputs`(`object`, `module`, `name`, `value`, `values`, `checked`, `type`, `caption_system`, `caption`, `info`, `required`, `collapsed`, `html`, `attrs`, `attrs_tr`, `attrs_wrapper`, `checker_func`, `checker_params`, `checker_error`, `db_pass`, `db_params`, `editable`, `deletable`) VALUES 
+('bx_market', 'bx_market', 'cf', '1', '#!sys_content_filter', 0, 'select', '_sys_form_entry_input_sys_cf', '_sys_form_entry_input_cf', '', 0, 0, 0, '', '', '', '', '', '', 'Int', '', 1, 0),
+('bx_market', 'bx_market', 'allow_view_to', '', '', 0, 'custom', '_bx_market_form_entry_input_sys_allow_view_to', '_bx_market_form_entry_input_allow_view_to', '', 1, 0, 0, '', '', '', '', '', '', '', '', 1, 0),
+('bx_market', 'bx_market', 'allow_purchase_to', '', '', 0, 'custom', '_bx_market_form_entry_input_sys_allow_purchase_to', '_bx_market_form_entry_input_allow_purchase_to', '', 1, 0, 0, '', '', '', '', '', '', '', '', 1, 0),
+('bx_market', 'bx_market', 'allow_comment_to', '', '', 0, 'custom', '_bx_market_form_entry_input_sys_allow_comment_to', '_bx_market_form_entry_input_allow_comment_to', '', 1, 0, 0, '', '', '', '', '', '', '', '', 1, 0),
+('bx_market', 'bx_market', 'allow_vote_to', '', '', 0, 'custom', '_bx_market_form_entry_input_sys_allow_vote_to', '_bx_market_form_entry_input_allow_vote_to', '', 1, 0, 0, '', '', '', '', '', '', '', '', 1, 0),
+('bx_market', 'bx_market', 'delete_confirm', 1, '', 0, 'checkbox', '_bx_market_form_entry_input_sys_delete_confirm', '_bx_market_form_entry_input_delete_confirm', '_bx_market_form_entry_input_delete_confirm_info', 1, 0, 0, '', '', '', 'Avail', '', '_bx_market_form_entry_input_delete_confirm_error', '', '', 1, 0),
+('bx_market', 'bx_market', 'do_publish', '_bx_market_form_entry_input_do_publish', '', 0, 'submit', '_bx_market_form_entry_input_sys_do_publish', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 1, 0),
+('bx_market', 'bx_market', 'do_submit', '_bx_market_form_entry_input_do_submit', '', 0, 'submit', '_bx_market_form_entry_input_sys_do_submit', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 1, 0),
+('bx_market', 'bx_market', 'location', '', '', 0, 'location', '_sys_form_input_sys_location', '_sys_form_input_location', '', 0, 0, 0, '', '', '', '', '', '', '', '', 1, 0),
+('bx_market', 'bx_market', 'cover_raw', '', '', 0, 'textarea', '_bx_market_form_entry_input_sys_cover_raw', '_bx_market_form_entry_input_cover_raw', '_bx_market_form_entry_input_cover_raw_inf', 0, 0, 0, '', '', '', '', '', '', 'XssHtml', '', 1, 0),
+('bx_market', 'bx_market', 'pictures', 'a:1:{i:0;s:15:"bx_market_html5";}', 'a:1:{s:15:"bx_market_html5";s:25:"_sys_uploader_html5_title";}', 0, 'files', '_bx_market_form_entry_input_sys_pictures', '_bx_market_form_entry_input_pictures', '', 0, 0, 0, '', '', '', '', '', '', '', '', 1, 0),
+('bx_market', 'bx_market', 'files', 'a:1:{i:0;s:15:"bx_market_html5";}', 'a:1:{s:15:"bx_market_html5";s:25:"_sys_uploader_html5_title";}', 0, 'files', '_bx_market_form_entry_input_sys_files', '_bx_market_form_entry_input_files', '', 0, 0, 0, '', '', '', '', '', '', '', '', 1, 0),
+('bx_market', 'bx_market', 'text', '', '', 0, 'textarea', '_bx_market_form_entry_input_sys_text', '_bx_market_form_entry_input_text', '', 1, 0, 2, '', '', '', 'Avail', '', '_bx_market_form_entry_input_text_err', 'XssHtml', '', 1, 0),
+('bx_market', 'bx_market', 'notes', '', '', 0, 'textarea', '_bx_market_form_entry_input_sys_notes', '_bx_market_form_entry_input_notes', '_bx_market_form_entry_input_notes_inf', 0, 0, 0, '', '', '', '', '', '', 'Xss', '', 1, 0),
+('bx_market', 'bx_market', 'notes_purchased', '', '', 0, 'textarea', '_bx_market_form_entry_input_sys_notes_purchased', '_bx_market_form_entry_input_notes_purchased', '_bx_market_form_entry_input_notes_purchased_inf', 0, 0, 3, '', '', '', '', '', '', 'XssHtml', '', 1, 0),
+('bx_market', 'bx_market', 'title', '', '', 0, 'text', '_bx_market_form_entry_input_sys_title', '_bx_market_form_entry_input_title', '', 1, 0, 0, '', '', '', 'Avail', '', '_bx_market_form_entry_input_title_err', 'Xss', '', 1, 0),
+('bx_market', 'bx_market', 'name', '', '', 0, 'text', '_bx_market_form_entry_input_sys_name', '_bx_market_form_entry_input_name', '_bx_market_form_entry_input_name_inf', 1, 0, 0, '', '', '', '', '', '', 'Xss', '', 1, 0),
+('bx_market', 'bx_market', 'cat', '', '#!bx_market_cats', 0, 'select', '_bx_market_form_entry_input_sys_cat', '_bx_market_form_entry_input_cat', '', 1, 0, 0, '', '', '', 'avail', '', '_bx_market_form_entry_input_cat_err', 'Xss', '', 1, 0),
+('bx_market', 'bx_market', 'price_single', '', '', 0, 'price', '_bx_market_form_entry_input_sys_price_single', '_bx_market_form_entry_input_price_single', '_bx_market_form_entry_input_price_single_inf', 0, 0, 0, '', '', '', '', '', '', 'Float', '', 1, 0),
+('bx_market', 'bx_market', 'price_recurring', '', '', 0, 'price', '_bx_market_form_entry_input_sys_price_recurring', '_bx_market_form_entry_input_price_recurring', '_bx_market_form_entry_input_price_recurring_inf', 0, 0, 0, '', '', '', '', '', '', 'Float', '', 1, 0),
+('bx_market', 'bx_market', 'duration_recurring', 'month', '#!bx_market_durations', 0, 'select', '_bx_market_form_entry_input_sys_duration_recurring', '_bx_market_form_entry_input_duration_recurring', '', 0, 0, 0, '', '', '', '', '', '', 'Xss', '', 1, 0),
+('bx_market', 'bx_market', 'trial_recurring', '', '', 0, 'text', '_bx_market_form_entry_input_sys_trial_recurring', '_bx_market_form_entry_input_trial_recurring', '_bx_market_form_entry_input_trial_recurring_inf', 0, 0, 0, '', '', '', '', '', '', 'Int', '', 1, 0),
+('bx_market', 'bx_market', 'added', '', '', 0, 'datetime', '_bx_market_form_entry_input_sys_added', '_bx_market_form_entry_input_added', '', 0, 0, 0, '', '', '', '', '', '', '', '', 1, 0),
+('bx_market', 'bx_market', 'changed', '', '', 0, 'datetime', '_bx_market_form_entry_input_sys_changed', '_bx_market_form_entry_input_changed', '', 0, 0, 0, '', '', '', '', '', '', '', '', 1, 0),
+('bx_market', 'bx_market', 'header_beg_single', '', '', 0, 'block_header', '_bx_market_form_entry_input_sys_header_beg_single', '_bx_market_form_entry_input_header_beg_single', '', 0, 1, 0, '', '', '', '', '', '', '', '', 1, 0),
+('bx_market', 'bx_market', 'header_beg_recurring', '', '', 0, 'block_header', '_bx_market_form_entry_input_sys_header_beg_recurring', '_bx_market_form_entry_input_header_beg_recurring', '', 0, 1, 0, '', '', '', '', '', '', '', '', 1, 0),
+('bx_market', 'bx_market', 'header_beg_privacy', '', '', 0, 'block_header', '_bx_market_form_entry_input_sys_header_beg_privacy', '_bx_market_form_entry_input_header_beg_privacy', '', 0, 1, 0, '', '', '', '', '', '', '', '', 1, 0),
+('bx_market', 'bx_market', 'header_beg_notes', '', '', 0, 'block_header', '_bx_market_form_entry_input_sys_header_beg_notes', '_bx_market_form_entry_input_header_beg_notes', '', 0, 1, 0, '', '', '', '', '', '', '', '', 1, 0),
+('bx_market', 'bx_market', 'header_beg_other', '', '', 0, 'block_header', '_bx_market_form_entry_input_sys_header_beg_other', '_bx_market_form_entry_input_header_beg_other', '', 0, 1, 0, '', '', '', '', '', '', '', '', 1, 0),
+('bx_market', 'bx_market', 'header_end_single', '', '', 0, 'block_end', '_bx_market_form_entry_input_sys_header_end_single', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 0, 0),
+('bx_market', 'bx_market', 'header_end_recurring', '', '', 0, 'block_end', '_bx_market_form_entry_input_sys_header_end_recurring', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 0, 0),
+('bx_market', 'bx_market', 'header_end_privacy', '', '', 0, 'block_end', '_bx_market_form_entry_input_sys_header_end_privacy', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 0, 0),
+('bx_market', 'bx_market', 'header_end_notes', '', '', 0, 'block_end', '_bx_market_form_entry_input_sys_header_end_notes', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 0, 0),
+('bx_market', 'bx_market', 'header_end_other', '', '', 0, 'block_end', '_bx_market_form_entry_input_sys_header_end_other', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 0, 0),
+('bx_market', 'bx_market', 'warning_single', '_bx_market_err_not_accept_payments_single', '', 0, 'value', '_bx_market_form_entry_input_sys_warning_single', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 1, 0),
+('bx_market', 'bx_market', 'warning_recurring', '_bx_market_err_not_accept_payments_recurring', '', 0, 'value', '_bx_market_form_entry_input_sys_warning_recurring', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 1, 0),
+('bx_market', 'bx_market', 'subentries', '', '', 0, 'custom', '_bx_market_form_entry_input_sys_subentries', '_bx_market_form_entry_input_subentries', '_bx_market_form_entry_input_subentries_inf', 0, 0, 0, '', '', '', '', '', '', '', '', 1, 0),
+('bx_market', 'bx_market', 'labels', '', '', 0, 'custom', '_sys_form_input_sys_labels', '_sys_form_input_labels', '', 0, 0, 0, '', '', '', '', '', '', '', '', 1, 0);
+
+INSERT INTO `sys_form_display_inputs`(`display_name`, `input_name`, `visible_for_levels`, `active`, `order`) VALUES 
+('bx_market_entry_add', 'title', 2147483647, 1, 1),
+('bx_market_entry_add', 'name', 2147483647, 1, 2),
+('bx_market_entry_add', 'cat', 2147483647, 1, 3),
+('bx_market_entry_add', 'text', 2147483647, 1, 4),
+('bx_market_entry_add', 'cover_raw', 2147483647, 0, 5),
+('bx_market_entry_add', 'pictures', 2147483647, 1, 6),
+('bx_market_entry_add', 'files', 2147483647, 1, 7),
+('bx_market_entry_add', 'header_beg_single', 2147483647, 1, 8),
+('bx_market_entry_add', 'warning_single', 2147483647, 1, 9),
+('bx_market_entry_add', 'price_single', 2147483647, 1, 10),
+('bx_market_entry_add', 'header_end_single', 2147483647, 1, 11),
+('bx_market_entry_add', 'header_beg_recurring', 2147483647, 1, 12),
+('bx_market_entry_add', 'warning_recurring', 2147483647, 1, 13),
+('bx_market_entry_add', 'duration_recurring', 2147483647, 1, 14),
+('bx_market_entry_add', 'price_recurring', 2147483647, 1, 15),
+('bx_market_entry_add', 'trial_recurring', 2147483647, 1, 16),
+('bx_market_entry_add', 'header_end_recurring', 2147483647, 1, 17),
+('bx_market_entry_add', 'header_beg_privacy', 2147483647, 1, 18),
+('bx_market_entry_add', 'allow_view_to', 2147483647, 1, 19),
+('bx_market_entry_add', 'allow_purchase_to', 2147483647, 1, 20),
+('bx_market_entry_add', 'allow_comment_to', 2147483647, 1, 21),
+('bx_market_entry_add', 'allow_vote_to', 2147483647, 1, 22),
+('bx_market_entry_add', 'cf', 2147483647, 1, 23),
+('bx_market_entry_add', 'header_end_privacy', 2147483647, 1, 24),
+('bx_market_entry_add', 'header_beg_notes', 2147483647, 1, 25),
+('bx_market_entry_add', 'notes', 2147483647, 1, 26),
+('bx_market_entry_add', 'notes_purchased', 2147483647, 1, 27),
+('bx_market_entry_add', 'header_end_notes', 2147483647, 1, 28),
+('bx_market_entry_add', 'header_beg_other', 2147483647, 1, 29),
+('bx_market_entry_add', 'location', 2147483647, 1, 30),
+('bx_market_entry_add', 'subentries', 2147483647, 1, 31),
+('bx_market_entry_add', 'header_end_other', 2147483647, 1, 32),
+('bx_market_entry_add', 'do_publish', 2147483647, 1, 33),
+
+('bx_market_entry_delete', 'delete_confirm', 2147483647, 1, 1),
+('bx_market_entry_delete', 'do_submit', 2147483647, 1, 2),
+
+('bx_market_entry_edit', 'title', 2147483647, 1, 1),
+('bx_market_entry_edit', 'name', 2147483647, 1, 2),
+('bx_market_entry_edit', 'cat', 2147483647, 1, 3),
+('bx_market_entry_edit', 'text', 2147483647, 1, 4),
+('bx_market_entry_edit', 'cover_raw', 2147483647, 0, 5),
+('bx_market_entry_edit', 'pictures', 2147483647, 1, 6),
+('bx_market_entry_edit', 'files', 2147483647, 1, 7),
+('bx_market_entry_edit', 'header_beg_single', 2147483647, 1, 8),
+('bx_market_entry_edit', 'warning_single', 2147483647, 1, 9),
+('bx_market_entry_edit', 'price_single', 2147483647, 1, 10),
+('bx_market_entry_edit', 'header_end_single', 2147483647, 1, 11),
+('bx_market_entry_edit', 'header_beg_recurring', 2147483647, 1, 12),
+('bx_market_entry_edit', 'warning_recurring', 2147483647, 1, 13),
+('bx_market_entry_edit', 'duration_recurring', 2147483647, 1, 14),
+('bx_market_entry_edit', 'price_recurring', 2147483647, 1, 15),
+('bx_market_entry_edit', 'trial_recurring', 2147483647, 1, 16),
+('bx_market_entry_edit', 'header_end_recurring', 2147483647, 1, 17),
+('bx_market_entry_edit', 'header_beg_privacy', 2147483647, 1, 18),
+('bx_market_entry_edit', 'allow_view_to', 2147483647, 1, 19),
+('bx_market_entry_edit', 'allow_purchase_to', 2147483647, 1, 20),
+('bx_market_entry_edit', 'allow_comment_to', 2147483647, 1, 21),
+('bx_market_entry_edit', 'allow_vote_to', 2147483647, 1, 22),
+('bx_market_entry_edit', 'cf', 2147483647, 1, 23),
+('bx_market_entry_edit', 'header_end_privacy', 2147483647, 1, 24),
+('bx_market_entry_edit', 'header_beg_notes', 2147483647, 1, 25),
+('bx_market_entry_edit', 'notes', 2147483647, 1, 26),
+('bx_market_entry_edit', 'notes_purchased', 2147483647, 1, 27),
+('bx_market_entry_edit', 'header_end_notes', 2147483647, 1, 28),
+('bx_market_entry_edit', 'header_beg_other', 2147483647, 1, 29),
+('bx_market_entry_edit', 'location', 2147483647, 1, 30),
+('bx_market_entry_edit', 'subentries', 2147483647, 1, 31),
+('bx_market_entry_edit', 'header_end_other', 2147483647, 1, 32),
+('bx_market_entry_edit', 'do_submit', 2147483647, 1, 33),
+
+('bx_market_entry_view', 'cat', 2147483647, 1, 1),
+('bx_market_entry_view', 'added', 2147483647, 1, 2),
+('bx_market_entry_view', 'changed', 2147483647, 1, 3),
+
+('bx_market_entry_view_full', 'cat', 2147483647, 1, 1),
+('bx_market_entry_view_full', 'added', 2147483647, 1, 2),
+('bx_market_entry_view_full', 'changed', 2147483647, 1, 3),
+('bx_market_entry_view_full', 'notes', 2147483647, 1, 4);
+
+-- FORMS: License
+INSERT INTO `sys_objects_form`(`object`, `module`, `title`, `action`, `form_attrs`, `table`, `key`, `uri`, `uri_title`, `submit_name`, `params`, `deletable`, `active`, `override_class_name`, `override_class_file`) VALUES 
+('bx_market_license', 'bx_market', '_bx_market_form_license', '', 'a:1:{s:7:"enctype";s:19:"multipart/form-data";}', 'bx_market_licenses', 'id', '', '', 'do_submit', '', 0, 1, 'BxMarketFormLicense', 'modules/boonex/market/classes/BxMarketFormLicense.php');
+
+INSERT INTO `sys_form_displays`(`object`, `display_name`, `module`, `view_mode`, `title`) VALUES 
+('bx_market_license', 'bx_market_license_edit', 'bx_market', 0, '_bx_market_form_license_display_edit');
+
+INSERT INTO `sys_form_inputs`(`object`, `module`, `name`, `value`, `values`, `checked`, `type`, `caption_system`, `caption`, `info`, `required`, `collapsed`, `html`, `attrs`, `attrs_tr`, `attrs_wrapper`, `checker_func`, `checker_params`, `checker_error`, `db_pass`, `db_params`, `editable`, `deletable`) VALUES 
+('bx_market_license', 'bx_market', 'order', '', '', 0, 'text', '_bx_market_form_license_input_sys_order', '_bx_market_form_license_input_order', '', 1, 0, 0, '', '', '', 'Avail', '', '_bx_market_form_license_input_order_err', 'Xss', '', 1, 0),
+('bx_market_license', 'bx_market', 'license', '', '', 0, 'text', '_bx_market_form_license_input_sys_license', '_bx_market_form_license_input_license', '', 1, 0, 0, '', '', '', 'Avail', '', '_bx_market_form_license_input_license_err', 'Xss', '', 1, 0),
+('bx_market_license', 'bx_market', 'domain', '', '', 0, 'text', '_bx_market_form_license_input_sys_domain', '_bx_market_form_license_input_domain', '', 0, 0, 0, '', '', '', '', '', '', 'Xss', '', 1, 0),
+('bx_market_license', 'bx_market', 'added', '', '', 0, 'datetime', '_bx_market_form_license_input_sys_added', '_bx_market_form_license_input_added', '', 0, 0, 0, '', '', '', '', '', '', 'DateTimeUtc', '', 1, 0),
+('bx_market_license', 'bx_market', 'expired', '', '', 0, 'datetime', '_bx_market_form_license_input_sys_expired', '_bx_market_form_license_input_expired', '', 0, 0, 0, '', '', '', '', '', '', 'DateTimeUtc', '', 1, 0),
+('bx_market_license', 'bx_market', 'controls', '', 'do_submit,do_cancel', 0, 'input_set', '_bx_market_form_license_input_sys_controls', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 0, 0),
+('bx_market_license', 'bx_market', 'do_submit', '_bx_market_form_license_input_do_submit', '', 0, 'submit', '_bx_market_form_license_input_sys_do_submit', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 1, 0),
+('bx_market_license', 'bx_market', 'do_cancel', '_bx_market_form_license_input_do_cancel', '', 0, 'button', '_bx_market_form_license_input_sys_do_cancel', '', '', 0, 0, 0, 'a:2:{s:7:"onclick";s:45:"$(''.bx-popup-applied:visible'').dolPopupHide()";s:5:"class";s:22:"bx-def-margin-sec-left";}', '', '', '', '', '', '', '', 0, 0);
+
+INSERT INTO `sys_form_display_inputs`(`display_name`, `input_name`, `visible_for_levels`, `active`, `order`) VALUES 
+('bx_market_license_edit', 'order', 2147483647, 1, 1),
+('bx_market_license_edit', 'license', 2147483647, 1, 2),
+('bx_market_license_edit', 'domain', 2147483647, 1, 3),
+('bx_market_license_edit', 'added', 2147483647, 1, 4),
+('bx_market_license_edit', 'expired', 2147483647, 1, 5),
+('bx_market_license_edit', 'controls', 2147483647, 1, 6),
+('bx_market_license_edit', 'do_submit', 2147483647, 1, 7),
+('bx_market_license_edit', 'do_cancel', 2147483647, 1, 8);
+
+-- PRE-VALUES
+INSERT INTO `sys_form_pre_lists`(`key`, `title`, `module`, `use_for_sets`) VALUES
+('bx_market_cats', '_bx_market_pre_lists_cats', 'bx_market', '0'),
+('bx_market_durations', '_bx_market_pre_lists_durations', 'bx_market', '0');
+
+INSERT INTO `sys_form_pre_values`(`Key`, `Value`, `Order`, `LKey`, `LKey2`) VALUES
+('bx_market_cats', '', 0, '_sys_please_select', ''),
+('bx_market_cats', '1', 1, '_bx_market_cat_administration', ''),
+('bx_market_cats', '2', 2, '_bx_market_cat_adult', ''),
+('bx_market_cats', '3', 3, '_bx_market_cat_advertisement', ''),
+('bx_market_cats', '4', 4, '_bx_market_cat_affiliates', ''),
+('bx_market_cats', '5', 5, '_bx_market_cat_authentication', ''),
+('bx_market_cats', '6', 6, '_bx_market_cat_calendars', ''),
+('bx_market_cats', '7', 7, '_bx_market_cat_communication', ''),
+('bx_market_cats', '8', 8, '_bx_market_cat_content', ''),
+('bx_market_cats', '9', 9, '_bx_market_cat_conversion', ''),
+('bx_market_cats', '10', 10, '_bx_market_cat_core_changes', ''),
+('bx_market_cats', '11', 11, '_bx_market_cat_dating', ''),
+('bx_market_cats', '12', 12, '_bx_market_cat_documentation', ''),
+('bx_market_cats', '13', 13, '_bx_market_cat_ecommerce', ''),
+('bx_market_cats', '14', 14, '_bx_market_cat_events', ''),
+('bx_market_cats', '15', 15, '_bx_market_cat_feedback', ''),
+('bx_market_cats', '16', 16, '_bx_market_cat_flash', ''),
+('bx_market_cats', '17', 17, '_bx_market_cat_games', ''),
+('bx_market_cats', '18', 18, '_bx_market_cat_graphics', ''),
+('bx_market_cats', '19', 19, '_bx_market_cat_hosting', ''),
+('bx_market_cats', '20', 20, '_bx_market_cat_integrations', ''),
+('bx_market_cats', '21', 21, '_bx_market_cat_location', ''),
+('bx_market_cats', '22', 22, '_bx_market_cat_management', ''),
+('bx_market_cats', '23', 23, '_bx_market_cat_mobile', ''),
+('bx_market_cats', '24', 24, '_bx_market_cat_multimedia', ''),
+('bx_market_cats', '25', 25, '_bx_market_cat_music', ''),
+('bx_market_cats', '26', 26, '_bx_market_cat_navigation', ''),
+('bx_market_cats', '27', 27, '_bx_market_cat_other', ''),
+('bx_market_cats', '28', 28, '_bx_market_cat_performance', ''),
+('bx_market_cats', '29', 29, '_bx_market_cat_photos', ''),
+('bx_market_cats', '30', 30, '_bx_market_cat_search', ''),
+('bx_market_cats', '31', 31, '_bx_market_cat_security', ''),
+('bx_market_cats', '32', 32, '_bx_market_cat_services', ''),
+('bx_market_cats', '33', 33, '_bx_market_cat_social', ''),
+('bx_market_cats', '34', 34, '_bx_market_cat_spam_prevention', ''),
+('bx_market_cats', '35', 35, '_bx_market_cat_statistics', ''),
+('bx_market_cats', '36', 36, '_bx_market_cat_templates', ''),
+('bx_market_cats', '37', 37, '_bx_market_cat_tools', ''),
+('bx_market_cats', '38', 38, '_bx_market_cat_translations', ''),
+('bx_market_cats', '39', 39, '_bx_market_cat_video', ''),
+
+('bx_market_durations', 'day', 1, '_bx_market_cat_duration_day', ''),
+('bx_market_durations', 'week', 2, '_bx_market_cat_duration_week', ''),
+('bx_market_durations', 'month', 3, '_bx_market_cat_duration_month', ''),
+('bx_market_durations', 'year', 4, '_bx_market_cat_duration_year', '');
+
+-- COMMENTS
+INSERT INTO `sys_objects_cmts` (`Name`, `Module`, `Table`, `CharsPostMin`, `CharsPostMax`, `CharsDisplayMax`, `Html`, `PerView`, `PerViewReplies`, `BrowseType`, `IsBrowseSwitch`, `PostFormPosition`, `NumberOfLevels`, `IsDisplaySwitch`, `IsRatable`, `ViewingThreshold`, `IsOn`, `RootStylePrefix`, `BaseUrl`, `ObjectVote`, `TriggerTable`, `TriggerFieldId`, `TriggerFieldAuthor`, `TriggerFieldTitle`, `TriggerFieldComments`, `ClassName`, `ClassFile`) VALUES
+('bx_market', 'bx_market', 'bx_market_cmts', 1, 5000, 1000, 3, 5, 3, 'tail', 1, 'bottom', 1, 1, 1, -3, 1, 'cmt', 'page.php?i=view-product&id={object_id}', '', 'bx_market_products', 'id', 'author', 'title', 'comments', 'BxMarketCmts', 'modules/boonex/market/classes/BxMarketCmts.php'),
+('bx_market_notes', 'bx_market', 'bx_market_cmts_notes', 1, 5000, 1000, 0, 5, 3, 'tail', 1, 'bottom', 1, 1, 1, -3, 1, 'cmt', 'page.php?i=view-post&id={object_id}', '', 'bx_market_products', 'id', 'author', 'title', '', 'BxTemplCmtsNotes', '');
+
+-- VOTES
+INSERT INTO `sys_objects_vote` (`Name`, `Module`, `TableMain`, `TableTrack`, `PostTimeout`, `MinValue`, `MaxValue`, `IsUndo`, `IsOn`, `TriggerTable`, `TriggerFieldId`, `TriggerFieldAuthor`, `TriggerFieldRate`, `TriggerFieldRateCount`, `ClassName`, `ClassFile`) VALUES 
+('bx_market', 'bx_market', 'bx_market_votes', 'bx_market_votes_track', '604800', '1', '5', '0', '1', 'bx_market_products', 'id', 'author', 'rate', 'votes', 'BxMarketVoteStars', 'modules/boonex/market/classes/BxMarketVoteStars.php'),
+('bx_market_reactions', 'bx_market', 'bx_market_reactions', 'bx_market_reactions_track', '604800', '1', '1', '1', '1', 'bx_market_products', 'id', 'author', 'rrate', 'rvotes', 'BxMarketVoteReactions', 'modules/boonex/market/classes/BxMarketVoteReactions.php');
+
+-- SCORES
+INSERT INTO `sys_objects_score` (`name`, `module`, `table_main`, `table_track`, `post_timeout`, `is_on`, `trigger_table`, `trigger_field_id`, `trigger_field_author`, `trigger_field_score`, `trigger_field_cup`, `trigger_field_cdown`, `class_name`, `class_file`) VALUES 
+('bx_market', 'bx_market', 'bx_market_scores', 'bx_market_scores_track', '604800', '0', 'bx_market_products', 'id', 'author', 'score', 'sc_up', 'sc_down', 'BxMarketScore', 'modules/boonex/market/classes/BxMarketScore.php');
+
+-- REPORTS
+INSERT INTO `sys_objects_report` (`name`, `module`, `table_main`, `table_track`, `is_on`, `base_url`, `object_comment`, `trigger_table`, `trigger_field_id`, `trigger_field_author`, `trigger_field_count`, `class_name`, `class_file`) VALUES 
+('bx_market', 'bx_market', 'bx_market_reports', 'bx_market_reports_track', '1', 'page.php?i=view-product&id={object_id}', 'bx_market_notes', 'bx_market_products', 'id', 'author', 'reports', '', '');
+
+-- VIEWS
+INSERT INTO `sys_objects_view` (`name`, `module`, `table_track`, `period`, `is_on`, `trigger_table`, `trigger_field_id`, `trigger_field_author`, `trigger_field_count`, `class_name`, `class_file`) VALUES 
+('bx_market', 'bx_market', 'bx_market_views_track', '86400', '1', 'bx_market_products', 'id', 'author', 'views', '', '');
+
+-- FAFORITES
+INSERT INTO `sys_objects_favorite` (`name`, `table_track`, `table_lists`, `is_on`, `is_undo`, `is_public`, `base_url`, `trigger_table`, `trigger_field_id`, `trigger_field_author`, `trigger_field_count`, `class_name`, `class_file`) VALUES 
+('bx_market', 'bx_market_favorites_track', 'bx_market_favorites_lists', '1', '1', '1', 'page.php?i=view-product&id={object_id}', 'bx_market_products', 'id', 'author', 'favorites', '', '');
+
+-- FEATURED
+INSERT INTO `sys_objects_feature` (`name`, `module`, `is_on`, `is_undo`, `base_url`, `trigger_table`, `trigger_field_id`, `trigger_field_author`, `trigger_field_flag`, `class_name`, `class_file`) VALUES 
+('bx_market', 'bx_market', '1', '1', 'page.php?i=view-product&id={object_id}', 'bx_market_products', 'id', 'author', 'featured', '', '');
+
+-- CONTENT INFO
+INSERT INTO `sys_objects_content_info` (`name`, `title`, `alert_unit`, `alert_action_add`, `alert_action_update`, `alert_action_delete`, `class_name`, `class_file`) VALUES
+('bx_market', '_bx_market', 'bx_market', 'added', 'edited', 'deleted', '', ''),
+('bx_market_cmts', '_bx_market_cmts', 'bx_market', 'commentPost', 'commentUpdated', 'commentRemoved', 'BxDolContentInfoCmts', '');
+
+INSERT INTO `sys_content_info_grids` (`object`, `grid_object`, `grid_field_id`, `condition`, `selection`) VALUES
+('bx_market', 'bx_market_administration', 'id', '', ''),
+('bx_market', 'bx_market_common', 'id', '', '');
+
+-- SEARCH EXTENDED
+INSERT INTO `sys_objects_search_extended` (`object`, `object_content_info`, `module`, `title`, `active`, `class_name`, `class_file`) VALUES
+('bx_market', 'bx_market', 'bx_market', '_bx_market_search_extended', 1, '', ''),
+('bx_market_cmts', 'bx_market_cmts', 'bx_market', '_bx_market_search_extended_cmts', 1, 'BxTemplSearchExtendedCmts', '');
+
+-- STUDIO: page & widget
+INSERT INTO `sys_std_pages`(`index`, `name`, `header`, `caption`, `icon`) VALUES
+(3, 'bx_market', '_bx_market', '_bx_market', 'bx_market@modules/boonex/market/|std-icon.svg');
+SET @iPageId = LAST_INSERT_ID();
+
+SET @iParentPageId = (SELECT `id` FROM `sys_std_pages` WHERE `name` = 'home');
+SET @iParentPageOrder = (SELECT MAX(`order`) FROM `sys_std_pages_widgets` WHERE `page_id` = @iParentPageId);
+INSERT INTO `sys_std_widgets` (`page_id`, `module`, `type`, `url`, `click`, `icon`, `caption`, `cnt_notices`, `cnt_actions`) VALUES
+(@iPageId, 'bx_market', 'content', '{url_studio}module.php?name=bx_market', '', 'bx_market@modules/boonex/market/|std-icon.svg', '_bx_market', '', 'a:4:{s:6:"module";s:6:"system";s:6:"method";s:11:"get_actions";s:6:"params";a:0:{}s:5:"class";s:18:"TemplStudioModules";}');
+INSERT INTO `sys_std_pages_widgets` (`page_id`, `widget_id`, `order`) VALUES
+(@iParentPageId, LAST_INSERT_ID(), IF(ISNULL(@iParentPageOrder), 1, @iParentPageOrder + 1));

+ 51 - 0
modules/boonex/notifications/updates/14.0.6_14.0.7/install/config.php

@@ -0,0 +1,51 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ */
+
+$aConfig = array(
+    /**
+     * Main Section.
+     */
+    'title' => 'Notifications',
+    'version_from' => '14.0.6',
+    'version_to' => '14.0.7',
+    'vendor' => 'UNA INC',
+
+    'compatible_with' => array(
+        '14.0.0-RC4'
+    ),
+
+    /**
+     * 'home_dir' and 'home_uri' - should be unique. Don't use spaces in 'home_uri' and the other special chars.
+     */
+    'home_dir' => 'boonex/notifications/updates/update_14.0.6_14.0.7/',
+    'home_uri' => 'notifications_update_1406_1407',
+
+    'module_dir' => 'boonex/notifications/',
+    'module_uri' => 'notifications',
+
+    'db_prefix' => 'bx_notifications_',
+    'class_prefix' => 'BxNtfs',
+
+    /**
+     * Installation/Uninstallation Section.
+     */
+    'install' => array(
+        'execute_sql' => 0,
+        'update_files' => 1,
+        'update_languages' => 0,
+        'clear_db_cache' => 0,
+    ),
+
+    /**
+     * Category for language keys.
+     */
+    'language_category' => 'Notifications',
+
+    /**
+     * Files Section
+     */
+    'delete_files' => array(),
+);

+ 13 - 0
modules/boonex/notifications/updates/14.0.6_14.0.7/install/installer.php

@@ -0,0 +1,13 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ */
+
+class BxNtfsUpdater extends BxDolStudioUpdater
+{
+    function __construct($aConfig)
+    {
+        parent::__construct($aConfig);
+    }
+}

+ 855 - 0
modules/boonex/notifications/updates/14.0.6_14.0.7/source/classes/BxNtfsModule.php

@@ -0,0 +1,855 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Notifications Notifications
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+bx_import('BxBaseModNotificationsModule');
+
+define('BX_NTFS_TYPE_OBJECT_OWNER_AND_CONNECTIONS', 'obj_own_and_con');
+define('BX_NTFS_TYPE_DEFAULT', BX_NTFS_TYPE_OBJECT_OWNER_AND_CONNECTIONS);
+
+/**
+ * STYPE - Setting Type:
+ * 1. personal - related to you;
+ * 2. follow_member - related to members you follow;
+ * 3. follow_context - related to contexts you follow;
+ * 4. other - others.
+ */
+define('BX_NTFS_STYPE_PERSONAL', 'personal');
+define('BX_NTFS_STYPE_FOLLOW_MEMBER', 'follow_member');
+define('BX_NTFS_STYPE_FOLLOW_CONTEXT', 'follow_context');
+define('BX_NTFS_STYPE_OTHER', 'other');
+
+/**
+ * DTYPE - Delivery Type
+ */
+define('BX_NTFS_DTYPE_SITE', 'site');
+define('BX_NTFS_DTYPE_EMAIL', 'email');
+define('BX_NTFS_DTYPE_PUSH', 'push');
+
+/**
+ * SLTMODE - Silent mode:
+ * It is needed for alert sending module to tell that the alert should be ignored 
+ * with Notifications module completely or partially. Available values: 
+ * 1. disabled (global, value = 0) - all notifications are available;
+ * 2. absolute (global, value = 1) - alert isn't registered which means that there is no notifications at all;
+ * 3. absolute (for Notifications only, value = 11) - the same as global absolute.
+ * 3. on-site only (value = 12) - alert is registered. It means that on-site notification is available while the others are disabled.
+ * 4. on-site + email (value = 13) - alert is registered (on-site) and notification via 'email' is enabled.
+ * 5. on-site + push (value = 14) - alert is registered (on-site) and notification via 'push' is enabled.
+ * 
+ * @see BxNtfsResponse::response - 'silent_mode' parameter in Alerts Extras array.
+ */
+define('BX_NTFS_SLTMODE_ABSOLUTE', 11);
+define('BX_NTFS_SLTMODE_SITE', 12);
+define('BX_NTFS_SLTMODE_SITE_EMAIL', 13);
+define('BX_NTFS_SLTMODE_SITE_PUSH', 14);
+
+class BxNtfsModule extends BxBaseModNotificationsModule
+{
+    /**
+     * Constructor
+     */
+    function __construct($aModule)
+    {
+        parent::__construct($aModule);
+
+        $this->_iOwnerId = $this->getUserId();
+    }
+
+    /**
+     * ACTION METHODS
+     */
+    function actionMarkAsClicked()
+    {
+        $iId = bx_process_input(bx_get('id'), BX_DATA_INT);
+        $aEvent = $this->_oDb->getEvents(['browse' => 'id', 'value' => $iId]);
+        if(empty($aEvent) || !is_array($aEvent))
+            return echoJson(['code' => 1]);
+
+        $aParams = $this->_prepareParamsGet();
+        if($this->_oDb->markAsClicked($aParams['viewer_id'], $iId) === false)
+            return echoJson(['code' => 2]);
+
+        echoJson([
+            'code' => 0, 
+            'id' => $iId
+        ]);
+    }
+
+    function actionGetPosts()
+    {
+        $aParams = $this->_prepareParamsGet();
+        if(empty($aParams['owner_id']) || (int)$aParams['owner_id'] != $this->_iOwnerId)
+            return echoJson([]);
+
+        echoJson([
+            'events' => $this->_oTemplate->getPosts($aParams)
+        ]);
+    }
+
+    /**
+     * SERVICE METHODS
+     */
+
+    public function serviceGetSafeServices()
+    {
+        return [
+            'GetBlockView' => '',
+            'GetData' => '',
+            'GetUnreadNotificationsNum' => '',
+            'GetUnreadNotificationsNumEx' => '',
+            'MarkAsRead' => '',
+            'EnableSetting' => '',
+            'ChangeSetting' => '',
+        ];
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_notifications Invitations
+     * @subsection bx_notifications-other Other
+     * @subsubsection bx_notifications-get_include get_include
+     * 
+     * @code bx_srv('bx_notifications', 'get_include', [...]); @endcode
+     * 
+     * Get all necessary CSS and JS files to include in a page.
+     *
+     * @return string with all necessary CSS and JS files.
+     * 
+     * @see BxInvModule::serviceGetInclude
+     */
+    /** 
+     * @ref bx_notifications-get_include "get_include"
+     */
+    public function serviceGetInclude($bIncludeCss = true, $mixedIncludeJs = false)
+    {
+        return $this->_oTemplate->getInclude($bIncludeCss, $mixedIncludeJs);
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_notifications Notifications
+     * @subsection bx_notifications-page_blocks Page Blocks
+     * @subsubsection bx_notifications-get_block_settings get_block_settings
+     * 
+     * @code bx_srv('bx_notifications', 'get_block_settings', [...]); @endcode
+     * 
+     * Get Settings block for a separate page.
+     *
+     * @return a string with block content to display on the site. All necessary CSS and JS files are automatically added to the HEAD section of the site HTML.
+     * 
+     * @see BxNtfsModule::serviceGetBlockSettings
+     */
+    /** 
+     * @ref bx_notifications-get_block_settings "get_block_settings"
+     */
+    public function serviceGetBlockSettings($sDeliveryType = '', $aParams = array())
+    {
+        if(!isLogged())
+            return '';
+
+        if(empty($sDeliveryType) && bx_get('delivery') !== false)
+            $sDeliveryType = bx_process_input(bx_get('delivery'));
+
+        if(empty($sDeliveryType))
+            $sDeliveryType = BX_BASE_MOD_NTFS_DTYPE_SITE;
+
+        $iUserId = bx_get_logged_profile_id();
+        if(!empty($aParams['user_id']))
+            $iUserId = (int)$aParams['user_id'];
+        else
+            $aParams['user_id'] = $iUserId;
+
+        $this->_oDb->initSettingUser($iUserId);
+
+        return array(
+            'content' => $this->getBlockSettings($sDeliveryType, $aParams),
+        );
+    }
+
+    
+    /**
+     * @page service Service Calls
+     * @section bx_notifications Notifications
+     * @subsection bx_notifications-page_blocks Page Blocks
+     * @subsubsection bx_notifications-get_data get_data
+     * 
+     * @code bx_srv('bx_notifications', 'get_data', [...]); @endcode
+     * 
+     * Get data for app
+     *
+     * @return an array .
+     * 
+     * @see BxNtfsModule::serviceGetData
+     */
+     /** 
+     * @ref bx_notifications-get_data "get_data"
+     * @api @ref bx_notifications-get_data "get_data"
+     */
+    public function serviceGetData($aParams)
+    {
+        if(is_string($aParams))
+            $aParams = bx_api_get_browse_params($aParams, true);
+
+        return call_user_func_array([$this, 'serviceGetBlockView'], [
+            isset($aParams['type']) ? $aParams['type'] : '',
+            isset($aParams['start']) ? (int)$aParams['start'] : -1,
+            isset($aParams['per_page']) ? (int)$aParams['per_page'] : -1,
+            isset($aParams['modules']) ? $aParams['modules'] : [],
+        ]);
+    }
+    
+    /**
+     * @page service Service Calls
+     * @section bx_notifications Notifications
+     * @subsection bx_notifications-page_blocks Page Blocks
+     * @subsubsection bx_notifications-get_block_view get_block_view
+     * 
+     * @code bx_srv('bx_notifications', 'get_block_view', [...]); @endcode
+     * 
+     * Get View block for a separate page. Will return a block with "Empty" message if nothing found.
+     *
+     * @return an array describing a block to display on the site. All necessary CSS and JS files are automatically added to the HEAD section of the site HTML.
+     * 
+     * @see BxNtfsModule::serviceGetBlockView
+     */
+    /** 
+     * @ref bx_notifications-get_block_view "get_block_view"
+     */
+    public function serviceGetBlockView($sType = '', $iStart = -1, $iPerPage = -1, $aModules = [])
+    {
+    	$aBrowseTypes = [BX_NTFS_TYPE_OBJECT_OWNER_AND_CONNECTIONS, BX_BASE_MOD_NTFS_TYPE_CONNECTIONS, BX_BASE_MOD_NTFS_TYPE_OBJECT_OWNER];
+
+    	if(empty($sType)) {
+            $mixedType = bx_get('type');
+            if($mixedType !== false && in_array($mixedType, $aBrowseTypes))
+                $sType = $mixedType;
+
+            if(empty($sType))
+                $sType = BX_NTFS_TYPE_DEFAULT;
+    	}
+
+    	$iOwnerId = $this->getUserId();
+        if(!$iOwnerId) {
+            $sResult = _t('_bx_ntfs_txt_msg_no_results');
+            return $this->_bIsApi ? [bx_api_get_msg($sResult)] : ['content' => MsgBox($sResult)];
+        }
+
+        $aParams = $this->_prepareParams($sType, $iOwnerId, $iStart, $iPerPage, $aModules);
+
+        if($this->_bIsApi) {
+            $aParams['start_from_item'] = true;
+
+            $aContent = defined('BX_API_PAGE') ? [] : $this->_oTemplate->getPosts($aParams);
+            if(!empty($aContent) && is_array($aContent)) {
+                $iContent = count($aContent);
+                if($iContent > $aParams['per_page'])
+                    $aContent = array_slice($aContent, 0, -($iContent - $aParams['per_page']));
+
+                $aParams['start'] = end($aContent)['id'];
+            }
+
+            //if($aParams['start'] == 0)
+            //    $this->markAsRead($iOwnerId, $aParams);
+
+            return [bx_api_get_block('browse', [
+                'unit' => 'notifications',  
+                'request_url' => '/api.php?r=bx_notifications/get_data/&params[]=',
+                'params' => $aParams,
+                'id' => $iOwnerId,
+                'data' => $aContent]),
+            ];
+        }
+
+        $sContent = $this->_oTemplate->getViewBlock($aParams);
+
+        $this->markAsRead($iOwnerId, $aParams);
+
+        return ['content' => $sContent]; 
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_notifications Notifications
+     * @subsection bx_notifications-browsing Browsing
+     * @subsubsection bx_notifications-get_event_by_id get_event_by_id
+     * 
+     * @code bx_srv('bx_notifications', 'get_event_by_id', [...]); @endcode
+     * 
+     * Get event's data by event ID.
+     *
+     * @return an array with event's data.
+     * 
+     * @see BxNtfsModule::serviceGetEventById
+     */
+    /** 
+     * @ref bx_notifications-get_event_by_id "get_event_by_id"
+     */
+    public function serviceGetEventById($iId)
+    {
+        $aParams = array(
+            'browse' => 'id',
+            'value' => $iId,
+        );
+    	return $this->_oDb->getEvents($aParams);
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_notifications Notifications
+     * @subsection bx_notifications-other Other
+     * @subsubsection bx_notifications-get_notifications get_notifications
+     * 
+     * @code bx_srv('bx_notifications', 'get_notifications', [...]); @endcode
+     * 
+     * Get notifications by params.
+     *
+     * @return array with notifications.
+     * 
+     * @see BxNtfsModule::serviceGetNotifications
+     */
+    /** 
+     * @ref bx_notifications-get_notifications "get_notifications"
+     */
+    public function serviceGetNotifications($iOwnerId = 0, $aBrowseParams = array())
+    {
+        if(!$iOwnerId)
+            $iOwnerId = $this->getUserId();
+
+        if(!$iOwnerId)
+            return 0;
+
+        $aParams = $this->_prepareParams(BX_NTFS_TYPE_DEFAULT, $iOwnerId);
+        if(!empty($aBrowseParams) && is_array($aBrowseParams))
+            $aParams = array_merge($aParams, $aBrowseParams);
+
+        $aEvents = $this->_oDb->getEvents($aParams);
+
+        if($this->_oConfig->isEventsGrouped())
+            $this->groupEvents($aEvents);
+
+        // returns parsed content for React Jot
+        if (!is_array($aBrowseParams) && $aBrowseParams === 'return_parsed_content')
+            foreach ($aEvents as &$aContent)
+                $this->_oTemplate->getPost($aContent, array('return_parsed_content'));
+
+        return $aEvents;
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_notifications Notifications
+     * @subsection bx_notifications-other Other
+     * @subsubsection bx_notifications-get_unread_notifications get_unread_notifications
+     * 
+     * @code bx_srv('bx_notifications', 'get_unread_notifications', [...]); @endcode
+     * 
+     * Get unread notifications.
+     *
+     * @return array with unread notifications.
+     * 
+     * @see BxNtfsModule::serviceGetUnreadNotifications
+     */
+    /** 
+     * @ref bx_notifications-get_unread_notifications "get_unread_notifications"
+     */
+    public function serviceGetUnreadNotifications($iOwnerId = 0)
+    {
+        return $this->serviceGetNotifications($iOwnerId, array('new' => 1));
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_notifications Notifications
+     * @subsection bx_notifications-other Other
+     * @subsubsection bx_notifications-get_unread_notifications_num get_unread_notifications_num
+     * 
+     * @code bx_srv('bx_notifications', 'get_unread_notifications_num', [...]); @endcode
+     * 
+     * Get number of unread notifications.
+     *
+     * @return integer value with number of unread notifications.
+     * 
+     * @see BxNtfsModule::serviceGetUnreadNotificationsNum
+     */
+    /** 
+     * @ref bx_notifications-get_unread_notifications_num "get_unread_notifications_num"
+     */
+    public function serviceGetUnreadNotificationsNum($iOwnerId = 0)
+    {
+        if(!$iOwnerId)
+            $iOwnerId = $this->getUserId();
+
+        if(!$iOwnerId)
+            return 0;
+
+        $sModule = $this->_oConfig->getName();
+        $aBrowseParams = $this->_prepareParams(BX_NTFS_TYPE_DEFAULT, $iOwnerId, 0, PHP_INT_MAX);
+
+        $sParamCheck = 'perform_privacy_check';
+        $sParamCheckFor = 'perform_privacy_check_for';
+
+        $iEvents = 0;
+        if($this->_oConfig->isEventsGrouped()) {
+            $aEvents = $this->_oDb->getEvents($aBrowseParams);
+
+            $this->groupEvents($aEvents);
+
+            $iCount = 0;
+            $iLastRead = $this->_oDb->getLastRead((int)$aBrowseParams['owner_id']);
+            foreach($aEvents as $aEvent)
+                if($aEvent['id'] > $iLastRead)
+                    $iCount++;
+
+            $aEvents = array_slice($aEvents, 0, $iCount);
+        }
+        else {
+            $aBrowseParams = array_merge($aBrowseParams, [
+                'new' => 1,
+            ]);
+
+            $aEvents = $this->_oDb->getEvents($aBrowseParams);
+        }
+
+        foreach($aEvents as $aEvent) {
+            if(isset($aBrowseParams[$sParamCheck]) && $aBrowseParams[$sParamCheck] !== true) 
+                continue;
+
+            $iViewerId = !empty($aBrowseParams[$sParamCheckFor]) ? (int)$aBrowseParams[$sParamCheckFor] : 0;
+
+            $oPrivacyInt = BxDolPrivacy::getObjectInstance($this->_oConfig->getObject('privacy_view'));
+            if(!$oPrivacyInt->check($aEvent['id'], $iViewerId))
+                continue;
+
+            $oPrivacyExt = $this->_oConfig->getPrivacyObject($aEvent['type'] . '_' . $aEvent['action']);
+            if($oPrivacyExt !== false && !$oPrivacyExt->check($aEvent['id'], $iViewerId))
+                continue;
+
+            $iContentObjectId = $this->_oConfig->getContentObjectId($aEvent);
+            if($iContentObjectId === false) {
+                $this->_oTemplate->getPost($aEvent, $aBrowseParams);
+                $iContentObjectId = $this->_oConfig->getContentObjectId($aEvent);
+            }
+
+            $sSrvModule = $this->_oConfig->getContentModule($aEvent);
+            $sSrvMethod = 'check_allowed_with_content_for_profile';
+            if($sSrvModule && bx_is_srv($sSrvModule, $sSrvMethod) && bx_srv($sSrvModule, $sSrvMethod, ['view', $iContentObjectId, $iViewerId]) !== CHECK_ACTION_RESULT_ALLOWED)
+                continue;
+
+            $bEventCanceled = false;
+            
+            /**
+             * @hooks
+             * @hookdef hook-bx_notifications-is_notification 'bx_notifications', 'is_notification' - hook to override checking if an event is available or not
+             * - $unit_name - equals `bx_notifications`
+             * - $action - equals `is_notification`
+             * - $object_id - not used
+             * - $sender_id - not used
+             * - $extra_params - array of additional params with the following array keys:
+             *      - `browse_params` - [array] browse params array as key&value pairs
+             *      - `event` - [array] by ref, array with event data as key&value pairs, can be overridden in hook processing
+             *      - `event_canceled` - [boolean] by ref, if event is canceled (not available) or not, can be overridden in hook processing
+             * @hook @ref hook-bx_notifications-is_notification
+             */
+            bx_alert($sModule, 'is_notification', 0, 0, [
+                'browse_params' => $aBrowseParams,
+                'event' => &$aEvent, 
+                'event_canceled' => &$bEventCanceled
+            ]);
+
+            if($bEventCanceled)
+                continue;
+
+            $iEvents++;
+        }
+
+        return $iEvents;
+    }
+    
+    public function serviceGetUnreadNotificationsNumEx($iOwnerId, $iCount)
+    {
+         header('Content-Type: text/event-stream');
+         header('Cache-Control: no-cache');
+         $iTmp = $this->serviceGetUnreadNotificationsNum($iOwnerId);
+         if ($iCount != $iTmp){
+             $time = date('r');
+             echo "id: " . time() . "\n";
+             echo "data: $iTmp\n\n";
+             flush();
+         }
+         exit();
+            
+     }
+
+    /**
+     * @page service Service Calls
+     * @section bx_notifications Notifications
+     * @subsection bx_notifications-other Other
+     * @subsubsection bx_notifications-get_live_updates get_live_updates
+     * 
+     * @code bx_srv('bx_notifications', 'get_live_updates', [...]); @endcode
+     * 
+     * Get data for Live Updates system.
+     *
+     * @return an array with special format.
+     * 
+     * @see BxNtfsModule::serviceGetLiveUpdates
+     */
+    /** 
+     * @ref bx_notifications-get_live_updates "get_live_updates"
+     */
+    public function serviceGetLiveUpdates($aMenuItemParent, $aMenuItemChild, $iCount = 0)
+    {
+        $iOwnerId = $this->getUserId();
+        $iCountNew = $this->serviceGetUnreadNotificationsNum($iOwnerId);
+        if($iCountNew == $iCount)
+			return false;
+
+        return array(
+    		'count' => $iCountNew, // required
+    		'method' => 'bx_menu_show_live_update(oData)', // required
+    		'data' => array(
+    			'code' => BxDolTemplate::getInstance()->parseHtmlByTemplateName('menu_item_addon', array(
+    				'content' => '{count}'
+                )),
+                'mi_parent' => $aMenuItemParent,
+                'mi_child' => $aMenuItemChild
+    		),  // optional, may have some additional data to be passed in JS method provided using 'method' param above.
+    	);
+    }
+
+    /*
+     * COMMON METHODS
+     */
+    public function getBlockSettings($sDeliveryType, $aParams = array())
+    {
+        return $this->_oTemplate->getSettingsBlock($sDeliveryType, $aParams);
+    }
+
+    public function setSubmenu($sSelected)
+    {
+    	$oSubmenuSystem = BxDolMenu::getObjectInstance('sys_site_submenu');
+        if(!$oSubmenuSystem)
+            return;
+
+        $CNF = &$this->_oConfig->CNF;
+
+        $oSubmenuSystem->setObjectSubmenu($CNF['OBJECT_MENU_SUBMENU'], array (
+            'title' => _t('_bx_ntfs'),
+            'link' => bx_absolute_url(BxDolPermalinks::getInstance()->permalink($CNF['URL_HOME'])),
+            'icon' => '',
+        ));
+
+        $oSubmenuModule = BxDolMenu::getObjectInstance($CNF['OBJECT_MENU_SUBMENU']);
+        if($oSubmenuModule)
+            $oSubmenuModule->setSelected($this->_oConfig->getName(), $sSelected);
+    }
+
+    public function onPost($iId)
+    {
+    	//--- Event -> Post for Alerts Engine ---//
+        $oAlert = new BxDolAlerts($this->_oConfig->getObject('alert'), 'post', $iId);
+        $oAlert->alert();
+        //--- Event -> Post for Alerts Engine ---//
+    }
+
+    public function enableSettingsLike($iId, $bValue, $bAdministration = false)
+    {
+        $aSetting = $this->_oDb->getSetting(array(
+            'by' => $bAdministration ? 'id' : 'tsu_id', 
+            'id' => (int)$iId
+        ));
+        if(empty($aSetting) || !is_array($aSetting))
+            return false;
+
+        $aSettingsIds = $this->_oDb->getSetting(array(
+            'by' => 'group_type_delivery', 
+            'group' => $aSetting['group'], 
+            'delivery' => $aSetting['delivery'], 
+            'type' => $aSetting['type'], 
+            'active' => !$bAdministration
+        ));
+        if(empty($aSettingsIds) || !is_array($aSettingsIds))
+            return false;
+
+        $iUserId = bx_get_logged_profile_id();
+
+        $mixedResult = false;
+        if($bAdministration)
+            $mixedResult =  $this->_oDb->activateSettingById($bValue, $aSettingsIds);
+        else
+            $mixedResult = $this->_oDb->activateSettingByIdUser($bValue, $iUserId, $aSettingsIds);
+
+        return $mixedResult;
+    }
+
+    public function changeSettingsValueLike($iId, $sField, $mixedValue, $bAdministration = false)
+    {
+        $aSetting = $this->_oDb->getSetting(array(
+            'by' => $bAdministration ? 'id' : 'tsu_id', 
+            'id' => (int)$iId
+        ));
+        if(empty($aSetting) || !is_array($aSetting))
+            return false;
+
+        $aSettingsIds = $this->_oDb->getSetting(array(
+            'by' => 'group_type_delivery', 
+            'group' => $aSetting['group'], 
+            'delivery' => $aSetting['delivery'], 
+            'type' => $aSetting['type'], 
+            'active' => !$bAdministration
+        ));
+        if(empty($aSettingsIds) || !is_array($aSettingsIds))
+            return false;
+
+        $iUserId = bx_get_logged_profile_id();
+
+        $mixedResult = false;
+        if($bAdministration)
+            $mixedResult =  $this->_oDb->changeSettingById($sField, $mixedValue, $aSettingsIds);
+        else
+            $mixedResult = $this->_oDb->changeSettingByIdUser($sField, $mixedValue, $iUserId, $aSettingsIds);
+
+        return $mixedResult;
+    }
+
+    public function sendNotificationEmail($iProfile, $aNotification)
+    {
+        if(!$iProfile)
+            return false;
+
+        $aSettings = &$aNotification['settings'];
+
+        $sTemplate = !empty($aSettings['template']) ? $aSettings['template'] : 'bx_notifications_new_event';
+        $aTemplateMarkers = ['subject' => $aNotification['subject'], 'content' => $aNotification['content']];
+        if(!empty($aSettings['markers']) && is_array($aSettings['markers']))
+            $aTemplateMarkers = array_merge($aTemplateMarkers, $aSettings['markers']);              
+
+        $aTemplate = null;
+        /**
+         * @hooks
+         * @hookdef hook-bx_notifications-before_parse_email_template 'bx_notifications', 'before_parse_email_template' - hook to override email template
+         * - $unit_name - equals `bx_notifications`
+         * - $action - equals `before_parse_email_template`
+         * - $object_id - not used
+         * - $sender_id - not used
+         * - $extra_params - array of additional params with the following array keys:
+         *      - `profile_id` - [int] recipient profile id
+         *      - `template` - [string] email template name
+         *      - `markers` - [array] parsable variables array as key&value pairs
+         *      - `notification` - [array] notification data array as key&value pairs
+         *      - `override_result` - [array] by ref, email template (subject and body), if null, then default one will be used, can be overridden in hook processing
+         * @hook @ref hook-bx_notifications-before_parse_email_template
+         */
+        bx_alert($this->_aModule['name'], 'before_parse_email_template', 0, 0, [
+            'profile_id' => $iProfile, 
+            'template' => $sTemplate, 
+            'markers' => $aTemplateMarkers, 
+            'notification' => $aNotification, 
+            'override_result' => &$aTemplate
+        ]);
+        if(is_null($aTemplate))
+            $aTemplate = BxDolEmailTemplates::getInstance()->parseTemplate($sTemplate, $aTemplateMarkers, 0, $iProfile);
+        if(!$aTemplate)
+            return false;
+
+        $sEmail = BxDolProfileQuery::getInstance()->getEmailById($iProfile);
+        $sSubject = !empty($aSettings['subject']) ? $aSettings['subject'] : $aTemplate['Subject'];
+        return sendMail($sEmail, $sSubject, $aTemplate['Body'], 0, array(), BX_EMAIL_NOTIFY, 'html', false, array(), true);
+    }
+
+    public function sendNotificationPush($iProfile, $aNotification)
+    {
+        if(!$iProfile)
+            return false;
+
+        $aContent = &$aNotification['content'];
+        $aSettings = &$aNotification['settings'];
+        
+        /**
+         * @hooks
+         * @hookdef hook-bx_notifications-before_send_notification_push 'bx_notifications', 'before_send_notification_push' - hook to override push message
+         * - $unit_name - equals `bx_notifications`
+         * - $action - equals `before_send_notification_push`
+         * - $object_id - not used
+         * - $sender_id - not used
+         * - $extra_params - array of additional params with the following array keys:
+         *      - `profile_id` - [int] recipient profile id
+         *      - `content` - [array] by ref, push message params array as key&value pairs, can be overridden in hook processing
+         *      - `setting` - [array] by ref, push settings array as key&value pairs, can be overridden in hook processing
+         *      - `subject` - [string] by ref, push message subject, can be overridden in hook processing
+         * @hook @ref hook-bx_notifications-before_send_notification_push
+         */
+        bx_alert($this->_aModule['name'], 'before_send_notification_push', 0, 0, [
+            'profile_id' => $iProfile, 
+            'content' => &$aContent, 
+            'setting' => &$aSettings, 
+            'subject' => &$sSubject
+        ]);
+        
+        if (!$aContent)
+            return false;
+
+        $sSubject = !empty($aSettings['subject']) ? $aSettings['subject'] : _t('_bx_ntfs_push_new_event_subject', getParam('site_title'));
+
+        return BxDolPush::getObjectInstance()->send($iProfile, array(
+            'contents' => array(
+                'en' => $aContent['message']
+            ),
+            'headings' => array(
+                'en' => $sSubject
+            ),
+            'url' => $aContent['url'],
+            'icon' => $aContent['icon']
+        ), true);
+    }
+
+    public function groupEvents(&$aEvents)
+    {
+        //--- Check for Visual Grouping
+        $aGroups = [];
+        foreach($aEvents as $iIndex => $aEvent) {
+            if(empty($aEvent['source']))
+                continue;
+
+            $sSource = $aEvent['source'];
+            if(!isset($aGroups[$sSource]))
+               $aGroups[$sSource] = [];
+
+            $aGroups[$sSource][$iIndex] = $aEvent['priority'];
+        }
+
+        //--- Perform Visual Grouping
+        foreach($aGroups as $sSource => $aGroup) {
+            if(!is_array($aGroup) || count($aGroup) < 2)
+                continue;
+
+            arsort($aGroup);
+            $iPriorityMax = reset($aGroup);
+
+            foreach($aGroup as $iIndex => $iPriority)
+                if($iPriority != $iPriorityMax)
+                    unset($aEvents[$iIndex]);
+        }
+    }
+    
+    public function serviceMarkAsRead()
+    {
+        $iOwnerId = bx_get_logged_profile_id();
+        $aParams = $this->_prepareParams(BX_NTFS_TYPE_OBJECT_OWNER_AND_CONNECTIONS, $iOwnerId);
+        $this->markAsRead($iOwnerId, $aParams);
+    }
+
+    public function markAsRead($iOwnerId, $aParams)
+    {
+        $aParams['browse'] = 'first';
+    	$aEvent = $this->_oDb->getEvents($aParams);
+    	if(empty($aEvent) || !is_array($aEvent))
+            return false;
+
+        return $this->_oDb->markAsRead($iOwnerId, $aEvent['id']) !== false;
+    }
+
+    public function serviceEnableSetting($mixedParams)
+    {
+        if(!is_array($mixedParams))
+            $mixedParams = json_decode($mixedParams, true);
+
+        if(!isset($mixedParams['id'], $mixedParams['value']))
+            return false;
+
+        $iId = (int)$mixedParams['id'];
+        $iValue = (int)$mixedParams['value'];
+        $bAdministration = isset($mixedParams['admin']) && $mixedParams['admin'];
+
+        if(!$this->_oConfig->isSettingsGrouped())
+            $mixedResult = $this->_oDb->updateSetting(['active' => $iValue], ['id' => $iId]);
+        else 
+            $mixedResult = $this->enableSettingsLike($iId, $iValue, $bAdministration);
+
+        return $mixedResult !== false;
+    }
+            
+    public function serviceChangeSetting($mixedParams)
+    {
+        if(!is_array($mixedParams))
+            $mixedParams = json_decode($mixedParams, true);
+
+        if(!isset($mixedParams['id'], $mixedParams['value']))
+            return false;
+
+        $iId = (int)$mixedParams['id'];
+        $iValue = (int)$mixedParams['value'];
+
+        if(!$this->_oConfig->isSettingsGrouped())
+            $mixedResult = $this->_oDb->updateSetting(['value' => $iValue], ['id' => $iId]);
+        else 
+            $mixedResult = $this->changeSettingsValueLike($iId, 'value', $iValue, true);
+
+        return $mixedResult !== false;
+    }
+
+    /*
+     * INTERNAL METHODS
+     */
+    protected function _prepareParams($sType = '', $iOwnerId = 0, $iStart = -1, $iPerPage = -1, $aModules = [])
+    {
+        $iUserId = $this->getUserId();
+        $iOwnerId = (int)$iOwnerId != 0 ? $iOwnerId : $iUserId;
+
+        $aParams = [
+            'browse' => 'list',
+            'type' => !empty($sType) ? $sType : BX_NTFS_TYPE_DEFAULT,
+            'owner_id' => $iOwnerId,
+            'start' => (int)$iStart > 0 ? $iStart : 0,
+            'start_from_item' => false,
+            'per_page' => (int)$iPerPage > 0 ? $iPerPage : $this->_oConfig->getPerPage(),
+            'modules' => is_array($aModules) && !empty($aModules) ? $aModules : [],
+            'last_read' => $this->_oDb->getLastRead($iOwnerId),
+            'viewer_id' => $iUserId,
+            'active' => 1
+        ];
+
+        return $aParams;
+    }
+
+    protected function _prepareParamsGet()
+    {
+        $aParams = [];
+        $aParams['browse'] = 'list';
+
+        $sType = bx_get('type');
+        $aParams['type'] = $sType !== false ? bx_process_input($sType, BX_DATA_TEXT) : BX_NTFS_TYPE_DEFAULT;
+
+        $aParams['owner_id'] = $sType !== false ? bx_process_input(bx_get('owner_id'), BX_DATA_INT) : $this->getUserId();
+
+        $iStart = bx_get('start');
+        $aParams['start'] = $iStart !== false ? bx_process_input($iStart, BX_DATA_INT) : 0;
+        $aParams['start_from_item'] = false;
+
+        $iPerPage = bx_get('per_page');
+        $aParams['per_page'] = $iPerPage !== false ? bx_process_input($iPerPage, BX_DATA_INT) : $this->_oConfig->getPerPage();
+
+        $aModules = bx_get('modules');
+        $aParams['modules'] = $aModules !== false ? bx_process_input($aModules, BX_DATA_TEXT) : [];
+
+        $iViewerId = $this->getUserId();
+        if(($aParams['viewer_id'] = bx_get('viewer_id')) !== false)
+            $aParams['viewer_id'] = bx_process_input($aParams['viewer_id'], BX_DATA_INT);
+        if(!$aParams['viewer_id'] || $aParams['viewer_id'] != $iViewerId)
+            $aParams['viewer_id'] = $iViewerId;
+
+        $aParams['active'] = 1;
+
+        return $aParams;
+    }
+}
+
+/** @} */

+ 82 - 0
modules/boonex/notifications/updates/14.0.6_14.0.7/source/install/config.php

@@ -0,0 +1,82 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Notifications Notifications
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+$aConfig = array(
+    /**
+     * Main Section.
+     */
+    'type' => BX_DOL_MODULE_TYPE_MODULE,
+    'name' => 'bx_notifications',
+    'title' => 'Notifications',
+    'note' => 'Notifications module.',
+    'version' => '14.0.7',
+    'vendor' => 'UNA INC',
+    'help_url' => 'http://feed.una.io/?section={module_name}',
+
+    'compatible_with' => array(
+        '14.0.0-RC4'
+    ),
+
+    /**
+     * 'home_dir' and 'home_uri' - should be unique. Don't use spaces in 'home_uri' and the other special chars.
+     */
+    'home_dir' => 'boonex/notifications/',
+    'home_uri' => 'notifications',
+
+    'db_prefix' => 'bx_notifications_',
+    'class_prefix' => 'BxNtfs',
+
+    /**
+     * Category for language keys.
+     */
+    'language_category' => 'Notifications',
+
+    /**
+     * Installation/Uninstallation Section.
+     */
+    'install' => array(
+        'execute_sql' => 1,
+        'update_languages' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'uninstall' => array (
+        'execute_sql' => 1,
+        'update_languages' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'enable' => array(
+        'execute_sql' => 1,
+    	'update_relations_for_all' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'disable' => array (
+        'execute_sql' => 1,
+    	'update_relations_for_all' => 1,
+        'clear_db_cache' => 1,
+    ),
+
+    /**
+     * Dependencies Section
+     */
+    'dependencies' => array(),
+
+    /**
+     * Relations Section
+     */
+    'relation_handlers' => array(
+    	'on_install' => '',
+    	'on_uninstall' => 'delete_module_events',
+	    'on_enable' => 'add_handlers',
+	    'on_disable' => 'delete_handlers',
+    ),
+);
+
+/** @} */

+ 16 - 0
modules/boonex/notifications/updates/14.0.6_14.0.7/source/template/event.html

@@ -0,0 +1,16 @@
+<div id="__html_id__" class="__style_prefix__-event bx-def-box bx-def-box-round-corners bx-def-color-bg-box bx-def-color-bg-box-hover relative mb-2 __class__">
+    <a class="__style_prefix__-event-link hover:no-underline" href="__link__" <bx_if:show_onclick>onclick="return __js_object__.markAsClicked(this, __id__)"</bx_if:show_onclick>>
+        <div class="__style_prefix__-event-gap p-4">
+            <div class="__style_prefix__-event-cnt relative flex items-center">
+                <div class="__style_prefix__-owner-avatar bx-def-thumb-size">__author_unit__</div>
+                <div class="__style_prefix__-body bx-def-thumb-size-min-height flex flex-col ltr:ml-4 rtl:mr-4">
+                    <div class="__style_prefix__-content">__content__</div>
+                    <div class="__style_prefix__-date">__date__</div>
+                </div>
+                <bx_if:show_clicked_indicator>
+                    <div class="absolute h-2 w-2 ltr:right-0 rtl:left-0 bg-blue-500 rounded-full"></div>
+                </bx_if:show_clicked_indicator>
+            </div>
+        </div>
+    </a>
+</div>

+ 51 - 0
modules/boonex/organizations/updates/14.0.7_14.0.8/install/config.php

@@ -0,0 +1,51 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ */
+
+$aConfig = array(
+    /**
+     * Main Section.
+     */
+    'title' => 'Organizations',
+    'version_from' => '14.0.7',
+    'version_to' => '14.0.8',
+    'vendor' => 'UNA INC',
+
+    'compatible_with' => array(
+        '14.0.0-RC4'
+    ),
+
+    /**
+     * 'home_dir' and 'home_uri' - should be unique. Don't use spaces in 'home_uri' and the other special chars.
+     */
+    'home_dir' => 'boonex/organizations/updates/update_14.0.7_14.0.8/',
+    'home_uri' => 'orgs_update_1407_1408',
+
+    'module_dir' => 'boonex/organizations/',
+    'module_uri' => 'orgs',
+
+    'db_prefix' => 'bx_organizations_',
+    'class_prefix' => 'BxOrgs',
+
+    /**
+     * Installation/Uninstallation Section.
+     */
+    'install' => array(
+        'execute_sql' => 0,
+        'update_files' => 1,
+        'update_languages' => 0,
+        'clear_db_cache' => 0,
+    ),
+
+    /**
+     * Category for language keys.
+     */
+    'language_category' => 'Organizations',
+
+    /**
+     * Files Section
+     */
+    'delete_files' => array(),
+);

+ 13 - 0
modules/boonex/organizations/updates/14.0.7_14.0.8/install/installer.php

@@ -0,0 +1,13 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ */
+
+class BxOrgsUpdater extends BxDolStudioUpdater
+{
+    function __construct($aConfig)
+    {
+        parent::__construct($aConfig);
+    }
+}

+ 335 - 0
modules/boonex/organizations/updates/14.0.7_14.0.8/source/classes/BxOrgsConfig.php

@@ -0,0 +1,335 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Organizations Organizations
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+class BxOrgsConfig extends BxBaseModGroupsConfig
+{
+    function __construct($aModule)
+    {
+        parent::__construct($aModule);
+
+        $this->_aMenuItems2MethodsSubmenu = array_merge($this->_aMenuItems2MethodsSubmenu, array(
+            'organization-profile-relations' => 'checkAllowedRelationsView',
+            'organization-profile-subscriptions' => 'checkAllowedSubscriptionsView'
+        ));
+
+        $this->_aMenuItems2MethodsActions = array_merge($this->_aMenuItems2MethodsActions, array(
+            'view-organization-profile' => 'checkAllowedView',
+            'edit-organization-profile' => 'checkAllowedEdit',
+            'organization-manage' => 'checkAllowedEdit',
+            'edit-organization-cover' => 'checkAllowedChangeCover',
+            'invite-to-organization' => 'checkAllowedInvite',
+            'delete-organization-profile' => 'checkAllowedDelete',
+            'profile-friend-add' => 'checkAllowedFriendAdd',
+            'profile-friend-remove' => 'checkAllowedFriendRemove',
+            'profile-relation-add' => 'checkAllowedRelationAdd',
+            'profile-relation-remove' => 'checkAllowedRelationRemove',
+            'profile-set-acl-level' => 'checkAllowedSetMembership',
+            'messenger' => 'checkAllowedCompose',
+        ));
+
+        $this->CNF = array_merge($this->CNF, array (
+
+            // module icon
+            'ICON' => 'building col-red2',
+
+            // database tables
+            'TABLE_ENTRIES' => $aModule['db_prefix'] . 'data',
+            'TABLE_ENTRIES_FULLTEXT' => 'search_fields',
+            'TABLE_ADMINS' => $aModule['db_prefix'] . 'admins',
+            'TABLE_INVITES' => $aModule['db_prefix'] . 'invites',
+            'TABLE_PRICES' => $aModule['db_prefix'] . 'prices',
+
+            // database fields
+            'FIELD_ID' => 'id',
+            'FIELD_AUTHOR' => 'author',
+            'FIELD_ADDED' => 'added',
+            'FIELD_CHANGED' => 'changed',
+            'FIELD_NAME' => 'org_name',
+            'FIELD_TITLE' => 'org_name',
+            'FIELD_TEXT' => 'org_desc',
+            'FIELD_CATEGORY' => 'org_cat',
+            'FIELD_PICTURE' => 'picture',
+            'FIELD_COVER' => 'cover',
+            'FIELD_COVER_POSITION' => 'cover_data',
+            'FIELD_JOIN_CONFIRMATION' => 'join_confirmation',
+            'FIELD_ALLOW_VIEW_TO' => 'allow_view_to',
+            'FIELD_ALLOW_POST_TO' => 'allow_post_to',
+            'FIELD_ALLOW_CONTACT_TO' => 'allow_contact_to',
+            'FIELD_VIEWS' => 'views',
+            'FIELD_VOTES' => 'votes',
+            'FIELD_STATUS' => 'status',
+            'FIELD_COMMENTS' => 'comments',
+            'FIELDS_QUICK_SEARCH' => array('org_name'),
+            'FIELD_LOCATION' => 'location',
+            'FIELD_LOCATION_PREFIX' => 'location',
+            'FIELD_LABELS' => 'labels',
+            'FIELD_MULTICAT' => 'multicat',
+            'FIELDS_WITH_KEYWORDS' => 'auto', // can be 'auto', array of fields or comma separated string of field names, works only when OBJECT_METATAGS is specified
+
+            'FIELD_PRICE_ROLE_ID' => 'role_id',
+            'FIELD_PRICE_NAME' => 'name',
+
+            // page URIs
+            'URI_VIEW_ENTRY' => 'view-organization-profile',
+            'URI_VIEW_FRIENDS' => 'organization-profile-friends',
+            'URI_VIEW_FRIEND_REQUESTS' => 'organization-friend-requests',
+            'URI_VIEW_FAVORITES' => 'organization-profile-favorites',
+            'URI_EDIT_ENTRY' => 'edit-organization-profile',
+            'URI_JOIN_ENTRY' => 'join-organization-profile',
+            'URI_JOINED_ENTRIES' => 'joined-organizations',
+            'URI_MANAGE_COMMON' => 'organizations-manage',
+            'URI_VIEW_SUBSCRIPTIONS' => 'organization-profile-subscriptions',
+            'URI_FAVORITES_LIST' => 'organizations-favorites',
+            
+            'URL_HOME' => 'page.php?i=organizations-home',
+            'URL_CREATE' => 'page.php?i=create-organization-profile',
+            'URL_ENTRY_FANS' => 'page.php?i=organization-profile-fans',
+            'URL_ENTRY_MANAGE' => 'page.php?i=organization-manage',
+            'URL_MANAGE_COMMON' => 'page.php?i=organizations-manage',
+            'URL_MANAGE_ADMINISTRATION' => 'page.php?i=organizations-administration',
+
+            // some params
+            'ALLOW_AS_CONTEXT' => true,
+
+            'PARAM_AUTOAPPROVAL' => 'bx_organizations_autoapproval',
+            'PARAM_ENABLE_ACTIVATION_LETTER' => 'bx_organizations_enable_profile_activation_letter',
+            'PARAM_DEFAULT_ACL_LEVEL' => 'bx_organizations_default_acl_level',
+            'PARAM_NUM_RSS' => 'bx_organizations_num_rss',
+            'PARAM_NUM_CONNECTIONS_QUICK' => 'bx_organizations_num_connections_quick',
+            'PARAM_SEARCHABLE_FIELDS' => 'bx_organizations_searchable_fields',
+            'PARAM_PER_PAGE_BROWSE_SHOWCASE' => 'bx_organizations_per_page_browse_showcase',
+            'PARAM_PER_PAGE_BROWSE_RECOMMENDED' => 'bx_organizations_per_page_browse_recommended',
+            'PARAM_MMODE' => 'bx_organizations_members_mode',
+            'PARAM_PAID_JOIN_ENABLED' => true,
+            'PARAM_RECURRING_RESERVE' => 3, // 3 days for recurring payment to be registered
+            'PARAM_PUBLIC_SBSN' => 'bx_organizations_public_subscriptions',
+            'PARAM_PUBLIC_SBSD' => 'bx_organizations_public_subscribed_me',
+            'PARAM_SBS_WO_JOIN' => 'bx_organizations_enable_subscribe_wo_join',
+            'PARAM_REDIRECT_AADD' => 'bx_organizations_redirect_aadd',
+            'PARAM_REDIRECT_AADD_CUSTOM_URL' => 'bx_organizations_redirect_aadd_custom_url',
+            
+            'PARAM_MULTICAT_ENABLED' => true,
+            'PARAM_MULTICAT_AUTO_ACTIVATION_FOR_CATEGORIES' => 'bx_organizations_auto_activation_for_categories',
+            'PARAM_PER_PAGE_FOR_FAVORITES_LISTS' => 'bx_organizations_per_page_for_favorites_lists',
+            'PARAM_USE_IN' => 'bx_organizations_internal_notifications',
+
+            // objects
+            'OBJECT_STORAGE' => 'bx_organizations_pics',
+            'OBJECT_STORAGE_COVER' => 'bx_organizations_pics',
+            'OBJECT_IMAGES_TRANSCODER_THUMB' => 'bx_organizations_thumb',
+            'OBJECT_IMAGES_TRANSCODER_ICON' => 'bx_organizations_icon',
+            'OBJECT_IMAGES_TRANSCODER_AVATAR' => 'bx_organizations_avatar',
+            'OBJECT_IMAGES_TRANSCODER_AVATAR_BIG' => 'bx_organizations_avatar_big',
+            'OBJECT_IMAGES_TRANSCODER_PICTURE' => 'bx_organizations_picture',
+            'OBJECT_IMAGES_TRANSCODER_COVER' => 'bx_organizations_cover',
+            'OBJECT_IMAGES_TRANSCODER_COVER_THUMB' => 'bx_organizations_cover_thumb',
+            'OBJECT_IMAGES_TRANSCODER_GALLERY' => 'bx_organizations_gallery',
+            'OBJECT_VIEWS' => 'bx_organizations',
+            'OBJECT_VOTES' => 'bx_organizations',
+            'OBJECT_SCORES' => 'bx_organizations',
+            'OBJECT_FAVORITES' => 'bx_organizations',
+            'OBJECT_FEATURED' => 'bx_organizations',
+            'OBJECT_COMMENTS' => 'bx_organizations',
+            'OBJECT_NOTES' => 'bx_organizations_notes',
+            'OBJECT_REPORTS' => 'bx_organizations',
+            'OBJECT_METATAGS' => 'bx_organizations',
+            'OBJECT_CATEGORY' => 'bx_organizations_cats',
+            'OBJECT_FORM_ENTRY' => 'bx_organization',
+            'OBJECT_FORM_ENTRY_DISPLAY_VIEW' => 'bx_organization_view',
+            'OBJECT_FORM_ENTRY_DISPLAY_VIEW_FULL' => 'bx_organization_view_full', // for "info" tab on view profile page
+            'OBJECT_FORM_ENTRY_DISPLAY_ADD' => 'bx_organization_add',
+            'OBJECT_FORM_ENTRY_DISPLAY_EDIT' => 'bx_organization_edit',
+            'OBJECT_FORM_ENTRY_DISPLAY_EDIT_COVER' => 'bx_organization_edit_cover',
+            'OBJECT_FORM_ENTRY_DISPLAY_DELETE' => 'bx_organization_delete',
+            'OBJECT_FORM_ENTRY_DISPLAY_INVITE' => 'bx_organization_invite',
+            'OBJECT_FORM_PRICE' => 'bx_organizations_price',
+            'OBJECT_FORM_PRICE_DISPLAY_ADD' => 'bx_organizations_price_add',
+            'OBJECT_FORM_PRICE_DISPLAY_EDIT' => 'bx_organizations_price_edit',
+            'OBJECT_MENU_ACTIONS_VIEW_ENTRY' => 'bx_organizations_view_actions', // actions menu on view entry page
+            'OBJECT_MENU_ACTIONS_VIEW_ENTRY_MORE' => 'bx_organizations_view_actions_more', // actions menu on view entry page for "more" popup
+            'OBJECT_MENU_ACTIONS_VIEW_ENTRY_ALL' => 'bx_organizations_view_actions_all', // all actions menu on view entry page
+            'OBJECT_MENU_ACTIONS_MY_ENTRIES' => 'bx_organizations_my', // actions menu on profile entries page
+            'OBJECT_MENU_SUBMENU' => 'bx_organizations_submenu', // main module submenu
+            'OBJECT_MENU_SUBMENU_VIEW_ENTRY' => 'bx_organizations_view_submenu',  // view entry submenu
+            'OBJECT_MENU_SUBMENU_VIEW_ENTRY_MAIN_SELECTION' => 'organizations-home', // first item in view entry submenu from main module submenu
+            'OBJECT_MENU_MANAGE_VIEW_ENTRY' => '',
+            'OBJECT_MENU_VIEW_ENTRY_META' => 'bx_organizations_view_meta', // meta menu on view entry page
+            'OBJECT_MENU_SNIPPET_META' => 'bx_organizations_snippet_meta', // menu for snippet meta info
+            'OBJECT_MENU_MANAGE_TOOLS' => 'bx_organizations_menu_manage_tools', //manage menu in content administration tools
+            'OBJECT_PAGE_VIEW_ENTRY' => 'bx_organizations_view_profile',
+            'OBJECT_PAGE_VIEW_ENTRY_CLOSED' => 'bx_organizations_view_profile_closed',
+            'OBJECT_PAGE_JOINED_ENTRY' => 'bx_organizations_join_profile',
+            'OBJECT_PRIVACY_VIEW' => 'bx_organizations_allow_view_to',
+            'OBJECT_PRIVACY_LIST_VIEW' => 'bx_organizations_allow_view_favorite_list',
+            'OBJECT_PRIVACY_VIEW_NOTIFICATION_EVENT' => 'bx_organizations_allow_view_notification_to',
+            'OBJECT_PRIVACY_POST' => 'bx_organizations_allow_post_to',
+            'OBJECT_PRIVACY_CONTACT' => 'bx_organizations_allow_contact_to',
+            'OBJECT_GRID_ADMINISTRATION' => 'bx_organizations_administration',
+            'OBJECT_GRID_COMMON' => 'bx_organizations_common',
+            'OBJECT_GRID_CONNECTIONS' => 'bx_organizations_fans',
+            'OBJECT_GRID_INVITES' => 'bx_organizations_invites',
+            'OBJECT_GRID_PRICES_MANAGE' => 'bx_organizations_prices_manage',
+            'OBJECT_GRID_PRICES_VIEW' => 'bx_organizations_prices_view',
+            'OBJECT_CONNECTIONS' => 'bx_organizations_fans',
+            'OBJECT_UPLOADERS_COVER' => array('bx_organizations_cover_crop'),
+            'OBJECT_UPLOADERS_PICTURE' => array('bx_organizations_picture_crop'),
+            'OBJECT_PRE_LIST_ROLES' => 'bx_organizations_roles',
+            'OBJECT_PRE_LIST_PERIOD_UNITS' => 'bx_organizations_period_units',
+            
+            'BADGES_AVALIABLE' => true,
+            'INVITES_KEYS_LIFETIME' => 86400,
+
+            'EMAIL_FRIEND_REQUEST' => 'bx_organizations_friend_request',
+            'EMAIL_INVITATION' => 'bx_organizations_invitation',
+            'EMAIL_JOIN_REQUEST' => 'bx_organizations_join_request',
+            'EMAIL_JOIN_CONFIRM' => 'bx_organizations_join_confirm',
+            'EMAIL_FAN_BECOME_ADMIN' => 'bx_organizations_fan_become_admin',
+            'EMAIL_ADMIN_BECOME_FAN' => 'bx_organizations_admin_become_fan',
+            'EMAIL_FAN_SET_ROLE' => 'bx_organizations_set_role',
+            'EMAIL_FAN_REMOVE' => 'bx_organizations_fan_remove',
+            'EMAIL_JOIN_REJECT' => 'bx_organizations_join_reject',
+
+            'TRIGGER_MENU_PROFILE_VIEW_SUBMENU' => 'trigger_profile_view_submenu',
+            'TRIGGER_MENU_PROFILE_SNIPPET_META' => 'trigger_profile_snippet_meta',
+            'TRIGGER_MENU_PROFILE_VIEW_ACTIONS' => 'trigger_profile_view_actions',
+            'TRIGGER_PAGE_VIEW_ENTRY' => 'trigger_page_profile_view_entry',
+
+            // menu items which visibility depends on custom visibility checking
+            'MENU_ITEM_TO_METHOD' => array (
+                'bx_organizations_view_submenu' => $this->_aMenuItems2MethodsSubmenu,
+                'bx_organizations_view_actions' => $this->_aMenuItems2MethodsActions,
+                'bx_organizations_view_actions_more' => $this->_aMenuItems2MethodsActions,
+                'bx_organizations_view_actions_all' => $this->_aMenuItems2MethodsActions,
+            ),
+
+            // informer messages
+            'INFORMERS' => array (
+                'status' => array (
+                    'name' => 'bx-organizations-status-not-active',
+                    'map' => array (
+                        BX_PROFILE_STATUS_PENDING => '_bx_orgs_txt_account_pending',
+                        BX_PROFILE_STATUS_SUSPENDED => '_bx_orgs_txt_account_suspended',
+                    ),
+                ),
+                'status_moderation' => array (
+                    'name' => 'bx-organizations-status-not-active-moderation',
+                    'map' => array (
+                        BX_PROFILE_STATUS_PENDING => '_bx_orgs_txt_account_pending_moderation',
+                        BX_PROFILE_STATUS_SUSPENDED => '_bx_orgs_txt_account_suspended_moderation',
+                    ),
+                ),
+            ),
+
+            // some language keys
+            'T' => array (
+                'txt_sample_single' => '_bx_orgs_txt_sample_single',
+            	'txt_sample_comment_single' => '_bx_orgs_txt_sample_comment_single',
+                'txt_sample_vote_single' => '_bx_orgs_txt_sample_vote_single',
+                'txt_sample_score_up_single' => '_bx_orgs_txt_sample_score_up_single',
+                'txt_sample_score_down_single' => '_bx_orgs_txt_sample_score_down_single',
+            	'txt_sample_pp_single' => '_bx_orgs_txt_sample_pp_single',
+            	'txt_sample_pp_single_with_article' => '_bx_orgs_txt_sample_pp_single_with_article',
+                'txt_sample_pc_single' => '_bx_orgs_txt_sample_pc_single',
+            	'txt_sample_pc_single_with_article' => '_bx_orgs_txt_sample_pc_single_with_article',
+            	'txt_sample_pi_action' => '_bx_orgs_txt_sample_pi_action',
+            	'txt_sample_pi_action_user' => '_bx_orgs_txt_sample_pi_action_user',
+            	'txt_private_group' => '_bx_orgs_txt_private_organization',
+                'txt_group_participants' => '_bx_orgs_ps_group_title_participants',
+                'txt_N_fans' => '_bx_orgs_txt_N_friends',
+                'txt_ntfs_join_invitation' => '_bx_orgs_txt_ntfs_join_invitation',
+            	'txt_ntfs_join_request' => '_bx_orgs_txt_ntfs_join_request',
+                'txt_ntfs_join_request_for_owner' => '_bx_orgs_txt_ntfs_join_request_for_owner',
+                'txt_ntfs_accept_request' => '_bx_orgs_txt_ntfs_accept_request',
+                'txt_ntfs_accept_request_for_owner' => '_bx_orgs_txt_ntfs_accept_request_for_owner',
+                'txt_ntfs_fan_added' => '_bx_orgs_txt_ntfs_fan_added',
+            	'txt_ntfs_timeline_post_common' => '_bx_orgs_txt_ntfs_timeline_post_common',
+                'option_members_mode_multi_roles' => '_bx_orgs_option_members_mode_multi_roles',
+            	'txt_all_entries_by_author' => '_bx_orgs_page_title_browse_by_author',
+            	'form_field_picture' => '_bx_orgs_form_profile_input_picture_search',
+                'form_field_online' => '_bx_orgs_form_profile_input_online_search',
+                'menu_item_title_befriend_sent' => '_bx_orgs_menu_item_title_befriend_sent',
+                'menu_item_title_unfriend_cancel_request' => '_bx_orgs_menu_item_title_unfriend_cancel_request',
+                'menu_item_title_befriend_confirm' => '_bx_orgs_menu_item_title_befriend_confirm',
+                'menu_item_title_unfriend_reject_request' => '_bx_orgs_menu_item_title_unfriend_reject_request',
+                'menu_item_title_befriend' => '_bx_orgs_menu_item_title_befriend',
+                'menu_item_title_unfriend' => '_bx_orgs_menu_item_title_unfriend',
+                'menu_item_title_sm_join' => '_bx_orgs_menu_item_title_become_fan',
+                'menu_item_title_sm_join_requested' => '_bx_orgs_menu_item_title_become_fan_sent',
+                'menu_item_title_sm_leave' => '_bx_orgs_menu_item_title_leave_organization',
+                'menu_item_title_sm_leave_cancel' => '_bx_orgs_menu_item_title_leave_organization_cancel_request',
+            	'menu_item_manage_my' => '_bx_orgs_menu_item_title_manage_my',
+            	'menu_item_manage_all' => '_bx_orgs_menu_item_title_manage_all',
+            	'grid_action_err_delete' => '_bx_orgs_grid_action_err_delete',
+            	'grid_txt_account_manager' => '_bx_orgs_grid_txt_account_manager',
+                'filter_item_active' => '_bx_orgs_grid_filter_item_title_adm_active',
+            	'filter_item_pending' => '_bx_orgs_grid_filter_item_title_adm_pending',
+            	'filter_item_suspended' => '_bx_orgs_grid_filter_item_title_adm_suspended',
+                'filter_item_unconfirmed' => '_bx_orgs_grid_filter_item_title_adm_unconfirmed',
+            	'filter_item_select_one_filter1' => '_bx_orgs_grid_filter_item_title_adm_select_one_filter1',
+                'filter_item_select_one_filter2' => '_bx_orgs_grid_filter_item_title_adm_select_one_filter2',
+            	'txt_browse_favorites' => '_bx_orgs_page_title_browse_favorites',
+            	'option_redirect_aadd_profile' => '_bx_orgs_option_redirect_aadd_profile',
+            	'option_redirect_aadd_last' => '_bx_orgs_option_redirect_aadd_last',
+            	'option_redirect_aadd_custom' => '_bx_orgs_option_redirect_aadd_custom',
+                'option_redirect_aadd_homepage' => '_bx_orgs_option_redirect_aadd_homepage',
+                'option_activation_on' => '_bx_orgs_option_activation_on',
+            	'option_activation_off' => '_bx_orgs_option_activation_off',
+            	'option_activation_add' => '_bx_orgs_option_activation_add',
+                'option_activation_edit' => '_bx_orgs_option_activation_edit',
+                'txt_invitation_popup_title' => '_bx_orgs_txt_invite_popup_title',
+                'txt_invitation_popup_text' => '_bx_orgs_txt_invite_popup_text',
+                'txt_invitation_popup_accept_button' => '_bx_orgs_txt_invite_popup_button_accept',
+                'txt_invitation_popup_decline_button' => '_bx_orgs_txt_invite_popup_button_decline',
+                'txt_invitation_popup_error_invitation_absent' => '_bx_orgs_txt_invite_popup_error_invitation_absent',
+                'txt_invitation_popup_error_wrong_user' => '_bx_orgs_txt_invite_popup_error_invitation_wrong_user',
+                'txt_n_unit' => '_bx_orgs_txt_n_unit',
+                'txt_buy_title' => '_bx_orgs_grid_action_title_buy_title',
+                'txt_cart_item_title' => '_bx_orgs_txt_cart_item_title',
+                'txt_cart_item_title_lifetime' => '_bx_orgs_txt_cart_item_title_lifetime',
+                'txt_subscribe_title' => '_bx_orgs_grid_action_title_subscribe_title',
+                'popup_title_price_add' => '_bx_orgs_popup_title_price_add',
+                'popup_title_price_edit' => '_bx_orgs_popup_title_price_edit',
+                'msg_performed' => '_bx_orgs_msg_performed',
+                'err_period_unit' => '_bx_orgs_form_price_input_err_period_unit',
+                'err_price_duplicate' => '_bx_orgs_err_price_duplicate',
+                'err_cannot_perform' => '_bx_orgs_err_cannot_perform',
+            ),
+        ));
+
+        $this->_aJsClasses = array(
+            'main' => 'BxOrgsMain',
+            'manage_tools' => 'BxOrgsManageTools',
+            'categories' => 'BxDolCategories',
+            'invite_popup' => 'BxOrgsInvitePopup',
+            'prices' => 'BxOrgsPrices'
+        );
+
+        $this->_aJsObjects = array(
+            'main' => 'oBxOrgsMain',
+            'manage_tools' => 'oBxOrgsManageTools',
+            'categories' => 'oBxDolCategories',
+            'invite_popup' => 'oBxOrgsInvitePopup',
+            'prices' => 'oBxOrgsPrices'
+        );
+
+        $this->_aGridObjects = array(
+            'common' => $this->CNF['OBJECT_GRID_COMMON'],
+            'administration' => $this->CNF['OBJECT_GRID_ADMINISTRATION'],
+        );
+    }
+
+    protected function _initUseCoverAsThumb()
+    {
+        return false;
+    }
+}
+
+/** @} */

+ 152 - 0
modules/boonex/organizations/updates/14.0.7_14.0.8/source/install/config.php

@@ -0,0 +1,152 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Organizations Organizations
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+$aConfig = array(
+
+    /**
+     * Main Section.
+     */
+    'type' => BX_DOL_MODULE_TYPE_MODULE,
+    'name' => 'bx_organizations',
+    'title' => 'Organizations',
+    'note' => 'Basic organization profiles functionality.',
+    'version' => '14.0.8',
+    'vendor' => 'UNA INC',
+    'help_url' => 'http://feed.una.io/?section={module_name}',
+
+    'compatible_with' => array(
+        '14.0.0-RC4'
+    ),
+
+    /**
+     * 'home_dir' and 'home_uri' - should be unique. Don't use spaces in 'home_uri' and the other special chars.
+     */
+    'home_dir' => 'boonex/organizations/',
+    'home_uri' => 'orgs',
+
+    'db_prefix' => 'bx_organizations_',
+    'class_prefix' => 'BxOrgs',
+
+    /**
+     * Category for language keys.
+     */
+    'language_category' => 'Organizations',
+
+    /**
+     * Connections.
+     */
+    'connections' => array(
+    	'sys_profiles_friends' => array ('type' => 'profiles'),
+        'sys_profiles_subscriptions' => array ('type' => 'profiles'),
+        'sys_profiles_relations' => array ('type' => 'profiles'),
+    ),
+
+    /**
+     * Menu triggers.
+     */
+    'menu_triggers' => array(
+        'trigger_profile_view_submenu',
+        'trigger_profile_snippet_meta',
+        'trigger_profile_view_actions',
+    ),
+
+    /**
+     * Page triggers.
+     */
+    'page_triggers' => array (
+    	'trigger_page_profile_view_entry', 
+    ),
+
+	/**
+     * Storage objects to automatically delete files from upon module uninstallation.
+     * Note. Don't add storage objects used in transcoder objects.
+     */
+    'storages' => array(
+    	'bx_organizations_pics'
+    ),
+
+	/**
+     * Transcoders.
+     */
+    'transcoders' => array(
+    	'bx_organizations_icon', 
+    	'bx_organizations_thumb', 
+    	'bx_organizations_avatar', 
+        'bx_organizations_avatar_big', 
+    	'bx_organizations_picture', 
+    	'bx_organizations_cover', 
+    	'bx_organizations_cover_thumb',
+    	'bx_organizations_gallery'
+    ),
+
+	/**
+     * Extended Search Forms.
+     */
+    'esearches' => array(
+        'bx_organizations',
+    	'bx_organizations_cmts',
+    ),
+
+    /**
+     * Installation/Uninstallation Section.
+     */
+    'install' => array(
+        'execute_sql' => 1,
+        'update_languages' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'uninstall' => array (
+    	'process_esearches' => 1,
+        'execute_sql' => 1,
+        'update_languages' => 1,
+    	'process_connections' => 1,
+    	'process_deleted_profiles' => 1,
+    	'update_relations' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'enable' => array(
+        'execute_sql' => 1,
+    	'update_relations' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'enable_success' => array(
+    	'process_menu_triggers' => 1,
+    	'process_page_triggers' => 1,
+    	'process_esearches' => 1,
+    	'register_transcoders' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'disable' => array (
+        'execute_sql' => 1,
+    	'unregister_transcoders' => 1,
+    	'update_relations' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'disable_failed' => array (
+    	'register_transcoders' => 1,
+    	'clear_db_cache' => 1,
+    ),
+
+    /**
+     * Dependencies Section
+     */
+    'dependencies' => array(),
+
+    /**
+     * Connections Section
+     */
+    'relations' => array(
+        'bx_timeline',
+        'bx_notifications',
+    ),
+);
+
+/** @} */

+ 20 - 0
modules/boonex/organizations/updates/14.0.7_14.0.8/source/js/main.js

@@ -0,0 +1,20 @@
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Organizations Organizations
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+function BxOrgsMain(oOptions) {
+    BxBaseModGroupsMain.call(this, oOptions);
+
+    this._sObjName = oOptions.sObjName == undefined ? 'oBxOrgsMain' : oOptions.sObjName;
+}
+
+BxOrgsMain.prototype = Object.create(BxBaseModGroupsMain.prototype);
+BxOrgsMain.prototype.constructor = BxOrgsMain;
+
+/** @} */

+ 51 - 0
modules/boonex/payment/updates/14.0.7_14.0.8/install/config.php

@@ -0,0 +1,51 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ */
+
+$aConfig = array(
+    /**
+     * Main Section.
+     */
+    'title' => 'Payment',
+    'version_from' => '14.0.7',
+    'version_to' => '14.0.8',
+    'vendor' => 'UNA INC',
+
+    'compatible_with' => array(
+        '14.0.0-RC4'
+    ),
+
+    /**
+     * 'home_dir' and 'home_uri' - should be unique. Don't use spaces in 'home_uri' and the other special chars.
+     */
+    'home_dir' => 'boonex/payment/updates/update_14.0.7_14.0.8/',
+    'home_uri' => 'payment_update_1407_1408',
+
+    'module_dir' => 'boonex/payment/',
+    'module_uri' => 'payment',
+
+    'db_prefix' => 'bx_payment_',
+    'class_prefix' => 'BxPayment',
+
+    /**
+     * Installation/Uninstallation Section.
+     */
+    'install' => array(
+        'execute_sql' => 1,
+        'update_files' => 1,
+        'update_languages' => 0,
+        'clear_db_cache' => 1,
+    ),
+
+    /**
+     * Category for language keys.
+     */
+    'language_category' => 'Payment',
+
+    /**
+     * Files Section
+     */
+    'delete_files' => array(),
+);

+ 13 - 0
modules/boonex/payment/updates/14.0.7_14.0.8/install/installer.php

@@ -0,0 +1,13 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ */
+
+class BxPaymentUpdater extends BxDolStudioUpdater
+{
+    function __construct($aConfig)
+    {
+        parent::__construct($aConfig);
+    }
+}

+ 5 - 0
modules/boonex/payment/updates/14.0.7_14.0.8/install/sql/install.sql

@@ -0,0 +1,5 @@
+SET @sName = 'bx_payment';
+
+
+-- GRIDS
+UPDATE `sys_objects_grid` SET `show_total_count`='0' WHERE `object`='bx_payment_grid_providers';

+ 70 - 0
modules/boonex/payment/updates/14.0.7_14.0.8/source/install/config.php

@@ -0,0 +1,70 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Payment Payment
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+$aConfig = array(
+    /**
+     * Main Section.
+     */
+    'type' => BX_DOL_MODULE_TYPE_MODULE,
+    'name' => 'bx_payment',
+    'title' => 'Payment',
+    'note' => 'Payment module.',
+    'version' => '14.0.8',
+    'vendor' => 'UNA INC',
+    'help_url' => 'http://feed.una.io/?section={module_name}',
+
+    'compatible_with' => array(
+        '14.0.0-RC4'
+    ),
+
+    /**
+     * 'home_dir' and 'home_uri' - should be unique. Don't use spaces in 'home_uri' and the other special chars.
+     */
+    'home_dir' => 'boonex/payment/',
+    'home_uri' => 'payment',
+
+    'db_prefix' => 'bx_payment_',
+    'class_prefix' => 'BxPayment',
+
+    /**
+     * Category for language keys.
+     */
+    'language_category' => 'Payment',
+
+    /**
+     * Installation/Uninstallation Section.
+     */
+    'install' => array(
+        'execute_sql' => 1,
+        'update_languages' => 1,
+        'clear_db_cache' => 1,
+    ),
+	'uninstall' => array (
+        'execute_sql' => 1,
+        'update_languages' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'enable' => array(
+        'execute_sql' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'disable' => array (
+        'execute_sql' => 1,
+        'clear_db_cache' => 1,
+    ),
+
+    /**
+     * Dependencies Section
+     */
+    'dependencies' => array(),
+);
+
+/** @} */

+ 679 - 0
modules/boonex/payment/updates/14.0.7_14.0.8/source/install/sql/install.sql

@@ -0,0 +1,679 @@
+SET @sName = 'bx_payment';
+
+
+-- TABLES
+CREATE TABLE IF NOT EXISTS `bx_payment_currencies` (
+  `id` int(11) NOT NULL auto_increment,
+  `code` varchar(4) NOT NULL default '',
+  `rate` float NOT NULL default '0',
+  PRIMARY KEY(`id`),
+  UNIQUE KEY `code`(`code`)
+);
+
+CREATE TABLE IF NOT EXISTS `bx_payment_providers` (
+  `id` int(11) NOT NULL auto_increment,
+  `name` varchar(64) NOT NULL default '',
+  `caption` varchar(128) NOT NULL default '',
+  `description` varchar(128) NOT NULL default '',
+  `option_prefix` varchar(32) NOT NULL default '',
+  `for_visitor` tinyint(4) NOT NULL default '0',
+  `for_owner_only` tinyint(4) NOT NULL default '0',
+  `for_single` tinyint(4) NOT NULL default '0',
+  `for_recurring` tinyint(4) NOT NULL default '0',
+  `single_seller` tinyint(4) NOT NULL default '0',
+  `time_tracker` tinyint(4) NOT NULL default '0',
+  `active` tinyint(4) NOT NULL default '0',
+  `order` tinyint(4) NOT NULL default '0',
+  `class_name` varchar(128) NOT NULL default '',
+  `class_file` varchar(255) NOT NULL  default '',
+  PRIMARY KEY(`id`)
+);
+
+CREATE TABLE IF NOT EXISTS `bx_payment_providers_options` (
+  `id` int(11) NOT NULL auto_increment,
+  `provider_id` varchar(64) NOT NULL default '',
+  `name` varchar(64) NOT NULL default '',
+  `type` varchar(64) NOT NULL default 'text',
+  `caption` varchar(255) NOT NULL default '',
+  `description` text NOT NULL default '',
+  `extra` varchar(255) NOT NULL default '',
+  `check_type` varchar(64) NOT NULL default '',
+  `check_params` varchar(128) NOT NULL default '',
+  `check_error` varchar(128) NOT NULL default '',
+  `order` tinyint(4) NOT NULL default '0',
+  PRIMARY KEY(`id`),
+  UNIQUE KEY `name`(`name`)
+);
+
+CREATE TABLE IF NOT EXISTS `bx_payment_user_values` (
+  `id` int(11) NOT NULL auto_increment,
+  `user_id` int(11) NOT NULL default '0',
+  `option_id` int(11) NOT NULL default '0',  
+  `value` varchar(255) NOT NULL default '',
+  PRIMARY KEY(`id`),
+  UNIQUE KEY `value`(`user_id`, `option_id`)
+);
+
+CREATE TABLE IF NOT EXISTS `bx_payment_cart` (
+  `client_id` int(11) NOT NULL default '0',
+  `items` text NOT NULL default '',
+  `customs` text NOT NULL default '',
+  PRIMARY KEY(`client_id`)
+);
+
+CREATE TABLE IF NOT EXISTS `bx_payment_transactions` (
+  `id` int(11) NOT NULL auto_increment,
+  `pending_id` int(11) NOT NULL default '0',
+  `client_id` int(11) NOT NULL default '0',
+  `seller_id` int(11) NOT NULL default '0',
+  `author_id` int(11) NOT NULL default '0',
+  `module_id` int(11) NOT NULL default '0',  
+  `item_id` int(11) NOT NULL default '0',
+  `item_count` int(11) NOT NULL default '0',
+  `amount` float NOT NULL default '0',
+  `currency` varchar(4) NOT NULL default '',
+  `license` varchar(16) NOT NULL default '',
+  `date` int(11) NOT NULL default '0',
+  `new` tinyint(1) NOT NULL default '1',
+  PRIMARY KEY(`id`)
+);
+
+CREATE TABLE IF NOT EXISTS `bx_payment_subscriptions` (
+  `id` int(11) NOT NULL auto_increment,
+  `pending_id` int(11) NOT NULL default '0',
+  `customer_id` varchar(32) NOT NULL default '',
+  `subscription_id` varchar(32) NOT NULL default '',
+  `period` int(11) unsigned NOT NULL default '1',
+  `period_unit` varchar(32) NOT NULL default '',
+  `trial` int(11) unsigned NOT NULL default '0',
+  `date_add` int(11) NOT NULL default '0',
+  `date_next` int(11) NOT NULL default '0',
+  `pay_attempts` tinyint(4) NOT NULL default '0',
+  `status` varchar(32) NOT NULL default 'unpaid',
+  PRIMARY KEY(`id`),
+  UNIQUE KEY `pending_id` (`pending_id`)
+);
+
+CREATE TABLE IF NOT EXISTS `bx_payment_subscriptions_deleted` (
+  `id` int(11) NOT NULL auto_increment,
+  `pending_id` int(11) NOT NULL default '0',
+  `customer_id` varchar(32) NOT NULL default '',
+  `subscription_id` varchar(32) NOT NULL default '',
+  `period` int(11) unsigned NOT NULL default '1',
+  `period_unit` varchar(32) NOT NULL default '',
+  `trial` int(11) unsigned NOT NULL default '0',
+  `date_add` int(11) NOT NULL default '0',
+  `date_next` int(11) NOT NULL default '0',
+  `pay_attempts` tinyint(4) NOT NULL default '0',
+  `status` varchar(32) NOT NULL default 'unpaid',
+  `reason` varchar(16) NOT NULL default '',
+  `deleted` int(11) NOT NULL default '0',
+  PRIMARY KEY(`id`),
+  UNIQUE KEY `pending_id` (`pending_id`)
+);
+
+CREATE TABLE IF NOT EXISTS `bx_payment_transactions_pending` (
+  `id` int(10) unsigned NOT NULL auto_increment,
+  `client_id` int(11) NOT NULL default '0',
+  `seller_id` int(11) NOT NULL default '0',
+  `type` varchar(16) NOT NULL default 'single',
+  `provider` varchar(32) NOT NULL default '',
+  `items` text NOT NULL default '',
+  `customs` text NOT NULL default '',
+  `amount` float NOT NULL default '0',
+  `currency` varchar(4) NOT NULL default '',
+  `order` varchar(32) NOT NULL default '',
+  `data` text NOT NULL,
+  `error_code` varchar(16) NOT NULL default '',
+  `error_msg` varchar(255) NOT NULL default '',
+  `date` int(11) NOT NULL default '0',
+  `authorized` tinyint(4) NOT NULL default '0',
+  `processed` tinyint(4) NOT NULL default '0',
+  PRIMARY KEY(`id`)
+);
+
+CREATE TABLE IF NOT EXISTS `bx_payment_modules` (
+  `id` int(11) NOT NULL auto_increment,
+  `name` varchar(32) NOT NULL default '',
+  PRIMARY KEY(`id`),
+  UNIQUE KEY `uri`(`name`)
+);
+
+INSERT INTO `bx_payment_modules`(`name`) VALUES
+(@sName);
+
+CREATE TABLE IF NOT EXISTS `bx_payment_commissions` (
+  `id` int(11) NOT NULL auto_increment,
+  `name` varchar(64) NOT NULL default '',
+  `caption` varchar(128) NOT NULL default '',
+  `description` varchar(128) NOT NULL default '',
+  `acl_id` int(11) NOT NULL default '0',
+  `percentage` float NOT NULL default '0',
+  `installment` float NOT NULL default '0',
+  `active` tinyint(4) NOT NULL default '0',
+  `order` tinyint(4) NOT NULL default '0',
+  PRIMARY KEY(`id`),
+  UNIQUE KEY `name`(`name`)
+);
+
+CREATE TABLE IF NOT EXISTS `bx_payment_invoices` (
+  `id` int(11) NOT NULL auto_increment,
+  `name` varchar(64) NOT NULL default '',
+  `commissionaire_id` varchar(32) NOT NULL default '',
+  `committent_id` varchar(32) NOT NULL default '',
+  `amount` float NOT NULL default '0',
+  `currency` varchar(4) NOT NULL default '',
+  `period_start` int(11) NOT NULL default '0',
+  `period_end` int(11) NOT NULL default '0',
+  `date_issue` int(11) NOT NULL default '0',
+  `date_due` int(11) NOT NULL default '0',
+  `status` varchar(32) NOT NULL default 'unpaid',
+  `ntf_exp` tinyint(4) NOT NULL default '0',
+  `ntf_due` tinyint(4) NOT NULL default '0',
+  PRIMARY KEY(`id`),
+  UNIQUE KEY `name`(`name`)
+);
+
+CREATE TABLE IF NOT EXISTS `bx_payment_stripe_payments_pending` (
+  `id` int(11) NOT NULL auto_increment,
+  `subscription_id` varchar(32) NOT NULL default '',
+  `amount` float NOT NULL default '0',
+  `currency` varchar(4) NOT NULL default '',
+  PRIMARY KEY(`id`),
+  UNIQUE KEY `subscription_id` (`subscription_id`)
+);
+
+-- Generic payment provider
+INSERT INTO `bx_payment_providers`(`name`, `caption`, `description`, `option_prefix`, `for_visitor`, `for_single`, `for_recurring`, `single_seller`, `time_tracker`, `active`, `order`, `class_name`) VALUES
+('generic', '_bx_payment_gc_cpt', '_bx_payment_gc_dsc', 'gc_', 0, 0, 0, 0, 0, 1, 0, 'BxPaymentProviderGeneric');
+SET @iProviderId = LAST_INSERT_ID();
+
+INSERT INTO `bx_payment_providers_options`(`provider_id`, `name`, `type`, `caption`, `description`, `extra`, `check_type`, `check_params`, `check_error`, `order`) VALUES
+(@iProviderId, 'gc_currency_code', 'select', '_bx_payment_gc_currency_code_cpt', '_bx_payment_gc_currency_code_dsc', 'a:2:{s:6:"module";s:10:"bx_payment";s:6:"method";s:34:"get_options_personal_currency_code";}', '', '', '', 1);
+
+-- Offline payment provider
+INSERT INTO `bx_payment_providers`(`name`, `caption`, `description`, `option_prefix`, `for_visitor`, `for_single`, `for_recurring`, `single_seller`, `time_tracker`, `active`, `order`, `class_name`) VALUES
+('offline', '_bx_payment_off_cpt', '_bx_payment_off_dsc', 'off_', 0, 1, 0, 0, 0, 1, 5, 'BxPaymentProviderOffline');
+SET @iProviderId = LAST_INSERT_ID();
+
+INSERT INTO `bx_payment_providers_options`(`provider_id`, `name`, `type`, `caption`, `description`, `extra`, `check_type`, `check_params`, `check_error`, `order`) VALUES
+(@iProviderId, 'off_active', 'checkbox', '_bx_payment_off_active_cpt', '_bx_payment_off_active_dsc', '', '', '', '', 1),
+(@iProviderId, 'off_checkout_email', 'text', '_bx_payment_off_checkout_email_cpt', '_bx_payment_off_checkout_email_dsc', '', 'EmailOrEmpty', '', '_sys_form_account_input_email_error', 2);
+
+
+-- Credits payment provider
+INSERT INTO `bx_payment_providers`(`name`, `caption`, `description`, `option_prefix`, `for_visitor`, `for_single`, `for_recurring`, `single_seller`, `time_tracker`, `active`, `order`, `class_name`) VALUES
+('credits', '_bx_payment_cdt_cpt', '_bx_payment_cdt_dsc', 'cdt_', 0, 1, 1, 1, 1, 1, 6, 'BxPaymentProviderCredits');
+SET @iProviderId = LAST_INSERT_ID();
+
+INSERT INTO `bx_payment_providers_options`(`provider_id`, `name`, `type`, `caption`, `description`, `extra`, `check_type`, `check_params`, `check_error`, `order`) VALUES
+(@iProviderId, 'cdt_active', 'checkbox', '_bx_payment_cdt_active_cpt', '_bx_payment_cdt_active_dsc', '', '', '', '', 1);
+
+
+-- PayPal payment provider
+INSERT INTO `bx_payment_providers`(`name`, `caption`, `description`, `option_prefix`, `for_visitor`, `for_single`, `for_recurring`, `single_seller`, `active`, `order`, `class_name`) VALUES
+('paypal', '_bx_payment_pp_cpt', '_bx_payment_pp_dsc', 'pp_', 1, 1, 0, 1, 1, 10, 'BxPaymentProviderPayPal');
+SET @iProviderId = LAST_INSERT_ID();
+
+INSERT INTO `bx_payment_providers_options`(`provider_id`, `name`, `type`, `caption`, `description`, `extra`, `check_type`, `check_params`, `check_error`, `order`) VALUES
+(@iProviderId, 'pp_active', 'checkbox', '_bx_payment_pp_active_cpt', '_bx_payment_pp_active_dsc', '', '', '', '', 1),
+(@iProviderId, 'pp_mode', 'select', '_bx_payment_pp_mode_cpt', '_bx_payment_pp_mode_dsc', '1|_bx_payment_pp_mode_live,2|_bx_payment_pp_mode_test', '', '', '', 2),
+(@iProviderId, 'pp_business', 'text', '_bx_payment_pp_business_cpt', '_bx_payment_pp_business_dsc', '', 'EmailOrEmpty', '', '_bx_payment_form_input_email_err_cor_or_emp', 3),
+(@iProviderId, 'pp_prc_type', 'select', '_bx_payment_pp_prc_type_cpt', '_bx_payment_pp_prc_type_dsc', '1|_bx_payment_pp_prc_type_direct,2|_bx_payment_pp_prc_type_pdt,3|_bx_payment_pp_prc_type_ipn', '', '', '', 4),
+(@iProviderId, 'pp_token', 'text', '_bx_payment_pp_token_cpt', '_bx_payment_pp_token_dsc', '', '', '', '', 5),
+(@iProviderId, 'pp_sandbox', 'text', '_bx_payment_pp_sandbox_cpt', '_bx_payment_pp_sandbox_dsc', '', 'EmailOrEmpty', '', '_bx_payment_form_input_email_err_cor_or_emp', 6),
+(@iProviderId, 'pp_return_data_url', 'value', '_bx_payment_pp_return_data_url_cpt', '', '', '', '', '', 7);
+
+-- PayPal API payment provider
+INSERT INTO `bx_payment_providers`(`name`, `caption`, `description`, `option_prefix`, `for_visitor`, `for_single`, `for_recurring`, `single_seller`, `active`, `order`, `class_name`) VALUES
+('paypal_api', '_bx_payment_pp_api_cpt', '_bx_payment_pp_api_dsc', 'pp_api_', 1, 1, 1, 1, 1, 15, 'BxPaymentProviderPayPalApi');
+SET @iProviderId = LAST_INSERT_ID();
+
+INSERT INTO `bx_payment_providers_options`(`provider_id`, `name`, `type`, `caption`, `description`, `extra`, `check_type`, `check_params`, `check_error`, `order`) VALUES
+(@iProviderId, 'pp_api_active', 'checkbox', '_bx_payment_pp_api_active_cpt', '_bx_payment_pp_api_active_dsc', '', '', '', '', 1),
+(@iProviderId, 'pp_api_hidden', 'checkbox', '_bx_payment_pp_api_hidden_cpt', '_bx_payment_pp_api_hidden_dsc', '', '', '', '', 2),
+(@iProviderId, 'pp_api_mode', 'select', '_bx_payment_pp_api_mode_cpt', '_bx_payment_pp_api_mode_dsc', '1|_bx_payment_pp_api_mode_live,2|_bx_payment_pp_api_mode_test', '', '', '', 3),
+(@iProviderId, 'pp_api_live_account', 'text', '_bx_payment_pp_api_live_account_cpt', '_bx_payment_pp_api_live_account_dsc', '', 'EmailOrEmpty', '', '_bx_payment_form_input_email_err_cor_or_emp', 4),
+(@iProviderId, 'pp_api_live_client_id', 'text', '_bx_payment_pp_api_live_client_id_cpt', '_bx_payment_pp_api_live_client_id_dsc', '', '', '', '', 5),
+(@iProviderId, 'pp_api_live_secret', 'text', '_bx_payment_pp_api_live_secret_cpt', '_bx_payment_pp_api_live_secret_dsc', '', '', '', '', 6),
+(@iProviderId, 'pp_api_test_account', 'text', '_bx_payment_pp_api_test_account_cpt', '_bx_payment_pp_api_test_account_dsc', '', 'EmailOrEmpty', '', '_bx_payment_form_input_email_err_cor_or_emp', 7),
+(@iProviderId, 'pp_api_test_client_id', 'text', '_bx_payment_pp_api_test_client_id_cpt', '_bx_payment_pp_api_test_client_id_dsc', '', '', '', '', 8),
+(@iProviderId, 'pp_api_test_secret', 'text', '_bx_payment_pp_api_test_secret_cpt', '_bx_payment_pp_api_test_secret_dsc', '', '', '', '', 9),
+(@iProviderId, 'pp_api_return_data_url', 'value', '_bx_payment_pp_api_return_data_url_cpt', '', '', '', '', '', 10),
+(@iProviderId, 'pp_api_notify_url', 'value', '_bx_payment_pp_api_notify_url_cpt', '', '', '', '', '', 11);
+
+-- Chargebee payment provider
+INSERT INTO `bx_payment_providers`(`name`, `caption`, `description`, `option_prefix`, `for_visitor`, `for_single`, `for_recurring`, `active`, `order`, `class_name`) VALUES
+('chargebee', '_bx_payment_cbee_cpt', '_bx_payment_cbee_dsc', 'cbee_', 1, 0, 1, 1, 40, 'BxPaymentProviderChargebee');
+SET @iProviderId = LAST_INSERT_ID();
+
+INSERT INTO `bx_payment_providers_options`(`provider_id`, `name`, `type`, `caption`, `description`, `extra`, `check_type`, `check_params`, `check_error`, `order`) VALUES
+(@iProviderId, 'cbee_active', 'checkbox', '_bx_payment_cbee_active_cpt', '_bx_payment_cbee_active_dsc', '', '', '', '', 1),
+(@iProviderId, 'cbee_hidden', 'checkbox', '_bx_payment_cbee_hidden_cpt', '_bx_payment_cbee_hidden_dsc', '', '', '', '', 2),
+(@iProviderId, 'cbee_mode', 'select', '_bx_payment_cbee_mode_cpt', '_bx_payment_cbee_mode_dsc', '1|_bx_payment_cbee_mode_live,2|_bx_payment_cbee_mode_test', '', '', '', 3),
+(@iProviderId, 'cbee_live_site', 'text', '_bx_payment_cbee_live_site_cpt', '_bx_payment_cbee_live_site_dsc', '', '', '', '', 4),
+(@iProviderId, 'cbee_live_api_key', 'text', '_bx_payment_cbee_live_api_key_cpt', '_bx_payment_cbee_live_api_key_dsc', '', '', '', '', 5),
+(@iProviderId, 'cbee_test_site', 'text', '_bx_payment_cbee_test_site_cpt', '_bx_payment_cbee_test_site_dsc', '', '', '', '', 6),
+(@iProviderId, 'cbee_test_api_key', 'text', '_bx_payment_cbee_test_api_key_cpt', '_bx_payment_cbee_test_api_key_dsc', '', '', '', '', 7),
+(@iProviderId, 'cbee_check_amount', 'checkbox', '_bx_payment_cbee_check_amount_cpt', '_bx_payment_cbee_check_amount_dsc', '', '', '', '', 8),
+(@iProviderId, 'cbee_ssl', 'checkbox', '_bx_payment_cbee_ssl_cpt', '_bx_payment_cbee_ssl_dsc', '', '', '', '', 9),
+(@iProviderId, 'cbee_cancellation_email', 'text', '_bx_payment_cbee_cancellation_email_cpt', '', '', 'EmailOrEmpty', '', '_bx_payment_form_input_email_err_cor_or_emp', 10),
+(@iProviderId, 'cbee_expiration_email', 'text', '_bx_payment_cbee_expiration_email_cpt', '', '', 'EmailOrEmpty', '', '_bx_payment_form_input_email_err_cor_or_emp', 11),
+(@iProviderId, 'cbee_return_data_url', 'value', '_bx_payment_cbee_return_data_url_cpt', '', '', '', '', '', 12),
+(@iProviderId, 'cbee_notify_url', 'value', '_bx_payment_cbee_notify_url_cpt', '', '', '', '', '', 13);
+
+-- Chargebee V3 payment provider
+INSERT INTO `bx_payment_providers`(`name`, `caption`, `description`, `option_prefix`, `for_visitor`, `for_single`, `for_recurring`, `active`, `order`, `class_name`) VALUES
+('chargebee_v3', '_bx_payment_cbee_v3_cpt', '_bx_payment_cbee_v3_dsc', 'cbee_v3_', 1, 1, 1, 1, 41, 'BxPaymentProviderChargebeeV3');
+SET @iProviderId = LAST_INSERT_ID();
+
+INSERT INTO `bx_payment_providers_options`(`provider_id`, `name`, `type`, `caption`, `description`, `extra`, `check_type`, `check_params`, `check_error`, `order`) VALUES
+(@iProviderId, 'cbee_v3_active', 'checkbox', '_bx_payment_cbee_active_cpt', '_bx_payment_cbee_active_dsc', '', '', '', '', 1),
+(@iProviderId, 'cbee_v3_hidden', 'checkbox', '_bx_payment_cbee_hidden_cpt', '_bx_payment_cbee_hidden_dsc', '', '', '', '', 2),
+(@iProviderId, 'cbee_v3_mode', 'select', '_bx_payment_cbee_mode_cpt', '_bx_payment_cbee_mode_dsc', '1|_bx_payment_cbee_mode_live,2|_bx_payment_cbee_mode_test', '', '', '', 3),
+(@iProviderId, 'cbee_v3_live_site', 'text', '_bx_payment_cbee_live_site_cpt', '_bx_payment_cbee_live_site_dsc', '', '', '', '', 4),
+(@iProviderId, 'cbee_v3_live_api_key', 'text', '_bx_payment_cbee_live_api_key_cpt', '_bx_payment_cbee_live_api_key_dsc', '', '', '', '', 5),
+(@iProviderId, 'cbee_v3_test_site', 'text', '_bx_payment_cbee_test_site_cpt', '_bx_payment_cbee_test_site_dsc', '', '', '', '', 6),
+(@iProviderId, 'cbee_v3_test_api_key', 'text', '_bx_payment_cbee_test_api_key_cpt', '_bx_payment_cbee_test_api_key_dsc', '', '', '', '', 7),
+(@iProviderId, 'cbee_v3_check_amount', 'checkbox', '_bx_payment_cbee_check_amount_cpt', '_bx_payment_cbee_check_amount_dsc', '', '', '', '', 8),
+(@iProviderId, 'cbee_v3_ssl', 'checkbox', '_bx_payment_cbee_ssl_cpt', '_bx_payment_cbee_ssl_dsc', '', '', '', '', 9),
+(@iProviderId, 'cbee_v3_cancellation_email', 'text', '_bx_payment_cbee_cancellation_email_cpt', '', '', 'EmailOrEmpty', '', '_bx_payment_form_input_email_err_cor_or_emp', 10),
+(@iProviderId, 'cbee_v3_expiration_email', 'text', '_bx_payment_cbee_expiration_email_cpt', '', '', 'EmailOrEmpty', '', '_bx_payment_form_input_email_err_cor_or_emp', 11),
+(@iProviderId, 'cbee_v3_return_data_url', 'value', '_bx_payment_cbee_return_data_url_cpt', '', '', '', '', '', 12),
+(@iProviderId, 'cbee_v3_notify_url', 'value', '_bx_payment_cbee_notify_url_cpt', '', '', '', '', '', 13);
+
+-- Stripe payment provider
+INSERT INTO `bx_payment_providers`(`name`, `caption`, `description`, `option_prefix`, `for_visitor`, `for_single`, `for_recurring`, `active`, `order`, `class_name`) VALUES
+('stripe', '_bx_payment_strp_cpt', '_bx_payment_strp_dsc', 'strp_', 1, 1, 1, 1, 60, 'BxPaymentProviderStripe');
+SET @iProviderId = LAST_INSERT_ID();
+
+INSERT INTO `bx_payment_providers_options`(`provider_id`, `name`, `type`, `caption`, `description`, `extra`, `check_type`, `check_params`, `check_error`, `order`) VALUES
+(@iProviderId, 'strp_active', 'checkbox', '_bx_payment_strp_active_cpt', '_bx_payment_strp_active_dsc', '', '', '', '', 1),
+(@iProviderId, 'strp_hidden', 'checkbox', '_bx_payment_strp_hidden_cpt', '_bx_payment_strp_hidden_dsc', '', '', '', '', 2),
+(@iProviderId, 'strp_mode', 'select', '_bx_payment_strp_mode_cpt', '_bx_payment_strp_mode_dsc', '1|_bx_payment_strp_mode_live,2|_bx_payment_strp_mode_test', '', '', '', 3),
+(@iProviderId, 'strp_live_pub_key', 'text', '_bx_payment_strp_live_pub_key_cpt', '_bx_payment_strp_live_pub_key_dsc', '', '', '', '', 4),
+(@iProviderId, 'strp_live_sec_key', 'text', '_bx_payment_strp_live_sec_key_cpt', '_bx_payment_strp_live_sec_key_dsc', '', '', '', '', 5),
+(@iProviderId, 'strp_test_pub_key', 'text', '_bx_payment_strp_test_pub_key_cpt', '_bx_payment_strp_test_pub_key_dsc', '', '', '', '', 6),
+(@iProviderId, 'strp_test_sec_key', 'text', '_bx_payment_strp_test_sec_key_cpt', '_bx_payment_strp_test_sec_key_dsc', '', '', '', '', 7),
+(@iProviderId, 'strp_check_amount', 'checkbox', '_bx_payment_strp_check_amount_cpt', '_bx_payment_strp_check_amount_dsc', '', '', '', '', 8),
+(@iProviderId, 'strp_ssl', 'checkbox', '_bx_payment_strp_ssl_cpt', '_bx_payment_strp_ssl_dsc', '', '', '', '', 9),
+(@iProviderId, 'strp_cancellation_email', 'text', '_bx_payment_strp_cancellation_email_cpt', '', '', 'EmailOrEmpty', '', '_bx_payment_form_input_email_err_cor_or_emp', 10),
+(@iProviderId, 'strp_expiration_email', 'text', '_bx_payment_strp_expiration_email_cpt', '', '', 'EmailOrEmpty', '', '_bx_payment_form_input_email_err_cor_or_emp', 11),
+(@iProviderId, 'strp_notify_url', 'value', '_bx_payment_strp_notify_url_cpt', '', '', '', '', '', 12);
+
+-- Stripe V3 payment provider (with 3D Secure authentication for Strong Customer Authentication (SCA) support)
+INSERT INTO `bx_payment_providers`(`name`, `caption`, `description`, `option_prefix`, `for_visitor`, `for_single`, `for_recurring`, `active`, `order`, `class_name`) VALUES
+('stripe_v3', '_bx_payment_strp_v3_cpt', '_bx_payment_strp_v3_dsc', 'strp_v3_', 1, 1, 1, 1, 61, 'BxPaymentProviderStripeV3');
+SET @iProviderId = LAST_INSERT_ID();
+
+INSERT INTO `bx_payment_providers_options`(`provider_id`, `name`, `type`, `caption`, `description`, `extra`, `check_type`, `check_params`, `check_error`, `order`) VALUES
+(@iProviderId, 'strp_v3_active', 'checkbox', '_bx_payment_strp_active_cpt', '_bx_payment_strp_active_dsc', '', '', '', '', 1),
+(@iProviderId, 'strp_v3_hidden', 'checkbox', '_bx_payment_strp_hidden_cpt', '_bx_payment_strp_hidden_dsc', '', '', '', '', 2),
+(@iProviderId, 'strp_v3_mode', 'select', '_bx_payment_strp_mode_cpt', '_bx_payment_strp_mode_dsc', '1|_bx_payment_strp_mode_live,2|_bx_payment_strp_mode_test', '', '', '', 3),
+(@iProviderId, 'strp_v3_live_pub_key', 'text', '_bx_payment_strp_live_pub_key_cpt', '_bx_payment_strp_live_pub_key_dsc', '', '', '', '', 4),
+(@iProviderId, 'strp_v3_live_sec_key', 'text', '_bx_payment_strp_live_sec_key_cpt', '_bx_payment_strp_live_sec_key_dsc', '', '', '', '', 5),
+(@iProviderId, 'strp_v3_test_pub_key', 'text', '_bx_payment_strp_test_pub_key_cpt', '_bx_payment_strp_test_pub_key_dsc', '', '', '', '', 6),
+(@iProviderId, 'strp_v3_test_sec_key', 'text', '_bx_payment_strp_test_sec_key_cpt', '_bx_payment_strp_test_sec_key_dsc', '', '', '', '', 7),
+(@iProviderId, 'strp_v3_check_amount', 'checkbox', '_bx_payment_strp_check_amount_cpt', '_bx_payment_strp_check_amount_dsc', '', '', '', '', 8),
+(@iProviderId, 'strp_v3_ssl', 'checkbox', '_bx_payment_strp_ssl_cpt', '_bx_payment_strp_ssl_dsc', '', '', '', '', 9),
+(@iProviderId, 'strp_v3_cancellation_email', 'text', '_bx_payment_strp_cancellation_email_cpt', '', '', 'EmailOrEmpty', '', '_bx_payment_form_input_email_err_cor_or_emp', 10),
+(@iProviderId, 'strp_v3_expiration_email', 'text', '_bx_payment_strp_expiration_email_cpt', '', '', 'EmailOrEmpty', '', '_bx_payment_form_input_email_err_cor_or_emp', 11),
+(@iProviderId, 'strp_v3_notify_url', 'value', '_bx_payment_strp_notify_url_cpt', '', '', '', '', '', 12);
+
+-- Apple In-App payment provider
+INSERT INTO `bx_payment_providers`(`name`, `caption`, `description`, `option_prefix`, `for_visitor`, `for_owner_only`, `for_single`, `for_recurring`, `active`, `order`, `class_name`) VALUES
+('apple_in_app', '_bx_payment_aina_cpt', '_bx_payment_aina_dsc', 'aina_', 0, 1, 1, 1, 1, 70, 'BxPaymentProviderAppleInApp');
+SET @iProviderId = LAST_INSERT_ID();
+
+INSERT INTO `bx_payment_providers_options`(`provider_id`, `name`, `type`, `caption`, `description`, `extra`, `check_type`, `check_params`, `check_error`, `order`) VALUES
+(@iProviderId, 'aina_active', 'checkbox', '_bx_payment_aina_active_cpt', '_bx_payment_aina_active_dsc', '', '', '', '', 1),
+(@iProviderId, 'aina_hidden', 'checkbox', '_bx_payment_aina_hidden_cpt', '_bx_payment_aina_hidden_dsc', '', '', '', '', 2),
+(@iProviderId, 'aina_secret', 'text', '_bx_payment_aina_secret_cpt', '_bx_payment_aina_secret_dsc', '', '', '', '', 3),
+(@iProviderId, 'aina_notify_url', 'value', '_bx_payment_aina_notify_url_cpt', '', '', '', '', '', 4);
+
+-- GRIDS
+INSERT INTO `sys_objects_grid` (`object`, `source_type`, `source`, `table`, `field_id`, `field_order`, `field_active`, `paginate_url`, `paginate_per_page`, `paginate_simple`, `paginate_get_start`, `paginate_get_per_page`, `filter_fields`, `filter_fields_translatable`, `filter_mode`, `sorting_fields`, `sorting_fields_translatable`, `visible_for_levels`, `show_total_count`, `override_class_name`, `override_class_file`) VALUES
+('bx_payment_grid_providers', 'Sql', 'SELECT * FROM `bx_payment_providers` WHERE 1 AND (`for_single` <> ''0'' OR `for_recurring` <> ''0'')', 'bx_payment_providers', 'id', 'order', 'active', '', 100, NULL, 'start', '', 'name', 'caption,description', 'auto', '', '', 192, 0, 'BxPaymentGridProviders', 'modules/boonex/payment/classes/BxPaymentGridProviders.php'),
+
+('bx_payment_grid_carts', 'Array', '', '', 'vendor_id', '', '', '', 20, NULL, 'start', '', '', '', 'like', '', '', 2147483647, 1, 'BxPaymentGridCarts', 'modules/boonex/payment/classes/BxPaymentGridCarts.php'),
+('bx_payment_grid_cart', 'Array', '', '', 'descriptor', '', '', '', 20, NULL, 'start', '', 'title,description', '', 'like', '', '', 2147483647, 1, 'BxPaymentGridCart', 'modules/boonex/payment/classes/BxPaymentGridCart.php'),
+
+('bx_payment_grid_sbs_list_my', 'Sql', 'SELECT `ttp`.`id` AS `id`, `ttp`.`seller_id` AS `seller_id`, `ts`.`customer_id` AS `customer_id`, `ts`.`subscription_id` AS `subscription_id`, `ttp`.`provider` AS `provider`, `ttp`.`items` AS `items`, `ts`.`date_add` AS `date_add`, `ts`.`date_next` AS `date_next`, `ts`.`status` AS `status` FROM `bx_payment_subscriptions` AS `ts` LEFT JOIN `bx_payment_transactions_pending` AS `ttp` ON `ts`.`pending_id`=`ttp`.`id` WHERE 1 AND `ttp`.`type`=''recurring'' ', 'bx_payment_subscriptions', 'id', 'date_add', '', '', 100, NULL, 'start', '', 'ts`.`customer_id,ts`.`subscription_id,ts`.`date_add', '', 'auto', '', '', 2147483647, 0, 'BxPaymentGridSbsList', 'modules/boonex/payment/classes/BxPaymentGridSbsList.php'),
+('bx_payment_grid_sbs_list_all', 'Sql', 'SELECT `ttp`.`id` AS `id`, `ttp`.`client_id` AS `client_id`, `tac`.`email` AS `client_email`, `ttp`.`seller_id` AS `seller_id`, `ts`.`customer_id` AS `customer_id`, `ts`.`subscription_id` AS `subscription_id`, `ttp`.`provider` AS `provider`, `ttp`.`items` AS `items`, `ts`.`date_add` AS `date_add`, `ts`.`date_next` AS `date_next`, `ts`.`status` AS `status` FROM `bx_payment_subscriptions` AS `ts` LEFT JOIN `bx_payment_transactions_pending` AS `ttp` ON `ts`.`pending_id`=`ttp`.`id` LEFT JOIN `sys_profiles` AS `tpc` ON `ttp`.`client_id`=`tpc`.`id` LEFT JOIN `sys_accounts` AS `tac` ON `tpc`.`account_id`=`tac`.`id` WHERE 1 AND `ttp`.`type`=''recurring'' ', 'bx_payment_subscriptions', 'id', 'date_add', '', '', 100, NULL, 'start', '', 'tac`.`email,ts`.`customer_id,ts`.`subscription_id,ts`.`date_add', '', 'auto', '', '', 192, 0, 'BxPaymentGridSbsAdministration', 'modules/boonex/payment/classes/BxPaymentGridSbsAdministration.php'),
+('bx_payment_grid_sbs_history', 'Sql', 'SELECT `tt`.`id` AS `id`, `tt`.`seller_id` AS `seller_id`, `ttp`.`order` AS `transaction`, `tt`.`license` AS `license`, `tt`.`amount` AS `amount`, `tt`.`currency` AS `currency`, `tt`.`date` AS `date` FROM `bx_payment_transactions` AS `tt` LEFT JOIN `bx_payment_transactions_pending` AS `ttp` ON `tt`.`pending_id`=`ttp`.`id` WHERE 1 AND `ttp`.`type`=''recurring'' ', 'bx_payment_transactions', 'id', 'date', '', '', 100, NULL, 'start', '', 'ttp`.`order,tt`.`license,tt`.`amount,tt`.`date', '', 'auto', '', '', 2147483647, 0, 'BxPaymentGridSbsHistory', 'modules/boonex/payment/classes/BxPaymentGridSbsHistory.php'),
+
+('bx_payment_grid_orders_history', 'Sql', 'SELECT `tt`.`id` AS `id`, `tt`.`seller_id` AS `seller_id`, `tt`.`module_id` AS `module_id`, `tt`.`item_id` AS `item_id`, `ttp`.`order` AS `transaction`, `tt`.`license` AS `license`, `tt`.`amount` AS `amount`, `tt`.`currency` AS `currency`, `tt`.`date` AS `date` FROM `bx_payment_transactions` AS `tt` LEFT JOIN `bx_payment_transactions_pending` AS `ttp` ON `tt`.`pending_id`=`ttp`.`id` WHERE 1 AND `ttp`.`type`=''single'' ', 'bx_payment_transactions', 'id', 'date', '', '', 100, NULL, 'start', '', 'ttp`.`order,tt`.`license,tt`.`amount,tt`.`date', '', 'auto', '', '', 2147483647, 0, 'BxPaymentGridHistory', 'modules/boonex/payment/classes/BxPaymentGridHistory.php'),
+('bx_payment_grid_orders_processed', 'Sql', 'SELECT `tt`.`id` AS `id`, `tt`.`client_id` AS `client_id`, `tt`.`seller_id` AS `seller_id`, `tt`.`author_id` AS `author_id`, `tt`.`module_id` AS `module_id`, `tt`.`item_id` AS `item_id`, `tt`.`item_count` AS `item_count`, `ttp`.`order` AS `transaction`, `ttp`.`error_msg` AS `error_msg`, `ttp`.`provider` AS `provider`, `tt`.`license` AS `license`, `tt`.`amount` AS `amount`, `tt`.`currency` AS `currency`, `tt`.`date` AS `date` FROM `bx_payment_transactions` AS `tt` LEFT JOIN `bx_payment_transactions_pending` AS `ttp` ON `tt`.`pending_id`=`ttp`.`id` LEFT JOIN `sys_profiles` AS `tup` ON `tt`.`client_id`=`tup`.`id` LEFT JOIN `sys_accounts` AS `tua` ON `tup`.`account_id`=`tua`.`id` WHERE 1 ', 'bx_payment_transactions', 'id', 'date', '', '', 100, NULL, 'start', '', 'ttp`.`order,tt`.`license,tt`.`amount,tt`.`date,tua`.`name,tua`.`email', '', 'auto', '', '', 2147483647, 0, 'BxPaymentGridProcessed', 'modules/boonex/payment/classes/BxPaymentGridProcessed.php'),
+('bx_payment_grid_orders_pending', 'Sql', 'SELECT `tt`.`id` AS `id`, `tt`.`client_id` AS `client_id`, `tt`.`seller_id` AS `seller_id`, `tt`.`items` AS `items`, `tt`.`amount` AS `amount`, `tt`.`currency` AS `currency`, `tt`.`order` AS `transaction`, `tt`.`error_msg` AS `error_msg`, `tt`.`provider` AS `provider`, `tt`.`date` AS `date` FROM `bx_payment_transactions_pending` AS `tt` LEFT JOIN `sys_profiles` AS `tup` ON `tt`.`client_id`=`tup`.`id` LEFT JOIN `sys_accounts` AS `tua` ON `tup`.`account_id`=`tua`.`id` WHERE 1 AND (ISNULL(`tt`.`order`) OR (NOT ISNULL(`tt`.`order`) AND `tt`.`error_code`<>''0'')) ', 'bx_payment_transactions_pending', 'id', 'date', '', '', 100, NULL, 'start', '', 'tt`.`order,tt`.`amount,tt`.`date,tua`.`name,tua`.`email', '', 'auto', '', '', 2147483647, 0, 'BxPaymentGridPending', 'modules/boonex/payment/classes/BxPaymentGridPending.php'),
+
+('bx_payment_grid_commissions', 'Sql', 'SELECT * FROM `bx_payment_commissions` WHERE 1 ', 'bx_payment_commissions', 'id', 'order', 'active', '', 100, NULL, 'start', '', 'name', 'caption,description', 'auto', '', '', 192, 1, 'BxPaymentGridCommissions', 'modules/boonex/payment/classes/BxPaymentGridCommissions.php'),
+('bx_payment_grid_invoices', 'Sql', 'SELECT * FROM `bx_payment_invoices` WHERE 1 ', 'bx_payment_invoices', 'id', '', '', '', 100, NULL, 'start', '', '', '', 'auto', '', '', 2147483647, 1, 'BxPaymentGridInvoices', 'modules/boonex/payment/classes/BxPaymentGridInvoices.php');
+
+INSERT INTO `sys_grid_fields` (`object`, `name`, `title`, `width`, `translatable`, `chars_limit`, `params`, `order`) VALUES
+('bx_payment_grid_providers', 'order', '', '2%', 0, '0', '', 1),
+('bx_payment_grid_providers', 'switcher', '', '8%', 0, '0', '', 2),
+('bx_payment_grid_providers', 'caption', '_bx_payment_grid_column_title_pdrs_caption', '20%', 1, '16', '', 3),
+('bx_payment_grid_providers', 'description', '_bx_payment_grid_column_title_pdrs_description', '30%', 1, '32', '', 4),
+('bx_payment_grid_providers', 'for_visitor', '_bx_payment_grid_column_title_pdrs_for_visitor', '8%', 0, '8', '', 5),
+('bx_payment_grid_providers', 'for_single', '_bx_payment_grid_column_title_pdrs_for_single', '8%', 0, '8', '', 6),
+('bx_payment_grid_providers', 'for_recurring', '_bx_payment_grid_column_title_pdrs_for_recurring', '8%', 0, '8', '', 7),
+('bx_payment_grid_providers', 'single_seller', '_bx_payment_grid_column_title_pdrs_single_seller', '8%', 0, '8', '', 8),
+('bx_payment_grid_providers', 'time_tracker', '_bx_payment_grid_column_title_pdrs_time_tracker', '8%', 0, '8', '', 9),
+
+('bx_payment_grid_carts', 'checkbox', '', '2%', 0, '', '', 1),
+('bx_payment_grid_carts', 'vendor_id', '_bx_payment_grid_column_title_crts_vendor_id', '40%', 0, '36', '', 2),
+('bx_payment_grid_carts', 'items_count', '_bx_payment_grid_column_title_crts_items_count', '20%', 0, '16', '', 3),
+('bx_payment_grid_carts', 'items_price', '_bx_payment_grid_column_title_crts_items_price', '20%', 0, '16', '', 4),
+('bx_payment_grid_carts', 'actions', '', '18%', 0, '', '', 5),
+
+('bx_payment_grid_cart', 'checkbox', '', '2%', 0, '', '', 1),
+('bx_payment_grid_cart', 'title', '_bx_payment_grid_column_title_crt_title', '25%', 0, '24', '', 2),
+('bx_payment_grid_cart', 'description', '_bx_payment_grid_column_title_crt_description', '35%', 0, '48', '', 3),
+('bx_payment_grid_cart', 'quantity', '_bx_payment_grid_column_title_crt_quantity', '10%', 0, '16', '', 4),
+('bx_payment_grid_cart', 'price_single', '_bx_payment_grid_column_title_crt_price', '10%', 0, '16', '', 5),
+('bx_payment_grid_cart', 'actions', '', '18%', 0, '', '', 6),
+
+('bx_payment_grid_sbs_list_my', 'checkbox', '', '2%', 0, '0', '', 1),
+('bx_payment_grid_sbs_list_my', 'seller_id', '_bx_payment_grid_column_title_sbs_seller_id', '16%', 0, '0', '', 2),
+('bx_payment_grid_sbs_list_my', 'customer_id', '_bx_payment_grid_column_title_sbs_customer_id', '10%', 0, '8', '', 3),
+('bx_payment_grid_sbs_list_my', 'subscription_id', '_bx_payment_grid_column_title_sbs_subscription_id', '10%', 0, '0', '', 4),
+('bx_payment_grid_sbs_list_my', 'provider', '_bx_payment_grid_column_title_sbs_provider', '10%', 0, '16', '', 5),
+('bx_payment_grid_sbs_list_my', 'date_add', '_bx_payment_grid_column_title_sbs_date_add', '14%', 0, '10', '', 6),
+('bx_payment_grid_sbs_list_my', 'date_next', '_bx_payment_grid_column_title_sbs_date_next', '14%', 0, '10', '', 7),
+('bx_payment_grid_sbs_list_my', 'status', '_bx_payment_grid_column_title_sbs_status', '6%', 0, '8', '', 8),
+('bx_payment_grid_sbs_list_my', 'actions', '', '18%', 0, '0', '', 9),
+
+('bx_payment_grid_sbs_list_all', 'seller_id', '_bx_payment_grid_column_title_sbs_seller_id', '12%', 0, '0', '', 1),
+('bx_payment_grid_sbs_list_all', 'client_id', '_bx_payment_grid_column_title_sbs_client_id', '12%', 0, '0', '', 2),
+('bx_payment_grid_sbs_list_all', 'client_email', '_bx_payment_grid_column_title_sbs_client_email', '15%', 0, '24', '', 3),
+('bx_payment_grid_sbs_list_all', 'customer_id', '_bx_payment_grid_column_title_sbs_customer_id', '5%', 0, '8', '', 4),
+('bx_payment_grid_sbs_list_all', 'subscription_id', '_bx_payment_grid_column_title_sbs_subscription_id', '5%', 0, '0', '', 5),
+('bx_payment_grid_sbs_list_all', 'provider', '_bx_payment_grid_column_title_sbs_provider', '5%', 0, '16', '', 6),
+('bx_payment_grid_sbs_list_all', 'date_add', '_bx_payment_grid_column_title_sbs_date_add', '12%', 0, '10', '', 7),
+('bx_payment_grid_sbs_list_all', 'date_next', '_bx_payment_grid_column_title_sbs_date_next', '12%', 0, '10', '', 8),
+('bx_payment_grid_sbs_list_all', 'status', '_bx_payment_grid_column_title_sbs_status', '6%', 0, '8', '', 9),
+('bx_payment_grid_sbs_list_all', 'actions', '', '16%', 0, '0', '', 10),
+
+('bx_payment_grid_sbs_history', 'seller_id', '_bx_payment_grid_column_title_sbs_seller_id', '24%', 0, '0', '', 1),
+('bx_payment_grid_sbs_history', 'transaction', '_bx_payment_grid_column_title_sbs_transaction', '22%', 0, '18', '', 2),
+('bx_payment_grid_sbs_history', 'license', '_bx_payment_grid_column_title_sbs_license', '22%', 0, '18', '', 3),
+('bx_payment_grid_sbs_history', 'amount', '_bx_payment_grid_column_title_sbs_amount', '10%', 1, '10', '', 4),
+('bx_payment_grid_sbs_history', 'date', '_bx_payment_grid_column_title_sbs_date', '10%', 0, '10', '', 5),
+('bx_payment_grid_sbs_history', 'actions', '', '12%', 0, '', '', 6),
+
+('bx_payment_grid_orders_history', 'seller_id', '_bx_payment_grid_column_title_ods_seller_id', '24%', 0, '0', '', 1),
+('bx_payment_grid_orders_history', 'transaction', '_bx_payment_grid_column_title_ods_transaction', '22%', 0, '18', '', 2),
+('bx_payment_grid_orders_history', 'item', '_bx_payment_grid_column_title_ods_item', '22%', 0, '18', '', 3),
+('bx_payment_grid_orders_history', 'amount', '_bx_payment_grid_column_title_ods_amount', '10%', 1, '10', '', 4),
+('bx_payment_grid_orders_history', 'date', '_bx_payment_grid_column_title_ods_date', '10%', 0, '10', '', 5),
+('bx_payment_grid_orders_history', 'actions', '', '12%', 0, '', '', 6),
+
+('bx_payment_grid_orders_processed', 'checkbox', '', '2%', 0, '0', '', 1),
+('bx_payment_grid_orders_processed', 'client_id', '_bx_payment_grid_column_title_ods_client_id', '16%', 0, '0', '', 2),
+('bx_payment_grid_orders_processed', 'author_id', '_bx_payment_grid_column_title_ods_author_id', '16%', 0, '0', '', 3),
+('bx_payment_grid_orders_processed', 'transaction', '_bx_payment_grid_column_title_ods_transaction', '10%', 0, '8', '', 4),
+('bx_payment_grid_orders_processed', 'item', '_bx_payment_grid_column_title_ods_item', '20%', 0, '', '', 5),
+('bx_payment_grid_orders_processed', 'amount', '_bx_payment_grid_column_title_ods_amount', '10%', 1, '10', '', 6),
+('bx_payment_grid_orders_processed', 'date', '_bx_payment_grid_column_title_ods_date', '10%', 0, '10', '', 7),
+('bx_payment_grid_orders_processed', 'actions', '', '16%', 0, '0', '', 8),
+
+('bx_payment_grid_orders_pending', 'checkbox', '', '2%', 0, '', '', 1),
+('bx_payment_grid_orders_pending', 'client_id', '_bx_payment_grid_column_title_ods_client_id', '25%', 0, '0', '', 2),
+('bx_payment_grid_orders_pending', 'transaction', '_bx_payment_grid_column_title_ods_transaction', '25%', 0, '25', '', 3),
+('bx_payment_grid_orders_pending', 'amount', '_bx_payment_grid_column_title_ods_amount', '14%', 1, '14', '', 4),
+('bx_payment_grid_orders_pending', 'date', '_bx_payment_grid_column_title_ods_date', '14%', 0, '14', '', 5),
+('bx_payment_grid_orders_pending', 'actions', '', '20%', 0, '', '', 6),
+
+('bx_payment_grid_commissions', 'order', '', '2%', 0, '0', '', 1),
+('bx_payment_grid_commissions', 'switcher', '', '8%', 0, '0', '', 2),
+('bx_payment_grid_commissions', 'caption', '_bx_payment_grid_column_title_cms_caption', '15%', 1, '16', '', 3),
+('bx_payment_grid_commissions', 'description', '_bx_payment_grid_column_title_cms_description', '20%', 1, '16', '', 4),
+('bx_payment_grid_commissions', 'acl_id', '_bx_payment_grid_column_title_cms_acl_id', '15%', 0, '16', '', 5),
+('bx_payment_grid_commissions', 'percentage', '_bx_payment_grid_column_title_cms_percentage', '10%', 0, '0', '', 6),
+('bx_payment_grid_commissions', 'installment', '_bx_payment_grid_column_title_cms_installment', '10%', 0, '0', '', 7),
+('bx_payment_grid_commissions', 'actions', '', '20%', 0, '0', '', 8),
+
+('bx_payment_grid_invoices', 'checkbox', '', '2%', 0, '0', '', 1),
+('bx_payment_grid_invoices', 'commissionaire_id', '_bx_payment_grid_column_title_inv_commissionaire_id', '10%', 1, '0', '', 2),
+('bx_payment_grid_invoices', 'committent_id', '_bx_payment_grid_column_title_inv_committent_id', '10%', 1, '0', '', 3),
+('bx_payment_grid_invoices', 'name', '_bx_payment_grid_column_title_inv_name', '8%', 1, '0', '', 4),
+('bx_payment_grid_invoices', 'period_start', '_bx_payment_grid_column_title_inv_period_start', '10%', 0, '0', '', 5),
+('bx_payment_grid_invoices', 'period_end', '_bx_payment_grid_column_title_inv_period_end', '10%', 0, '0', '', 6),
+('bx_payment_grid_invoices', 'amount', '_bx_payment_grid_column_title_inv_amount', '6%', 0, '0', '', 7),
+('bx_payment_grid_invoices', 'date_issue', '_bx_payment_grid_column_title_inv_date_issue', '10%', 0, '0', '', 8),
+('bx_payment_grid_invoices', 'date_due', '_bx_payment_grid_column_title_inv_date_due', '10%', 0, '0', '', 9),
+('bx_payment_grid_invoices', 'status', '_bx_payment_grid_column_title_inv_status', '6%', 0, '8', '', 10),
+('bx_payment_grid_invoices', 'actions', '', '18%', 0, '0', '', 11);
+
+INSERT INTO `sys_grid_actions` (`object`, `type`, `name`, `title`, `icon`, `icon_only`, `confirm`, `order`) VALUES
+('bx_payment_grid_carts', 'bulk', 'delete', '_bx_payment_grid_action_title_crts_delete', '', 0, 1, 1),
+('bx_payment_grid_carts', 'single', 'continue', '_bx_payment_grid_action_title_crts_continue', 'far credit-card', 1, 0, 1),
+('bx_payment_grid_carts', 'single', 'delete', '_bx_payment_grid_action_title_crts_delete', 'remove', 1, 1, 2),
+
+('bx_payment_grid_cart', 'bulk', 'checkout', '_bx_payment_grid_action_title_crt_checkout', '', 0, 0, 1),
+('bx_payment_grid_cart', 'single', 'delete', '_bx_payment_grid_action_title_crt_delete', 'remove', 1, 1, 1),
+
+('bx_payment_grid_sbs_list_my', 'single', 'view_order', '_bx_payment_grid_action_title_sbs_view_order', 'ellipsis-h', 1, 0, 1),
+('bx_payment_grid_sbs_list_my', 'single', 'actions', '_bx_payment_grid_action_title_sbs_actions', 'cog', 1, 0, 2),
+
+('bx_payment_grid_sbs_list_all', 'single', 'view_order', '_bx_payment_grid_action_title_sbs_view_order', 'ellipsis-h', 1, 0, 1),
+('bx_payment_grid_sbs_list_all', 'single', 'cancel', '_bx_payment_grid_action_title_sbs_cancel', 'ban', 1, 1, 2),
+('bx_payment_grid_sbs_list_all', 'single', 'delete', '_bx_payment_grid_action_title_sbs_delete', 'times', 1, 1, 3),
+
+('bx_payment_grid_sbs_history', 'single', 'view_order', '_bx_payment_grid_action_title_sbs_view_order', 'ellipsis-h', 1, 0, 1),
+
+('bx_payment_grid_orders_history', 'single', 'view_order', '_bx_payment_grid_action_title_ods_view_order', 'ellipsis-h', 1, 0, 1),
+
+('bx_payment_grid_orders_processed', 'independent', 'add', '_bx_payment_grid_action_title_ods_add', '', 0, 0, 1),
+('bx_payment_grid_orders_processed', 'bulk', 'cancel', '_bx_payment_grid_action_title_ods_cancel', '', 0, 1, 1),
+('bx_payment_grid_orders_processed', 'single', 'view_order', '_bx_payment_grid_action_title_ods_view_order', 'ellipsis-h', 1, 0, 1),
+('bx_payment_grid_orders_processed', 'single', 'cancel', '_bx_payment_grid_action_title_ods_cancel', 'times', 1, 1, 2),
+
+('bx_payment_grid_orders_pending', 'bulk', 'cancel', '_bx_payment_grid_action_title_ods_cancel', '', 0, 1, 1),
+('bx_payment_grid_orders_pending', 'single', 'view_order', '_bx_payment_grid_action_title_ods_view_order', 'ellipsis-h', 1, 0, 1),
+('bx_payment_grid_orders_pending', 'single', 'process', '_bx_payment_grid_action_title_ods_process', 'sync', 1, 0, 2),
+('bx_payment_grid_orders_pending', 'single', 'cancel', '_bx_payment_grid_action_title_ods_cancel', 'times', 1, 1, 3),
+
+('bx_payment_grid_commissions', 'independent', 'add', '_bx_payment_grid_action_title_cms_add', '', 0, 0, 1),
+('bx_payment_grid_commissions', 'bulk', 'delete', '_bx_payment_grid_action_title_cms_delete', '', 0, 1, 1),
+('bx_payment_grid_commissions', 'single', 'edit', '_bx_payment_grid_action_title_cms_edit', 'pencil-alt', 1, 0, 1),
+('bx_payment_grid_commissions', 'single', 'delete', '_bx_payment_grid_action_title_cms_delete', 'remove', 1, 1, 2),
+
+('bx_payment_grid_invoices', 'bulk', 'delete', '_bx_payment_grid_action_title_inv_delete', '', 0, 1, 1),
+('bx_payment_grid_invoices', 'single', 'pay', '_bx_payment_grid_action_title_inv_pay', 'credit-card', 1, 0, 1),
+('bx_payment_grid_invoices', 'single', 'edit', '_bx_payment_grid_action_title_inv_edit', 'pencil-alt', 1, 0, 2),
+('bx_payment_grid_invoices', 'single', 'delete', '_bx_payment_grid_action_title_inv_delete', 'remove', 1, 1, 3);
+
+
+-- FORMS
+INSERT INTO `sys_objects_form` (`object`, `module`, `title`, `action`, `form_attrs`, `submit_name`, `table`, `key`, `uri`, `uri_title`, `params`, `deletable`, `active`, `override_class_name`, `override_class_file`) VALUES
+('bx_payment_form_details', @sName, '_bx_payment_form_details_form', '', '', 'submit', '', 'id', '', '', 'a:1:{s:14:"checker_helper";s:33:"BxPaymentDetailsFormCheckerHelper";}', 0, 1, 'BxPaymentFormDetails', 'modules/boonex/payment/classes/BxPaymentFormDetails.php'),
+
+('bx_payment_form_pendings', @sName, '_bx_payment_form_pendings_form', '', '', 'do_submit', 'bx_payment_transactions_pending', 'id', '', '', '', 0, 1, 'BxPaymentFormView', 'modules/boonex/payment/classes/BxPaymentFormView.php'),
+('bx_payment_form_processed', @sName, '_bx_payment_form_processed_form', '', '', 'do_submit', 'bx_payment_transactions', 'id', '', '', '', 0, 1, 'BxPaymentFormView', 'modules/boonex/payment/classes/BxPaymentFormView.php'),
+
+('bx_payment_form_commissions', @sName, '_bx_payment_form_commissions_form', '', '', 'do_submit', 'bx_payment_commissions', 'id', '', '', '', 0, 1, 'BxPaymentFormCommissions', 'modules/boonex/payment/classes/BxPaymentFormCommissions.php'),
+('bx_payment_form_invoices', @sName, '_bx_payment_form_invoices_form', '', '', 'do_submit', 'bx_payment_invoices', 'id', '', '', '', 0, 1, 'BxPaymentFormInvoices', 'modules/boonex/payment/classes/BxPaymentFormInvoices.php'),
+
+-- FORMS: Recurly
+('bx_payment_form_rcrl_card', @sName, '_bx_payment_form_rcrl_card', '', '', 'do_submit', '', '', '', '', '', 0, 1, '', ''),
+
+-- FORMS: Stripe
+('bx_payment_form_strp_details', @sName, '_bx_payment_form_strp_details', '', '', 'do_submit', '', '', '', '', '', 0, 1, '', ''),
+('bx_payment_form_strp_card', @sName, '_bx_payment_form_strp_card', '', '', 'do_submit', '', '', '', '', '', 0, 1, '', '');
+
+
+INSERT INTO `sys_form_displays` (`display_name`, `module`, `object`, `title`, `view_mode`) VALUES
+('bx_payment_form_details_edit', @sName, 'bx_payment_form_details', '_bx_payment_form_details_display_edit', 0),
+
+('bx_payment_form_pendings_process', @sName, 'bx_payment_form_pendings', '_bx_payment_form_pendings_display_process', 0),
+('bx_payment_form_processed_add', @sName, 'bx_payment_form_processed', '_bx_payment_form_processed_display_add', 0),
+
+('bx_payment_form_commissions_add', @sName, 'bx_payment_form_commissions', '_bx_payment_form_commissions_display_add', 0),
+('bx_payment_form_commissions_edit', @sName, 'bx_payment_form_commissions', '_bx_payment_form_commissions_display_edit', 0),
+
+('bx_payment_form_invoices_edit', @sName, 'bx_payment_form_invoices', '_bx_payment_form_invoices_display_edit', 0),
+
+-- FORMS: Recurly
+('bx_payment_form_rcrl_card_add', @sName, 'bx_payment_form_rcrl_card', '_bx_payment_form_rcrl_card_display_add', 0),
+
+-- FORMS: Stripe
+('bx_payment_form_strp_details_edit', @sName, 'bx_payment_form_strp_details', '_bx_payment_form_strp_details_display_edit', 0),
+('bx_payment_form_strp_card_add', @sName, 'bx_payment_form_strp_card', '_bx_payment_form_strp_card_display_add', 0);
+
+INSERT INTO `sys_form_inputs` (`object`, `module`, `name`, `value`, `values`, `checked`, `type`, `caption_system`, `caption`, `info`, `required`, `collapsed`, `html`, `attrs`, `attrs_tr`, `attrs_wrapper`, `checker_func`, `checker_params`, `checker_error`, `db_pass`, `db_params`, `editable`, `deletable`) VALUES
+('bx_payment_form_pendings', @sName, 'id', '0', '', 0, 'hidden', '_bx_payment_form_pendings_input_id_sys', '', '', 0, 0, 0, '', '', '', '', '', '', 'Int', '', 0, 0),
+('bx_payment_form_pendings', @sName, 'seller_id', '0', '', 0, 'hidden', '_bx_payment_form_pendings_input_seller_id_sys', '', '', 0, 0, 0, '', '', '', '', '', '', 'Int', '', 0, 0),
+('bx_payment_form_pendings', @sName, 'order', '', '', 0, 'text', '_bx_payment_form_pendings_input_order_sys', '_bx_payment_form_pendings_input_order', '', 1, 0, 0, '', '', '', 'Avail', '', '_bx_payment_form_pendings_input_order_err', 'Xss', '', 0, 0),
+('bx_payment_form_pendings', @sName, 'controls', '', 'do_submit,do_cancel', 0, 'input_set', '', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 0, 0),
+('bx_payment_form_pendings', @sName, 'do_submit', '_bx_payment_form_pendings_input_process', '', 0, 'submit', '_bx_payment_form_pendings_input_process_sys', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 0, 0),
+('bx_payment_form_pendings', @sName, 'do_cancel', '_bx_payment_form_pendings_input_cancel', '', 0, 'button', '_bx_payment_form_pendings_input_cancel_sys', '', '', 0, 0, 0, 'a:2:{s:7:"onclick";s:45:"$(''.bx-popup-applied:visible'').dolPopupHide()";s:5:"class";s:22:"bx-def-margin-sec-left";}', '', '', '', '', '', '', '', 0, 0),
+
+('bx_payment_form_processed', @sName, 'seller_id', '0', '', 0, 'hidden', '_bx_payment_form_processed_input_seller_id_sys', '', '', 0, 0, 0, '', '', '', '', '', '', 'Int', '', 0, 0),
+('bx_payment_form_processed', @sName, 'client_id', '0', '', 0, 'hidden', '_bx_payment_form_processed_input_client_id_sys', '', '', 0, 0, 0, '', '', '', '', '', '', 'Int', '', 0, 0),
+('bx_payment_form_processed', @sName, 'client', '0', '', 0, 'custom', '_bx_payment_form_processed_input_client_sys', '_bx_payment_form_processed_input_client', '', 0, 0, 0, '', '', '', 'Avail', '', '_bx_payment_form_processed_input_client_err', 'Xss', '', 0, 0),
+('bx_payment_form_processed', @sName, 'order', '0', '', 0, 'text', '_bx_payment_form_processed_input_order_sys', '_bx_payment_form_processed_input_order', '', 0, 0, 0, '', '', '', 'Avail', '', '_bx_payment_form_processed_input_order_err', 'Xss', '', 0, 0),
+('bx_payment_form_processed', @sName, 'module_id', '0', '', 0, 'select', '_bx_payment_form_processed_input_module_id_sys', '_bx_payment_form_processed_input_module_id', '', 0, 0, 0, '', '', '', 'Avail', '', '_bx_payment_form_processed_input_module_id_err', 'Int', '', 0, 0),
+('bx_payment_form_processed', @sName, 'items', '0', '', 0, 'custom', '_bx_payment_form_processed_input_items_sys', '_bx_payment_form_processed_input_items', '', 0, 0, 0, '', '', '', '', '', '_bx_payment_form_processed_input_items_err', '', '', 0, 0),
+('bx_payment_form_processed', @sName, 'controls', '', 'do_submit,do_cancel', 0, 'input_set', '', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 0, 0),
+('bx_payment_form_processed', @sName, 'do_submit', '_bx_payment_form_processed_input_add', '', 0, 'submit', '_bx_payment_form_processed_input_add_sys', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 0, 0),
+('bx_payment_form_processed', @sName, 'do_cancel', '_bx_payment_form_processed_input_cancel', '', 0, 'button', '_bx_payment_form_processed_input_cancel_sys', '', '', 0, 0, 0, 'a:2:{s:7:"onclick";s:45:"$(''.bx-popup-applied:visible'').dolPopupHide()";s:5:"class";s:22:"bx-def-margin-sec-left";}', '', '', '', '', '', '', '', 0, 0),
+
+('bx_payment_form_commissions', @sName, 'caption', '0', '', 0, 'text_translatable', '_bx_payment_form_commissions_input_caption_sys', '_bx_payment_form_commissions_input_caption', '', 1, 0, 0, '', '', '', 'AvailTranslatable', 'a:1:{i:0;s:7:"caption";}', '_bx_payment_form_commissions_input_caption_err', 'Xss', '', 0, 0),
+('bx_payment_form_commissions', @sName, 'description', '0', '', 0, 'textarea_translatable', '_bx_payment_form_commissions_input_description_sys', '_bx_payment_form_commissions_input_description', '', 0, 0, 0, '', '', '', '', '', '', 'Xss', '', 0, 0),
+('bx_payment_form_commissions', @sName, 'acl_id', '0', '', 0, 'select', '_bx_payment_form_commissions_input_acl_id_sys', '_bx_payment_form_commissions_input_acl_id', '', 0, 0, 0, '', '', '', '', '', '', 'Int', '', 0, 0),
+('bx_payment_form_commissions', @sName, 'percentage', '0', '', 0, 'text', '_bx_payment_form_commissions_input_percentage_sys', '_bx_payment_form_commissions_input_percentage', '', 0, 0, 0, '', '', '', '', '', '', 'Float', '', 0, 0),
+('bx_payment_form_commissions', @sName, 'installment', '0', '', 0, 'text', '_bx_payment_form_commissions_input_installment_sys', '_bx_payment_form_commissions_input_installment', '', 0, 0, 0, '', '', '', '', '', '', 'Float', '', 0, 0),
+('bx_payment_form_commissions', @sName, 'controls', '', 'do_submit,do_cancel', 0, 'input_set', '', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 0, 0),
+('bx_payment_form_commissions', @sName, 'do_submit', '_bx_payment_form_commissions_input_submit', '', 0, 'submit', '_bx_payment_form_commissions_input_submit_sys', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 0, 0),
+('bx_payment_form_commissions', @sName, 'do_cancel', '_bx_payment_form_commissions_input_cancel', '', 0, 'button', '_bx_payment_form_commissions_input_cancel_sys', '', '', 0, 0, 0, 'a:2:{s:7:"onclick";s:45:"$(''.bx-popup-applied:visible'').dolPopupHide()";s:5:"class";s:22:"bx-def-margin-sec-left";}', '', '', '', '', '', '', '', 0, 0),
+
+('bx_payment_form_invoices', @sName, 'amount', '0', '', 0, 'text', '_bx_payment_form_invoices_input_amount_sys', '_bx_payment_form_invoices_input_amount', '', 1, 0, 0, '', '', '', 'Avail', '', '_bx_payment_form_invoices_input_amount_err', 'Float', '', 0, 0),
+('bx_payment_form_invoices', @sName, 'date_due', '', '', 0, 'datepicker', '_bx_payment_form_invoices_input_date_due_sys', '_bx_payment_form_invoices_input_date_due', '', 1, 0, 0, '', '', '', 'Avail', '', '_bx_payment_form_invoices_input_date_due_err', 'DateUtc', '', 0, 0),
+('bx_payment_form_invoices', @sName, 'status', '', '', 0, 'select', '_bx_payment_form_invoices_input_status_sys', '_bx_payment_form_invoices_input_status', '', 0, 0, 0, '', '', '', '', '', '', 'Xss', '', 0, 0),
+('bx_payment_form_invoices', @sName, 'controls', '', 'do_submit,do_cancel', 0, 'input_set', '', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 0, 0),
+('bx_payment_form_invoices', @sName, 'do_submit', '_bx_payment_form_invoices_input_submit', '', 0, 'submit', '_bx_payment_form_invoices_input_submit_sys', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 0, 0),
+('bx_payment_form_invoices', @sName, 'do_cancel', '_bx_payment_form_invoices_input_cancel', '', 0, 'button', '_bx_payment_form_invoices_input_cancel_sys', '', '', 0, 0, 0, 'a:2:{s:7:"onclick";s:45:"$(''.bx-popup-applied:visible'').dolPopupHide()";s:5:"class";s:22:"bx-def-margin-sec-left";}', '', '', '', '', '', '', '', 0, 0),
+
+-- FORMS: Recurly
+('bx_payment_form_rcrl_card', @sName, 'pending_id', '0', '', 0, 'hidden', '_bx_payment_form_rcrl_card_input_pending_id_sys', '', '', 0, 0, 0, '', '', '', '', '', '', 'Int', '', 0, 0),
+('bx_payment_form_rcrl_card', @sName, 'item', '', '', 0, 'hidden', '_bx_payment_form_rcrl_card_input_item_sys', '', '', 0, 0, 0, '', '', '', '', '', '', 'Xss', '', 0, 0),
+('bx_payment_form_rcrl_card', @sName, 'token', '', '', 0, 'hidden', '_bx_payment_form_rcrl_card_input_token_sys', '', '', 0, 0, 0, 'a:1:{s:12:"data-recurly";s:5:"token";}', '', '', '', '', '', 'Xss', '', 0, 0),
+('bx_payment_form_rcrl_card', @sName, 'first_name', '', '', 0, 'text', '_bx_payment_form_rcrl_card_input_first_name_sys', '_bx_payment_form_rcrl_card_input_first_name', '', 1, 0, 0, 'a:1:{s:12:"data-recurly";s:10:"first_name";}', '', '', 'Avail', '', '_bx_payment_form_rcrl_card_input_first_name_err', 'Xss', '', 0, 0),
+('bx_payment_form_rcrl_card', @sName, 'last_name', '', '', 0, 'text', '_bx_payment_form_rcrl_card_input_last_name_sys', '_bx_payment_form_rcrl_card_input_last_name', '', 1, 0, 0, 'a:1:{s:12:"data-recurly";s:9:"last_name";}', '', '', 'Avail', '', '_bx_payment_form_rcrl_card_input_last_name_err', 'Xss', '', 0, 0),
+('bx_payment_form_rcrl_card', @sName, 'email', '', '', 0, 'text', '_bx_payment_form_rcrl_card_input_email_sys', '_bx_payment_form_rcrl_card_input_email', '', 1, 0, 0, '', '', '', 'Email', '', '', 'Xss', '', 0, 0),
+('bx_payment_form_rcrl_card', @sName, 'card_number', '', '', 0, 'custom', '_bx_payment_form_rcrl_card_input_card_number_sys', '_bx_payment_form_rcrl_card_input_card_number', '_bx_payment_form_rcrl_card_input_card_number_inf', 1, 0, 0, 'a:1:{s:12:"data-recurly";s:6:"number";}', '', '', '', '', '', 'Xss', '', 0, 0),
+('bx_payment_form_rcrl_card', @sName, 'card_expire', '', '', 0, 'custom', '_bx_payment_form_rcrl_card_input_card_expire_sys', '_bx_payment_form_rcrl_card_input_card_expire', '_bx_payment_form_rcrl_card_input_card_expire_inf', 1, 0, 0, '', '', '', '', '', '', 'Xss', '', 0, 0),
+('bx_payment_form_rcrl_card', @sName, 'card_cvv', '', '', 0, 'custom', '_bx_payment_form_rcrl_card_input_card_cvv_sys', '_bx_payment_form_rcrl_card_input_card_cvv', '_bx_payment_form_rcrl_card_input_card_cvv_inf', 1, 0, 0, 'a:1:{s:12:"data-recurly";s:3:"cvv";}', '', '', '', '', '', 'Xss', '', 0, 0),
+('bx_payment_form_rcrl_card', @sName, 'controls', '', 'do_submit,do_cancel', 0, 'input_set', '', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 0, 0),
+('bx_payment_form_rcrl_card', @sName, 'do_submit', '_bx_payment_form_rcrl_card_input_submit', '', 0, 'submit', '_bx_payment_form_rcrl_card_input_submit_sys', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 0, 0),
+('bx_payment_form_rcrl_card', @sName, 'do_cancel', '_bx_payment_form_rcrl_card_input_cancel', '', 0, 'button', '_bx_payment_form_rcrl_card_input_cancel_sys', '', '', 0, 0, 0, 'a:2:{s:7:"onclick";s:45:"$(''.bx-popup-applied:visible'').dolPopupHide()";s:5:"class";s:22:"bx-def-margin-sec-left";}', '', '', '', '', '', '', '', 0, 0),
+
+-- FORMS: Stripe
+('bx_payment_form_strp_details', @sName, 'item_id', '', '', 0, 'select', '_bx_payment_form_strp_details_input_item_id_sys', '_bx_payment_form_strp_details_input_item_id', '', 1, 0, 0, '', '', '', 'Avail', '', '_bx_payment_form_strp_details_input_item_id_err', 'Int', '', 0, 0),
+('bx_payment_form_strp_details', @sName, 'controls', '', 'do_submit,do_cancel', 0, 'input_set', '', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 0, 0),
+('bx_payment_form_strp_details', @sName, 'do_submit', '_bx_payment_form_strp_details_input_submit', '', 0, 'submit', '_bx_payment_form_strp_details_input_submit_sys', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 0, 0),
+('bx_payment_form_strp_details', @sName, 'do_cancel', '_bx_payment_form_strp_details_input_cancel', '', 0, 'button', '_bx_payment_form_strp_details_input_cancel_sys', '', '', 0, 0, 0, 'a:2:{s:7:"onclick";s:45:"$(''.bx-popup-applied:visible'').dolPopupHide()";s:5:"class";s:22:"bx-def-margin-sec-left";}', '', '', '', '', '', '', '', 0, 0),
+
+('bx_payment_form_strp_card', @sName, 'card_number', '', '', 0, 'text', '_bx_payment_form_strp_card_input_card_number_sys', '_bx_payment_form_strp_card_input_card_number', '_bx_payment_form_strp_card_input_card_number_inf', 1, 0, 0, '', '', '', 'Avail', '', '_bx_payment_form_strp_card_input_card_number_err', 'Xss', '', 0, 0),
+('bx_payment_form_strp_card', @sName, 'card_expire', '', '', 0, 'text', '_bx_payment_form_strp_card_input_card_expire_sys', '_bx_payment_form_strp_card_input_card_expire', '_bx_payment_form_strp_card_input_card_expire_inf', 1, 0, 0, '', '', '', 'Avail', '', '_bx_payment_form_strp_card_input_card_expire_err', 'Xss', '', 0, 0),
+('bx_payment_form_strp_card', @sName, 'card_cvv', '', '', 0, 'text', '_bx_payment_form_strp_card_input_card_cvv_sys', '_bx_payment_form_strp_card_input_card_cvv', '_bx_payment_form_strp_card_input_card_cvv_inf', 1, 0, 0, '', '', '', 'Avail', '', '_bx_payment_form_strp_card_input_card_cvv_err', 'Xss', '', 0, 0),
+('bx_payment_form_strp_card', @sName, 'controls', '', 'do_submit,do_cancel', 0, 'input_set', '', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 0, 0),
+('bx_payment_form_strp_card', @sName, 'do_submit', '_bx_payment_form_strp_card_input_submit', '', 0, 'submit', '_bx_payment_form_strp_card_input_submit_sys', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 0, 0),
+('bx_payment_form_strp_card', @sName, 'do_cancel', '_bx_payment_form_strp_card_input_cancel', '', 0, 'button', '_bx_payment_form_strp_card_input_cancel_sys', '', '', 0, 0, 0, 'a:2:{s:7:"onclick";s:45:"$(''.bx-popup-applied:visible'').dolPopupHide()";s:5:"class";s:22:"bx-def-margin-sec-left";}', '', '', '', '', '', '', '', 0, 0);
+
+
+INSERT INTO `sys_form_display_inputs` (`display_name`, `input_name`, `visible_for_levels`, `active`, `order`) VALUES
+('bx_payment_form_pendings_process', 'id', 2147483647, 1, 1),
+('bx_payment_form_pendings_process', 'seller_id', 2147483647, 1, 2),
+('bx_payment_form_pendings_process', 'order', 2147483647, 1, 3),
+('bx_payment_form_pendings_process', 'controls', 2147483647, 1, 4),
+('bx_payment_form_pendings_process', 'do_submit', 2147483647, 1, 5),
+('bx_payment_form_pendings_process', 'do_cancel', 2147483647, 1, 6),
+
+('bx_payment_form_processed_add', 'seller_id', 2147483647, 1, 2),
+('bx_payment_form_processed_add', 'client_id', 2147483647, 1, 3),
+('bx_payment_form_processed_add', 'client', 2147483647, 1, 4),
+('bx_payment_form_processed_add', 'order', 2147483647, 1, 5),
+('bx_payment_form_processed_add', 'module_id', 2147483647, 1, 6),
+('bx_payment_form_processed_add', 'items', 2147483647, 1, 7),
+('bx_payment_form_processed_add', 'controls', 2147483647, 1, 8),
+('bx_payment_form_processed_add', 'do_submit', 2147483647, 1, 9),
+('bx_payment_form_processed_add', 'do_cancel', 2147483647, 1, 10),
+
+('bx_payment_form_commissions_add', 'caption', 2147483647, 1, 1),
+('bx_payment_form_commissions_add', 'description', 2147483647, 1, 2),
+('bx_payment_form_commissions_add', 'acl_id', 2147483647, 1, 3),
+('bx_payment_form_commissions_add', 'percentage', 2147483647, 1, 4),
+('bx_payment_form_commissions_add', 'installment', 2147483647, 1, 5),
+('bx_payment_form_commissions_add', 'controls', 2147483647, 1, 6),
+('bx_payment_form_commissions_add', 'do_submit', 2147483647, 1, 7),
+('bx_payment_form_commissions_add', 'do_cancel', 2147483647, 1, 8),
+
+('bx_payment_form_commissions_edit', 'caption', 2147483647, 1, 1),
+('bx_payment_form_commissions_edit', 'description', 2147483647, 1, 2),
+('bx_payment_form_commissions_edit', 'acl_id', 2147483647, 1, 3),
+('bx_payment_form_commissions_edit', 'percentage', 2147483647, 1, 4),
+('bx_payment_form_commissions_edit', 'installment', 2147483647, 1, 5),
+('bx_payment_form_commissions_edit', 'controls', 2147483647, 1, 6),
+('bx_payment_form_commissions_edit', 'do_submit', 2147483647, 1, 7),
+('bx_payment_form_commissions_edit', 'do_cancel', 2147483647, 1, 8),
+
+('bx_payment_form_invoices_edit', 'amount', 2147483647, 1, 1),
+('bx_payment_form_invoices_edit', 'date_due', 2147483647, 1, 2),
+('bx_payment_form_invoices_edit', 'status', 2147483647, 1, 3),
+('bx_payment_form_invoices_edit', 'controls', 2147483647, 1, 4),
+('bx_payment_form_invoices_edit', 'do_submit', 2147483647, 1, 5),
+('bx_payment_form_invoices_edit', 'do_cancel', 2147483647, 1, 6),
+
+-- FORMS: Recurly
+('bx_payment_form_rcrl_card_add', 'pending_id', 2147483647, 1, 1),
+('bx_payment_form_rcrl_card_add', 'item', 2147483647, 1, 2),
+('bx_payment_form_rcrl_card_add', 'token', 2147483647, 1, 3),
+('bx_payment_form_rcrl_card_add', 'first_name', 2147483647, 1, 4),
+('bx_payment_form_rcrl_card_add', 'last_name', 2147483647, 1, 5),
+('bx_payment_form_rcrl_card_add', 'email', 2147483647, 1, 6),
+('bx_payment_form_rcrl_card_add', 'card_number', 2147483647, 1, 7),
+('bx_payment_form_rcrl_card_add', 'card_expire', 2147483647, 1, 8),
+('bx_payment_form_rcrl_card_add', 'card_cvv', 2147483647, 1, 9),
+('bx_payment_form_rcrl_card_add', 'controls', 2147483647, 1, 10),
+('bx_payment_form_rcrl_card_add', 'do_submit', 2147483647, 1, 11),
+('bx_payment_form_rcrl_card_add', 'do_cancel', 2147483647, 1, 12),
+
+-- FORMS: Stripe
+('bx_payment_form_strp_details_edit', 'item_id', 2147483647, 1, 1),
+('bx_payment_form_strp_details_edit', 'controls', 2147483647, 1, 2),
+('bx_payment_form_strp_details_edit', 'do_submit', 2147483647, 1, 3),
+('bx_payment_form_strp_details_edit', 'do_cancel', 2147483647, 1, 4),
+
+('bx_payment_form_strp_card_add', 'card_number', 2147483647, 1, 1),
+('bx_payment_form_strp_card_add', 'card_expire', 2147483647, 1, 2),
+('bx_payment_form_strp_card_add', 'card_cvv', 2147483647, 1, 3),
+('bx_payment_form_strp_card_add', 'controls', 2147483647, 1, 4),
+('bx_payment_form_strp_card_add', 'do_submit', 2147483647, 1, 5),
+('bx_payment_form_strp_card_add', 'do_cancel', 2147483647, 1, 6);
+
+
+-- PRE-VALUES
+INSERT INTO `sys_form_pre_lists`(`key`, `title`, `module`, `use_for_sets`, `extendable`) VALUES
+('bx_payment_currencies', '_bx_payment_pre_lists_currencies', 'bx_payment', '0', '0');
+
+INSERT INTO `sys_form_pre_values`(`Key`, `Value`, `Order`, `LKey`, `LKey2`) VALUES
+('bx_payment_currencies', 'AUD', 1, 'AUD', 'A&#36;'),
+('bx_payment_currencies', 'CAD', 2, 'CAD', 'C&#36;'),
+('bx_payment_currencies', 'EUR', 3, 'EUR', '&#8364;'),
+('bx_payment_currencies', 'GBP', 4, 'GBP', '&#163;'),
+('bx_payment_currencies', 'USD', 5, 'USD', '&#36;'),
+('bx_payment_currencies', 'JPY', 6, 'YEN', '&#165;');
+
+-- STUDIO PAGE & WIDGET
+INSERT INTO `sys_std_pages`(`index`, `name`, `header`, `caption`, `icon`) VALUES
+(3, @sName, '_bx_payment', '_bx_payment', 'bx_payment@modules/boonex/payment/|std-icon.svg');
+SET @iPageId = LAST_INSERT_ID();
+
+SET @iParentPageId = (SELECT `id` FROM `sys_std_pages` WHERE `name` = 'home');
+SET @iParentPageOrder = (SELECT MAX(`order`) FROM `sys_std_pages_widgets` WHERE `page_id` = @iParentPageId);
+INSERT INTO `sys_std_widgets` (`page_id`, `module`, `type`, `url`, `click`, `icon`, `caption`, `cnt_notices`, `cnt_actions`) VALUES
+(@iPageId, @sName, 'extensions', '{url_studio}module.php?name=bx_payment', '', 'bx_payment@modules/boonex/payment/|std-icon.svg', '_bx_payment', '', 'a:4:{s:6:"module";s:6:"system";s:6:"method";s:11:"get_actions";s:6:"params";a:0:{}s:5:"class";s:18:"TemplStudioModules";}');
+INSERT INTO `sys_std_pages_widgets` (`page_id`, `widget_id`, `order`) VALUES
+(@iParentPageId, LAST_INSERT_ID(), IF(ISNULL(@iParentPageOrder), 1, @iParentPageOrder + 1));

+ 76 - 0
modules/boonex/payment/updates/14.0.7_14.0.8/source/template/css/orders.css

@@ -0,0 +1,76 @@
+iframe.hidden {
+    width: 0px;
+    height: 0px;
+    display: none;
+}
+
+/*--- 'Manual Order' and 'More' windows ---*/
+.ui-autocomplete.ui-front {
+	z-index: 10001;
+}
+div.bx-payment-pa-items {
+	max-height: 300px;
+	overflow-x: hidden;
+	overflow-y: auto;
+}
+div.bx-payment-pa-item {
+    display: -webkit-flex; 
+    display: flex;
+    width: 100%;
+
+    -webkit-align-items: center;
+    align-items: center;
+}
+div.bx-payment-pa-item.bx-payment-pai-filter .bx-form-input-text {
+    width: 40%;
+}
+
+div.bx-payment-pa-item-title,
+div.bx-payment-pa-item-price,
+div.bx-payment-pa-item-quantity {
+    position: relative;
+    box-sizing: border-box;
+}
+div.bx-payment-pa-item-title {
+    width: 50%;
+}
+div.bx-payment-pa-item-title .bx-form-input-checkbox {
+    display: block;
+    margin: 0px;
+    padding: 0px;
+    vertical-align: middle;
+}
+div.bx-payment-pa-item-price {
+    width: 20%;
+}
+div.bx-payment-pa-item-quantity {
+    width: 10%;
+}
+
+/*--- View Order ---*/
+div.bx-payment-view-order {
+    border-top-width: 0px;
+}
+div.bx-payment-vo-row {
+	white-space: nowrap;
+}
+div.bx-payment-vo-caption,
+div.bx-payment-vo-content,
+div.bx-payment-vo-items {
+    position: relative;
+    display: inline-block;
+	vertical-align: top;
+
+    overflow: hidden;
+}
+div.bx-payment-vo-caption {
+    width: 30%;
+}
+div.bx-payment-vo-content,
+div.bx-payment-vo-items {
+    width: 70%;
+	
+	TEXT-OVERFLOW: ellipsis;
+    -o-text-overflow: ellipsis;
+    white-space: nowrap;
+}