AntonLV 8 лет назад
Родитель
Сommit
dbb9cdb154
100 измененных файлов с 15272 добавлено и 0 удалено
  1. 467 0
      modules/boonex/invites/updates/9.0.4_9.0.5/source/classes/BxInvModule.php
  2. 70 0
      modules/boonex/invites/updates/9.0.4_9.0.5/source/install/config.php
  3. 74 0
      modules/boonex/invites/updates/9.0.4_9.0.5/source/js/main.js
  4. 8 0
      modules/boonex/invites/updates/9.0.4_9.0.5/source/template/block_request.html
  5. 218 0
      modules/boonex/market/updates/9.0.6_9.0.7/source/classes/BxMarketConfig.php
  6. 648 0
      modules/boonex/market/updates/9.0.6_9.0.7/source/classes/BxMarketDb.php
  7. 285 0
      modules/boonex/market/updates/9.0.6_9.0.7/source/classes/BxMarketFormEntry.php
  8. 33 0
      modules/boonex/market/updates/9.0.6_9.0.7/source/classes/BxMarketMenuSnippetMeta.php
  9. 1042 0
      modules/boonex/market/updates/9.0.6_9.0.7/source/classes/BxMarketModule.php
  10. 160 0
      modules/boonex/market/updates/9.0.6_9.0.7/source/classes/BxMarketSearchResult.php
  11. 459 0
      modules/boonex/market/updates/9.0.6_9.0.7/source/classes/BxMarketTemplate.php
  12. 139 0
      modules/boonex/market/updates/9.0.6_9.0.7/source/install/config.php
  13. 390 0
      modules/boonex/market/updates/9.0.6_9.0.7/source/install/langs/en.xml
  14. 57 0
      modules/boonex/market/updates/9.0.6_9.0.7/source/install/sql/disable.sql
  15. 536 0
      modules/boonex/market/updates/9.0.6_9.0.7/source/install/sql/enable.sql
  16. 100 0
      modules/boonex/market/updates/9.0.6_9.0.7/source/js/entry.js
  17. 39 0
      modules/boonex/market/updates/9.0.6_9.0.7/source/template/attachments.html
  18. 1 0
      modules/boonex/market/updates/9.0.6_9.0.7/source/template/breadcrumb.html
  19. 38 0
      modules/boonex/market/updates/9.0.6_9.0.7/source/template/css/forms.css
  20. 138 0
      modules/boonex/market/updates/9.0.6_9.0.7/source/template/css/main.css
  21. 27 0
      modules/boonex/market/updates/9.0.6_9.0.7/source/template/form.html
  22. 42 0
      modules/boonex/market/updates/9.0.6_9.0.7/source/template/form_ghost_template.html
  23. 49 0
      modules/boonex/market/updates/9.0.6_9.0.7/source/template/form_ghost_template_file.html
  24. 78 0
      modules/boonex/market/updates/9.0.6_9.0.7/source/template/unit_gallery.html
  25. 1 0
      modules/boonex/market/updates/9.0.6_9.0.7/source/template/unit_meta_item.html
  26. 109 0
      modules/boonex/notifications/updates/9.0.5_9.0.6/source/classes/BxNtfsConfig.php
  27. 108 0
      modules/boonex/notifications/updates/9.0.5_9.0.6/source/classes/BxNtfsDb.php
  28. 267 0
      modules/boonex/notifications/updates/9.0.5_9.0.6/source/classes/BxNtfsModule.php
  29. 326 0
      modules/boonex/notifications/updates/9.0.5_9.0.6/source/classes/BxNtfsResponse.php
  30. 238 0
      modules/boonex/notifications/updates/9.0.5_9.0.6/source/classes/BxNtfsTemplate.php
  31. 82 0
      modules/boonex/notifications/updates/9.0.5_9.0.6/source/install/config.php
  32. 47 0
      modules/boonex/notifications/updates/9.0.5_9.0.6/source/install/langs/en.xml
  33. 38 0
      modules/boonex/notifications/updates/9.0.5_9.0.6/source/install/sql/disable.sql
  34. 78 0
      modules/boonex/notifications/updates/9.0.5_9.0.6/source/install/sql/enable.sql
  35. 14 0
      modules/boonex/notifications/updates/9.0.5_9.0.6/source/template/et_new_event.html
  36. 20 0
      modules/boonex/notifications/updates/9.0.5_9.0.6/source/template/event.html
  37. 10 0
      modules/boonex/ocean/updates/9.0.5_9.0.6/source/data/template/system/_header_js_custom.html
  38. 46 0
      modules/boonex/ocean/updates/9.0.5_9.0.6/source/data/template/system/_sub_footer.html
  39. 68 0
      modules/boonex/ocean/updates/9.0.5_9.0.6/source/data/template/system/_sub_header.html
  40. 55 0
      modules/boonex/ocean/updates/9.0.5_9.0.6/source/data/template/system/css/general.css
  41. 21 0
      modules/boonex/ocean/updates/9.0.5_9.0.6/source/data/template/system/scripts/BxTemplCaptchaReCAPTCHAInvisible.php
  42. 34 0
      modules/boonex/ocean/updates/9.0.5_9.0.6/source/data/template/system/scripts/BxTemplConfig.php
  43. 68 0
      modules/boonex/ocean/updates/9.0.5_9.0.6/source/install/config.php
  44. 44 0
      modules/boonex/organizations/updates/9.0.5_9.0.6/source/classes/BxOrgsAlertsResponse.php
  45. 24 0
      modules/boonex/organizations/updates/9.0.5_9.0.6/source/classes/BxOrgsCmtsSearchResult.php
  46. 228 0
      modules/boonex/organizations/updates/9.0.5_9.0.6/source/classes/BxOrgsConfig.php
  47. 23 0
      modules/boonex/organizations/updates/9.0.5_9.0.6/source/classes/BxOrgsDb.php
  48. 24 0
      modules/boonex/organizations/updates/9.0.5_9.0.6/source/classes/BxOrgsFormEntry.php
  49. 23 0
      modules/boonex/organizations/updates/9.0.5_9.0.6/source/classes/BxOrgsFormsEntryHelper.php
  50. 21 0
      modules/boonex/organizations/updates/9.0.5_9.0.6/source/classes/BxOrgsGridAdministration.php
  51. 21 0
      modules/boonex/organizations/updates/9.0.5_9.0.6/source/classes/BxOrgsGridCommon.php
  52. 21 0
      modules/boonex/organizations/updates/9.0.5_9.0.6/source/classes/BxOrgsGridConnections.php
  53. 24 0
      modules/boonex/organizations/updates/9.0.5_9.0.6/source/classes/BxOrgsMenu.php
  54. 25 0
      modules/boonex/organizations/updates/9.0.5_9.0.6/source/classes/BxOrgsMenuManageTools.php
  55. 22 0
      modules/boonex/organizations/updates/9.0.5_9.0.6/source/classes/BxOrgsMenuSnippetMeta.php
  56. 25 0
      modules/boonex/organizations/updates/9.0.5_9.0.6/source/classes/BxOrgsMenuView.php
  57. 49 0
      modules/boonex/organizations/updates/9.0.5_9.0.6/source/classes/BxOrgsModule.php
  58. 24 0
      modules/boonex/organizations/updates/9.0.5_9.0.6/source/classes/BxOrgsPageBrowse.php
  59. 27 0
      modules/boonex/organizations/updates/9.0.5_9.0.6/source/classes/BxOrgsPageEntry.php
  60. 24 0
      modules/boonex/organizations/updates/9.0.5_9.0.6/source/classes/BxOrgsPageJoinedEntries.php
  61. 23 0
      modules/boonex/organizations/updates/9.0.5_9.0.6/source/classes/BxOrgsPrivacy.php
  62. 21 0
      modules/boonex/organizations/updates/9.0.5_9.0.6/source/classes/BxOrgsPrivacyNotifications.php
  63. 224 0
      modules/boonex/organizations/updates/9.0.5_9.0.6/source/classes/BxOrgsSearchResult.php
  64. 34 0
      modules/boonex/organizations/updates/9.0.5_9.0.6/source/classes/BxOrgsTemplate.php
  65. 21 0
      modules/boonex/organizations/updates/9.0.5_9.0.6/source/classes/BxOrgsUploaderCoverCrop.php
  66. 21 0
      modules/boonex/organizations/updates/9.0.5_9.0.6/source/classes/BxOrgsUploaderPictureCrop.php
  67. 148 0
      modules/boonex/organizations/updates/9.0.5_9.0.6/source/install/config.php
  68. 392 0
      modules/boonex/organizations/updates/9.0.5_9.0.6/source/install/langs/en.xml
  69. 75 0
      modules/boonex/organizations/updates/9.0.5_9.0.6/source/install/sql/disable.sql
  70. 579 0
      modules/boonex/organizations/updates/9.0.5_9.0.6/source/install/sql/enable.sql
  71. 320 0
      modules/boonex/organizations/updates/9.0.5_9.0.6/source/install/sql/install.sql
  72. 38 0
      modules/boonex/organizations/updates/9.0.5_9.0.6/source/install/sql/uninstall.sql
  73. 1 0
      modules/boonex/organizations/updates/9.0.5_9.0.6/source/template/unit_live_search.html
  74. 1 0
      modules/boonex/organizations/updates/9.0.5_9.0.6/source/template/unit_meta_item.html
  75. 1 0
      modules/boonex/organizations/updates/9.0.5_9.0.6/source/template/unit_wo_info_links.html
  76. 339 0
      modules/boonex/payment/updates/9.0.5_9.0.6/source/classes/BxPaymentCart.php
  77. 273 0
      modules/boonex/payment/updates/9.0.5_9.0.6/source/classes/BxPaymentConfig.php
  78. 465 0
      modules/boonex/payment/updates/9.0.5_9.0.6/source/classes/BxPaymentDb.php
  79. 210 0
      modules/boonex/payment/updates/9.0.5_9.0.6/source/classes/BxPaymentDetails.php
  80. 25 0
      modules/boonex/payment/updates/9.0.5_9.0.6/source/classes/BxPaymentFormView.php
  81. 139 0
      modules/boonex/payment/updates/9.0.5_9.0.6/source/classes/BxPaymentGridProcessed.php
  82. 136 0
      modules/boonex/payment/updates/9.0.5_9.0.6/source/classes/BxPaymentJoin.php
  83. 954 0
      modules/boonex/payment/updates/9.0.5_9.0.6/source/classes/BxPaymentModule.php
  84. 200 0
      modules/boonex/payment/updates/9.0.5_9.0.6/source/classes/BxPaymentOrders.php
  85. 314 0
      modules/boonex/payment/updates/9.0.5_9.0.6/source/classes/BxPaymentProviderPayPal.php
  86. 869 0
      modules/boonex/payment/updates/9.0.5_9.0.6/source/classes/BxPaymentProviderStripe.php
  87. 208 0
      modules/boonex/payment/updates/9.0.5_9.0.6/source/classes/BxPaymentSubscriptions.php
  88. 434 0
      modules/boonex/payment/updates/9.0.5_9.0.6/source/classes/BxPaymentTemplate.php
  89. 70 0
      modules/boonex/payment/updates/9.0.5_9.0.6/source/install/config.php
  90. 496 0
      modules/boonex/payment/updates/9.0.5_9.0.6/source/install/langs/en.xml
  91. 39 0
      modules/boonex/payment/updates/9.0.5_9.0.6/source/install/sql/disable.sql
  92. 441 0
      modules/boonex/payment/updates/9.0.5_9.0.6/source/install/sql/install.sql
  93. 99 0
      modules/boonex/payment/updates/9.0.5_9.0.6/source/js/cart.js
  94. 25 0
      modules/boonex/payment/updates/9.0.5_9.0.6/source/js/main.js
  95. 57 0
      modules/boonex/payment/updates/9.0.5_9.0.6/source/js/orders.js
  96. 111 0
      modules/boonex/payment/updates/9.0.5_9.0.6/source/js/stripe.js
  97. 68 0
      modules/boonex/payment/updates/9.0.5_9.0.6/source/js/subscriptions.js
  98. 4 0
      modules/boonex/payment/updates/9.0.5_9.0.6/source/template/add_to_cart.html
  99. 1 0
      modules/boonex/payment/updates/9.0.5_9.0.6/source/template/add_to_cart_js.html
  100. 19 0
      modules/boonex/payment/updates/9.0.5_9.0.6/source/template/order_processed_add.html

+ 467 - 0
modules/boonex/invites/updates/9.0.4_9.0.5/source/classes/BxInvModule.php

@@ -0,0 +1,467 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Invites Invites
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+bx_import('BxDolAcl');
+
+define('BX_INV_TYPE_FROM_MEMBER', 'from_member');
+define('BX_INV_TYPE_FROM_SYSTEM', 'from_system');
+
+class BxInvModule extends BxDolModule
+{
+    /**
+     * Constructor
+     */
+    function __construct($aModule)
+    {
+        parent::__construct($aModule);
+
+        $this->_oConfig->init($this->_oDb);
+    }
+
+	/**
+     * ACTION METHODS
+     */
+	function actionGetLink()
+    {
+    	$iProfileId = $this->getProfileId();
+		$iAccountId = $this->getAccountId($iProfileId);
+
+        $mixedAllowed = $this->isAllowedInvite($iProfileId);
+        if($mixedAllowed !== true)
+        	return echoJson(array('message' => $mixedAllowed));
+
+	    if(!isAdmin($iAccountId)) {
+			$iInvited = (int)$this->_oDb->getInvites(array('type' => 'count_by_account', 'value' => $iAccountId));
+			if(($this->_oConfig->getCountPerUser() - $iInvited) <= 0)
+				return echoJson(array('message' => _t('_bx_invites_err_limit_reached')));
+		}
+
+    	$oKeys = BxDolKey::getInstance();
+    	if(!$oKeys)
+    		return  echoJson(array('message' => _t('_bx_invites_err_not_available')));  		
+
+    	$sKey = $oKeys->getNewKey(false, $this->_oConfig->getKeyLifetime());
+
+    	$oForm = $this->getFormObjectInvite();
+    	$oForm->insert(array(
+			'account_id' => $iAccountId,
+			'profile_id' => $iProfileId,
+			'key' => $sKey,
+			'email' => '',
+			'date' => time()
+		));
+
+        echoJson(array('popup' => $this->_oTemplate->getLinkPopup(
+        	$this->getJoinLink($sKey)
+        )));
+    }
+
+    /**
+     * SERVICE METHODS
+     */
+    /**
+     * @page service Service Calls
+     * @section bx_invites Invitations
+     * @subsection bx_invites-page_blocks Page Blocks
+     * @subsubsection bx_invites-get_block_invite get_block_invite
+     * 
+     * @code bx_srv('bx_invites', 'get_block_invite', [...]); @endcode
+     * 
+     * Get page block for member's Dashboard which displays invitations related info and action(s).
+     *
+     * @return an array describing a block to display on the site or empty string if something is wrong. All necessary CSS and JS files are automatically added to the HEAD section of the site HTML.
+     * 
+     * @see BxInvModule::serviceGetBlockInvite
+     */
+    /** 
+     * @ref bx_invites-get_block_invite "get_block_invite"
+     */
+    public function serviceGetBlockInvite()
+    {
+		$iProfileId = $this->getProfileId();
+		$iAccountId = $this->getAccountId($iProfileId);
+
+		$mixedAllowed = $this->isAllowedInvite($iProfileId);
+        if($mixedAllowed !== true)
+            return '';
+
+		$iInvited = (int)$this->_oDb->getInvites(array('type' => 'count_by_account', 'value' => $iAccountId));
+		if(!isAdmin($iAccountId) && $iInvited >= $this->_oConfig->getCountPerUser())
+			return '';
+
+    	return array(
+    		'content' => $this->_oTemplate->getBlockInvite($iAccountId, $iProfileId)
+    	);
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_invites Invitations
+     * @subsection bx_invites-page_blocks Page Blocks
+     * @subsubsection bx_invites-get_block_form_invite get_block_form_invite
+     * 
+     * @code bx_srv('bx_invites', 'get_block_form_invite', [...]); @endcode
+     * 
+     * Get page block with invite form.
+     *
+     * @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 BxInvModule::serviceGetBlockFormInvite
+     */
+    /** 
+     * @ref bx_invites-get_block_form_invite "get_block_form_invite"
+     */
+    public function serviceGetBlockFormInvite()
+    {
+    	$iProfileId = $this->getProfileId();
+		$iAccountId = $this->getAccountId($iProfileId);
+
+        $mixedAllowed = $this->isAllowedInvite($iProfileId);
+        if($mixedAllowed !== true)
+            return array(
+                'content' => MsgBox($mixedAllowed)
+            );
+
+		$mixedInvites = false;
+		if(!isAdmin($iAccountId)) {
+			$iInvited = (int)$this->_oDb->getInvites(array('type' => 'count_by_account', 'value' => $iAccountId));
+			$mixedInvites = $this->_oConfig->getCountPerUser() - $iInvited;
+			if($mixedInvites <= 0)
+				return array(
+					'content' => MsgBox(_t('_bx_invites_err_limit_reached'))
+				);
+		}
+
+        $oForm = $this->getFormObjectInvite();
+        $oForm->aInputs['text']['value'] = _t('_bx_invites_msg_invitation');
+
+        $sResult = '';
+        $oForm->initChecker();
+        if($oForm->isSubmittedAndValid()) {
+        	$sEmails = bx_process_input($oForm->getCleanValue('emails'));
+        	$sText = bx_process_pass($oForm->getCleanValue('text'));
+
+        	$mixedResult = $this->invite(BX_INV_TYPE_FROM_MEMBER, $sEmails, $sText, $mixedInvites, $oForm);
+        	if($mixedResult !== false)
+        		$sResult = _t('_bx_invites_msg_invitation_sent', (int)$mixedResult);
+        	else
+				$sResult = _t('_bx_invites_err_not_available');
+
+        	$sResult = MsgBox($sResult);
+        }
+
+        return array(
+            'content' => $sResult . $oForm->getCode()
+        );
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_invites Invitations
+     * @subsection bx_invites-page_blocks Page Blocks
+     * @subsubsection bx_invites-get_block_form_request get_block_form_request
+     * 
+     * @code bx_srv('bx_invites', 'get_block_form_request', [...]); @endcode
+     * 
+     * Get page block with request invitation form.
+     *
+     * @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 BxInvModule::serviceGetBlockFormRequest
+     */
+    /** 
+     * @ref bx_invites-get_block_form_request "get_block_form_request"
+     */
+    public function serviceGetBlockFormRequest()
+    {
+    	if(!$this->_oConfig->isRequestInvite())
+    		return array(
+                'content' => MsgBox(_t('_bx_invites_err_not_available'))
+            );
+
+    	$mixedAllowed = $this->isAllowedRequest(0);
+        if($mixedAllowed !== true)
+            return array(
+                'content' => MsgBox($mixedAllowed)
+            );
+
+    	$sResult = '';
+
+        $oForm = BxDolForm::getObjectInstance($this->_oConfig->getObject('form_request'), $this->_oConfig->getObject('form_display_request_send'));
+
+        $oForm->initChecker();
+        if($oForm->isSubmittedAndValid()) {
+        	$sIp = getVisitorIP();
+
+        	$iId = (int)$oForm->insert(array(
+        		'nip' => ip2long($sIp),
+				'date' => time()
+			));
+
+			if($iId !== false) {
+				$sRequestsEmail = $this->_oConfig->getRequestsEmail();
+				if(!empty($sRequestsEmail)) {
+					$sManageUrl = BX_DOL_URL_ROOT . BxDolPermalinks::getInstance()->permalink('page.php?i=invites-requests');
+
+					$aMessage = BxDolEmailTemplates::getInstance()->parseTemplate('bx_invites_request_form_message', array(
+						'sender_name' => bx_process_output($oForm->getCleanValue('name')),
+						'sender_email' => bx_process_output($oForm->getCleanValue('email')),
+						'sender_ip' => $sIp,
+						'manage_url' => $sManageUrl
+					));
+
+					sendMail($sRequestsEmail, $aMessage['Subject'], $aMessage['Body'], 0, array(), BX_EMAIL_SYSTEM);
+				}
+
+				$sResult = MsgBox(_t('_bx_invites_msg_request_sent'));
+			}
+        }
+
+        return array(
+            'content' => $sResult . $oForm->getCode()
+        );
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_invites Invitations
+     * @subsection bx_invites-page_blocks Page Blocks
+     * @subsubsection bx_invites-get_block_manage_requests get_block_manage_requests
+     * 
+     * @code bx_srv('bx_invites', 'get_block_manage_requests', [...]); @endcode
+     * 
+     * Get page block with manage invitation requests table.
+     *
+     * @return HTML string with block content to display on the site or empty string if something is wrong. All necessary CSS and JS files are automatically added to the HEAD section of the site HTML.
+     * 
+     * @see BxInvModule::serviceGetBlockManageRequests
+     */
+    /** 
+     * @ref bx_invites-get_block_manage_requests "get_block_manage_requests"
+     */
+    public function serviceGetBlockManageRequests()
+    {
+        $oGrid = BxDolGrid::getObjectInstance($this->_oConfig->getObject('grid_requests'));
+        if(!$oGrid)
+            return '';
+
+		$this->_oTemplate->addCss(array('main.css'));
+		return $oGrid->getCode();
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_invites Invitations
+     * @subsection bx_invites-other Other
+     * @subsubsection bx_invites-get_menu_addon_requests get_menu_addon_requests
+     * 
+     * @code bx_srv('bx_invites', 'get_menu_addon_requests', [...]); @endcode
+     * 
+     * Get number or invitation requests.
+     *
+     * @return integer value with number of invitation requests.
+     * 
+     * @see BxInvModule::serviceGetMenuAddonRequests
+     */
+    /** 
+     * @ref bx_invites-get_menu_addon_requests "get_menu_addon_requests"
+     */
+	public function serviceGetMenuAddonRequests()
+	{
+        return $this->_oDb->getRequests(array('type' => 'count_all'));
+	}
+
+	/**
+     * @page service Service Calls
+     * @section bx_invites Invitations
+     * @subsection bx_invites-other Other
+     * @subsubsection bx_invites-account_add_form_check account_add_form_check
+     * 
+     * @code bx_srv('bx_invites', 'account_add_form_check', [...]); @endcode
+     * 
+     * Perform neccessary checking on join form.
+     *
+     * @return empty string - if join is allowed and should be processed as usual, non-empty string - if join form need to be replaced with this code.
+     * 
+     * @see BxInvModule::serviceAccountAddFormCheck
+     */
+    /** 
+     * @ref bx_invites-account_add_form_check "account_add_form_check"
+     */
+	public function serviceAccountAddFormCheck()
+	{
+	    $sReturn = '';
+    	if (!$this->_oConfig->isRegistrationByInvitation())
+    		return $sReturn;
+
+    	$oSession = BxDolSession::getInstance();
+		$sKeyCode = $this->_oConfig->getKeyCode();
+
+		$bKey = bx_get($sKeyCode) !== false;
+		if($bKey) {
+			$sKey = bx_process_input(bx_get($sKeyCode));
+
+        	$oKeys = BxDolKey::getInstance();
+        	if($oKeys && $oKeys->isKeyExists($sKey))
+		    	$oSession->setValue($sKeyCode, $sKey);
+		}
+
+		$sKey = $oSession->getValue($sKeyCode);
+		if($sKey !== false)
+		    return $sReturn;
+
+        if($bKey)
+            $sReturn .= MsgBox(_t('_bx_invites_err_used'));
+        $sReturn .= $this->_oTemplate->getBlockRequest();
+
+        return $sReturn;
+	}
+
+	public function invite($sType, $sEmails, $sText, $mixedLimit = false, $oForm = null)
+	{
+		$iProfileId = $this->getProfileId();
+		$iAccountId = $this->getAccountId($iProfileId);
+
+		$oKeys = BxDolKey::getInstance();
+		if(!$oKeys || !in_array($sType, array(BX_INV_TYPE_FROM_MEMBER, BX_INV_TYPE_FROM_SYSTEM)))
+			return false;
+
+		$iKeyLifetime = $this->_oConfig->getKeyLifetime();
+
+		$sEmailTemplate = '';
+		switch($sType) {
+			case BX_INV_TYPE_FROM_MEMBER:
+				$sEmailTemplate = 'bx_invites_invite_form_message';
+				break;
+
+			case BX_INV_TYPE_FROM_SYSTEM:
+				$sEmailTemplate = 'bx_invites_invite_by_request_message';
+				break;
+		}
+
+		if(empty($oForm))
+			$oForm = $this->getFormObjectInvite();
+
+		$aMessage = BxDolEmailTemplates::getInstance()->parseTemplate($sEmailTemplate, array(
+			'text' => $sText
+		), $iAccountId, $iProfileId);
+
+		$iSent = 0;
+		$iDate = time();
+		$aEmails = preg_split("/[\s\n,;]+/", $sEmails);
+		if(is_array($aEmails) && !empty($aEmails))
+			foreach($aEmails as $sEmail) {
+				if($mixedLimit !== false && (int)$mixedLimit <= 0)
+					break;
+
+				$sEmail = trim($sEmail);
+				if(empty($sEmail))
+					continue;
+
+				$sKey = $oKeys->getNewKey(false, $iKeyLifetime);
+				if(sendMail($sEmail, $aMessage['Subject'], $aMessage['Body'], 0, array('join_url' => $this->getJoinLink($sKey)), BX_EMAIL_SYSTEM)) {
+					$oForm->insert(array(
+						'account_id' => $iAccountId,
+						'profile_id' => $iProfileId,
+						'key' => $sKey,
+						'email' => $sEmail,
+						'date' => $iDate
+					));
+
+					$this->onInvite($iAccountId, $iProfileId);
+
+					$iSent += 1;
+					if($mixedLimit !== false) 
+						$mixedLimit -= 1;					
+				}
+			}
+
+		return $iSent;
+	}
+
+	public function isAllowedInvite($iProfileId, $bPerform = false)
+    {
+        $aCheckResult = checkActionModule($iProfileId, 'invite', $this->getName(), $bPerform);
+        return $aCheckResult[CHECK_ACTION_RESULT] !== CHECK_ACTION_RESULT_ALLOWED ? $aCheckResult[CHECK_ACTION_MESSAGE] : true;
+    }
+
+	public function isAllowedRequest($iProfileId, $bPerform = false)
+    {
+        $aCheckResult = checkActionModule($iProfileId, 'request', $this->getName(), $bPerform);
+        return $aCheckResult[CHECK_ACTION_RESULT] !== CHECK_ACTION_RESULT_ALLOWED ? $aCheckResult[CHECK_ACTION_MESSAGE] : true;
+    }
+
+	public function isAllowedDeleteRequest($iProfileId, $bPerform = false)
+    {
+        $aCheckResult = checkActionModule($iProfileId, 'delete request', $this->getName(), $bPerform);
+        return $aCheckResult[CHECK_ACTION_RESULT] !== CHECK_ACTION_RESULT_ALLOWED ? $aCheckResult[CHECK_ACTION_MESSAGE] : true;
+    }
+
+    public function getProfileId()
+    {
+        return isLogged() ? bx_get_logged_profile_id() : 0;
+    }
+
+    public function getProfileObject($iProfileId = 0)
+    {
+        $oProfile = BxDolProfile::getInstance($iProfileId);
+        if (!$oProfile)
+            $oProfile = BxDolProfileUndefined::getInstance();
+
+        return $oProfile;
+    }
+
+	public function getAccountId($iProfileId)
+    {
+    	$oProfile = $this->getProfileObject($iProfileId);
+    	if($oProfile->id() == 0)
+    		return 0;
+
+        return $oProfile->getAccountId();
+    }
+
+    protected function onInvite($iAccountId, $iProfileId)
+    {
+        $this->isAllowedInvite($iProfileId, true);
+
+        //--- Event -> Invite for Alerts Engine ---//
+        $oAlert = new BxDolAlerts($this->_oConfig->getObject('alert'), 'invite', 0, $iProfileId);
+        $oAlert->alert();
+        //--- Event -> Invite for Alerts Engine ---//
+    }
+
+	protected function onRequest()
+    {
+        //--- Event -> Request for Alerts Engine ---//
+        $oAlert = new BxDolAlerts($this->_oConfig->getObject('alert'), 'request');
+        $oAlert->alert();
+        //--- Event -> Request for Alerts Engine ---//
+    }
+
+    protected function getFormObjectInvite($sDisplay = '')
+    {
+    	if(empty($sDisplay))
+    		$sDisplay = $this->_oConfig->getObject('form_display_invite_send');
+
+        bx_import('FormCheckerHelper', $this->_aModule);
+        return BxDolForm::getObjectInstance($this->_oConfig->getObject('form_invite'), $sDisplay);
+    }
+
+	protected function getJoinLink($sKey)
+	{
+		$sKeyCode = $this->_oConfig->getKeyCode();
+
+		$sJoinUrl = BX_DOL_URL_ROOT . BxDolPermalinks::getInstance()->permalink('page.php?i=create-account');
+		return bx_append_url_params($sJoinUrl, array($sKeyCode => $sKey));
+	}
+}
+
+/** @} */

+ 70 - 0
modules/boonex/invites/updates/9.0.4_9.0.5/source/install/config.php

@@ -0,0 +1,70 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Invites Invites
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+$aConfig = array(
+    /**
+     * Main Section.
+     */
+    'type' => BX_DOL_MODULE_TYPE_MODULE,
+    'name' => 'bx_invites',
+    'title' => 'Invitations',
+    'note' => 'Invitations module.',
+    'version' => '9.0.5',
+    'vendor' => 'BoonEx',
+	'help_url' => 'http://feed.una.io/?section={module_name}',
+
+    'compatible_with' => array(
+        '9.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/invites/',
+    'home_uri' => 'invites',
+
+    'db_prefix' => 'bx_inv_',
+    'class_prefix' => 'BxInv',
+
+    /**
+     * Category for language keys.
+     */
+    'language_category' => 'Invitations',
+
+    /**
+     * 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(),
+);
+
+/** @} */

+ 74 - 0
modules/boonex/invites/updates/9.0.4_9.0.5/source/js/main.js

@@ -0,0 +1,74 @@
+function BxInvMain(oOptions) {
+	this._sActionsUri = oOptions.sActionUri;
+    this._sActionsUrl = oOptions.sActionUrl;
+    this._sObjName = oOptions.sObjName == undefined ? 'oInvMain' : oOptions.sObjName;
+    this._aHtmlIds = oOptions.aHtmlIds == undefined ? {} : oOptions.aHtmlIds;
+    this._oRequestParams = oOptions.oRequestParams == undefined ? {} : oOptions.oRequestParams;
+}
+
+BxInvMain.prototype.showLinkPopup = function(oElement) {
+    var $this = this;
+
+    this.loadingInButton(oElement, true);
+
+    jQuery.get(
+        this._sActionsUrl + 'get_link/',
+        this._getDefaultData(),
+        function(oData) {
+        	$this.loadingInButton(oElement, false);
+
+        	if(oData && oData.popup != undefined) {
+        		var oPopup = $(oData.popup);
+        		var sPopupId = oPopup.attr('id');
+        		var oClipboard = null;
+
+            	$('#' + sPopupId).remove();
+                oPopup.hide().prependTo('body').dolPopup({
+                    fog: {
+        				color: '#fff',
+        				opacity: .7
+                    },
+                    onShow: function () {
+                    	oClipboard = new Clipboard('#' + $this._aHtmlIds['link_popup'] + ' .bx-btn[name = "clipboard"]', {
+                    	    target: function(oTrigger) {
+                    	        return $('#' + sPopupId).find('[name = "link"]').get(0);
+                    	    }
+                    	});
+                    	oClipboard.on('success', function(oObject) {
+                    		$this.hideLinkPopup();
+                    	});
+                    },
+                    onHide: function () {
+                    	if(oClipboard)
+                    		oClipboard.destroy();
+                    }
+                });
+        	}
+
+        	if(oData && oData.message != undefined)
+        		bx_alert(oData.message);
+        },
+        'json'
+    );
+};
+
+BxInvMain.prototype.hideLinkPopup = function() {
+	$('#' + this._aHtmlIds['link_popup']).dolPopupHide();	
+};
+
+BxInvMain.prototype.loadingInButton = function(e, bShow) {
+	if($(e).length)
+		bx_loading_btn($(e), bShow);
+	else
+		bx_loading($('body'), bShow);	
+};
+
+BxInvMain.prototype._loading = function(e, bShow) {
+	var oParent = $(e).length ? $(e) : $('body'); 
+	bx_loading(oParent, bShow);
+};
+
+BxInvMain.prototype._getDefaultData = function () {
+	var oDate = new Date();
+    return jQuery.extend({}, this._oRequestParams, {_t:oDate.getTime()});
+};

+ 8 - 0
modules/boonex/invites/updates/9.0.4_9.0.5/source/template/block_request.html

@@ -0,0 +1,8 @@
+<div class="__style_prefix__-request-text">__text__</div>
+<div class="__style_prefix__-request-btn bx-def-margin-top bx-clearfix">
+	<bx_if:show_button_request>
+		<button type="button" onclick="javascript: window.open('__url__','_self');" class="bx-btn">
+			<bx_text:_bx_invites_btn_request />
+		</button>
+	</bx_if:show_button_request>
+</div>

+ 218 - 0
modules/boonex/market/updates/9.0.6_9.0.7/source/classes/BxMarketConfig.php

@@ -0,0 +1,218 @@
+<?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
+ *
+ * @{
+ */
+
+class BxMarketConfig extends BxBaseModTextConfig
+{
+	protected $_aCurrency;
+
+    function __construct($aModule)
+    {
+        parent::__construct($aModule);
+
+        $aMenuItems2Methods = array (
+            'edit-product' => 'checkAllowedEdit',
+            'delete-product' => 'checkAllowedDelete',
+        );
+
+        $this->CNF = array (
+
+            // module icon
+            'ICON' => 'shopping-cart col-green3',
+
+            // database tables
+            'TABLE_ENTRIES' => $aModule['db_prefix'] . 'products',
+        	'TABLE_ENTRIES_FULLTEXT' => 'title_text',
+        	'TABLE_PHOTOS2ENTRIES' => $aModule['db_prefix'] . 'photos2products',
+        	'TABLE_FILES2ENTRIES' => $aModule['db_prefix'] . 'files2products',
+        	'TABLE_FILES' => $aModule['db_prefix'] . 'files',
+        	'TABLE_DOWNLOADS' => $aModule['db_prefix'] . 'downloads_track',
+        	'TABLE_LICENSES' => $aModule['db_prefix'] . 'licenses',
+        	'TABLE_LICENSES_DELETED' => $aModule['db_prefix'] . 'licenses_deleted',
+
+            // database fields
+            'FIELD_ID' => 'id',
+            'FIELD_AUTHOR' => 'author',
+            'FIELD_ADDED' => 'added',
+            'FIELD_CHANGED' => 'changed',
+        	'FIELD_NAME' => 'name',
+            'FIELD_TITLE' => 'title',
+            'FIELD_TEXT' => 'text',
+            'FIELD_TEXT_ID' => 'product-text',
+        	'FIELD_CATEGORY' => 'cat',
+        	'FIELD_HEADER_BEG_SINGLE' => 'header_beg_single',
+        	'FIELD_WARNING_SINGLE' => 'warning_single',
+        	'FIELD_PRICE_SINGLE' => 'price_single',
+        	'FIELD_HEADER_END_SINGLE' => 'header_end_single',
+        	'FIELD_HEADER_BEG_RECURRING' => 'header_beg_recurring',
+        	'FIELD_WARNING_RECURRING' => 'warning_recurring',
+        	'FIELD_PRICE_RECURRING' => 'price_recurring',
+        	'FIELD_DURATION_RECURRING' => 'duration_recurring',
+        	'FIELD_TRIAL_RECURRING' => 'trial_recurring',
+        	'FIELD_HEADER_END_RECURRING' => 'header_end_recurring',
+            'FIELD_ALLOW_VIEW_TO' => 'allow_view_to',
+			'FIELD_ALLOW_PURCHASE_TO' => 'allow_purchase_to',
+			'FIELD_ALLOW_COMMENT_TO' => 'allow_comment_to',
+			'FIELD_ALLOW_VOTE_TO' => 'allow_vote_to',
+            'FIELD_SUBENTRIES' => 'subentries',
+            'FIELD_PHOTO' => 'pictures',
+            'FIELD_THUMB' => 'thumb',
+        	'FIELD_COVER' => 'cover',
+        	'FIELD_FILE' => 'files',
+        	'FIELD_PACKAGE' => 'package',
+        	'FIELD_VIEWS' => 'views',
+            'FIELD_COMMENTS' => 'comments',
+        	'FIELD_FEATURED' => 'featured',
+        	'FIELD_STATUS' => 'status',
+        	'FIELD_STATUS_ADMIN' => 'status_admin',
+            'FIELD_LOCATION_PREFIX' => 'location',
+        	'FIELDS_QUICK_SEARCH' => array('title'),
+            'FIELDS_WITH_KEYWORDS' => 'auto', // can be 'auto', array of fields or comma separated string of field names, works only when OBJECT_METATAGS is specified
+
+            // page URIs
+            'URI_VIEW_ENTRY' => 'view-product',
+            'URI_AUTHOR_ENTRIES' => 'products-author',
+			'URI_CATEGORY_ENTRIES' => 'products-category',
+            'URI_ADD_ENTRY' => 'create-product',
+        	'URI_EDIT_ENTRY' => 'edit-product',
+        	'URI_DOWNLOAD_ENTRY' => 'download-product',
+        	'URI_MANAGE_COMMON' => 'products-manage',
+
+            'URL_HOME' => 'page.php?i=products-home',
+            'URL_LATEST' => 'page.php?i=products-latest',
+            'URL_FEATURED' => 'page.php?i=products-featured',
+            'URL_POPULAR' => 'page.php?i=products-popular',
+            'URL_UPDATED' => 'page.php?i=products-updated',
+        	'URL_MANAGE_COMMON' => 'page.php?i=products-manage',
+        	'URL_MANAGE_ADMINISTRATION' => 'page.php?i=products-administration',
+        	'URL_VIEW_ENTRY' => 'page.php?i=view-product&id=',
+
+            // some params
+            'PARAM_CHARS_SUMMARY' => 'bx_market_summary_chars',
+            'PARAM_CHARS_SUMMARY_PLAIN' => 'bx_market_plain_summary_chars',
+            'PARAM_NUM_RSS' => 'bx_market_rss_num',
+        	'PARAM_SEARCHABLE_FIELDS' => 'bx_market_searchable_fields',
+
+            // objects            
+            'OBJECT_STORAGE' => 'bx_market_photos',
+        	'OBJECT_STORAGE_FILES' => 'bx_market_files',
+            'OBJECT_IMAGES_TRANSCODER_PREVIEW' => 'bx_market_preview',
+        	'OBJECT_IMAGES_TRANSCODER_ICON' => 'bx_market_icon',
+        	'OBJECT_IMAGES_TRANSCODER_THUMB' => 'bx_market_thumb',
+        	'OBJECT_IMAGES_TRANSCODER_COVER' => 'bx_market_cover',
+        	'OBJECT_IMAGES_TRANSCODER_SCREENSHOT' => 'bx_market_screenshot',
+            'OBJECT_IMAGES_TRANSCODER_GALLERY' => 'bx_market_gallery',
+            'OBJECT_VIDEOS_TRANSCODERS' => array(),
+        	'OBJECT_REPORTS' => 'bx_market',
+            'OBJECT_VIEWS' => 'bx_market',
+            'OBJECT_VOTES' => 'bx_market',
+        	'OBJECT_FAVORITES' => 'bx_market',
+            'OBJECT_FEATURED' => 'bx_market',
+            'OBJECT_METATAGS' => 'bx_market',
+            'OBJECT_COMMENTS' => 'bx_market',
+        	'OBJECT_CATEGORY' => 'bx_market_cats',
+            'OBJECT_PRIVACY_VIEW' => 'bx_market_allow_view_to',
+			'OBJECT_PRIVACY_PURCHASE' => 'bx_market_allow_purchase_to',
+			'OBJECT_PRIVACY_COMMENT' => 'bx_market_allow_comment_to',
+			'OBJECT_PRIVACY_VOTE' => 'bx_market_allow_vote_to',
+            'OBJECT_FORM_ENTRY' => 'bx_market',
+            'OBJECT_FORM_ENTRY_DISPLAY_VIEW' => 'bx_market_entry_view',
+        	'OBJECT_FORM_ENTRY_DISPLAY_VIEW_FULL' => 'bx_market_entry_view_full',
+            'OBJECT_FORM_ENTRY_DISPLAY_ADD' => 'bx_market_entry_add',
+            'OBJECT_FORM_ENTRY_DISPLAY_EDIT' => 'bx_market_entry_edit',
+            'OBJECT_FORM_ENTRY_DISPLAY_DELETE' => 'bx_market_entry_delete',
+            'OBJECT_MENU_ACTIONS_VIEW_ENTRY' => 'bx_market_view', // actions menu on view entry page
+            'OBJECT_MENU_ACTIONS_VIEW_ENTRY_POPUP' => 'bx_market_view_popup', // actions menu from view entry page but created for popup submenu
+            'OBJECT_MENU_ACTIONS_MY_ENTRIES' => 'bx_market_my', // actions menu on my entries page
+            'OBJECT_MENU_ACTIONS_SNIPPET' => 'bx_market_snippet', // actions menu for entry snippet
+            'OBJECT_MENU_SUBMENU' => 'bx_market_submenu', // main module submenu
+            'OBJECT_MENU_SUBMENU_VIEW_ENTRY' => 'bx_market_view_submenu', // view entry submenu
+            'OBJECT_MENU_SUBMENU_VIEW_ENTRY_MAIN_SELECTION' => 'products-home', // first item in view entry submenu from main module submenu
+            'OBJECT_MENU_SNIPPET_META' => 'bx_market_snippet_meta', // menu for snippet meta info
+            'OBJECT_MENU_MANAGE_TOOLS' => 'bx_market_menu_manage_tools', //manage menu in content administration tools
+            'OBJECT_GRID_ADMINISTRATION' => 'bx_market_administration',
+        	'OBJECT_GRID_COMMON' => 'bx_market_common',
+        	'OBJECT_GRID_LICENSES' => 'bx_market_licenses',
+            'OBJECT_UPLOADERS' => array('bx_market_simple', 'bx_market_html5'),
+        	'OBJECT_CONNECTION_SUBENTRIES' => 'bx_market_subentries',
+
+            // menu items which visibility depends on custom visibility checking
+            'MENU_ITEM_TO_METHOD' => array (
+                'bx_market_my' => array (
+                    'create-product' => 'checkAllowedAdd',
+                ),
+                'bx_market_view' => $aMenuItems2Methods,
+                'bx_market_view_popup' => $aMenuItems2Methods,
+            ),
+
+            // global settings
+			'OPTION_ENABLE_RECURRING' => 'bx_market_enable_recurring',
+            'OPTION_RECURRING_RESERVE' => 'bx_market_recurring_reserve',
+
+            // some language keys
+            'T' => array (
+                'txt_sample_single' => '_bx_market_txt_sample_single',
+            	'txt_sample_single_with_article' => '_bx_market_txt_sample_single_with_article',
+            	'txt_sample_comment_single' => '_bx_market_txt_sample_comment_single',
+            	'txt_sample_vote_single' => '_bx_market_txt_sample_vote_single',
+            	'form_field_author' => '_bx_market_form_entry_input_author',
+            	'grid_action_err_delete' => '_bx_market_grid_action_err_delete',
+            	'grid_txt_account_manager' => '_bx_market_grid_txt_account_manager',
+				'filter_item_active' => '_bx_market_grid_filter_item_title_adm_active',
+            	'filter_item_hidden' => '_bx_market_grid_filter_item_title_adm_hidden',
+            	'filter_item_select_one_filter1' => '_bx_market_grid_filter_item_title_adm_select_one_filter1',
+            	'menu_item_manage_my' => '_bx_market_menu_item_title_manage_my',
+            	'menu_item_manage_all' => '_bx_market_menu_item_title_manage_all',
+                'txt_all_entries_by' => '_bx_market_txt_all_entries_by',
+                'txt_all_entries_by_author' => '_bx_market_page_title_browse_by_author',
+                'txt_per_day' => '_bx_market_txt_per_day',
+                'txt_per_day_short' => '_bx_market_txt_per_day_short',
+                'txt_per_week' => '_bx_market_txt_per_week',
+                'txt_per_week_short' => '_bx_market_txt_per_week_short',
+                'txt_per_month' => '_bx_market_txt_per_month',
+                'txt_per_month_short' => '_bx_market_txt_per_month_short',
+            	'txt_per_year' => '_bx_market_txt_per_year',
+                'txt_per_year_short' => '_bx_market_txt_per_year_short',
+                
+            ),
+        );
+
+        $this->_aJsClasses = array(
+        	'entry' => 'BxMarketEntry',
+        	'manage_tools' => 'BxMarketManageTools',
+        	'licenses' => 'BxMarketLicenses'
+        );
+
+        $this->_aJsObjects = array(
+        	'entry' => 'oBxMarketEntry',
+        	'manage_tools' => 'oBxMarketManageTools',
+        	'licenses' => 'oBxMarketLicenses'
+        );
+
+        $this->_aGridObjects = array(
+        	'common' => $this->CNF['OBJECT_GRID_COMMON'],
+        	'administration' => $this->CNF['OBJECT_GRID_ADMINISTRATION'],
+        	'licenses' => $this->CNF['OBJECT_GRID_LICENSES'],
+        );
+
+        $oPayments = BxDolPayments::getInstance();
+        $this->_aCurrency = array(
+        	'code' => $oPayments->getOption('default_currency_code'),
+        	'sign' => $oPayments->getOption('default_currency_sign')
+        );
+    }
+
+    public function getCurrency()
+    {
+    	return $this->_aCurrency;
+    }
+}
+
+/** @} */

+ 648 - 0
modules/boonex/market/updates/9.0.6_9.0.7/source/classes/BxMarketDb.php

@@ -0,0 +1,648 @@
+<?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
+ *
+ * @{
+ */
+
+/*
+ * Module database queries
+ */
+class BxMarketDb extends BxBaseModTextDb
+{
+	protected $_aRecurringDurations;
+
+    function __construct(&$oConfig)
+    {
+        parent::__construct($oConfig);
+
+        $this->_aRecurringDurations = array(
+        	'day' => 'INTERVAL 1 DAY',
+        	'week' => 'INTERVAL 7 DAY',
+        	'month' => 'INTERVAL 1 MONTH',
+        	'year' => 'INTERVAL 1 YEAR',
+        );
+    }
+
+    public function getContentInfoBy ($aParams)
+    {
+    	$CNF = &$this->_oConfig->CNF;
+
+    	$aMethod = array('name' => 'getAll', 'params' => array(0 => 'query'));
+		$aOrderWay = array('up' => 'ASC', 'down' => 'DESC');
+
+    	$sFieldsClause = $sJoinClause = $sWhereClause = $sGroupClause = $sOrderClause = $sLimitClause = '';
+
+    	//--- Add file info.
+    	$sFieldsClause .= " `te`.`" . $CNF['FIELD_PACKAGE'] . "` AS `file_id`, `tf`.`file_name` AS `file_name`, `tfe`.`version` AS `file_version`, ";
+    	$sJoinClause .= " LEFT JOIN `" . $CNF['TABLE_FILES2ENTRIES'] . "` AS `tfe` ON `te`.`" . $CNF['FIELD_ID'] . "`=`tfe`.`content_id` AND `te`.`" . $CNF['FIELD_PACKAGE'] . "`=`tfe`.`file_id` LEFT JOIN `" . $CNF['TABLE_FILES'] . "` AS `tf` ON `te`.`" . $CNF['FIELD_PACKAGE'] . "`=`tf`.`id` ";
+
+    	//--- Add license checking for Public listings if Client is specified.
+    	if(in_array($aParams['type'], array('featured', 'category', 'tag', 'vendor', 'keyword')) && isset($aParams['client']) && (int)$aParams['client'] != 0) {
+    	    //--- Direct license purchase for a product
+    	    $sLicDir = $this->prepareAsString("SELECT `tl`.`added` FROM `" . $CNF['TABLE_LICENSES'] . "` AS `tl` WHERE `tl`.`product_id`=`te`.`" . $CNF['FIELD_ID'] . "` AND `tl`.`profile_id`=? AND (`tl`.`domain`=?" . (empty($aParams['key_assigned']) ? " OR `tl`.`domain`=''" : "") . ") LIMIT 1", (int)$aParams['client'], $aParams['key']);
+
+    	    //--- License got with package purchase
+    	    $oConnnection = BxDolConnection::getObjectInstance($CNF['OBJECT_CONNECTION_SUBENTRIES']);
+            $aConnectionSql = $oConnnection->getConnectedInitiatorsAsSQLPartsMultiple('tl', 'product_id', 'te', $CNF['FIELD_ID']);
+
+    	    $sLicPack = $this->prepareAsString("SELECT `tl`.`added` FROM `" . $CNF['TABLE_LICENSES'] . "` AS `tl` " . $aConnectionSql['join'] . " WHERE 1 " . $aConnectionSql['where'] . " AND `tl`.`profile_id`=? AND (`tl`.`domain`=?" . (empty($aParams['key_assigned']) ? " OR `tl`.`domain`=''" : "") . ") LIMIT 1", (int)$aParams['client'], $aParams['key']);
+
+    		$sFieldsClause .= " ((" . $sLicDir . ") OR (" . $sLicPack . ")) AS `purchased_on`, ";
+    	}
+
+    	//--- Exclude content by ids or names
+		if(!empty($aParams['exclude_by']) && in_array($aParams['exclude_by'], array('id', 'name')) && !empty($aParams['exclude_values']))
+			$sWhereClause .= " AND `te`.`" . $aParams['exclude_by'] . "` NOT IN (" . $this->implode_escape($aParams['exclude_values']) . ") ";
+
+    	if(isset($aParams['start']) && !empty($aParams['per_page']))
+    		$sLimitClause = $aParams['start'] . ", " . $aParams['per_page'];
+
+		switch($aParams['type']) {
+			case 'id':
+				$aMethod['name'] = 'getRow';
+				$sFieldsClause .= "";
+				$sJoinClause .= "";
+				$sWhereClause .= $this->prepareAsString(" AND `te`.`" . $CNF['FIELD_ID'] . "`=? ", $aParams['value']);
+				$sOrderClause .= "";
+				break;
+
+			case 'name':
+				$aMethod['name'] = 'getRow';
+				$sFieldsClause .= "";
+				$sJoinClause .= "";
+				$sWhereClause .= $this->prepareAsString(" AND `te`.`" . $CNF['FIELD_NAME'] . "`=? ", $aParams['value']);
+				$sOrderClause .= "";
+				break;
+
+			case 'file_id':
+				$aMethod['name'] = 'getRow';
+				$sFieldsClause .= "";
+				$sJoinClause .= "";
+				$sWhereClause .= $this->prepareAsString(" AND `te`.`" . $CNF['FIELD_PACKAGE'] . "`=? ", $aParams['value']);
+				$sOrderClause .= "";
+				break;
+
+			case 'latest':
+				$sFieldsClause .= "";
+				$sJoinClause .= "";
+				$sWhereClause .= "";
+				$sOrderClause = "`te`.`added` " . (isset($aParams['order_way']) ? $aOrderWay[$aParams['order_way']] : "DESC");
+				break;
+
+			case 'featured':
+				$sFieldsClause .= "";
+				$sJoinClause .= "";
+				$sWhereClause .= " AND `te`.`" . $CNF['FIELD_FEATURED'] . "`<>0";
+				$sOrderClause = "`te`.`" . $CNF['FIELD_FEATURED'] . "` " . (isset($aParams['order_way']) ? $aOrderWay[$aParams['order_way']] : "DESC");
+				break;
+
+            case 'popular':
+				$sFieldsClause .= "";
+				$sJoinClause .= "";
+				$sWhereClause .= "";
+				$sOrderClause = "`te`.`views` " . (isset($aParams['order_way']) ? $aOrderWay[$aParams['order_way']] : "DESC");
+				break;
+
+			case 'selected':
+				$sFieldsClause .= "";
+				$sJoinClause .= "";
+				$sWhereClause .= " AND `te`.`id` IN (" . $this->implode_escape($aParams['selected']) . ") ";
+				$sOrderClause = "`te`.`added` " . (isset($aParams['order_way']) ? $aOrderWay[$aParams['order_way']] : "DESC");
+				break;
+
+			case 'category':
+				if(!is_array($aParams['value']))
+					$aParams['value'] = array($aParams['value']);
+
+				$sFieldsClause .= "";
+				$sJoinClause .= "";
+				$sWhereClause .= " AND `te`.`" . $CNF['FIELD_CATEGORY'] . "` IN (" . $this->implode_escape($aParams['value']) . ")";
+				$sOrderClause = "`te`.`added` " . (isset($aParams['order_way']) ? $aOrderWay[$aParams['order_way']] : "DESC");
+				break;
+
+			case 'tag':
+			    $sFieldsClause .= "";
+
+			    $aSql = BxDolMetatags::getObjectInstance($CNF['OBJECT_METATAGS'])->keywordsGetAsSQLPart('te', $CNF['FIELD_ID'], $aParams['value']);
+                if(!empty($aSql['where'])) {
+                    $sWhereClause .= $aSql['where'];
+                
+                    if(!empty($aSql['join']))
+                        $sJoinClause .= $aSql['join'];
+                }
+
+				$sOrderClause = "`te`.`added` " . (isset($aParams['order_way']) ? $aOrderWay[$aParams['order_way']] : "DESC");
+				break;
+
+			case 'vendor':
+				$sFieldsClause .= "";
+				$sJoinClause .= "";
+
+				$sWhereClause .= $this->prepareAsString(" AND `te`.`" . $CNF['FIELD_AUTHOR'] . "`=? ", (int)$aParams['value']); 
+				if(isset($aParams['paid']) && (int)$aParams['paid'] == 1)
+					$sWhereClause .= " AND `te`.`" . $CNF['FIELD_PRICE_SINGLE'] . "`<>'0' AND `te`.`" . $CNF['FIELD_PRICE_RECURRING'] . "`<>'0'";
+
+				$sOrderClause = "`te`.`" . (isset($aParams['order_by']) ? $aParams['order_by'] : "added") . "` " . (isset($aParams['order_way']) ? $aOrderWay[$aParams['order_way']] : "DESC");
+				break;
+
+			case 'keyword':
+				$sFieldsClause .= $this->prepareAsString(" MATCH(`" . $CNF['FIELD_TITLE'] . "`, `" . $CNF['FIELD_TEXT'] . "`) AGAINST (?) AS `search_condition`, ", $aParams['value']);
+				$sJoinClause .= "";
+				$sWhereClause .= $this->prepareAsString(" AND MATCH(`" . $CNF['FIELD_TITLE'] . "`, `" . $CNF['FIELD_TEXT'] . "`) AGAINST (?) ", $aParams['value']);
+				$sOrderClause = "`search_condition` " . (isset($aParams['order_way']) ? $aOrderWay[$aParams['order_way']] : "DESC");
+				break;
+
+			case 'granted':
+				$sFieldsClause .= " '" . $aParams['license']['license'] . "' AS `license`, '" . $aParams['license']['profile_id'] . "' AS `purchased_by`, '' AS `purchased_for`, '" . $aParams['license']['added'] . "' AS `purchased_on`, ";
+				$sWhereClause .= $this->prepareAsString(" AND `te`.`" . $CNF['FIELD_AUTHOR'] . "`=? AND (`te`.`" . $CNF['FIELD_PRICE_SINGLE'] . "`<>'0' OR `te`.`" . $CNF['FIELD_PRICE_RECURRING'] . "`<>'0') ", (int)$aParams['value']);
+				$sOrderClause = "`te`.`added` " . (isset($aParams['order_way']) ? $aOrderWay[$aParams['order_way']] : "DESC");
+				break;
+
+			case 'purchased':
+				$sFieldsClause .= " `tl`.`license` AS `license`, `tl`.`profile_id` AS `purchased_by`, `tl`.`domain` AS `purchased_for`, `tl`.`added` AS `purchased_on`, ";
+
+				if(isset($aParams['package']) && (int)$aParams['package'] == 1) {
+				    $oConnnection = BxDolConnection::getObjectInstance($CNF['OBJECT_CONNECTION_SUBENTRIES']);
+                    $aConnectionSql = $oConnnection->getConnectedContentAsSQLPartsMultiple('te', $CNF['FIELD_ID'], 'tl', 'product_id');
+
+                    $sJoinClause .= " " . $aConnectionSql['join'] . " LEFT JOIN `" . $CNF['TABLE_LICENSES'] . "` AS `tl` ON " . trim($aConnectionSql['where'], " AND ") . " ";
+				}
+				else
+    				$sJoinClause .= " LEFT JOIN `" . $CNF['TABLE_LICENSES'] . "` AS `tl` ON `te`.`" . $CNF['FIELD_ID'] . "`=`tl`.`product_id` ";
+
+				$sWhereClause .= $this->prepareAsString(" AND `tl`.`profile_id`=? AND (`tl`.`domain`=?" . (empty($aParams['key_assigned']) ? " OR `tl`.`domain`=''" : "") . ") ", (int)$aParams['client'], $aParams['key']);
+				$sGroupClause .= "`te`.`" . $CNF['FIELD_ID'] . "`";
+				$sOrderClause = "`tl`.`added` " . (isset($aParams['order_way']) ? $aOrderWay[$aParams['order_way']] : "DESC");
+				break;
+		}
+
+		$sGroupClause = $sGroupClause ? "GROUP BY " . $sGroupClause : "";
+		$sOrderClause = $sOrderClause ? "ORDER BY " . $sOrderClause : "";
+		$sLimitClause = $sLimitClause ? "LIMIT " . $sLimitClause : "";
+
+		$aMethod['params'][0] = "SELECT
+        		" . $sFieldsClause . "`te`.*
+            FROM `" . $CNF['TABLE_ENTRIES'] . "` AS `te`" . $sJoinClause . "
+            WHERE 1" . $sWhereClause . " " . $sGroupClause . " " . $sOrderClause . " " . $sLimitClause;
+
+        return call_user_func_array(array($this, $aMethod['name']), $aMethod['params']);
+    }
+
+	public function getContentInfoByName ($sContentName)
+    {
+        $sQuery = $this->prepare ("SELECT * FROM `" . $this->_oConfig->CNF['TABLE_ENTRIES'] . "` WHERE `" . $this->_oConfig->CNF['FIELD_NAME'] . "` = ?", $sContentName);
+        return $this->getRow($sQuery);
+    }
+
+	public function getPhoto($aParams = array())
+    {
+    	return $this->_getAttachment($this->_oConfig->CNF['TABLE_PHOTOS2ENTRIES'], $aParams);
+    }
+
+	public function updatePhoto($aSet, $aWhere)
+    {
+    	return $this->_updateAttachment($this->_oConfig->CNF['TABLE_PHOTOS2ENTRIES'], $aSet, $aWhere);
+    }
+
+    public function getFile($aParams = array())
+    {
+    	return $this->_getAttachment($this->_oConfig->CNF['TABLE_FILES2ENTRIES'], $aParams);
+    }
+
+	public function updateFile($aSet, $aWhere)
+    {
+    	return $this->_updateAttachment($this->_oConfig->CNF['TABLE_FILES2ENTRIES'], $aSet, $aWhere);
+    }
+
+	public function associatePhotoWithContent($iContentId, $iFileId, $sTitle)
+    {
+        $sQuery = $this->prepare ("SELECT MAX(`order`) FROM `" . $this->_oConfig->CNF['TABLE_PHOTOS2ENTRIES'] . "` WHERE `content_id` = ?", $iContentId);
+        $iOrder = 1 + (int)$this->getOne($sQuery);
+
+        $sQuery = $this->prepare ("INSERT INTO `" . $this->_oConfig->CNF['TABLE_PHOTOS2ENTRIES'] . "` SET `content_id` = ?, `file_id` = ?, `title` = ?, `order` = ? ON DUPLICATE KEY UPDATE `title` = ?", $iContentId, $iFileId, $sTitle, $iOrder, $sTitle);
+        return $this->res($sQuery);
+    }
+
+	public function deassociatePhotoWithContent($iContentId, $iFileId)
+    {
+    	return $this->_deassociateAttachmentWithContent($this->_oConfig->CNF['TABLE_PHOTOS2ENTRIES'], $iContentId, $iFileId);
+    }
+
+    public function associateFileWithContent($iContentId, $iFileId, $aParams)
+    {
+        $sQuery = $this->prepare ("SELECT MAX(`order`) FROM `" . $this->_oConfig->CNF['TABLE_FILES2ENTRIES'] . "` WHERE `content_id` = ?", $iContentId);
+        $iOrder = 1 + (int)$this->getOne($sQuery);
+
+        $aBindings = array_merge(array(
+        	'content_id' => $iContentId,
+        	'file_id' => $iFileId,
+        	'order' => $iOrder,
+        ), $aParams);
+
+        $sDiv = ", ";
+        $sParams = "";
+        foreach($aParams as $sKey => $mixedValue)
+            $sParams .= "`" . $sKey . "` = :" . $sKey . $sDiv;
+		$sParams = trim($sParams, $sDiv);
+
+        $sQuery = $this->prepare("INSERT INTO `" . $this->_oConfig->CNF['TABLE_FILES2ENTRIES'] . "` SET `content_id` = :content_id, `file_id` = :file_id, " . $sParams . ", `order` = :order ON DUPLICATE KEY UPDATE " . $sParams);
+        return $this->res($sQuery, $aBindings);
+    }
+
+    public function deassociateFileWithContent($iContentId, $iFileId)
+    {
+    	return $this->_deassociateAttachmentWithContent($this->_oConfig->CNF['TABLE_FILES2ENTRIES'], $iContentId, $iFileId);
+    }
+
+    public function insertDownload($iFileId, $iProfileId, $iProfileNip)
+    {
+    	$sQuery = $this->prepare("INSERT IGNORE INTO `" . $this->_oConfig->CNF['TABLE_DOWNLOADS'] . "` SET `file_id` = ?, `profile_id` = ?, `profile_nip` = ?, `date` = UNIX_TIMESTAMP()", $iFileId, $iProfileId, $iProfileNip);
+		return (int)$this->query($sQuery) > 0;
+    }
+
+    /**
+     * Integration with Payment based modules.  
+     */
+	public function getLicense($aParams = array())
+    {
+    	$CNF = &$this->_oConfig->CNF;
+    	$aMethod = array('name' => 'getAll', 'params' => array(0 => 'query'));
+
+    	$sSelectClause = "`tl`.*";
+    	$sJoinClause = $sWhereClause = $sLimitClause = "";
+        switch($aParams['type']) {
+            case 'id':
+            	$aMethod['name'] = 'getRow';
+            	$aMethod['params'][1] = array(
+                	'id' => $aParams['id']
+                );
+
+                $sWhereClause = " AND `tl`.`id`=:id";
+                break;
+
+            case 'new':
+				$aMethod['params'][1] = array(
+                	'profile_id' => $aParams['profile_id']
+                );
+
+                $sWhereClause = " AND `tl`.`profile_id`=:profile_id AND `tl`.`new`='1'";
+                break;
+
+			case 'unused':
+				$aMethod['params'][1] = array(
+                	'profile_id' => $aParams['profile_id']
+                );
+
+                $sWhereClause = " AND `tl`.`profile_id`=:profile_id AND `tl`.`domain`=''";
+                break;
+
+			case 'expired':
+				$aMethod['params'][1] = array(
+                	'type' => BX_MARKET_LICENSE_TYPE_RECURRING
+                );
+
+				$sWhereClause = " AND `type` = :type AND `added` < UNIX_TIMESTAMP() AND `expired` <> 0 AND `expired` < UNIX_TIMESTAMP()";
+				break;
+
+			case 'profile_id':
+				$aMethod['params'][1] = array(
+                	'profile_id' => $aParams['profile_id']
+                );
+
+				$sWhereClause = " AND `tl`.`profile_id`=:profile_id";
+
+				if(!empty($aParams['product_id'])) {
+					$aMethod['params'][1]['product_id'] = $aParams['product_id'];
+					$sWhereClause .= " AND `tl`.`product_id`=:product_id";
+				}
+				break;
+
+			case 'profile_id_file_id_key':
+				$aMethod['name'] = "getRow";
+				$aMethod['params'][1] = array(
+                	'profile_id' => $aParams['profile_id'],
+					'key' => $aParams['key']
+                );
+
+				$iProductId = $this->getOne("SELECT `" . $CNF['FIELD_ID'] . "` FROM `" . $this->_oConfig->CNF['TABLE_ENTRIES'] . "` WHERE `" . $CNF['FIELD_PACKAGE'] . "`=:file_id LIMIT 1", array(
+				    'file_id' => $aParams['file_id']
+				));
+
+				if(isset($aParams['package']) && (int)$aParams['package'] == 1) {
+				    $oConnnection = BxDolConnection::getObjectInstance($CNF['OBJECT_CONNECTION_SUBENTRIES']);
+                    $aConnectionSql = $oConnnection->getConnectedInitiatorsAsSQLParts('tl', 'product_id', $iProductId);
+
+                    $sJoinClause .= $aConnectionSql['join'];
+				}
+				else {
+                    $aMethod['params'][1]['product_id'] = $iProductId;
+
+                    $sWhereClause .= " AND `tl`.`product_id`=:product_id";
+				}
+
+				$sWhereClause .= " AND `tl`.`profile_id`=:profile_id AND (`tl`.`domain`='' OR `tl`.`domain`=:key)";
+				$sLimitClause = "1";
+				break;
+
+			case 'has_by':
+				$aMethod['name'] = "getOne";
+				$aMethod['params'][1] = array(
+                	'profile_id' => $aParams['profile_id']
+                );
+
+                $sSelectClause = "`tl`.`id`";
+                $sWhereClause = " AND `tl`.`profile_id`=:profile_id";
+
+                if(isset($aParams['package']) && (int)$aParams['package'] == 1) {
+                    $oConnnection = BxDolConnection::getObjectInstance($CNF['OBJECT_CONNECTION_SUBENTRIES']);
+                    $aConnectionSql = $oConnnection->getConnectedInitiatorsAsSQLParts('tl', 'product_id', $aParams['product_id']);
+
+                    $sJoinClause .= $aConnectionSql['join'];
+                }
+                else {
+                    $aMethod['params'][1]['product_id'] = $aParams['product_id'];
+
+                    $sWhereClause .= " AND `tl`.`product_id`=:product_id";
+                }
+
+                if(!empty($aParams['domain'])) {
+                	$aMethod['params'][1]['domain'] = $aParams['domain'];
+                	$sWhereClause .= " AND `tl`.`domain`=:domain";
+                }
+
+		        if(!empty($aParams['order'])) {
+                	$aMethod['params'][1]['order'] = $aParams['order'];
+                	$sWhereClause .= " AND `tl`.`order`=:order";
+                }
+
+                $sLimitClause = "1";
+                break;
+        }
+
+        $sLimitClause = !empty($sLimitClause) ? "LIMIT " . $sLimitClause : $sLimitClause;
+
+        $aMethod['params'][0] = "SELECT
+        		" . $sSelectClause . "
+            FROM `" . $this->_oConfig->CNF['TABLE_LICENSES'] . "` AS `tl`" . $sJoinClause . "
+            WHERE 1" . $sWhereClause . " " . $sLimitClause;
+
+        return call_user_func_array(array($this, $aMethod['name']), $aMethod['params']);
+    }
+
+	public function updateLicense($aSet, $aWhere)
+    {
+        $sQuery = "UPDATE `" . $this->_oConfig->CNF['TABLE_LICENSES'] . "` SET " . $this->arrayToSQL($aSet) . " WHERE " . (!empty($aWhere) ? $this->arrayToSQL($aWhere, ' AND ') : "1");
+        return (int)$this->query($sQuery) > 0;
+    }
+
+	public function deleteLicense($aWhere)
+    {
+    	if(empty($aWhere))
+    		return false;
+
+        $sQuery = "DELETE FROM `" . $this->_oConfig->CNF['TABLE_LICENSES'] . "` WHERE " . $this->arrayToSQL($aWhere, ' AND ');
+        return (int)$this->query($sQuery) > 0;
+    }
+
+    public function hasLicense ($iProfileId, $iProductId, $sDomain = '')
+    {
+        $aParams = array(
+    		'type' => 'has_by', 
+    		'profile_id' => $iProfileId, 
+    		'product_id' => $iProductId, 
+    		'domain' => !empty($sDomain) ? $sDomain : ''
+    	);
+ 
+        $iLicenseId = (int)$this->getLicense($aParams);
+    	if($iLicenseId > 0)
+    	    return true;
+
+        $aParams['package'] = 1;
+        $iLicenseId = (int)$this->getLicense($aParams);
+    	if($iLicenseId > 0)
+    	    return true;
+
+    	return false;
+    }
+
+	public function hasLicenseByOrder ($iProfileId, $iProductId, $sOrder = '')
+    {
+        $aParams = array(
+    		'type' => 'has_by', 
+    		'profile_id' => $iProfileId, 
+    		'product_id' => $iProductId, 
+    		'order' => !empty($sOrder) ? $sOrder : ''
+    	);
+
+        $iLicenseId = (int)$this->getLicense($aParams);
+        if($iLicenseId > 0)
+    	    return true;
+
+        $aParams['package'] = 1;
+        $iLicenseId = (int)$this->getLicense($aParams);
+    	if($iLicenseId > 0)
+    	    return true;
+
+    	return false;
+    }
+
+	public function registerLicense($iProfileId, $iProductId, $iCount, $sOrder, $sLicense, $sType, $sDuration = '', $iTrial = 0)
+    {
+    	$CNF = &$this->_oConfig->CNF;
+
+    	$aQueryParams = array(
+    		'profile_id' => $iProfileId,
+    		'product_id' => $iProductId,
+    		'count' => $iCount, 
+    		'order' => $sOrder, 
+    		'license' => $sLicense,
+    		'type' => $sType
+    	);
+
+		$sExpireParam = '';
+		if(!empty($iTrial))
+		    $sExpireParam = ', `expired`=UNIX_TIMESTAMP(DATE_ADD(DATE_ADD(NOW(), INTERVAL ' . (int)$iTrial . ' DAY), INTERVAL ' . (int)$this->getParam($CNF['OPTION_RECURRING_RESERVE']) . ' DAY))';
+		else if(!empty($sDuration) && isset($this->_aRecurringDurations[$sDuration]))
+			$sExpireParam = ', `expired`=UNIX_TIMESTAMP(DATE_ADD(DATE_ADD(NOW(), ' . $this->_aRecurringDurations[$sDuration] . '), INTERVAL ' . (int)$this->getParam($CNF['OPTION_RECURRING_RESERVE']) . ' DAY))';
+
+    	$sQuery = $this->prepare("INSERT INTO `" . $CNF['TABLE_LICENSES'] . "` SET " . $this->arrayToSQL($aQueryParams) . ", `added`=UNIX_TIMESTAMP()" . $sExpireParam);
+        return (int)$this->query($sQuery) > 0;
+    }
+
+    public function prolongLicense($iProfileId, $iProductId, $iCount, $sOrder, $sLicense, $sType, $sDuration = '', $iTrial = 0)
+    {
+    	$CNF = &$this->_oConfig->CNF;
+
+    	if($sType == BX_MARKET_LICENSE_TYPE_SINGLE)
+    		return true;
+
+    	if(empty($sDuration) || empty($this->_aRecurringDurations[$sDuration]))
+    		return false;
+
+    	$sQuery = $this->prepare("UPDATE 
+    			`" . $CNF['TABLE_LICENSES'] . "` 
+    		SET 
+    			`expired`=UNIX_TIMESTAMP(DATE_ADD(FROM_UNIXTIME(`expired`), " . $this->_aRecurringDurations[$sDuration] . ")) 
+    		WHERE 
+    			`profile_id` = ? AND 
+    			`product_id` = ? AND 
+    			`order` = ? 
+    		LIMIT 1", $iProfileId, $iProductId, $sOrder);
+
+        return (int)$this->query($sQuery) > 0;
+    }
+
+    public function unregisterLicense($iProfileId, $iProductId, $sOrder, $sLicense, $sType)
+    {
+    	$sWhereClause = "`profile_id` = :profile_id AND `product_id` = :product_id AND `order` = :order AND `license` = :license";
+    	$aWhereBindings = array(
+    		'profile_id' => $iProfileId,
+    		'product_id' => $iProductId,
+    		'order' => $sOrder,
+    		'license' => $sLicense
+    	);
+    	
+		//--- Move to deleted licenses table with 'refund' as reason.   
+    	$sQuery = "INSERT IGNORE INTO `" . $this->_oConfig->CNF['TABLE_LICENSES_DELETED'] . "` SELECT *, 'refund' AS `reason`, UNIX_TIMESTAMP() AS `deleted` FROM `" . $this->_oConfig->CNF['TABLE_LICENSES'] . "` WHERE " . $sWhereClause;
+		$this->query($sQuery, $aWhereBindings);
+
+    	$sQuery = "DELETE FROM `" . $this->_oConfig->CNF['TABLE_LICENSES'] . "` WHERE " . $sWhereClause;
+        return $this->query($sQuery, $aWhereBindings) !== false;
+    }
+
+	function processExpiredLicenses()
+	{
+		$sWhereClause = "`type` = :type AND `added` < UNIX_TIMESTAMP() AND `expired` <> 0 AND `expired` < UNIX_TIMESTAMP()";
+    	$aWhereBindings = array(
+    		'type' => BX_MARKET_LICENSE_TYPE_RECURRING
+    	);
+
+    	//--- Move to deleted licenses table with 'expire' as reason.  
+		$sQuery = "INSERT IGNORE INTO `" . $this->_oConfig->CNF['TABLE_LICENSES_DELETED'] . "` SELECT *, 'expire' AS `reason`, UNIX_TIMESTAMP() AS `deleted` FROM `" . $this->_oConfig->CNF['TABLE_LICENSES'] . "` WHERE " . $sWhereClause;
+		$this->query($sQuery, $aWhereBindings);
+
+		$sQuery = "DELETE FROM `" . $this->_oConfig->CNF['TABLE_LICENSES'] . "` WHERE " . $sWhereClause;
+		return $this->query($sQuery, $aWhereBindings) !== false;	    
+	}
+
+	protected function _deassociateAttachmentWithContent($sTable, $iContentId, $iFileId)
+    {
+        $sWhere = '';
+        $aBindings = array();
+        if ($iContentId) {
+            $sWhere .= " AND `content_id` = :content_id ";
+            $aBindings['content_id'] = $iContentId;
+        }
+
+        if ($iFileId) {
+            $sWhere .= " AND `file_id` = :file_id ";
+            $aBindings['file_id'] = $iFileId;
+        }
+
+        $sQuery = "DELETE FROM `" . $sTable . "` WHERE 1 " . $sWhere;
+        return $this->query($sQuery, $aBindings) !== false;
+    }
+
+	protected function _getAttachment($sTable, $aParams = array())
+    {
+    	$aMethod = array('name' => 'getRow', 'params' => array(0 => 'query'));
+    	
+    	$sFieldsClause = "`tfe`.*";
+    	$sJoinClause = $sWhereClause = $sOrderClause = $sLimitClause = "";
+        switch($aParams['type']) {
+            case 'id':
+            	$aMethod['params'][1] = array(
+                	'id' => $aParams['id']
+                );
+
+                $sWhereClause = " AND `tfe`.`id`=:id";
+                break;
+
+			case 'file_id':
+				$aMethod['params'][1] = array(
+                	'file_id' => $aParams['file_id']
+                );
+
+                $sWhereClause = " AND `tfe`.`file_id`=:file_id";
+                break;
+
+			case 'file_id_ext':
+				$aMethod['params'][1] = array(
+                	'file_id' => $aParams['file_id']
+                );
+
+                $sFieldsClause .= ", `tf`.`file_name`, `tf`.`size` AS `file_size`";
+                $sJoinClause = " LEFT JOIN `" . $this->_oConfig->CNF['TABLE_FILES'] . "` AS `tf` ON `tfe`.`file_id`=`tf`.`id` ";
+                $sWhereClause = " AND `tfe`.`file_id`=:file_id";
+                break;
+                
+
+            case 'content_id':
+            	$aMethod['name'] = 'getAll';
+            	$aMethod['params'][1] = array(
+                	'content_id' => $aParams['content_id']
+                );
+
+            	$sWhereClause = " AND `tfe`.`content_id`=:content_id";
+            	if(!empty($aParams['except']))
+            		$sWhereClause .= " AND `tfe`.`file_id` NOT IN (" . $this->implode_escape($aParams['except']) . ")";
+
+            	break;
+
+			case 'content_id_key_file_id':
+				$aMethod['name'] = 'getAllWithKey';
+				$aMethod['params'][1] = 'file_id';
+				$aMethod['params'][2] = array(
+                	'content_id' => $aParams['content_id']
+                );
+
+                $sWhereClause = " AND `tfe`.`content_id`=:content_id";
+                $sOrderClause = "`tfe`.`type` ASC, `tfe`.`version` DESC";
+                break;
+
+			case 'content_id_and_type':
+				$aMethod['name'] = 'getAll';
+            	$aMethod['params'][1] = array(
+                	'content_id' => $aParams['content_id'],
+            		'type' => $aParams['file_type']
+                );
+
+                $sFieldsClause .= ", `tf`.`file_name`, `tf`.`size` AS `file_size`";
+                $sJoinClause = " LEFT JOIN `" . $this->_oConfig->CNF['TABLE_FILES'] . "` AS `tf` ON `tfe`.`file_id`=`tf`.`id` ";
+                $sWhereClause = " AND `tfe`.`content_id`=:content_id AND `tfe`.`type`=:type";
+
+                if(!empty($aParams['version'])) {
+                	$aMethod['name'] = 'getRow';
+                	$aMethod['params'][1]['version'] = $aParams['version'];
+                	$sWhereClause .= " AND `tfe`.`version`=:version";
+                }
+            	break;
+        }
+
+        if(!empty($sOrderClause))
+            $sOrderClause = " ORDER BY " . $sOrderClause;
+
+        if(!empty($sLimitClause))
+            $sLimitClause = " LIMIT " . $sLimitClause;
+
+        $aMethod['params'][0] = "SELECT
+        		" . $sFieldsClause . "
+            FROM `" . $sTable . "` AS `tfe`" . $sJoinClause . "
+            WHERE 1" . $sWhereClause . $sOrderClause . $sLimitClause;
+
+        return call_user_func_array(array($this, $aMethod['name']), $aMethod['params']);
+    }
+
+	protected function _updateAttachment($sTable, $aSet, $aWhere)
+    {
+        $sQuery = "UPDATE `" . $sTable . "` SET " . $this->arrayToSQL($aSet) . " WHERE " . (!empty($aWhere) ? $this->arrayToSQL($aWhere, ' AND ') : "1");
+        return (int)$this->query($sQuery) > 0;
+    }
+}
+
+/** @} */

+ 285 - 0
modules/boonex/market/updates/9.0.6_9.0.7/source/classes/BxMarketFormEntry.php

@@ -0,0 +1,285 @@
+<?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
+{
+    public function __construct($aInfo, $oTemplate = false)
+    {
+        $this->MODULE = 'bx_market';
+        parent::__construct($aInfo, $oTemplate);
+
+        $CNF = &$this->_oModule->_oConfig->CNF;
+
+        $iProfileId = bx_get_logged_profile_id();
+
+        if(isset($this->aInputs[$CNF['FIELD_TITLE']], $this->aInputs[$CNF['FIELD_NAME']])) {
+        	$sJsObject = $this->_oModule->_oConfig->getJsObject('entry');
+
+        	$this->aInputs[$CNF['FIELD_TITLE']]['attrs']['onblur'] = "javascript:" . $sJsObject . ".checkName('" . $CNF['FIELD_TITLE'] . "', '" . $CNF['FIELD_NAME'] . "');";
+        }
+
+	    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();
+        if(isset($this->aInputs[$CNF['FIELD_WARNING_SINGLE']])) {
+	        if(!$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($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)
+    {
+        return $this->_oModule->_oTemplate->parseHtmlByName('form.html', array(
+            'content' => parent::getCode($bDynamicMode)
+        ));
+    }
+
+	function initChecker ($aValues = array (), $aSpecificValues = array())
+    {
+        $CNF = &$this->_oModule->_oConfig->CNF;
+
+        if (isset($this->aInputs[$CNF['FIELD_FILE']])) {
+
+            $aContentInfo = false;
+            if ($aValues && !empty($aValues['id'])) {
+                $aContentInfo = $this->_oModule->_oDb->getContentInfoById ($aValues['id']);
+                $this->aInputs[$CNF['FIELD_FILE']]['content_id'] = $aValues['id'];
+            }
+
+            $this->aInputs[$CNF['FIELD_FILE']]['ghost_template'] = $this->_oModule->_oTemplate->getGhostTemplateFile($this, $aContentInfo);
+        }
+
+        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 = array(), $isIgnore = false)
+    {
+        $CNF = &$this->_oModule->_oConfig->CNF;
+
+	    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($this->_oModule->checkAllowedSetCover() === CHECK_ACTION_RESULT_ALLOWED) {
+            $aCover = bx_process_input (bx_get($CNF['FIELD_COVER']), 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 = array())
+    {
+    	$CNF = &$this->_oModule->_oConfig->CNF;
+
+    	$aResult = parent::_getPhotoGhostTmplVars($aContentInfo);
+    	$aResult = array_merge($aResult, array(
+    		'cover_id' => isset($aContentInfo[$CNF['FIELD_COVER']]) ? $aContentInfo[$CNF['FIELD_COVER']] : 0,
+    		'bx_if:set_cover' => array (
+				'condition' => CHECK_ACTION_RESULT_ALLOWED === $this->_oModule->checkAllowedSetCover(),
+				'content' => array (
+					'name_cover' => $CNF['FIELD_COVER'],
+				),
+			),
+    	));
+
+    	return $aResult;
+	}
+
+    protected function genCustomInputSubentries($aInput)
+    {
+        $CNF = &$this->_oModule->_oConfig->CNF;
+
+        $sGetSubentriesUrl = BX_DOL_URL_ROOT . $this->_oModule->_oConfig->getBaseUri() . 'get_subentries';
+        $sPlaceholder = bx_html_attribute(_t('_bx_market_form_entry_input_subentries_placeholder'), BX_ESCAPE_STR_QUOTE);
+
+        $this->addJsJQueryUI();
+
+        $this->oTemplate->addJs(array(
+            'jquery.form.min.js',
+        ));
+
+        $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, ',');
+        }
+
+        return $this->oTemplate->parseHtmlByName('form_field_custom_suggestions.html', array(
+            'id' => $aInput['name'] . time(),
+            'url_get_recipients' => $sGetSubentriesUrl,
+            'name' => $aInput['name'],
+			'b_img' => 1,
+			'only_once' => 0,
+			'on_select' => 'null',
+		    'placeholder' => $sPlaceholder,
+            'vals' => $sVals,
+        ));
+    }
+}
+
+/** @} */

+ 33 - 0
modules/boonex/market/updates/9.0.6_9.0.7/source/classes/BxMarketMenuSnippetMeta.php

@@ -0,0 +1,33 @@
+<?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
+ *
+ * @{
+ */
+
+class BxMarketMenuSnippetMeta extends BxBaseModTextMenuSnippetMeta
+{
+    public function __construct($aObject, $oTemplate = false)
+    {
+        $this->_sModule = 'bx_market';
+
+        parent::__construct($aObject, $oTemplate);
+    }
+
+    protected function _getMenuItemAuthor($aItem)
+    {
+        $CNF = &$this->_oModule->_oConfig->CNF;
+
+        $oProfile = BxDolProfile::getInstance($this->_aContentInfo[$CNF['FIELD_AUTHOR']]);
+        if(!$oProfile) 
+            $oProfile = BxDolProfileUndefined::getInstance();
+
+        return $this->_oTemplate->getUnitMetaItemText($oProfile->getDisplayName());
+    }
+}
+
+/** @} */

+ 1042 - 0
modules/boonex/market/updates/9.0.6_9.0.7/source/classes/BxMarketModule.php

@@ -0,0 +1,1042 @@
+<?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
+ *
+ * @{
+ */
+
+define('BX_MARKET_LICENSE_TYPE_SINGLE', 'single'); //--- one-time payment license
+define('BX_MARKET_LICENSE_TYPE_RECURRING', 'recurring'); //--- recurring payment license
+
+define('BX_MARKET_FILE_TYPE_VERSION', 'version');
+define('BX_MARKET_FILE_TYPE_UPDATE', 'update');
+
+/**
+ * Market module
+ */
+class BxMarketModule extends BxBaseModTextModule
+{
+    function __construct(&$aModule)
+    {
+        parent::__construct($aModule);
+
+        $CNF = &$this->_oConfig->CNF;
+        $this->_aSearchableNamesExcept = array_merge($this->_aSearchableNamesExcept, array(
+             $CNF['FIELD_NAME'],
+             $CNF['FIELD_PRICE_SINGLE'],
+             $CNF['FIELD_PRICE_RECURRING'],
+             $CNF['FIELD_DURATION_RECURRING'],
+             $CNF['FIELD_TRIAL_RECURRING'],
+             $CNF['FIELD_ALLOW_PURCHASE_TO'],
+             $CNF['FIELD_ALLOW_COMMENT_TO'],
+             $CNF['FIELD_ALLOW_VOTE_TO']
+        ));
+    }
+
+    public function actionCheckName()
+    {
+    	$CNF = &$this->_oConfig->CNF;
+
+    	$sTitle = strtolower(bx_process_input(bx_get('title')));
+    	if(empty($sTitle))
+    		return echoJson(array());
+
+    	echoJson(array(
+    		'title' => $sTitle,
+    		'name' => uriGenerate($sTitle, $CNF['TABLE_ENTRIES'], $CNF['FIELD_NAME'])
+    	));
+    }
+
+    public function actionGetSubentries()
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        $sTerm = bx_get('term');
+        $iLimit = (int)bx_get('limit');
+        if(empty($iLimit))
+            $iLimit = 10;
+
+        $aResult = array();
+        $aEntries = $this->_oDb->searchByAuthorTerm($this->_iProfileId, $sTerm, $iLimit);
+        foreach ($aEntries as $aEntry)
+            $aResult[] = array('value' => $aEntry[$CNF['FIELD_ID']], 'label' => $aEntry[$CNF['FIELD_TITLE']]);
+
+        // sort result
+        usort($aResult, function($r1, $r2) {
+            return strcmp($r1['label'], $r2['label']);
+        });
+
+        echoJson(array_slice($aResult, 0, $iLimit));
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_market Market
+     * @subsection bx_market-other Other
+     * @subsubsection bx_market-get_searchable_fields get_searchable_fields
+     * 
+     * @code bx_srv('bx_market', 'get_searchable_fields', [...]); @endcode
+     * 
+     * Get a list of searchable fields. Is used in common search engine. 
+     *
+     * @return an array with a list of searchable fields.
+     * 
+     * @see BxMarketModule::serviceGetSearchableFields
+     */
+    /** 
+     * @ref bx_market-get_searchable_fields "get_searchable_fields"
+     */
+    public function serviceGetSearchableFields ()
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        $aResult = parent::serviceGetSearchableFields();
+        unset($aResult[$CNF['FIELD_PRICE_SINGLE']], $aResult[$CNF['FIELD_TRIAL_RECURRING']]);
+
+        return $aResult;
+    }
+    
+    /**
+     * @page service Service Calls
+     * @section bx_market Market
+     * @subsection bx_market-page_blocks Page Blocks
+     * @subsubsection bx_market-entity_create entity_create
+     * 
+     * @code bx_srv('bx_market', 'entity_create', [...]); @endcode
+     * 
+     * Get page block with product creation form or an error message if something wasn't configured correctly.
+     *
+     * @return HTML 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 BxMarketModule::serviceEntityCreate
+     */
+    /** 
+     * @ref bx_market-entity_create "entity_create"
+     */
+    public function serviceEntityCreate ()
+    {
+    	$oPayments = BxDolPayments::getInstance();
+    	if(!$oPayments->isActive())
+    		return MsgBox(_t('_bx_market_err_no_payments'));
+
+    	if(!$oPayments->isAcceptingPayments($this->_iProfileId))
+    		return MsgBox(_t('_bx_market_err_not_accept_payments', $oPayments->getDetailsUrl()));
+
+    	$this->_oTemplate->addJs(array('entry.js'));
+    	return $this->_oTemplate->getJsCode('entry') . parent::serviceEntityCreate();
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_market Market
+     * @subsection bx_market-page_blocks Page Blocks
+     * @subsubsection bx_market-entity_download entity_download
+     * 
+     * @code bx_srv('bx_market', 'entity_download', [...]); @endcode
+     * 
+     * Get page block with a list of downloadable packages attached to the product. If something is wrong an error message is returned.
+     *
+     * @param $iContentId (optional) product's ID. If empty value is provided, an attempt to get it from GET/POST arrays will be performed.
+     * @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 BxMarketModule::serviceEntityDownload
+     */
+    /** 
+     * @ref bx_market-entity_download "entity_download"
+     */
+    public function serviceEntityDownload ($iContentId = 0)
+    {
+    	$CNF = &$this->_oConfig->CNF;
+
+    	if(!$iContentId)
+            $iContentId = bx_process_input(bx_get('id'), BX_DATA_INT);
+
+        if(!$iContentId)
+            return false;
+
+		$aContentInfo = $this->_oDb->getContentInfoById($iContentId);
+		if(empty($aContentInfo) || !is_array($aContentInfo))
+            return MsgBox(_t('_sys_txt_error_occured'));
+
+    	if($this->checkAllowedDownload($aContentInfo) !== CHECK_ACTION_RESULT_ALLOWED)
+    		return MsgBox(_t('_bx_market_err_access_denied'));
+
+        $sJsObject = $this->_oConfig->getJsObject('entry');
+        $oMenu = new BxTemplMenu(array('template' => 'menu_vertical.html', 'menu_id'=> 'bx-market-downloads', 'menu_items' => array(
+            array('id' => 'bx-market-show-more', 'name' => 'bx-market-show-more', 'class' => '', 'link' => 'javascript:void(0)', 'target' => '_self', 'onclick' => 'javascript:' . $sJsObject . '.showMore();', 'title' => _t('_bx_market_menu_item_title_downloads_more')),
+        )));
+
+        return array(
+            'menu' => $oMenu,
+            'content' => $this->_oTemplate->entryAttachmentsByStorage($CNF['OBJECT_STORAGE_FILES'], $aContentInfo, array(
+                'filter_field' => ''
+            ))
+        );
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_market Market
+     * @subsection bx_market-page_blocks Page Blocks
+     * @subsubsection bx_market-entity_rating entity_rating
+     * 
+     * @code bx_srv('bx_market', 'entity_rating', [...]); @endcode
+     * 
+     * Get page block with Stars based product's rating.
+     *
+     * @param $iContentId (optional) product's ID. If empty value is provided, an attempt to get it from GET/POST arrays will be performed.
+     * @return HTML string with block content 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 BxMarketModule::serviceEntityRating
+     */
+    /** 
+     * @ref bx_market-entity_rating "entity_rating"
+     */
+    public function serviceEntityRating($iContentId = 0)
+    {
+    	return $this->_serviceTemplateFunc ('entryRating', $iContentId);
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_market Market
+     * @subsection bx_market-page_blocks Page Blocks
+     * @subsubsection bx_market-entity_author_entities entity_author_entities
+     * 
+     * @code bx_srv('bx_market', 'entity_author_entities', [...]); @endcode
+     * 
+     * Get page block with a list of other products of the same author.
+     *
+     * @param $iContentId (optional) product's ID. If empty value is provided, an attempt to get it from GET/POST arrays will be performed.
+     * @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 BxMarketModule::serviceEntityAuthorEntities
+     */
+    /** 
+     * @ref bx_market-entity_author_entities "entity_author_entities"
+     */
+	public function serviceEntityAuthorEntities($iContentId = 0)
+    {
+    	$CNF = &$this->_oConfig->CNF;
+
+    	$aContentInfo = $this->_getContentInfo($iContentId);
+    	if($aContentInfo === false)
+    		return false;
+
+		$oProfile = BxDolProfile::getInstance($aContentInfo[$CNF['FIELD_AUTHOR']]);
+        if (!$oProfile)
+            $oProfile = BxDolProfileUndefined::getInstance();
+
+		$aBlock = $this->_serviceBrowse ('author', array('author' => $aContentInfo[$CNF['FIELD_AUTHOR']], 'except' => array($iContentId), 'per_page' => 2), BX_DB_PADDING_DEF, true);
+		$aBlock['title'] = _t('_bx_market_page_block_title_entry_author_entries', $oProfile->getDisplayName());
+
+    	return $aBlock;
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_market Market
+     * @subsection bx_market-page_blocks Page Blocks
+     * @subsubsection bx_market-block_licenses block_licenses
+     * 
+     * @code bx_srv('bx_market', '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 BxMarketModule::serviceBlockLicenses
+     */
+    /** 
+     * @ref bx_market-block_licenses "block_licenses"
+     */
+	public function serviceBlockLicenses() 
+	{
+		$sGrid = $this->_oConfig->getGridObject('licenses');
+		$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(),
+        );
+	}
+
+	/**
+     * @page service Service Calls
+     * @section bx_market Market
+     * @subsection bx_market-page_blocks Page Blocks
+     * @subsubsection bx_market-block_licenses_note block_licenses_note
+     * 
+     * @code bx_srv('bx_market', '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 BxMarketModule::serviceBlockLicensesNote
+     */
+    /** 
+     * @ref bx_market-block_licenses_note "block_licenses_note"
+     */
+	public function serviceBlockLicensesNote()
+	{
+	    return MsgBox(_t('_bx_market_page_block_content_licenses_note'));
+	}
+
+	/**
+     * @page service Service Calls
+     * @section bx_market Market
+     * @subsection bx_market-licenses Licenses
+     * @subsubsection bx_market-get_unused_licenses_num get_unused_licenses_num
+     * 
+     * @code bx_srv('bx_market', 'get_unused_licenses_num', [...]); @endcode
+     * 
+     * Get number of unused licenses for some profile. It can be used in menus with "alert" counters.
+     *
+     * @param $iProfileId profile to get unused licenses for, if omitted then currently logged in profile is used
+     * @return an integer value with a number of unused licenses.
+     * 
+     * @see BxMarketModule::serviceGetUnusedLicensesNum
+     */
+    /** 
+     * @ref bx_market-get_unused_licenses_num "get_unused_licenses_num"
+     */
+    public function serviceGetUnusedLicensesNum ($iProfileId = 0)
+    {
+        if(!$iProfileId)
+			$iProfileId = bx_get_logged_profile_id();
+
+        $aLicenses = $this->_oDb->getLicense(array('type' => 'new', 'profile_id' => (int)$iProfileId));
+        return !empty($aLicenses) && is_array($aLicenses) ? count($aLicenses) : 0;
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_market Market
+     * @subsection bx_market-licenses Licenses
+     * @subsubsection bx_market-has_license has_license
+     * 
+     * @code bx_srv('bx_market', 'has_license', [...]); @endcode
+     * 
+     * Check whether a profile has a license for specified product. Domain on which the license is used can be attached to checking.
+     *
+     * @param $iProfileId profile which ownership will be checked.
+     * @param $iProductId product which the license(s) will be searched for.  
+     * @param $sDomain (optional) domain name on which the license is used.
+     * @return boolean value determining where the license is available or not.
+     * 
+     * @see BxMarketModule::serviceHasLicense
+     */
+    /** 
+     * @ref bx_market-has_license "has_license"
+     */
+	public function serviceHasLicense ($iProfileId, $iProductId, $sDomain = '')
+    {
+    	return $this->_oDb->hasLicense($iProfileId, $iProductId, $sDomain);
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_market Market
+     * @subsection bx_market-licenses Licenses
+     * @subsubsection bx_market-get_license get_license
+     * 
+     * @code bx_srv('bx_market', 'has_license', [...]); @endcode
+     * 
+     * Get a list of licenses which meet requirements provided in the input array.
+     *
+     * @param $aParams array of requirements which will be used for searching.
+     * @return an array of licenses which meet requirements.
+     * 
+     * @see BxMarketModule::serviceGetLicense
+     */
+    /** 
+     * @ref bx_market-get_license "get_license"
+     */
+    public function serviceGetLicense ($aParams)
+    {
+    	return $this->_oDb->getLicense($aParams);
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_market Market
+     * @subsection bx_market-licenses Licenses
+     * @subsubsection bx_market-update_license update_license
+     * 
+     * @code bx_srv('bx_market', 'update_license', [...]); @endcode
+     * 
+     * Update license(s) changing necessary fields. Updatable license(s) should meet requirements provided in the input array.
+     *
+     * @param $aSet an array of data to be saved  
+     * @param $aWhere an array of requirements which will be used for searching.
+     * @return an array of licenses which meet requirements.
+     * 
+     * @see BxMarketModule::serviceUpdateLicense
+     */
+    /** 
+     * @ref bx_market-update_license "update_license"
+     */
+    public function serviceUpdateLicense ($aSet, $aWhere)
+    {
+    	return $this->_oDb->updateLicense($aSet, $aWhere);
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_market Market
+     * @subsection bx_market-browsing Browsing
+     * @subsubsection bx_market-get_entry_by get_entry_by
+     * 
+     * @code bx_srv('bx_market', 'get_entry_by', [...]); @endcode
+     * 
+     * Get entry (product) which meets requirements.
+     *
+     * @param $sType string with search type.  
+     * @param $mixedValue mixed value to be used for searching.
+     * @return an array describing a product which meets requirements.
+     * 
+     * @see BxMarketModule::serviceGetEntryBy
+     */
+    /** 
+     * @ref bx_market-get_entry_by "get_entry_by"
+     */
+    public function serviceGetEntryBy($sType, $mixedValue)
+    {
+    	return $this->_oDb->getContentInfoBy(array('type' => $sType, 'value' => $mixedValue));
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_market Market
+     * @subsection bx_market-browsing Browsing
+     * @subsubsection bx_market-get_entries_by get_entries_by
+     * 
+     * @code bx_srv('bx_market', 'get_entries_by', [...]); @endcode
+     * 
+     * Get an array of entries (products) which meet requirements.
+     * 
+     * @param $aParams an array of requirements which will be used for searching.
+     * @return an array of products which meets requirements.
+     * 
+     * @see BxMarketModule::serviceGetEntriesBy
+     */
+    /** 
+     * @ref bx_market-get_entries_by "get_entries_by"
+     */
+    public function serviceGetEntriesBy($aParams)
+    {
+    	return $this->_oDb->getContentInfoBy($aParams);
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_market Market
+     * @subsection bx_market-entry Entry
+     * @subsubsection bx_market-get_thumbnail get_thumbnail
+     * 
+     * @code bx_srv('bx_market', 'get_thumbnail', [...]); @endcode
+     * 
+     * Get an array of image URLs for the product's thumbnail. Returned images have different dimensions ('small' and 'big').
+     * 
+     * @param $iPhotoId photo ID which is attached to a product as thumbnail.
+     * @return an array of image URLs.
+     * 
+     * @see BxMarketModule::serviceGetThumbnail
+     */
+    /** 
+     * @ref bx_market-get_thumbnail "get_thumbnail"
+     */
+    public function serviceGetThumbnail($iPhotoId)
+    {
+    	$CNF = &$this->_oConfig->CNF;
+
+    	$oStorage = BxDolStorage::getObjectInstance($CNF['OBJECT_STORAGE']);
+    	$oImagesTranscoder = BxDolTranscoderImage::getObjectInstance($CNF['OBJECT_IMAGES_TRANSCODER_GALLERY']);
+
+    	return array(
+    		'small' => $oImagesTranscoder ? $oImagesTranscoder->getFileUrl($iPhotoId) : '',
+    		'big' => $oStorage ? $oStorage->getFileUrlById($iPhotoId) : ''
+    	);
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_market Market
+     * @subsection bx_market-entry Entry
+     * @subsubsection bx_market-get_cover get_cover
+     * 
+     * @code bx_srv('bx_market', 'get_cover', [...]); @endcode
+     * 
+     * Get an array of image URLs for the product's cover. Returned images have different dimensions ('small', 'large' and 'big').
+     * 
+     * @param $iPhotoId photo ID which is attached to a product as cover.
+     * @return an array of image URLs.
+     * 
+     * @see BxMarketModule::serviceGetCover
+     */
+    /** 
+     * @ref bx_market-get_cover "get_cover"
+     */
+    public function serviceGetCover($iPhotoId)
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        $oTiGallery = BxDolTranscoderImage::getObjectInstance($CNF['OBJECT_IMAGES_TRANSCODER_GALLERY']);
+        $oTiPage = BxDolTranscoderImage::getObjectInstance($CNF['OBJECT_IMAGES_TRANSCODER_COVER']);
+        $oStorage = BxDolStorage::getObjectInstance($CNF['OBJECT_STORAGE']);
+
+        return array(
+            'medium' => $oTiGallery ? $oTiGallery->getFileUrl($iPhotoId) : '',
+            'large' => $oTiPage ? $oTiPage->getFileUrl($iPhotoId) : '',
+            'big' => $oStorage ? $oStorage->getFileUrlById($iPhotoId) : ''
+        );
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_market Market
+     * @subsection bx_market-entry Entry
+     * @subsubsection bx_market-get_file get_file
+     * 
+     * @code bx_srv('bx_market', 'get_file', [...]); @endcode
+     * 
+     * Get an array with file's description.
+     * 
+     * @param $iFileId file ID which is attached to a product as package (version, update, etc).
+     * @return an array with file's description.
+     * 
+     * @see BxMarketModule::serviceGetFile
+     */
+    /** 
+     * @ref bx_market-get_file "get_file"
+     */
+    public function serviceGetFile($iFileId)
+    {
+    	$CNF = &$this->_oConfig->CNF;
+
+    	$aFile = $this->_oDb->getFile(array(
+    		'type' => 'file_id_ext', 
+    		'file_id' => $iFileId
+    	));
+
+    	if(!empty($aFile) && is_array($aFile)) {
+	    	$oStorage = BxDolStorage::getObjectInstance($CNF['OBJECT_STORAGE_FILES']);
+	    	$aFile['file_url'] = $oStorage ? $oStorage->getFileUrlById($iFileId) : '';
+    	}
+
+    	return $aFile;
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_market Market
+     * @subsection bx_market-entry Entry
+     * @subsubsection bx_market-get_updates get_updates
+     * 
+     * @code bx_srv('bx_market', 'get_updates', [...]); @endcode
+     * 
+     * Get an array with update(s)' description(s).
+     * 
+     * @param $iContentId product's ID.
+     * @param $sVersion (optional) if version is specified then it will be used for searching as 'Version From'.
+     * @return an array with update(s)' description(s).
+     * 
+     * @see BxMarketModule::serviceGetUpdates
+     */
+    /** 
+     * @ref bx_market-get_updates "get_updates"
+     */
+	public function serviceGetUpdates($iContentId, $sVersion = '')
+    {
+    	$CNF = &$this->_oConfig->CNF;
+
+    	$aFile = $this->_oDb->getFile(array(
+    		'type' => 'content_id_and_type', 
+    		'content_id' => $iContentId, 
+    		'file_type' => 'update',
+    		'version' => $sVersion
+    	));
+
+    	if(!empty($aFile) && is_array($aFile)) {
+	    	$oStorage = BxDolStorage::getObjectInstance($CNF['OBJECT_STORAGE_FILES']);
+	    	$aFile['file_url'] = $oStorage ? $oStorage->getFileUrlById($aFile['file_id']) : '';
+    	}
+
+    	return $aFile;
+    }
+
+	/**
+     * @page service Service Calls
+     * @section bx_market Market
+     * @subsection bx_market-entry Entry
+     * @subsubsection bx_market-get_screenshots get_screenshots
+     * 
+     * @code bx_srv('bx_market', 'get_screenshots', [...]); @endcode
+     * 
+     * Get an array with screenshots' descriptions.
+     * 
+     * @param $iItemId product's ID.
+     * @return an array with screenshots' descriptions.
+     * 
+     * @see BxMarketModule::serviceGetScreenshots
+     */
+    /** 
+     * @ref bx_market-get_screenshots "get_screenshots"
+     */
+    public function serviceGetScreenshots($iItemId)
+    {
+    	$CNF = &$this->_oConfig->CNF;
+
+        if(!$iItemId)
+			return array();
+
+    	$aData = $this->_oDb->getContentInfoById($iItemId);
+    	
+    	$aPhotos = $this->_oDb->getPhoto(array('type' => 'content_id', 'content_id' => $aData[$CNF['FIELD_ID']], 'except' => array($aData[$CNF['FIELD_THUMB']], $aData[$CNF['FIELD_COVER']])));
+    	if(empty($aPhotos) || !is_array($aPhotos))
+    		return array();
+
+		$oStorage = BxDolStorage::getObjectInstance($CNF['OBJECT_STORAGE']);
+    	$oImagesTranscoder = BxDolTranscoderImage::getObjectInstance($CNF['OBJECT_IMAGES_TRANSCODER_SCREENSHOT']);
+
+    	$aResult = array();
+    	foreach($aPhotos as $aPhoto) 
+    		$aResult[] = array(
+    			'id' => $aPhoto['file_id'],
+    			'url_sm' => $oImagesTranscoder ? $oImagesTranscoder->getFileUrl($aPhoto['file_id']) : '',
+    			'url_bg' => $oStorage ? $oStorage->getFileUrlById($aPhoto['file_id']) : ''
+    		);
+
+		return $aResult;
+    }
+
+	/**
+     * @page service Service Calls
+     * @section bx_market Market
+     * @subsection bx_market-payments Payments
+     * @subsubsection bx_market-get_payment_data get_payment_data
+     * 
+     * @code bx_srv('bx_market', '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 BxMarketModule::serviceGetPaymentData
+     */
+    /** 
+     * @ref bx_market-get_payment_data "get_payment_data"
+     */
+	public function serviceGetPaymentData()
+    {
+        return $this->_aModule;
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_market Market
+     * @subsection bx_market-payments Payments
+     * @subsubsection bx_market-get_cart_item get_cart_item
+     * 
+     * @code bx_srv('bx_market', 'get_cart_item', [...]); @endcode
+     * 
+     * Get an array with prodict's description. Is used in Shopping Cart in payments processing module.
+     * 
+     * @param $iItemId product's ID.
+     * @return an array with prodict's description. Empty array is returned if something is wrong.
+     * 
+     * @see BxMarketModule::serviceGetCartItem
+     */
+    /** 
+     * @ref bx_market-get_cart_item "get_cart_item"
+     */
+    public function serviceGetCartItem($iItemId)
+    {
+    	$CNF = &$this->_oConfig->CNF;
+
+        if(!$iItemId)
+			return array();
+
+		$aItem = $this->_oDb->getContentInfoById($iItemId);
+        if(empty($aItem) || !is_array($aItem))
+			return array();
+
+        return array (
+            'id' => $aItem[$CNF['FIELD_ID']],
+            'author_id' => $aItem[$CNF['FIELD_AUTHOR']],
+            'name' => $aItem[$CNF['FIELD_NAME']],
+            'title' => $aItem[$CNF['FIELD_TITLE']],
+            'description' => $aItem[$CNF['FIELD_TEXT']],
+            'url' => BX_DOL_URL_ROOT . BxDolPermalinks::getInstance()->permalink('page.php?i=view-product&id=' . $aItem[$CNF['FIELD_ID']]),
+            'price_single' => $aItem[$CNF['FIELD_PRICE_SINGLE']],
+            'price_recurring' => $aItem[$CNF['FIELD_PRICE_RECURRING']],
+            'period_recurring' => 1,
+            'period_unit_recurring' => $aItem[$CNF['FIELD_DURATION_RECURRING']],
+            'trial_recurring' => $aItem[$CNF['FIELD_TRIAL_RECURRING']]
+        );
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_market Market
+     * @subsection bx_market-payments Payments
+     * @subsubsection bx_market-get_cart_items get_cart_items
+     * 
+     * @code bx_srv('bx_market', '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 BxMarketModule::serviceGetCartItems
+     */
+    /** 
+     * @ref bx_market-get_cart_items "get_cart_items"
+     */
+    public function serviceGetCartItems($iSellerId)
+    {
+    	$CNF = &$this->_oConfig->CNF;
+
+        $iSellerId = (int)$iSellerId;
+        if(empty($iSellerId))
+            return array();
+
+        $aItems = $this->_oDb->getEntriesByAuthor($iSellerId);
+
+        $aResult = array();
+        foreach($aItems as $aItem)
+            $aResult[] = array(
+                'id' => $aItem[$CNF['FIELD_ID']],
+                'author_id' => $aItem[$CNF['FIELD_AUTHOR']],
+                'name' => $aItem[$CNF['FIELD_NAME']],
+                'title' => $aItem[$CNF['FIELD_TITLE']],
+                'description' => $aItem[$CNF['FIELD_TEXT']],
+                'url' => BX_DOL_URL_ROOT . BxDolPermalinks::getInstance()->permalink('page.php?i=view-product&id=' . $aItem[$CNF['FIELD_ID']]),
+                'price_single' => $aItem[$CNF['FIELD_PRICE_SINGLE']],
+                'price_recurring' => $aItem[$CNF['FIELD_PRICE_RECURRING']],
+                'period_recurring' => 1,
+                'period_unit_recurring' => $aItem[$CNF['FIELD_DURATION_RECURRING']],
+                'trial_recurring' => $aItem[$CNF['FIELD_TRIAL_RECURRING']]
+            );
+
+        return $aResult;
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_market Market
+     * @subsection bx_market-payments Payments
+     * @subsubsection bx_market-register_cart_item register_cart_item
+     * 
+     * @code bx_srv('bx_market', 'register_cart_item', [...]); @endcode
+     * 
+     * Register a processed single time payment inside the Market 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 BxMarketModule::serviceRegisterCartItem
+     */
+    /** 
+     * @ref bx_market-register_cart_item "register_cart_item"
+     */
+    public function serviceRegisterCartItem($iClientId, $iSellerId, $iItemId, $iItemCount, $sOrder, $sLicense)
+    {
+        return $this->_serviceRegisterItem($iClientId, $iSellerId, $iItemId, $iItemCount, $sOrder, $sLicense, BX_MARKET_LICENSE_TYPE_SINGLE);
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_market Market
+     * @subsection bx_market-payments Payments
+     * @subsubsection bx_market-register_subscription_item register_subscription_item
+     * 
+     * @code bx_srv('bx_market', 'register_subscription_item', [...]); @endcode
+     * 
+     * Register a processed subscription (recurring payment) inside the Market 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 BxMarketModule::serviceRegisterSubscriptionItem
+     */
+    /** 
+     * @ref bx_market-register_subscription_item "register_subscription_item"
+     */
+    public function serviceRegisterSubscriptionItem($iClientId, $iSellerId, $iItemId, $iItemCount, $sOrder, $sLicense)
+    {
+		return $this->_serviceRegisterItem($iClientId, $iSellerId, $iItemId, $iItemCount, $sOrder, $sLicense, BX_MARKET_LICENSE_TYPE_RECURRING);
+    }
+
+	/**
+     * @page service Service Calls
+     * @section bx_market Market
+     * @subsection bx_market-payments Payments
+     * @subsubsection bx_market-unregister_cart_item unregister_cart_item
+     * 
+     * @code bx_srv('bx_market', 'unregister_cart_item', [...]); @endcode
+     * 
+     * Unregister an earlier processed single time payment inside the Market 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 BxMarketModule::serviceUnregisterCartItem
+     */
+    /** 
+     * @ref bx_market-unregister_cart_item "unregister_cart_item"
+     */
+    public function serviceUnregisterCartItem($iClientId, $iSellerId, $iItemId, $iItemCount, $sOrder, $sLicense)
+    {
+        return $this->_serviceUnregisterItem($iClientId, $iSellerId, $iItemId, $iItemCount, $sOrder, $sLicense, BX_MARKET_LICENSE_TYPE_SINGLE);
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_market Market
+     * @subsection bx_market-payments Payments
+     * @subsubsection bx_market-unregister_subscription_item unregister_subscription_item
+     * 
+     * @code bx_srv('bx_market', 'unregister_subscription_item', [...]); @endcode
+     * 
+     * Unregister an earlier processed subscription (recurring payment) inside the Market 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 BxMarketModule::serviceUnregisterSubscriptionItem
+     */
+    /** 
+     * @ref bx_market-unregister_subscription_item "unregister_subscription_item"
+     */
+    public function serviceUnregisterSubscriptionItem($iClientId, $iSellerId, $iItemId, $iItemCount, $sOrder, $sLicense)
+    {
+    	return $this->_serviceUnregisterItem($iClientId, $iSellerId, $iItemId, $iItemCount, $sOrder, $sLicense, BX_MARKET_LICENSE_TYPE_RECURRING); 
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_market Market
+     * @subsection bx_market-payments Payments
+     * @subsubsection bx_market-cancel_subscription_item cancel_subscription_item
+     * 
+     * @code bx_srv('bx_market', 'cancel_subscription_item', [...]); @endcode
+     * 
+     * Cancel an earlier processed subscription (recurring payment) inside the Market 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 BxMarketModule::serviceCancelSubscriptionItem
+     */
+    /** 
+     * @ref bx_market-cancel_subscription_item "cancel_subscription_item"
+     */
+	public function serviceCancelSubscriptionItem($iClientId, $iSellerId, $iItemId, $iItemCount, $sOrder)
+    {
+    	//TODO: Do something if it's necessary.
+    	return true;
+    }
+
+    protected function _serviceRegisterItem($iClientId, $iSellerId, $iItemId, $iItemCount, $sOrder, $sLicense, $sType)
+    {
+    	$aItem = $this->serviceGetCartItem($iItemId);
+        if(empty($aItem) || !is_array($aItem))
+			return array();
+
+        $iTrial = 0;
+		$sDuration = '';
+		if($sType == BX_MARKET_LICENSE_TYPE_RECURRING) {
+			$aProduct = $this->_oDb->getContentInfoById($iItemId);
+
+			$iTrial = $aProduct[$this->_oConfig->CNF['FIELD_TRIAL_RECURRING']];
+			$sDuration = $aProduct[$this->_oConfig->CNF['FIELD_DURATION_RECURRING']];
+		}
+
+    	$sAction = $this->_oDb->hasLicenseByOrder($iClientId, $iItemId, $sOrder) ? 'prolong' : 'register';
+        if(!$this->_oDb->{$sAction . 'License'}($iClientId, $iItemId, $iItemCount, $sOrder, $sLicense, $sType, $sDuration, $iTrial))
+            return array();
+
+		bx_alert($this->getName(), 'license_' . $sAction, 0, false, array(
+			'product_id' => $iItemId,
+			'profile_id' => $iClientId,
+			'order' => $sOrder,
+			'license' => $sLicense,
+			'type' => $sType,
+			'count' => $iItemCount,
+			'duration' => $sDuration,
+		    'trial' => $iTrial
+		));
+
+        return $aItem;
+    }
+
+    protected function _serviceUnregisterItem($iClientId, $iSellerId, $iItemId, $iItemCount, $sOrder, $sLicense, $sType)
+    {
+    	if(!$this->_oDb->unregisterLicense($iClientId, $iItemId, $sOrder, $sLicense, $sType))
+    		return false;
+
+    	bx_alert($this->getName(), 'license_unregister', 0, false, array(
+			'product_id' => $iItemId,
+			'profile_id' => $iClientId,
+			'order' => $sOrder,
+			'license' => $sLicense,
+			'type' => $sType,
+			'count' => $iItemCount
+		));
+
+    	return true;
+    }
+
+    public function getGhostTemplateVars($aFile, $iProfileId, $iContentId, $oStorage, $oImagesTranscoder)
+    {
+    	$CNF = &$this->_oConfig->CNF;
+
+    	$sMethod = '';
+    	$sStorage = $oStorage->getObject();
+        switch($sStorage) {
+        	case $CNF['OBJECT_STORAGE']:
+        		$sMethod = 'getPhoto';
+        		break;
+
+			case $CNF['OBJECT_STORAGE_FILES']:
+				$sMethod = 'getFile';
+				break;
+        }
+
+		$aFileInfo = $this->_oDb->$sMethod(array('type' => 'file_id', 'file_id' => $aFile['id']));
+        $bFileInfo = !empty($aFileInfo) && is_array($aFileInfo);
+
+        $bFileInfoTitle = $bFileInfo && isset($aFileInfo['title']);
+
+		$aTmplVars = array(
+			'file_title' => $bFileInfoTitle ? $aFileInfo['title'] : '',
+			'file_title_attr' => $bFileInfoTitle ? bx_html_attribute($aFileInfo['title']) : '',
+		);
+
+		if($sStorage == $CNF['OBJECT_STORAGE'])
+			return $aTmplVars;
+
+		$bFileInfoVersion = $bFileInfo && isset($aFileInfo['version']);
+
+        $bFileInfoTypeVersion = !$bFileInfo || ($bFileInfo && isset($aFileInfo['type']) && $aFileInfo['type'] == BX_MARKET_FILE_TYPE_VERSION);
+        $bFileInfoTypeUpdate = $bFileInfo && isset($aFileInfo['type']) && $aFileInfo['type'] == BX_MARKET_FILE_TYPE_UPDATE;
+
+        $aVersions = $this->_oDb->$sMethod(array('type' => 'content_id', 'content_id' => $iContentId));
+
+		$aTmplVars = array_merge($aTmplVars, array(
+			'file_version' => $bFileInfoVersion ? $aFileInfo['version'] : '',
+			'file_version_attr' => $bFileInfoVersion ? bx_html_attribute($aFileInfo['version']) : '',
+
+			'file_type_version_selected' => $bFileInfoTypeVersion ? ' selected="selected"' : '',
+			'file_type_update_selected' => $bFileInfoTypeUpdate ? ' selected="selected"' : '',
+
+			'file_type_version_elements' => !$bFileInfoTypeVersion ? ' style="display:none;"' : '',
+			'file_type_update_elements' => !$bFileInfoTypeUpdate ? ' style="display:none;"' : '',
+
+			'file_version_from_options' => $this->_oTemplate->getGhostTemplateFileOptions('version', $aFileInfo, $aVersions),
+			'file_version_to_options' => $this->_oTemplate->getGhostTemplateFileOptions('version_to', $aFileInfo, $aVersions)
+		));
+
+		return $aTmplVars;
+    }
+
+    public function checkAllowedSetCover ()
+    {
+        $aCheck = checkActionModule($this->_iProfileId, 'set cover', $this->getName(), false);
+        if($aCheck[CHECK_ACTION_RESULT] !== CHECK_ACTION_RESULT_ALLOWED)
+            return $aCheck[CHECK_ACTION_MESSAGE];
+
+        return CHECK_ACTION_RESULT_ALLOWED;
+    }
+
+    public function checkAllowedSetSubentries ()
+    {
+        $aCheck = checkActionModule($this->_iProfileId, 'set subentries', $this->getName(), false);
+        if($aCheck[CHECK_ACTION_RESULT] !== CHECK_ACTION_RESULT_ALLOWED)
+            return $aCheck[CHECK_ACTION_MESSAGE];
+
+        return CHECK_ACTION_RESULT_ALLOWED;
+    }
+
+	public function checkAllowedDownload($aDataEntry, $isPerformAction = false)
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        // moderator and owner always have access
+        if ($aDataEntry[$CNF['FIELD_AUTHOR']] == $this->_iProfileId || $this->_isModerator($isPerformAction))
+            return CHECK_ACTION_RESULT_ALLOWED;
+
+        // check ACL
+        $aCheck = checkActionModule($this->_iProfileId, 'download entry', $this->getName(), $isPerformAction);
+        if($aCheck[CHECK_ACTION_RESULT] !== CHECK_ACTION_RESULT_ALLOWED)
+			return $aCheck[CHECK_ACTION_MESSAGE];
+
+        if((float)$aDataEntry[$CNF['FIELD_PRICE_SINGLE']] == 0 && (float)$aDataEntry[$CNF['FIELD_PRICE_RECURRING']] == 0)
+            return CHECK_ACTION_RESULT_ALLOWED;
+
+		if(!$this->_oDb->hasLicense($this->_iProfileId, $aDataEntry[$CNF['FIELD_ID']]))
+            return CHECK_ACTION_RESULT_NOT_ALLOWED;
+
+        return CHECK_ACTION_RESULT_ALLOWED;
+    }
+
+    protected function _getContentInfo($iContentId = 0)
+    {
+    	if(!$iContentId)
+            $iContentId = bx_process_input(bx_get('id'), BX_DATA_INT);
+
+        if(!$iContentId)
+            return false;
+
+        $aContentInfo = $this->_oDb->getContentInfoById($iContentId);
+        if(!$aContentInfo)
+            return false;
+
+		return $aContentInfo;
+    }
+
+    protected function _entitySocialSharing ($iId, $aParams = array())
+    {
+        $CNF = &$this->_oConfig->CNF;
+        return parent::_entitySocialSharing($iId, array_merge($aParams, array(
+        	'object_vote' => ''
+        )));
+    }
+}
+
+/** @} */

+ 160 - 0
modules/boonex/market/updates/9.0.6_9.0.7/source/classes/BxMarketSearchResult.php

@@ -0,0 +1,160 @@
+<?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
+ *
+ * @{
+ */
+
+class BxMarketSearchResult extends BxBaseModTextSearchResult
+{
+    function __construct($sMode = '', $aParams = array())
+    {
+        parent::__construct($sMode, $aParams);
+
+        $this->aCurrent = array(
+            'name' => 'bx_market',
+            'module_name' => 'bx_market',
+            'object_metatags' => 'bx_market',
+            'title' => _t('_bx_market_page_title_browse'),
+            'table' => 'bx_market_products',
+            'ownFields' => array('id', 'title', 'text', 'price_single', 'price_recurring', 'duration_recurring', 'thumb', 'cover', 'author', 'added'),
+            'searchFields' => array(),
+            'restriction' => array(
+                'author' => array('value' => '', 'field' => 'author', 'operator' => '='),
+        		'featured' => array('value' => '', 'field' => 'featured', 'operator' => '<>'),
+        		'except' => array('value' => '', 'field' => 'id', 'operator' => 'not in'),
+        		'status' => array('value' => 'active', 'field' => 'status', 'operator' => '='),
+        		'statusAdmin' => array('value' => 'active', 'field' => 'status_admin', 'operator' => '='),
+            ),
+            'paginate' => array('perPage' => getParam('bx_market_per_page_browse'), 'start' => 0),
+            'sorting' => 'last',
+            'rss' => array(
+                'title' => '',
+                'link' => '',
+                'image' => '',
+                'profile' => 0,
+                'fields' => array (
+                    'Guid' => 'link',
+                    'Link' => 'link',
+                    'Title' => 'title',
+                    'DateTimeUTS' => 'added',
+                    'Desc' => 'text',
+                ),
+            ),
+            'ident' => 'id',
+        );
+
+        $this->sFilterName = 'bx_market_filter';
+        $this->oModule = $this->getMain();
+
+        $CNF = &$this->oModule->_oConfig->CNF;
+
+        $sSearchFields = getParam($CNF['PARAM_SEARCHABLE_FIELDS']);
+        $this->aCurrent['searchFields'] = !empty($sSearchFields) ? explode(',', $sSearchFields) : '';
+
+        $oProfileAuthor = null;
+
+        switch ($sMode) {
+
+            case 'author':
+                if(!$this->_updateCurrentForAuthor($sMode, $aParams, $oProfileAuthor)) {
+                    $this->isError = true;
+                    break;
+                }
+                break;
+
+            case 'favorite':
+                if(!$this->_updateCurrentForFavorite($sMode, $aParams, $oProfileAuthor)) {
+                    $this->isError = true;
+                    break;
+                }
+                break;
+
+            case 'public':
+                $this->sBrowseUrl = BxDolPermalinks::getInstance()->permalink($CNF['URL_LATEST']);
+                $this->aCurrent['title'] = _t('_bx_market_page_title_browse_latest');
+                $this->aCurrent['rss']['link'] = 'modules/?r=market/rss/' . $sMode;
+                break;
+
+            case 'featured':
+                $this->sBrowseUrl = BxDolPermalinks::getInstance()->permalink($CNF['URL_FEATURED']);
+                $this->aCurrent['title'] = _t('_bx_market_page_title_browse_featured');
+                $this->aCurrent['restriction']['featured']['value'] = '0';
+                $this->aCurrent['rss']['link'] = 'modules/?r=market/rss/' . $sMode;
+                $this->aCurrent['sorting'] = 'featured';
+                break;
+
+            case 'popular':
+                $this->sBrowseUrl = BxDolPermalinks::getInstance()->permalink($CNF['URL_POPULAR']);
+                $this->aCurrent['title'] = _t('_bx_market_page_title_browse_popular');
+                $this->aCurrent['rss']['link'] = 'modules/?r=market/rss/' . $sMode;
+                $this->aCurrent['sorting'] = 'popular';
+                break;
+
+            case 'updated':
+                $this->sBrowseUrl = BxDolPermalinks::getInstance()->permalink($CNF['URL_UPDATED']);
+                $this->aCurrent['title'] = _t('_bx_market_page_title_browse_updated');
+                $this->aCurrent['rss']['link'] = 'modules/?r=market/rss/' . $sMode;
+                $this->aCurrent['sorting'] = 'updated';
+                break;
+
+            case '': // search results
+                $this->sBrowseUrl = BX_DOL_SEARCH_KEYWORD_PAGE;
+                unset($this->aCurrent['paginate']['perPage'], $this->aCurrent['rss']);
+                break;
+
+            default:
+                $sMode = '';
+                $this->isError = true;
+        }
+
+        $this->processReplaceableMarkers($oProfileAuthor);
+
+        $this->addConditionsForPrivateContent($CNF, $oProfileAuthor);
+    }
+
+    public function setMetaType($s)
+    {
+        $this->_sMetaType = $s;
+        if(!empty($this->_sMetaType) && $this->_sMetaType == 'keyword')
+            $this->aCurrent['title'] = _t('_bx_market_page_title_browse_keyword', bx_process_pass(bx_get('keyword')));
+    }
+
+    public function setCategoryObject($s)
+    {
+        $this->_sCategoryObject = $s;
+        if(!empty($this->_sCategoryObject) && $o = BxDolCategory::getObjectInstance($this->_sCategoryObject))
+            $this->aCurrent['title'] = _t('_bx_market_page_title_browse_category', $o->getCategoryTitle((int)bx_get('keyword')));
+    }
+
+    function displayResultBlock ()
+    {
+    	return BxDolPayments::getInstance()->getCartJs() . parent::displayResultBlock();
+    }
+
+    function getAlterOrder()
+    {
+        $aSql = array();
+        switch ($this->aCurrent['sorting']) {
+            case 'last':
+                $aSql['order'] = ' ORDER BY `bx_market_products`.`added` DESC';
+                break;
+            case 'featured':
+                $aSql['order'] = ' ORDER BY `bx_market_products`.`featured` DESC';
+                break;
+            case 'updated':
+                $aSql['order'] = ' ORDER BY `bx_market_products`.`changed` DESC';
+                break;
+            case 'popular':
+                $aSql['order'] = ' ORDER BY `bx_market_products`.`views` DESC';
+                break;
+        }
+        return $aSql;
+    }
+}
+
+/** @} */

+ 459 - 0
modules/boonex/market/updates/9.0.6_9.0.7/source/classes/BxMarketTemplate.php

@@ -0,0 +1,459 @@
+<?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
+ *
+ * @{
+ */
+
+/*
+ * Module representation.
+ */
+class BxMarketTemplate extends BxBaseModTextTemplate
+{
+	protected $_aCurrency;
+
+    /**
+     * Constructor
+     */
+    function __construct(&$oConfig, &$oDb)
+    {
+        $this->MODULE = 'bx_market';
+
+        parent::__construct($oConfig, $oDb);
+
+        $this->_aCurrency = $this->_oConfig->getCurrency();
+    }
+
+    public function entryBreadcrumb($aContentInfo, $aTmplVarsItems = array())
+    {
+    	$CNF = &$this->getModule()->_oConfig->CNF;
+
+        $oPermalink = BxDolPermalinks::getInstance();
+        $oCategory = BxDolCategory::getObjectInstance($CNF['OBJECT_CATEGORY']);
+
+    	$aTmplVarsItems = array(array(
+        	'url' => bx_append_url_params($oPermalink->permalink('page.php?i=' . $CNF['URI_CATEGORY_ENTRIES']), array(
+        		'category' => $aContentInfo[$CNF['FIELD_CATEGORY']]
+        	)),
+        	'title' => $oCategory->getCategoryTitle($aContentInfo[$CNF['FIELD_CATEGORY']])
+        ), array(
+        	'url' => $oPermalink->permalink('page.php?i=' . $CNF['URI_VIEW_ENTRY'] . '&id=' . $aContentInfo[$CNF['FIELD_ID']]),
+        	'title' => bx_process_output($aContentInfo[$CNF['FIELD_TITLE']])
+        ));
+
+    	return parent::entryBreadcrumb($aContentInfo, $aTmplVarsItems);
+    }
+
+    public function entryRating($aData)
+    {
+        $CNF = &$this->getModule()->_oConfig->CNF;
+
+    	$sVotes = '';
+        $oVotes = BxDolVote::getObjectInstance($CNF['OBJECT_VOTES'], $aData['id']);
+        if($oVotes) {
+			$sVotes = $oVotes->getElementBlock(array('show_counter' => true, 'show_legend' => true));
+			if(!empty($sVotes))
+				$sVotes = $this->parseHtmlByName('entry-rating.html', array(
+		    		'content' => $sVotes,
+		    	));
+        }
+
+    	return $sVotes; 
+    }
+
+    public function entryText ($aData, $sTemplateName = 'entry-text.html')
+    {
+    	$sScreenshots = $this->getScreenshots($aData);
+
+    	$this->addCss(BX_DIRECTORY_PATH_PLUGINS_PUBLIC . 'flickity/|flickity.css');
+    	$this->addJs('flickity/flickity.pkgd.min.js');
+    	return $this->parseHtmlByContent(parent::entryText($aData), array(
+    		'bx_if:show_screenshots' => array(
+    			'condition' => !empty($sScreenshots),
+    			'content' => array(
+    				'screenshots' => $sScreenshots
+    			)
+    		)
+    	));
+    }
+
+    public function setCover($aData)
+    {
+		$CNF = &$this->getModule()->_oConfig->CNF;
+
+		if(empty($aData[$CNF['FIELD_COVER']]))
+			return;
+
+		$mixedOptions = BxDolPage::getObjectInstanceByURI()->getPageCoverParams();
+        if(empty($mixedOptions) || !is_array($mixedOptions))
+        	return;
+
+        //--- Get Cover image URL
+        $oTranscoderCover = BxDolTranscoderImage::getObjectInstance($CNF['OBJECT_IMAGES_TRANSCODER_COVER']);
+		if(empty($oTranscoderCover))
+			return;
+
+		$sCoverUrl = $oTranscoderCover->getFileUrl($aData[$CNF['FIELD_COVER']]);
+		if(empty($sCoverUrl))
+			return;
+
+		//--- Get Thumbnail image URL
+		$sThumbnailUrl = '';
+		$bThumbnailUrl = false;
+		if(!empty($aData[$CNF['FIELD_THUMB']])) {
+		    $oTranscoderThumbnail = BxDolTranscoderImage::getObjectInstance($CNF['OBJECT_IMAGES_TRANSCODER_THUMB']);
+    		if($oTranscoderThumbnail)
+    			$sThumbnailUrl = $oTranscoderThumbnail->getFileUrl($aData[$CNF['FIELD_THUMB']]);
+
+            $bThumbnailUrl = !empty($sThumbnailUrl);
+		}
+
+		$oCover = BxDolCover::getInstance($this);
+		$oCover->setCoverImageUrl($sCoverUrl);
+		$oCover->set(array_merge($mixedOptions, array(
+			'bx_if:image' => array (
+                'condition' => $bThumbnailUrl,
+                'content' => array(
+                	'icon_url' => $sThumbnailUrl
+		        ),
+            ),
+            'bx_if:icon' => array (
+                'condition' => !$bThumbnailUrl,
+                'content' => array(
+                    'icon' => $CNF['ICON']
+                ),
+            ),
+            'bx_if:bg' => array (
+                'condition' => true,
+                'content' => array('image_url' => $sCoverUrl),
+            ),
+		)));
+    }
+
+    public function getScreenshots($aData)
+    {
+    	$oModule = $this->getModule();
+
+    	$CNF = &$oModule->_oConfig->CNF;
+    	$aPhotos = $oModule->serviceGetScreenshots($aData[$CNF['FIELD_ID']]);
+		if(empty($aPhotos) || !is_array($aPhotos))
+    		return '';
+
+		return $this->parseHtmlByName('entry-screenshots.html', array(
+    		'bx_repeat:items' => $aPhotos
+    	));
+    }
+    
+    public function getAuthorAddon ($aData, $oProfile)
+    {
+        $aAccount = $oProfile->getAccountObject()->getInfo();
+
+        $sContent = $this->parseHtmlByName('entry-author.html', array(
+    		'joined' => bx_time_js($aAccount['added']),
+	    	'last_active' => bx_time_js($aAccount['logged']),
+	    	'installs' => '?',
+    	));
+
+    	return $sContent . parent::getAuthorAddon ($aData, $oProfile);
+    }
+
+    public function getGhostTemplateFileOptions($sField, $aFile, $aVersions)
+    {
+    	$bField = !empty($aFile) && is_array($aFile) && isset($aFile[$sField]);
+    	
+    	$aTmplVarsVersions = array();
+    	foreach ($aVersions as $aVersion) {
+    		if($aVersion['type'] != 'version' || empty($aVersion['version']))
+    			continue;
+
+			$aTmplVarsVersions[] = array(
+				'value' => $aVersion['version'],
+				'title' =>  $aVersion['version'],
+				'bx_if:selected' => array(
+					'condition' => $bField && $aFile[$sField] == $aVersion['version'],
+					'content' => array()
+				)
+			);
+    	}
+
+    	return $this->parseHtmlByName('form_ghost_template_file_options.html', array(
+    		'bx_repeat:versions' => $aTmplVarsVersions
+    	));    	
+    }
+
+    public function getGhostTemplateFile($oForm, $aContentInfo)
+    {
+    	$CNF = &$this->getModule()->_oConfig->CNF;
+
+    	return $this->parseHtmlByName('form_ghost_template_file.html', array (
+                'name' => $oForm->aInputs[$CNF['FIELD_FILE']]['name'],
+                'content_id' => $oForm->aInputs[$CNF['FIELD_FILE']]['content_id'],
+                'editor_id' => $CNF['FIELD_TEXT_ID'],
+                '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'],
+            		),
+                ),
+            ));
+    }
+
+    protected function getUnit ($aData, $aParams = array())
+    {
+        $bTmplVarsSectionAuthor = false;
+        $bTmplVarsSectionPricing = false;
+        $bTmplVarsSectionVoting = true;
+
+        $oModule = $this->getModule();
+    	$CNF = &$oModule->_oConfig->CNF;
+
+    	$aUnit = parent::getUnit($aData, $aParams);
+        $oPayment = BxDolPayments::getInstance();
+        $oPermalinks = BxDolPermalinks::getInstance();
+
+        list($sAuthorName, $sAuthorUrl, $sAuthorIcon, $sAuthorUnit, $sAuthorUnitShort) = $oModule->getUserInfo($aData[$CNF['FIELD_AUTHOR']]);
+
+        $aTmplVarsSectionAuthor = array();
+        if($bTmplVarsSectionAuthor) {
+            //--- Author Info
+            $bAuthorIcon = !empty($sAuthorIcon);
+            $sAuthorName = $this->parseHtmlByName('author_link.html', array(
+                'href' => $sAuthorUrl,
+                'title' => bx_html_attribute($sAuthorName),
+                'content' => $sAuthorName,
+                'bx_if:show_account' => array(
+                    'condition' => false,
+                    'content' => array()
+                )
+            ));
+
+            //--- Actions
+            $sActions = '';
+        	$oActions = BxDolMenu::getObjectInstance($CNF['OBJECT_MENU_ACTIONS_SNIPPET']);
+        	if($oActions) {
+        	    $oActions->setContentId($aData[$CNF['FIELD_ID']]);
+        	    $sActions = $oActions->getCode();
+        	}
+
+            $sDate = $this->parseHtmlByName('snippet-date.html', array(
+                'date' => bx_time_js($aData[$CNF['FIELD_ADDED']])
+            ));
+
+        	$aTmplVarsSectionAuthor = array(
+                'actions' => $sActions,
+                'author_unit' => $sAuthorUnitShort,
+                'author_width_date' => _t('_bx_market_txt_author_added_product', $sAuthorName, $sDate),
+	        );
+        }
+
+        //--- Main Info
+        $sUrl = BX_DOL_URL_ROOT . $oPermalinks->permalink('page.php?i=' . $CNF['URI_VIEW_ENTRY'] . '&id=' . $aData[$CNF['FIELD_ID']]);
+        $sLinkMore = ' <a title="' . bx_html_attribute(_t('_sys_read_more', $aData[$CNF['FIELD_TITLE']])) . '" href="' . $sUrl . '"><i class="sys-icon ellipsis-h"></i></a>';
+        $sSummary = strmaxtextlen($aData[$CNF['FIELD_TEXT']], (int)getParam($CNF['PARAM_CHARS_SUMMARY']), $sLinkMore);
+        $sSummaryPlain = BxTemplFunctions::getInstance()->getStringWithLimitedLength(strip_tags($sSummary), (int)getParam($CNF['PARAM_CHARS_SUMMARY_PLAIN']));
+        
+
+        //--- Icon Info
+        $sIconUrl = '';
+        if(!empty($CNF['FIELD_THUMB']) && $aData[$CNF['FIELD_THUMB']]) {
+            $oImagesTranscoder = BxDolTranscoderImage::getObjectInstance($CNF['OBJECT_IMAGES_TRANSCODER_ICON']);
+            if($oImagesTranscoder)
+                $sIconUrl = $oImagesTranscoder->getFileUrl($aData[$CNF['FIELD_THUMB']]);
+
+            if(empty($sIconUrl)) {
+                $oImagesTranscoder = BxDolTranscoderImage::getObjectInstance($CNF['OBJECT_IMAGES_TRANSCODER_THUMB']);
+                if($oImagesTranscoder)
+                    $sIconUrl = $oImagesTranscoder->getFileUrl($aData[$CNF['FIELD_THUMB']]);
+            }
+        }
+
+        //--- Cover Info
+        $sCoverUrl = '';
+        if(!empty($CNF['FIELD_COVER']) && $aData[$CNF['FIELD_COVER']]) {
+            $oImagesTranscoder = BxDolTranscoderImage::getObjectInstance($CNF['OBJECT_IMAGES_TRANSCODER_GALLERY']);
+                if($oImagesTranscoder)
+                    $sCoverUrl = $oImagesTranscoder->getFileUrl($aData[$CNF['FIELD_COVER']]);
+
+            if(empty($sCoverUrl)) {
+                $oImagesTranscoder = BxDolTranscoderImage::getObjectInstance($CNF['OBJECT_IMAGES_TRANSCODER_COVER']);
+                if($oImagesTranscoder)
+                    $sCoverUrl = $oImagesTranscoder->getFileUrl($aData[$CNF['FIELD_COVER']]);
+            }
+        }
+
+        $aTmplVarsSectionPricing = array();
+        if($bTmplVarsSectionPricing) {
+            //--- Price Single
+        	$bTmplVarsSingle = (float)$aData[$CNF['FIELD_PRICE_SINGLE']] != 0;
+        	$aTmplVarsSingle = array();
+        	if($bTmplVarsSingle) {
+        		$aJsSingle = $oPayment->getAddToCartJs($aData[$CNF['FIELD_AUTHOR']], $this->_oConfig->getName(), $aData[$CNF['FIELD_ID']], 1, true);
+        		if(!empty($aJsSingle) && is_array($aJsSingle)) {
+        			list($sJsCode, $sSingleOnclick) = $aJsSingle;
+        			
+    	    		$aTmplVarsSingle = array(
+    	    			'price_single_onclick' => $sSingleOnclick,
+    					'price_single' => _t('_bx_market_txt_price_single', $this->_aCurrency['sign'], $aData[$CNF['FIELD_PRICE_SINGLE']])
+    				);
+        		}
+        		else 
+        			$bTmplVarsSingle = false;
+        	}
+    
+        	//--- Price Recurring
+        	$bTmplVarsRecurring = (float)$aData[$CNF['FIELD_PRICE_RECURRING']] != 0;
+        	$aTmplVarsRecurring = array();
+        	if($bTmplVarsRecurring) {
+            	$aJsRecurring = $oPayment->getSubscribeJs($aData[$CNF['FIELD_AUTHOR']], '', $this->_oConfig->getName(), $aData[$CNF['FIELD_ID']], 1);
+            	if(!empty($aJsRecurring) && is_array($aJsRecurring)) {
+    				list($sJsCode, $sRecurringOnclick) = $aJsRecurring;
+    
+    	        	$aTmplVarsRecurring = array(
+    	        		'price_recurring_onclick' => $sRecurringOnclick,
+    					'price_recurring' => _t('_bx_market_txt_price_recurring', $this->_aCurrency['sign'], $aData[$CNF['FIELD_PRICE_RECURRING']], _t($CNF['T']['txt_per_' . $aData[$CNF['FIELD_DURATION_RECURRING']] . '_short']))
+    				);
+            	}
+            	else 
+            		$bTmplVarsRecurring = false;
+        	}
+
+        	$aTmplVarsSectionPricing = array(
+        	    'bx_if:show_single' => array(
+        			'condition' => $bTmplVarsSingle,
+        			'content' => $aTmplVarsSingle
+        		),
+        		'bx_if:show_recurring' => array(
+        			'condition' => $bTmplVarsRecurring,
+        			'content' => $aTmplVarsRecurring
+        		),
+        		'bx_if:show_free' => array(
+        			'condition' => !$bTmplVarsSingle && !$bTmplVarsRecurring,
+        			'content' => array(
+        		        'price_free_href' => $oPermalinks->permalink('page.php?i=' . $CNF['URI_DOWNLOAD_ENTRY'] . '&id=' . $aData[$CNF['FIELD_ID']])
+        		    )
+        		)
+        	);
+        }
+
+        $aTmplVarsSectionVoting = array();
+        if($bTmplVarsSectionVoting) {
+            $sVoting = '';
+        	$oVoting = BxDolVote::getObjectInstance($CNF['OBJECT_VOTES'], $aData[$CNF['FIELD_ID']]);
+            if($oVoting)
+    			$sVoting = $oVoting->getElementBlock(array('show_counter' => false));
+
+            $sPricing = "";
+            if((float)$aData[$CNF['FIELD_PRICE_RECURRING']] != 0)
+                $sPricing = _t('_bx_market_txt_price_recurring_short', $this->_aCurrency['sign'], $aData[$CNF['FIELD_PRICE_RECURRING']], _t($CNF['T']['txt_per_' . $aData[$CNF['FIELD_DURATION_RECURRING']] . '_short']));
+
+            if(empty($sPricing) && (float)$aData[$CNF['FIELD_PRICE_SINGLE']] != 0)
+                $sPricing = _t('_bx_market_txt_price_single_short', $this->_aCurrency['sign'], $aData[$CNF['FIELD_PRICE_SINGLE']]);
+
+            if(empty($sPricing))
+                 $sPricing = _t('_bx_market_txt_price_free');
+
+            $aTmplVarsSectionVoting = array(
+                'voting' => $sVoting,
+                'pricing' => $sPricing
+            );
+            
+        }
+
+
+    	$aUnit = array_merge($aUnit, array(
+    	    'bx_if:show_section_author' => array(
+    	        'condition' => $bTmplVarsSectionAuthor,
+    	        'content' => $aTmplVarsSectionAuthor
+    	    ),
+            'bx_if:show_icon' => array (
+                'condition' => $sIconUrl,
+                'content' => array(
+                	'icon_url' => $sIconUrl,
+                ),
+            ),
+            'bx_if:show_icon_empty' => array (
+                'condition' => !$sIconUrl,
+                'content' => array(
+                    'icon' => $CNF['ICON']
+                ),
+            ),
+            'bx_if:show_cover' => array (
+                'condition' => $sCoverUrl,
+                'content' => array (
+                    'summary_attr' => bx_html_attribute($sSummaryPlain),
+                    'content_url' => $sUrl,
+                    'cover_url' => $sCoverUrl,
+                    'strecher' => str_repeat('&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ', 40),
+                ),
+            ),
+            'bx_if:show_cover_empty' => array (
+                'condition' => !$sCoverUrl,
+                'content' => array (
+                    'summary_plain' => $sSummaryPlain,
+                    'strecher' => mb_strlen($sSummaryPlain) > 240 ? '' : str_repeat('&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ', round((240 - mb_strlen($sSummaryPlain)) / 6)),
+                ),
+            ),
+            'author_name' => $sAuthorName,
+            'content_url' => $sUrl,
+    		'bx_if:show_section_pricing' => array(
+                'condition' => $bTmplVarsSectionPricing,
+                'content' => $aTmplVarsSectionPricing
+            ),
+            'bx_if:show_section_voting' => array(
+            	'condition' => $bTmplVarsSectionVoting,
+                'content' => $aTmplVarsSectionVoting
+            )
+    	));
+
+    	return $aUnit;
+    }
+
+    protected function getAttachments($sStorage, $aData, $aParams = array())
+    {
+    	$aFiles = $this->_oDb->getFile(array('type' => 'content_id_key_file_id', 'content_id' => $aData['id']));
+
+    	$aAttachments = parent::getAttachments($sStorage, $aData, $aParams);
+    	if(empty($aAttachments) || !is_array($aAttachments))
+    		return $aAttachments;
+
+        $aResults = array();
+    	foreach($aAttachments as $iIndex => $aAttachment) {
+    		$iAttachmentId = (int)$aAttachment['id'];
+
+    		$aAttachments[$iIndex]['class'] = (int)$aData['package'] == $iAttachmentId ? ' bx-market-attachment-main' : '';
+    		$aAttachments[$iIndex]['bx_if:main'] = array(
+    			'condition' => (int)$aData['package'] == $iAttachmentId,
+    			'content' => array()
+    		);
+
+    		$bAttachment = !empty($aFiles[$iAttachmentId]);
+    		$aAttachments[$iIndex]['bx_if:not_image']['content'] = array_merge($aAttachments[$iIndex]['bx_if:not_image']['content'], array(
+    			'file_type' => $bAttachment ? _t('_bx_market_form_entry_input_files_type_' . $aFiles[$iAttachmentId]['type']) : '',
+    			'bx_if:show_version' => array(
+    				'condition' => $bAttachment && $aFiles[$iAttachmentId]['type'] == BX_MARKET_FILE_TYPE_VERSION,
+    				'content' => array(
+    					'file_version' => $bAttachment ? $aFiles[$iAttachmentId]['version'] : ''
+    				)
+    			),
+    			'bx_if:show_update' => array(
+    				'condition' => $bAttachment && $aFiles[$iAttachmentId]['type'] == BX_MARKET_FILE_TYPE_UPDATE,
+    				'content' => array(
+    					'file_version_from_to' => $bAttachment ? _t('_bx_market_form_entry_input_files_version_from_x_to_y', $aFiles[$iAttachmentId]['version'], $aFiles[$iAttachmentId]['version_to']) : ''
+    				)
+    			)
+    		));
+
+    		$aFiles[$iAttachmentId] = $aAttachments[$iIndex];
+    		$aResults[$iAttachmentId] = $aAttachments[$iIndex];
+    	}
+
+    	return array_intersect_key($aFiles, $aResults);
+    }
+}
+
+/** @} */

+ 139 - 0
modules/boonex/market/updates/9.0.6_9.0.7/source/install/config.php

@@ -0,0 +1,139 @@
+<?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' => '9.0.7',
+    'vendor' => 'BoonEx',
+	'help_url' => 'http://feed.una.io/?section={module_name}',
+
+    'compatible_with' => array(
+        '9.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'
+    ),
+
+	/**
+     * 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'
+    ),
+
+);
+
+/** @} */

+ 390 - 0
modules/boonex/market/updates/9.0.6_9.0.7/source/install/langs/en.xml

@@ -0,0 +1,390 @@
+<?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_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_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[Name]]></string>
+	<string name="_bx_market_form_entry_input_name"><![CDATA[Name]]></string>
+	<string name="_bx_market_form_entry_input_name_err"><![CDATA[Name 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[Select 'None' 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_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_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_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_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[Product icon]]></string>
+	<string name="_bx_market_form_entry_input_pictures_use_as_cover"><![CDATA[Product cover]]></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[Version from {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_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_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_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_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_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_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_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_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_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_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_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_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"><![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_view_profile"><![CDATA[My 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_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_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_title_view_entry_popup"><![CDATA[Product Actions (in popup)]]></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[New Product]]></string>
+    <string name="_bx_market_menu_item_title_create_entry"><![CDATA[New 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 Product]]></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 Product]]></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[Rent]]></string>
+    <string name="_bx_market_menu_item_title_subscribe"><![CDATA[Rent for {0}{1}/{2}]]></string>
+    <string name="_bx_market_menu_item_title_system_download"><![CDATA[Download]]></string>
+    <string name="_bx_market_menu_item_title_download"><![CDATA[Download]]></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_updated"><![CDATA[Updated Products]]></string>
+    <string name="_bx_market_menu_item_title_entries_updated"><![CDATA[Updated]]></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_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[{addon} 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 - {addon} hidden]]></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_item_title_downloads_more"><![CDATA[Show More]]></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_active"><![CDATA[Active]]></string>
+	<string name="_bx_market_grid_filter_item_title_adm_hidden"><![CDATA[Hidden]]></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_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_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_reset"><![CDATA[Reset]]></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_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_prices"><![CDATA[Product prices]]></string>
+    <string name="_bx_market_cat_price_0"><![CDATA[None]]></string>
+    <string name="_bx_market_cat_price_1"><![CDATA[1]]></string>
+    <string name="_bx_market_cat_price_2"><![CDATA[2]]></string>
+    <string name="_bx_market_cat_price_3"><![CDATA[3]]></string>
+    <string name="_bx_market_cat_price_4"><![CDATA[4]]></string>
+    <string name="_bx_market_cat_price_5"><![CDATA[5]]></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_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[<a href="{0}">All Products by {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_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[Rent 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_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>
+</resources>

+ 57 - 0
modules/boonex/market/updates/9.0.6_9.0.7/source/install/sql/disable.sql

@@ -0,0 +1,57 @@
+
+-- SETTINGS
+SET @iTypeId = (SELECT `ID` FROM `sys_options_types` WHERE `name` = 'bx_market' LIMIT 1);
+SET @iCategId = (SELECT `ID` FROM `sys_options_categories` WHERE `type_id` = @iTypeId LIMIT 1);
+DELETE FROM `sys_options` WHERE `category_id` = @iCategId;
+DELETE FROM `sys_options_categories` WHERE `type_id` = @iTypeId;
+DELETE FROM `sys_options_types` WHERE `id` = @iTypeId;
+
+-- PAGES
+DELETE FROM `sys_objects_page` WHERE `module` = 'bx_market';
+DELETE FROM `sys_pages_blocks` WHERE `module` = 'bx_market' OR `object` IN('bx_market_create_entry', 'bx_market_edit_entry', 'bx_market_delete_entry', 'bx_market_download_entry', 'bx_market_view_entry', 'bx_market_view_entry_comments', 'bx_market_home', 'bx_market_categories', 'bx_market_popular', 'bx_market_updated', 'bx_market_author', 'bx_market_search', 'bx_market_manage');
+
+-- MENU
+DELETE FROM `sys_objects_menu` WHERE `module` = 'bx_market';
+DELETE FROM `sys_menu_sets` WHERE `module` = 'bx_market';
+DELETE FROM `sys_menu_items` WHERE `module` = 'bx_market' OR `set_name` IN('bx_market_view', 'bx_market_submenu', 'bx_market_view_submenu', 'bx_market_my', 'bx_market_snippet', 'bx_market_snippet_meta', 'bx_market_menu_manage_tools');
+
+-- PRIVACY 
+DELETE FROM `sys_objects_privacy` WHERE `object` IN ('bx_market_allow_view_to', 'bx_market_allow_purchase_to', 'bx_market_allow_comment_to', 'bx_market_allow_vote_to');
+
+-- ACL
+DELETE `sys_acl_actions`, `sys_acl_matrix` FROM `sys_acl_actions`, `sys_acl_matrix` WHERE `sys_acl_matrix`.`IDAction` = `sys_acl_actions`.`ID` AND `sys_acl_actions`.`Module` = 'bx_market';
+DELETE FROM `sys_acl_actions` WHERE `Module` = 'bx_market';
+
+-- SEARCH
+DELETE FROM `sys_objects_search` WHERE `ObjectName` IN ('bx_market', 'bx_market_cmts');
+
+-- CONNECTIONS
+DELETE FROM `sys_objects_connection` WHERE `object` = 'bx_market_subentries';
+
+-- METATAGS
+DELETE FROM `sys_objects_metatags` WHERE `object` = 'bx_market';
+
+-- CATEGORY
+DELETE FROM `sys_objects_category` WHERE `object` = 'bx_market_cats';
+
+-- STATS
+DELETE FROM `sys_statistics` WHERE `name` LIKE 'bx_market%';
+
+-- CHARTS
+DELETE FROM `sys_objects_chart` WHERE `object` LIKE 'bx_market%';
+
+-- GRIDS
+DELETE FROM `sys_objects_grid` WHERE `object` IN ('bx_market_administration', 'bx_market_common', 'bx_market_licenses');
+DELETE FROM `sys_grid_fields` WHERE `object` IN ('bx_market_administration', 'bx_market_common', 'bx_market_licenses');
+DELETE FROM `sys_grid_actions` WHERE `object` IN ('bx_market_administration', 'bx_market_common', 'bx_market_licenses');
+
+-- UPLOADERS
+DELETE FROM `sys_objects_uploader` WHERE `object` IN('bx_market_simple', 'bx_market_html5');
+
+-- ALERTS
+SET @iHandler := (SELECT `id` FROM `sys_alerts_handlers` WHERE `name` = 'bx_market' LIMIT 1);
+DELETE FROM `sys_alerts` WHERE `handler_id` = @iHandler;
+DELETE FROM `sys_alerts_handlers` WHERE `id` = @iHandler;
+
+-- CRON
+DELETE FROM `sys_cron_jobs` WHERE `name` LIKE 'bx_market%';

+ 536 - 0
modules/boonex/market/updates/9.0.6_9.0.7/source/install/sql/enable.sql

@@ -0,0 +1,536 @@
+
+-- 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_market', '_bx_market', 'bx_market@modules/boonex/market/|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_market', '_bx_market', 1);
+SET @iCategId = LAST_INSERT_ID();
+
+INSERT INTO `sys_options` (`name`, `value`, `category_id`, `caption`, `type`, `check`, `check_error`, `extra`, `order`) VALUES
+('bx_market_enable_recurring', 'on', @iCategId, '_bx_market_option_enable_recurring', 'checkbox', '', '', '', 1),
+('bx_market_recurring_reserve', '4', @iCategId, '_bx_market_option_recurring_reserve', 'digit', '', '', '', 2),
+('bx_market_summary_chars', '700', @iCategId, '_bx_market_option_summary_chars', 'digit', '', '', '', 10),
+('bx_market_plain_summary_chars', '240', @iCategId, '_bx_market_option_plain_summary_chars', 'digit', '', '', '', 11),
+('bx_market_per_page_browse', '12', @iCategId, '_bx_market_option_per_page_browse', 'digit', '', '', '', 20),
+('bx_market_per_page_profile', '3', @iCategId, '_bx_market_option_per_page_profile', 'digit', '', '', '', 21),
+('bx_market_rss_num', '10', @iCategId, '_bx_market_option_rss_num', 'digit', '', '', '', 25),
+('bx_market_searchable_fields', 'title,text', @iCategId, '_bx_market_option_searchable_fields', 'list', '', '', 'a:2:{s:6:"module";s:9:"bx_market";s:6:"method";s:21:"get_searchable_fields";}', 30);
+
+-- PAGE: create entry
+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_market_create_entry', '_bx_market_page_title_sys_create_entry', '_bx_market_page_title_create_entry', 'bx_market', 5, 2147483647, 1, 'create-product', 'page.php?i=create-product', '', '', '', 0, 1, 0, 'BxMarketPageBrowse', 'modules/boonex/market/classes/BxMarketPageBrowse.php');
+
+INSERT INTO `sys_pages_blocks` (`object`, `cell_id`, `module`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `order`) VALUES
+('bx_market_create_entry', 1, 'bx_market', '_bx_market_page_block_title_create_entry', 11, 2147483647, 'service', 'a:2:{s:6:"module";s:9:"bx_market";s:6:"method";s:13:"entity_create";}', 0, 1, 1);
+
+
+-- PAGE: edit entry
+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_market_edit_entry', '_bx_market_page_title_sys_edit_entry', '_bx_market_page_title_edit_entry', 'bx_market', 5, 2147483647, 1, 'edit-product', '', '', '', '', 0, 1, 0, 'BxMarketPageEntry', 'modules/boonex/market/classes/BxMarketPageEntry.php');
+
+INSERT INTO `sys_pages_blocks` (`object`, `cell_id`, `module`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `order`) VALUES
+('bx_market_edit_entry', 1, 'bx_market', '_bx_market_page_block_title_edit_entry', 11, 2147483647, 'service', 'a:2:{s:6:"module";s:9:"bx_market";s:6:"method";s:11:"entity_edit";}', 0, 0, 0);
+
+
+-- PAGE: delete entry
+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_market_delete_entry', '_bx_market_page_title_sys_delete_entry', '_bx_market_page_title_delete_entry', 'bx_market', 5, 2147483647, 1, 'delete-product', '', '', '', '', 0, 1, 0, 'BxMarketPageEntry', 'modules/boonex/market/classes/BxMarketPageEntry.php');
+
+INSERT INTO `sys_pages_blocks` (`object`, `cell_id`, `module`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `order`) VALUES
+('bx_market_delete_entry', 1, 'bx_market', '_bx_market_page_block_title_delete_entry', 11, 2147483647, 'service', 'a:2:{s:6:"module";s:9:"bx_market";s:6:"method";s:13:"entity_delete";}', 0, 0, 0);
+
+
+-- PAGE: download entry
+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_market_download_entry', '_bx_market_page_title_sys_download_entry', '_bx_market_page_title_download_entry', 'bx_market', 5, 2147483647, 1, 'download-product', '', '', '', '', 0, 1, 0, 'BxMarketPageEntry', 'modules/boonex/market/classes/BxMarketPageEntry.php');
+
+INSERT INTO `sys_pages_blocks` (`object`, `cell_id`, `module`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `order`) VALUES
+('bx_market_download_entry', 1, 'bx_market', '_bx_market_page_block_title_download_entry', 11, 2147483647, 'service', 'a:2:{s:6:"module";s:9:"bx_market";s:6:"method";s:15:"entity_download";}', 0, 0, 0);
+
+
+-- PAGE: view entry
+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_market_view_entry', '_bx_market_page_title_sys_view_entry', '_bx_market_page_title_view_entry', 'bx_market', 7, 2147483647, 1, 'view-product', '', '', '', '', 0, 1, 0, 'BxMarketPageEntry', 'modules/boonex/market/classes/BxMarketPageEntry.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_market_view_entry', 1, 'bx_market', '', '_bx_market_page_block_title_entry_breadcrumb', 13, 2147483647, 'service', 'a:2:{s:6:"module";s:9:"bx_market";s:6:"method";s:17:"entity_breadcrumb";}', 0, 0, 1, 0),
+('bx_market_view_entry', 2, 'bx_market', '', '_bx_market_page_block_title_entry_text', 11, 2147483647, 'service', 'a:2:{s:6:"module";s:9:"bx_market";s:6:"method";s:17:"entity_text_block";}', 0, 0, 1, 0),
+('bx_market_view_entry', 2, 'bx_market', '', '_bx_market_page_block_title_entry_all_actions', 13, 2147483647, 'service', 'a:2:{s:6:"module";s:9:"bx_market";s:6:"method";s:18:"entity_all_actions";}', 0, 0, 0, 1),
+('bx_market_view_entry', 2, 'bx_market', '', '_bx_market_page_block_title_entry_actions', 13, 2147483647, 'service', 'a:2:{s:6:"module";s:9:"bx_market";s:6:"method";s:14:"entity_actions";}', 0, 0, 0, 2),
+('bx_market_view_entry', 2, 'bx_market', '', '_bx_market_page_block_title_entry_comments', 11, 2147483647, 'service', 'a:2:{s:6:"module";s:9:"bx_market";s:6:"method";s:15:"entity_comments";}', 0, 0, 1, 3),
+('bx_market_view_entry', 2, 'bx_market', '', '_bx_market_page_block_title_entry_author_entries', 11, 2147483647, 'service', 'a:2:{s:6:"module";s:9:"bx_market";s:6:"method";s:22:"entity_author_entities";}', 0, 0, 1, 4),
+('bx_market_view_entry', 3, 'bx_market', '', '_bx_market_page_block_title_entry_social_sharing', 13, 2147483647, 'service', 'a:2:{s:6:"module";s:9:"bx_market";s:6:"method";s:21:"entity_social_sharing";}', 0, 0, 1, 0),
+('bx_market_view_entry', 3, 'bx_market', '', '_bx_market_page_block_title_entry_info', 11, 2147483647, 'service', 'a:2:{s:6:"module";s:9:"bx_market";s:6:"method";s:11:"entity_info";}', 0, 0, 1, 2),
+('bx_market_view_entry', 3, 'bx_market', '', '_bx_market_page_block_title_entry_rating', 11, 2147483647, 'service', 'a:2:{s:6:"module";s:9:"bx_market";s:6:"method";s:13:"entity_rating";}', 0, 0, 1, 3),
+('bx_market_view_entry', 3, 'bx_market', '', '_bx_market_page_block_title_entry_author', 11, 2147483647, 'service', 'a:2:{s:6:"module";s:9:"bx_market";s:6:"method";s:13:"entity_author";}', 0, 0, 1, 4),
+('bx_market_view_entry', 3, 'bx_market', '', '_bx_market_page_block_title_entry_location', 13, 2147483647, 'service', 'a:2:{s:6:"module";s:9:"bx_market";s:6:"method";s:15:"entity_location";}', 0, 0, 0, 5),
+('bx_market_view_entry', 3, 'bx_market', '', '_bx_market_page_block_title_entry_location', 3, 2147483647, 'service', 'a:4:{s:6:"module";s:6:"system";s:6:"method";s:13:"locations_map";s:6:"params";a:2:{i:0;s:9:"bx_market";i:1;s:4:"{id}";}s:5:"class";s:20:"TemplServiceMetatags";}', 0, 0, 1, 6),
+('bx_market_view_entry', 3, 'bx_market', '', '_bx_market_page_block_title_entry_attachments', 11, 2147483647, 'service', 'a:2:{s:6:"module";s:9:"bx_market";s:6:"method";s:18:"entity_attachments";}', 0, 0, 0, 7);
+
+
+
+-- PAGE: view entry comments
+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_market_view_entry_comments', '_bx_market_page_title_sys_view_entry_comments', '_bx_market_page_title_view_entry_comments', 'bx_market', 5, 2147483647, 1, 'view-product-comments', '', '', '', '', 0, 1, 0, 'BxMarketPageEntry', 'modules/boonex/market/classes/BxMarketPageEntry.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_market_view_entry_comments', 1, 'bx_market', '_bx_market_page_block_title_entry_comments', '_bx_market_page_block_title_entry_comments_link', 11, 2147483647, 'service', 'a:2:{s:6:"module";s:9:"bx_market";s:6:"method";s:15:"entity_comments";}', 0, 0, 1);
+
+
+-- PAGE: view entry info
+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_market_view_entry_info', '_bx_market_page_title_sys_view_entry_info', '_bx_market_page_title_view_entry_info', 'bx_market', 5, 2147483647, 1, 'view-product-info', '', '', '', '', 0, 1, 0, 'BxMarketPageEntry', 'modules/boonex/market/classes/BxMarketPageEntry.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_market_view_entry_info', 1, 'bx_market', '_bx_market_page_block_title_entry_info', '_bx_market_page_block_title_entry_info_link', 11, 2147483647, 'service', 'a:2:{s:6:"module";s:9:"bx_market";s:6:"method";s:16:"entity_info_full";}', 0, 0, 1),
+('bx_market_view_entry_info', 1, 'bx_market', '', '_bx_market_page_block_title_entry_text', 11, 2147483647, 'service', 'a:2:{s:6:"module";s:9:"bx_market";s:6:"method";s:17:"entity_text_block";}', 0, 0, 2);
+
+
+-- PAGE: categories
+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_market_categories', '_bx_market_page_title_sys_entries_categories', '_bx_market_page_title_entries_categories', 'bx_market', 5, 2147483647, 1, 'products-categories', 'page.php?i=products-categories', '', '', '', 0, 1, 0, 'BxMarketPageBrowse', 'modules/boonex/market/classes/BxMarketPageBrowse.php');
+
+INSERT INTO `sys_pages_blocks`(`object`, `cell_id`, `module`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `order`) VALUES 
+('bx_market_categories', 1, 'bx_market', '_bx_market_page_block_title_cats', 11, 2147483647, 'service', 'a:4:{s:6:"module";s:6:"system";s:6:"method";s:15:"categories_list";s:6:"params";a:2:{i:0;s:14:"bx_market_cats";i:1;a:1:{s:10:"show_empty";b:1;}}s:5:"class";s:20:"TemplServiceCategory";}', 0, 1, 1);
+
+
+-- PAGE: latest entries
+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_market_latest', '_bx_market_page_title_sys_entries_latest', '_bx_market_page_title_entries_latest', 'bx_market', 5, 2147483647, 1, 'products-latest', 'page.php?i=products-latest', '', '', '', 0, 1, 0, 'BxMarketPageBrowse', 'modules/boonex/market/classes/BxMarketPageBrowse.php');
+
+INSERT INTO `sys_pages_blocks`(`object`, `cell_id`, `module`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `order`) VALUES 
+('bx_market_latest', 1, 'bx_market', '_bx_market_page_block_title_latest_entries', 11, 2147483647, 'service', 'a:3:{s:6:"module";s:9:"bx_market";s:6:"method";s:13:"browse_public";s:6:"params";a:3:{s:9:"unit_view";s:7:"gallery";s:13:"empty_message";b:1;s:13:"ajax_paginate";b:0;}}', 0, 0, 1);
+
+
+-- PAGE: featured entries
+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_market_featured', '_bx_market_page_title_sys_entries_featured', '_bx_market_page_title_entries_featured', 'bx_market', 5, 2147483647, 1, 'products-featured', 'page.php?i=products-featured', '', '', '', 0, 1, 0, 'BxMarketPageBrowse', 'modules/boonex/market/classes/BxMarketPageBrowse.php');
+
+INSERT INTO `sys_pages_blocks`(`object`, `cell_id`, `module`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `order`) VALUES 
+('bx_market_featured', 1, 'bx_market', '_bx_market_page_block_title_featured_entries', 11, 2147483647, 'service', 'a:3:{s:6:"module";s:9:"bx_market";s:6:"method";s:15:"browse_featured";s:6:"params";a:3:{s:9:"unit_view";s:7:"gallery";s:13:"empty_message";b:1;s:13:"ajax_paginate";b:0;}}', 0, 0, 1);
+
+
+-- PAGE: popular entries
+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_market_popular', '_bx_market_page_title_sys_entries_popular', '_bx_market_page_title_entries_popular', 'bx_market', 5, 2147483647, 1, 'products-popular', 'page.php?i=products-popular', '', '', '', 0, 1, 0, 'BxMarketPageBrowse', 'modules/boonex/market/classes/BxMarketPageBrowse.php');
+
+INSERT INTO `sys_pages_blocks`(`object`, `cell_id`, `module`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `order`) VALUES 
+('bx_market_popular', 1, 'bx_market', '_bx_market_page_block_title_popular_entries', 11, 2147483647, 'service', 'a:3:{s:6:"module";s:9:"bx_market";s:6:"method";s:14:"browse_popular";s:6:"params";a:3:{s:9:"unit_view";s:7:"gallery";s:13:"empty_message";b:1;s:13:"ajax_paginate";b:0;}}', 0, 0, 1);
+
+
+-- PAGE: updated entries
+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_market_updated', '_bx_market_page_title_sys_entries_updated', '_bx_market_page_title_entries_updated', 'bx_market', 5, 2147483647, 1, 'products-updated', 'page.php?i=products-updated', '', '', '', 0, 1, 0, 'BxMarketPageBrowse', 'modules/boonex/market/classes/BxMarketPageBrowse.php');
+
+INSERT INTO `sys_pages_blocks`(`object`, `cell_id`, `module`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `order`) VALUES 
+('bx_market_updated', 1, 'bx_market', '_bx_market_page_block_title_updated_entries', 11, 2147483647, 'service', 'a:3:{s:6:"module";s:9:"bx_market";s:6:"method";s:14:"browse_updated";s:6:"params";a:3:{s:9:"unit_view";s:7:"gallery";s:13:"empty_message";b:1;s:13:"ajax_paginate";b:0;}}', 0, 0, 1);
+
+
+-- PAGE: entries of author
+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_market_author', 'products-author', '_bx_market_page_title_sys_entries_of_author', '_bx_market_page_title_entries_of_author', 'bx_market', 5, 2147483647, 1, '', '', '', '', 0, 1, 0, 'BxMarketPageAuthor', 'modules/boonex/market/classes/BxMarketPageAuthor.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_market_author', 1, 'bx_market', '', '_bx_market_page_block_title_entries_actions', 13, 2147483647, 'service', 'a:2:{s:6:"module";s:9:"bx_market";s:6:"method";s:18:"my_entries_actions";}', 0, 0, 1, 1),
+('bx_market_author', 1, 'bx_market', '_bx_market_page_block_title_sys_favorites_of_author', '_bx_market_page_block_title_favorites_of_author', 11, 2147483647, 'service', 'a:3:{s:6:"module";s:9:"bx_market";s:6:"method";s:15:"browse_favorite";s:6:"params";a:1:{i:0;s:12:"{profile_id}";}}', 0, 1, 1, 2),
+('bx_market_author', 1, 'bx_market', '_bx_market_page_block_title_sys_entries_of_author', '_bx_market_page_block_title_entries_of_author', 11, 2147483647, 'service', 'a:2:{s:6:"module";s:9:"bx_market";s:6:"method";s:13:"browse_author";}', 0, 0, 1, 3);
+
+-- PAGE: profile's licenses
+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_market_licenses', '_bx_market_page_title_sys_licenses', '_bx_market_page_title_licenses', 'bx_market', 5, 2147483647, 1, 'products-licenses', '', '', '', '', 0, 1, 0, 'BxMarketPageLicenses', 'modules/boonex/market/classes/BxMarketPageLicenses.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_market_licenses', 1, 'bx_market', '', '_bx_market_page_block_title_licenses_note', 13, 2147483647, 'service', 'a:2:{s:6:"module";s:9:"bx_market";s:6:"method";s:19:"block_licenses_note";}', 0, 0, 1, 0),
+('bx_market_licenses', 1, 'bx_market', '', '_bx_market_page_block_title_licenses', 11, 2147483647, 'service', 'a:2:{s:6:"module";s:9:"bx_market";s:6:"method";s:14:"block_licenses";}', 0, 0, 1, 1);
+
+-- 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_market_home', 'products-home', '_bx_market_page_title_sys_home', '_bx_market_page_title_home', 'bx_market', 1, 2147483647, 1, 'page.php?i=products-home', '', '', '', 0, 1, 0, 'BxMarketPageBrowse', 'modules/boonex/market/classes/BxMarketPageBrowse.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_market_home', 1, 'bx_market', '', '_bx_market_page_block_title_popular_keywords', 11, 2147483647, 'service', 'a:4:{s:6:"module";s:6:"system";s:6:"method";s:14:"keywords_cloud";s:6:"params";a:2:{i:0;s:9:"bx_market";i:1;s:9:"bx_market";}s:5:"class";s:20:"TemplServiceMetatags";}', 0, 1, 1, 0),
+('bx_market_home', 1, 'bx_market', '', '_bx_market_page_block_title_cats', 11, 2147483647, 'service', 'a:4:{s:6:"module";s:6:"system";s:6:"method";s:15:"categories_list";s:6:"params";a:2:{i:0;s:14:"bx_market_cats";i:1;a:1:{s:10:"show_empty";b:1;}}s:5:"class";s:20:"TemplServiceCategory";}', 0, 0, 1, 1),
+('bx_market_home', 2, 'bx_market', '', '_bx_market_page_block_title_featured_entries', 11, 2147483647, 'service', 'a:3:{s:6:"module";s:9:"bx_market";s:6:"method";s:15:"browse_featured";s:6:"params";a:1:{i:0;s:7:"gallery";}}', 0, 1, 1, 0),
+('bx_market_home', 2, 'bx_market', '', '_bx_market_page_block_title_latest_entries', 11, 2147483647, 'service', 'a:3:{s:6:"module";s:9:"bx_market";s:6:"method";s:13:"browse_public";s:6:"params";a:1:{i:0;s:7:"gallery";}}', 0, 1, 1, 1),
+('bx_market_home', 2, 'bx_market', '', '_bx_market_page_block_title_popular_entries', 11, 2147483647, 'service', 'a:3:{s:6:"module";s:9:"bx_market";s:6:"method";s:14:"browse_popular";s:6:"params";a:2:{i:0;s:7:"gallery";i:1;b:0;}}', 0, 1, 1, 2),
+('bx_market_home', 2, 'bx_market', '', '_bx_market_page_block_title_updated_entries', 11, 2147483647, 'service', 'a:3:{s:6:"module";s:9:"bx_market";s:6:"method";s:14:"browse_updated";s:6:"params";a:2:{i:0;s:7:"gallery";i:1;b:0;}}', 0, 1, 0, 3);
+
+-- PAGE: search for entries
+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_market_search', '_bx_market_page_title_sys_entries_search', '_bx_market_page_title_entries_search', 'bx_market', 5, 2147483647, 1, 'products-search', 'page.php?i=products-search', '', '', '', 0, 1, 0, 'BxMarketPageBrowse', 'modules/boonex/market/classes/BxMarketPageBrowse.php');
+
+INSERT INTO `sys_pages_blocks`(`object`, `cell_id`, `module`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `active`, `order`) VALUES 
+('bx_market_search', 1, 'bx_market', '_bx_market_page_block_title_search_form', 11, 2147483647, 'service', 'a:4:{s:6:"module";s:6:"system";s:6:"method";s:8:"get_form";s:6:"params";a:1:{i:0;a:1:{s:6:"object";s:9:"bx_market";}}s:5:"class";s:27:"TemplSearchExtendedServices";}', 0, 1, 1, 1),
+('bx_market_search', 1, 'bx_market', '_bx_market_page_block_title_search_results', 11, 2147483647, 'service', 'a:4:{s:6:"module";s:6:"system";s:6:"method";s:11:"get_results";s:6:"params";a:1:{i:0;a:2:{s:6:"object";s:9:"bx_market";s:10:"show_empty";b:1;}}s:5:"class";s:27:"TemplSearchExtendedServices";}', 0, 1, 1, 2),
+('bx_market_search', 1, 'bx_market', '_bx_market_page_block_title_search_form_cmts', 11, 2147483647, 'service', 'a:4:{s:6:"module";s:6:"system";s:6:"method";s:8:"get_form";s:6:"params";a:1:{i:0;a:1:{s:6:"object";s:14:"bx_market_cmts";}}s:5:"class";s:27:"TemplSearchExtendedServices";}', 0, 1, 0, 3),
+('bx_market_search', 1, 'bx_market', '_bx_market_page_block_title_search_results_cmts', 11, 2147483647, 'service', 'a:4:{s:6:"module";s:6:"system";s:6:"method";s:11:"get_results";s:6:"params";a:1:{i:0;a:2:{s:6:"object";s:14:"bx_market_cmts";s:10:"show_empty";b:1;}}s:5:"class";s:27:"TemplSearchExtendedServices";}', 0, 1, 0, 4);
+
+-- PAGE: module manage own
+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_market_manage', '_bx_market_page_title_sys_manage', '_bx_market_page_title_manage', 'bx_market', 5, 2147483647, 1, 'products-manage', 'page.php?i=products-manage', '', '', '', 0, 1, 0, 'BxMarketPageBrowse', 'modules/boonex/market/classes/BxMarketPageBrowse.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_market_manage', 1, 'bx_market', '_bx_market_page_block_title_system_manage', '_bx_market_page_block_title_manage', 11, 2147483647, 'service', 'a:2:{s:6:"module";s:9:"bx_market";s:6:"method";s:12:"manage_tools";}}', 0, 1, 0);
+
+-- PAGE: module manage all
+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_market_administration', '_bx_market_page_title_sys_manage_administration', '_bx_market_page_title_manage', 'bx_market', 5, 192, 1, 'products-administration', 'page.php?i=products-administration', '', '', '', 0, 1, 0, 'BxMarketPageBrowse', 'modules/boonex/market/classes/BxMarketPageBrowse.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_market_administration', 1, 'bx_market', '_bx_market_page_block_title_system_manage_administration', '_bx_market_page_block_title_manage', 11, 192, 'service', 'a:3:{s:6:"module";s:9:"bx_market";s:6:"method";s:12:"manage_tools";s:6:"params";a:1:{i:0;s:14:"administration";}}', 0, 1, 0);
+
+-- PAGE: add block to homepage
+SET @iBlockOrder = (SELECT `order` FROM `sys_pages_blocks` WHERE `object` = 'sys_home' AND `cell_id` = 1 ORDER BY `order` DESC LIMIT 1);
+INSERT INTO `sys_pages_blocks`(`object`, `cell_id`, `module`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `active`, `order`) VALUES 
+('sys_home', 1, 'bx_market', '_bx_market_page_block_title_latest_entries', 11, 2147483647, 'service', 'a:3:{s:6:"module";s:9:"bx_market";s:6:"method";s:13:"browse_public";s:6:"params";a:2:{i:0;b:0;i:1;b:0;}}', 1, 0, 0, IFNULL(@iBlockOrder, 0) + 1);
+
+-- PAGES: add page block to profiles modules (trigger* page objects are processed separately upon modules enable/disable)
+SET @iPBCellProfile = 3;
+INSERT INTO `sys_pages_blocks` (`object`, `cell_id`, `module`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `order`) VALUES
+('trigger_page_profile_view_entry', @iPBCellProfile, 'bx_market', '_bx_market_page_block_title_view_profile', 11, 2147483647, 'service', 'a:3:{s:6:"module";s:9:"bx_market";s:6:"method";s:13:"browse_author";s:6:"params";a:2:{i:0;s:12:"{profile_id}";i:1;a:2:{s:8:"per_page";s:26:"bx_market_per_page_profile";s:13:"empty_message";b:0;}}}', 0, 0, 0);
+
+-- PAGE: service blocks
+SET @iBlockOrder = (SELECT `order` FROM `sys_pages_blocks` WHERE `object` = '' AND `cell_id` = 0 ORDER BY `order` DESC LIMIT 1);
+INSERT INTO `sys_pages_blocks`(`object`, `cell_id`, `module`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `order`) VALUES 
+('', 0, 'bx_market', '_bx_market_page_block_title_latest_entries_view_extended', 11, 2147483647, 'service', 'a:3:{s:6:"module";s:9:"bx_market";s:6:"method";s:13:"browse_public";s:6:"params";a:1:{s:9:"unit_view";s:8:"extended";}}', 0, 1, IFNULL(@iBlockOrder, 0) + 1),
+('', 0, 'bx_market', '_bx_market_page_block_title_latest_entries_view_full', 11, 2147483647, 'service', 'a:3:{s:6:"module";s:9:"bx_market";s:6:"method";s:13:"browse_public";s:6:"params";a:1:{i:0;s:4:"full";}}', 0, 1, IFNULL(@iBlockOrder, 0) + 2),
+('', 0, 'bx_market', '_bx_market_page_block_title_popular_entries_view_extended', 11, 2147483647, 'service', 'a:3:{s:6:"module";s:9:"bx_market";s:6:"method";s:14:"browse_popular";s:6:"params";a:1:{i:0;s:8:"extended";}}', 0, 1, IFNULL(@iBlockOrder, 0) + 3),
+('', 0, 'bx_market', '_bx_market_page_block_title_popular_entries_view_full', 11, 2147483647, 'service', 'a:3:{s:6:"module";s:9:"bx_market";s:6:"method";s:14:"browse_popular";s:6:"params";a:1:{i:0;s:4:"full";}}', 0, 1, IFNULL(@iBlockOrder, 0) + 4),
+('', 0, 'bx_market', '_bx_market_page_block_title_featured_entries_view_extended', 11, 2147483647, 'service', 'a:3:{s:6:"module";s:9:"bx_market";s:6:"method";s:15:"browse_featured";s:6:"params";a:1:{s:9:"unit_view";s:8:"extended";}}', 0, 1, IFNULL(@iBlockOrder, 0) + 5),
+('', 0, 'bx_market', '_bx_market_page_block_title_featured_entries_view_full', 11, 2147483647, 'service', 'a:3:{s:6:"module";s:9:"bx_market";s:6:"method";s:15:"browse_featured";s:6:"params";a:1:{i:0;s:4:"full";}}', 0, 1, IFNULL(@iBlockOrder, 0) + 6),
+('', 0, 'bx_market', '_bx_market_page_block_title_updated_entries_view_extended', 11, 2147483647, 'service', 'a:3:{s:6:"module";s:9:"bx_market";s:6:"method";s:14:"browse_updated";s:6:"params";a:1:{s:9:"unit_view";s:8:"extended";}}', 0, 1, IFNULL(@iBlockOrder, 0) + 7),
+('', 0, 'bx_market', '_bx_market_page_block_title_updated_entries_view_full', 11, 2147483647, 'service', 'a:3:{s:6:"module";s:9:"bx_market";s:6:"method";s:14:"browse_updated";s:6:"params";a:1:{i:0;s:4:"full";}}', 0, 1, IFNULL(@iBlockOrder, 0) + 8);
+
+
+-- MENU: add to site menu
+SET @iSiteMenuOrder = (SELECT `order` FROM `sys_menu_items` WHERE `set_name` = 'sys_site' 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_site', 'bx_market', 'products-home', '_bx_market_menu_item_title_system_entries_home', '_bx_market_menu_item_title_entries_home', 'page.php?i=products-home', '', '', 'shopping-cart col-green3', 'bx_market_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_market', 'products-home', '_bx_market_menu_item_title_system_entries_home', '_bx_market_menu_item_title_entries_home', 'page.php?i=products-home', '', '', 'shopping-cart col-green3', 'bx_market_submenu', 2147483647, 1, 1, IFNULL(@iHomepageMenuOrder, 0) + 1);
+
+-- MENU: add to "add content" menu
+SET @iAddMenuOrder = (SELECT `order` FROM `sys_menu_items` WHERE `set_name` = 'sys_add_content_links' 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_add_content_links', 'bx_market', 'create-product', '_bx_market_menu_item_title_system_create_entry', '_bx_market_menu_item_title_create_entry', 'page.php?i=create-product', '', '', 'shopping-cart col-green3', '', 2147483647, 1, 1, IFNULL(@iAddMenuOrder, 0) + 1);
+
+
+-- MENU: actions menu for view entry 
+INSERT INTO `sys_objects_menu`(`object`, `title`, `set_name`, `module`, `template_id`, `deletable`, `active`, `override_class_name`, `override_class_file`) VALUES 
+('bx_market_view', '_bx_market_menu_title_view_entry', 'bx_market_view', 'bx_market', 9, 0, 1, 'BxMarketMenuView', 'modules/boonex/market/classes/BxMarketMenuView.php'),
+('bx_market_view_popup', '_bx_market_menu_title_view_entry_popup', 'bx_market_view', 'bx_market', 4, 0, 1, 'BxMarketMenuView', 'modules/boonex/market/classes/BxMarketMenuView.php');
+
+INSERT INTO `sys_menu_sets`(`set_name`, `module`, `title`, `deletable`) VALUES 
+('bx_market_view', 'bx_market', '_bx_market_menu_set_title_view_entry', 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_market_view', 'bx_market', 'edit-product', '_bx_market_menu_item_title_system_edit_entry', '_bx_market_menu_item_title_edit_entry', 'page.php?i=edit-product&id={content_id}', '', '', 'pencil', '', 2147483647, 1, 0, 1),
+('bx_market_view', 'bx_market', 'delete-product', '_bx_market_menu_item_title_system_delete_entry', '_bx_market_menu_item_title_delete_entry', 'page.php?i=delete-product&id={content_id}', '', '', 'remove', '', 2147483647, 1, 0, 2),
+('bx_market_view', 'bx_market', 'download', '_bx_market_menu_item_title_system_download', '_bx_market_menu_item_title_download', 'page.php?i=download-product&id={content_id}', '', '', 'download', '', 2147483647, 1, 0, 3),
+('bx_market_view', 'bx_market', 'add-to-cart', '_bx_market_menu_item_title_system_add_to_cart', '{add_to_cart_title}', 'javascript:void(0);', 'javascript:{add_to_cart_onclick}', '', 'cart-plus', '', 2147483647, 1, 0, 4),
+('bx_market_view', 'bx_market', 'subscribe', '_bx_market_menu_item_title_system_subscribe', '{subscribe_title}', 'javascript:void(0);', 'javascript:{subscribe_onclick}', '', 'credit-card', '', 2147483647, 1, 0, 5);
+
+
+-- MENU: actions menu for my entries
+INSERT INTO `sys_objects_menu`(`object`, `title`, `set_name`, `module`, `template_id`, `deletable`, `active`, `override_class_name`, `override_class_file`) VALUES 
+('bx_market_my', '_bx_market_menu_title_entries_my', 'bx_market_my', 'bx_market', 9, 0, 1, 'BxMarketMenu', 'modules/boonex/market/classes/BxMarketMenu.php');
+
+INSERT INTO `sys_menu_sets`(`set_name`, `module`, `title`, `deletable`) VALUES 
+('bx_market_my', 'bx_market', '_bx_market_menu_set_title_entries_my', 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_market_my', 'bx_market', 'create-product', '_bx_market_menu_item_title_system_create_entry', '_bx_market_menu_item_title_create_entry', 'page.php?i=create-product', '', '', 'plus', '', 2147483647, 1, 0, 0);
+
+-- MENU: actions menu for snippet
+INSERT INTO `sys_objects_menu`(`object`, `title`, `set_name`, `module`, `template_id`, `deletable`, `active`, `override_class_name`, `override_class_file`) VALUES 
+('bx_market_snippet', '_bx_market_menu_title_snippet', 'bx_market_snippet', 'bx_market', 17, 0, 1, 'BxMarketMenuSnippetActions', 'modules/boonex/market/classes/BxMarketMenuSnippetActions.php');
+
+INSERT INTO `sys_menu_sets`(`set_name`, `module`, `title`, `deletable`) VALUES 
+('bx_market_snippet', 'bx_market', '_bx_market_menu_set_title_snippet', 0);
+
+INSERT INTO `sys_menu_items`(`set_name`, `module`, `name`, `title_system`, `title`, `link`, `onclick`, `target`, `icon`, `addon`, `submenu_object`, `submenu_popup`, `visible_for_levels`, `active`, `copyable`, `editable`, `order`) VALUES 
+('bx_market_snippet', 'bx_market', 'snippet-more', '_bx_market_menu_item_title_system_snippet_more', '_bx_market_menu_item_title_snippet_more', 'javascript:void(0)', 'bx_menu_popup(''bx_market_view_popup'', this, {''id'':''bx_market_snippet_{content_id}''}, {id:{content_id}});', '', 'ellipsis-v', '', 'bx_market_view_popup', 1, 2147483647, 1, 0, 0, 1);
+
+-- MENU: custom menu for snippet meta info
+INSERT INTO `sys_objects_menu`(`object`, `title`, `set_name`, `module`, `template_id`, `deletable`, `active`, `override_class_name`, `override_class_file`) VALUES 
+('bx_market_snippet_meta', '_sys_menu_title_snippet_meta', 'bx_market_snippet_meta', 'bx_market', 15, 0, 1, 'BxMarketMenuSnippetMeta', 'modules/boonex/market/classes/BxMarketMenuSnippetMeta.php');
+
+INSERT INTO `sys_menu_sets`(`set_name`, `module`, `title`, `deletable`) VALUES 
+('bx_market_snippet_meta', 'bx_market', '_sys_menu_set_title_snippet_meta', 0);
+
+INSERT INTO `sys_menu_items`(`set_name`, `module`, `name`, `title_system`, `title`, `link`, `onclick`, `target`, `icon`, `submenu_object`, `visible_for_levels`, `active`, `copyable`, `editable`, `order`) VALUES 
+('bx_market_snippet_meta', 'bx_market', 'author', '_sys_menu_item_title_system_sm_author', '_sys_menu_item_title_sm_author', '', '', '', '', '', 2147483647, 1, 0, 1, 1),
+('bx_market_snippet_meta', 'bx_market', 'date', '_sys_menu_item_title_system_sm_date', '_sys_menu_item_title_sm_date', '', '', '', '', '', 2147483647, 0, 0, 1, 2),
+('bx_market_snippet_meta', 'bx_market', 'category', '_sys_menu_item_title_system_sm_category', '_sys_menu_item_title_sm_category', '', '', '', '', '', 2147483647, 0, 0, 1, 3),
+('bx_market_snippet_meta', 'bx_market', 'tags', '_sys_menu_item_title_system_sm_tags', '_sys_menu_item_title_sm_tags', '', '', '', '', '', 2147483647, 0, 0, 1, 4),
+('bx_market_snippet_meta', 'bx_market', 'views', '_sys_menu_item_title_system_sm_views', '_sys_menu_item_title_sm_views', '', '', '', '', '', 2147483647, 0, 0, 1, 5),
+('bx_market_snippet_meta', 'bx_market', 'comments', '_sys_menu_item_title_system_sm_comments', '_sys_menu_item_title_sm_comments', '', '', '', '', '', 2147483647, 0, 0, 1, 6);
+
+-- 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_market_submenu', '_bx_market_menu_title_submenu', 'bx_market_submenu', 'bx_market', 8, 0, 1, '', '');
+
+INSERT INTO `sys_menu_sets`(`set_name`, `module`, `title`, `deletable`) VALUES 
+('bx_market_submenu', 'bx_market', '_bx_market_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_market_submenu', 'bx_market', 'products-home', '_bx_market_menu_item_title_system_entries_public', '_bx_market_menu_item_title_entries_public', 'page.php?i=products-home', '', '', '', '', 2147483647, 1, 1, 1),
+('bx_market_submenu', 'bx_market', 'products-latest', '_bx_market_menu_item_title_system_entries_latest', '_bx_market_menu_item_title_entries_latest', 'page.php?i=products-latest', '', '', '', '', 2147483647, 1, 1, 2),
+('bx_market_submenu', 'bx_market', 'products-featured', '_bx_market_menu_item_title_system_entries_featured', '_bx_market_menu_item_title_entries_featured', 'page.php?i=products-featured', '', '', '', '', 2147483647, 1, 1, 3),
+('bx_market_submenu', 'bx_market', 'products-popular', '_bx_market_menu_item_title_system_entries_popular', '_bx_market_menu_item_title_entries_popular', 'page.php?i=products-popular', '', '', '', '', 2147483647, 1, 1, 4),
+('bx_market_submenu', 'bx_market', 'products-updated', '_bx_market_menu_item_title_system_entries_updated', '_bx_market_menu_item_title_entries_updated', 'page.php?i=products-updated', '', '', '', '', 2147483647, 1, 1, 5),
+('bx_market_submenu', 'bx_market', 'products-categories', '_bx_market_menu_item_title_system_entries_categories', '_bx_market_menu_item_title_entries_categories', 'page.php?i=products-categories', '', '', '', '', 2147483647, 1, 1, 6),
+('bx_market_submenu', 'bx_market', 'products-search', '_bx_market_menu_item_title_system_entries_search', '_bx_market_menu_item_title_entries_search', 'page.php?i=products-search', '', '', '', '', 2147483647, 1, 1, 7),
+('bx_market_submenu', 'bx_market', 'products-manage', '_bx_market_menu_item_title_system_entries_manage', '_bx_market_menu_item_title_entries_manage', 'page.php?i=products-manage', '', '', '', '', 2147483646, 1, 1, 8);
+
+-- MENU: sub-menu for view entry
+INSERT INTO `sys_objects_menu`(`object`, `title`, `set_name`, `module`, `template_id`, `deletable`, `active`, `override_class_name`, `override_class_file`) VALUES 
+('bx_market_view_submenu', '_bx_market_menu_title_view_entry_submenu', 'bx_market_view_submenu', 'bx_market', 8, 0, 1, 'BxMarketMenuView', 'modules/boonex/market/classes/BxMarketMenuView.php');
+
+INSERT INTO `sys_menu_sets`(`set_name`, `module`, `title`, `deletable`) VALUES 
+('bx_market_view_submenu', 'bx_market', '_bx_market_menu_set_title_view_entry_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_market_view_submenu', 'bx_market', 'view-product', '_bx_market_menu_item_title_system_view_entry_submenu_entry', '_bx_market_menu_item_title_view_entry_submenu_entry', 'page.php?i=view-product&id={content_id}', '', '', '', '', 2147483647, 1, 0, 1),
+('bx_market_view_submenu', 'bx_market', 'view-product-info', '_bx_market_menu_item_title_system_view_entry_submenu_info', '_bx_market_menu_item_title_view_entry_submenu_info', 'page.php?i=view-product-info&id={content_id}', '', '', '', '', 2147483647, 1, 0, 2),
+('bx_market_view_submenu', 'bx_market', 'view-product-comments', '_bx_market_menu_item_title_system_view_entry_submenu_comments', '_bx_market_menu_item_title_view_entry_submenu_comments', 'page.php?i=view-product-comments&id={content_id}', '', '', '', '', 2147483647, 1, 0, 3);
+
+-- MENU: profile stats
+SET @iNotifMenuOrder = (SELECT IFNULL(MAX(`order`), 0) FROM `sys_menu_items` WHERE `set_name` = 'sys_profile_stats' AND `active` = 1 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_profile_stats', 'bx_market', 'profile-stats-manage-products', '_bx_market_menu_item_title_system_manage_my_products', '_bx_market_menu_item_title_manage_my_products', 'page.php?i=products-manage', '', '_self', 'shopping-cart col-green3', 'a:2:{s:6:"module";s:9:"bx_market";s:6:"method";s:41:"get_menu_addon_manage_tools_profile_stats";}', '', 2147483646, 1, 0, @iNotifMenuOrder + 1);
+
+-- MENU: manage tools submenu
+INSERT INTO `sys_objects_menu`(`object`, `title`, `set_name`, `module`, `template_id`, `deletable`, `active`, `override_class_name`, `override_class_file`) VALUES 
+('bx_market_menu_manage_tools', '_bx_market_menu_title_manage_tools', 'bx_market_menu_manage_tools', 'bx_market', 6, 0, 1, 'BxMarketMenuManageTools', 'modules/boonex/market/classes/BxMarketMenuManageTools.php');
+
+INSERT INTO `sys_menu_sets`(`set_name`, `module`, `title`, `deletable`) VALUES 
+('bx_market_menu_manage_tools', 'bx_market', '_bx_market_menu_set_title_manage_tools', 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_market_menu_manage_tools', 'bx_market', 'delete-with-content', '_bx_market_menu_item_title_system_delete_with_content', '_bx_market_menu_item_title_delete_with_content', 'javascript:void(0)', 'javascript:{js_object}.onClickDeleteWithContent({content_id});', '_self', 'trash-o', '', 128, 1, 0, 0);
+
+-- 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_market', 'products-administration', '_bx_market_menu_item_title_system_admt_products', '_bx_market_menu_item_title_admt_products', 'page.php?i=products-administration', '', '_self', '', 'a:2:{s:6:"module";s:9:"bx_market";s:6:"method";s:27:"get_menu_addon_manage_tools";}', '', 192, 1, 0, @iManageMenuOrder + 1);
+
+-- MENU: add menu item to profiles modules (trigger* menu sets are processed separately upon modules enable/disable)
+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 
+('trigger_profile_view_submenu', 'bx_market', 'products-author', '_bx_market_menu_item_title_system_view_entries_author', '_bx_market_menu_item_title_view_entries_author', 'page.php?i=products-author&profile_id={profile_id}', '', '', 'shopping-cart col-green3', '', 2147483647, 1, 0, 0);
+
+-- MENU: account dashboard
+SET @iMoAccountDashboard = (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_market', 'dashboard-licenses', '_bx_market_menu_item_title_system_licenses', '_bx_market_menu_item_title_licenses', 'page.php?i=products-licenses', '', '', 'certificate col-green2', '', '', 2147483646, 1, 0, 1, @iMoAccountDashboard + 1);
+
+
+-- PRIVACY 
+INSERT INTO `sys_objects_privacy` (`object`, `module`, `action`, `title`, `default_group`, `table`, `table_field_id`, `table_field_author`, `override_class_name`, `override_class_file`) VALUES
+('bx_market_allow_view_to', 'bx_market', 'view', '_bx_market_form_entry_input_allow_view_to', '3', 'bx_market_products', 'id', 'author', '', ''),
+('bx_market_allow_purchase_to', 'bx_market', 'purchase', '_bx_market_form_entry_input_allow_purchase_to', '3', 'bx_market_products', 'id', 'author', '', ''),
+('bx_market_allow_comment_to', 'bx_market', 'comment', '_bx_market_form_entry_input_allow_comment_to', 'c', 'bx_market_products', 'id', 'author', 'BxMarketPrivacy', 'modules/boonex/market/classes/BxMarketPrivacy.php'),
+('bx_market_allow_vote_to', 'bx_market', 'vote', '_bx_market_form_entry_input_allow_vote_to', 'c', 'bx_market_products', 'id', 'author', 'BxMarketPrivacy', 'modules/boonex/market/classes/BxMarketPrivacy.php');
+
+
+
+-- ACL
+INSERT INTO `sys_acl_actions` (`Module`, `Name`, `AdditionalParamName`, `Title`, `Desc`, `Countable`, `DisabledForLevels`) VALUES
+('bx_market', 'create entry', NULL, '_bx_market_acl_action_create_entry', '', 1, 3);
+SET @iIdActionEntryCreate = LAST_INSERT_ID();
+
+INSERT INTO `sys_acl_actions` (`Module`, `Name`, `AdditionalParamName`, `Title`, `Desc`, `Countable`, `DisabledForLevels`) VALUES
+('bx_market', 'delete entry', NULL, '_bx_market_acl_action_delete_entry', '', 1, 3);
+SET @iIdActionEntryDelete = LAST_INSERT_ID();
+
+INSERT INTO `sys_acl_actions` (`Module`, `Name`, `AdditionalParamName`, `Title`, `Desc`, `Countable`, `DisabledForLevels`) VALUES
+('bx_market', 'download entry', NULL, '_bx_market_acl_action_download_entry', '', 1, 0);
+SET @iIdActionEntryDownload = LAST_INSERT_ID();
+
+INSERT INTO `sys_acl_actions` (`Module`, `Name`, `AdditionalParamName`, `Title`, `Desc`, `Countable`, `DisabledForLevels`) VALUES
+('bx_market', 'view entry', NULL, '_bx_market_acl_action_view_entry', '', 1, 0);
+SET @iIdActionEntryView = LAST_INSERT_ID();
+
+INSERT INTO `sys_acl_actions` (`Module`, `Name`, `AdditionalParamName`, `Title`, `Desc`, `Countable`, `DisabledForLevels`) VALUES
+('bx_market', 'set thumb', NULL, '_bx_market_acl_action_set_thumb', '', 1, 3);
+SET @iIdActionSetThumb = LAST_INSERT_ID();
+
+INSERT INTO `sys_acl_actions` (`Module`, `Name`, `AdditionalParamName`, `Title`, `Desc`, `Countable`, `DisabledForLevels`) VALUES
+('bx_market', 'set cover', NULL, '_bx_market_acl_action_set_cover', '', 1, 3);
+SET @iIdActionSetCover = LAST_INSERT_ID();
+
+INSERT INTO `sys_acl_actions` (`Module`, `Name`, `AdditionalParamName`, `Title`, `Desc`, `Countable`, `DisabledForLevels`) VALUES
+('bx_market', 'set subentries', NULL, '_bx_market_acl_action_set_subentries', '', 1, 3);
+SET @iIdActionSetSubentries = LAST_INSERT_ID();
+
+INSERT INTO `sys_acl_actions` (`Module`, `Name`, `AdditionalParamName`, `Title`, `Desc`, `Countable`, `DisabledForLevels`) VALUES
+('bx_market', 'edit any entry', NULL, '_bx_market_acl_action_edit_any_entry', '', 1, 3);
+SET @iIdActionEntryEditAny = LAST_INSERT_ID();
+
+SET @iUnauthenticated = 1;
+SET @iAccount = 2;
+SET @iStandard = 3;
+SET @iUnconfirmed = 4;
+SET @iPending = 5;
+SET @iSuspended = 6;
+SET @iModerator = 7;
+SET @iAdministrator = 8;
+SET @iPremium = 9;
+
+INSERT INTO `sys_acl_matrix` (`IDLevel`, `IDAction`) VALUES
+
+-- entry create
+(@iStandard, @iIdActionEntryCreate),
+(@iModerator, @iIdActionEntryCreate),
+(@iAdministrator, @iIdActionEntryCreate),
+(@iPremium, @iIdActionEntryCreate),
+
+-- entry delete
+(@iStandard, @iIdActionEntryDelete),
+(@iModerator, @iIdActionEntryDelete),
+(@iAdministrator, @iIdActionEntryDelete),
+(@iPremium, @iIdActionEntryDelete),
+
+-- entry download
+(@iUnauthenticated, @iIdActionEntryDownload),
+(@iAccount, @iIdActionEntryDownload),
+(@iStandard, @iIdActionEntryDownload),
+(@iUnconfirmed, @iIdActionEntryDownload),
+(@iPending, @iIdActionEntryDownload),
+(@iModerator, @iIdActionEntryDownload),
+(@iAdministrator, @iIdActionEntryDownload),
+(@iPremium, @iIdActionEntryDownload),
+
+-- entry view
+(@iUnauthenticated, @iIdActionEntryView),
+(@iAccount, @iIdActionEntryView),
+(@iStandard, @iIdActionEntryView),
+(@iUnconfirmed, @iIdActionEntryView),
+(@iPending, @iIdActionEntryView),
+(@iModerator, @iIdActionEntryView),
+(@iAdministrator, @iIdActionEntryView),
+(@iPremium, @iIdActionEntryView),
+
+-- set entry thumb
+(@iStandard, @iIdActionSetThumb),
+(@iModerator, @iIdActionSetThumb),
+(@iAdministrator, @iIdActionSetThumb),
+(@iPremium, @iIdActionSetThumb),
+
+-- set entry cover
+(@iStandard, @iIdActionSetCover),
+(@iModerator, @iIdActionSetCover),
+(@iAdministrator, @iIdActionSetCover),
+(@iPremium, @iIdActionSetCover),
+
+-- set entry subentries
+(@iStandard, @iIdActionSetSubentries),
+(@iModerator, @iIdActionSetSubentries),
+(@iAdministrator, @iIdActionSetSubentries),
+(@iPremium, @iIdActionSetSubentries),
+
+-- edit any entry
+(@iModerator, @iIdActionEntryEditAny),
+(@iAdministrator, @iIdActionEntryEditAny);
+
+
+-- SEARCH
+SET @iSearchOrder = (SELECT IFNULL(MAX(`Order`), 0) FROM `sys_objects_search`);
+INSERT INTO `sys_objects_search` (`ObjectName`, `Title`, `Order`, `ClassName`, `ClassPath`) VALUES
+('bx_market', '_bx_market', @iSearchOrder + 1, 'BxMarketSearchResult', 'modules/boonex/market/classes/BxMarketSearchResult.php'),
+('bx_market_cmts', '_bx_market_cmts', @iSearchOrder + 2, 'BxMarketCmtsSearchResult', 'modules/boonex/market/classes/BxMarketCmtsSearchResult.php');
+
+-- CONNECTIONS
+INSERT INTO `sys_objects_connection` (`object`, `table`, `type`, `override_class_name`, `override_class_file`) VALUES
+('bx_market_subentries', 'bx_market_subproducts', 'one-way', '', '');
+
+-- METATAGS
+INSERT INTO `sys_objects_metatags` (`object`, `table_keywords`, `table_locations`, `table_mentions`, `override_class_name`, `override_class_file`) VALUES
+('bx_market', 'bx_market_meta_keywords', 'bx_market_meta_locations', '', '', '');
+
+-- CATEGORY
+INSERT INTO `sys_objects_category` (`object`, `search_object`, `form_object`, `list_name`, `table`, `field`, `join`, `where`, `override_class_name`, `override_class_file`) VALUES
+('bx_market_cats', 'bx_market', 'bx_market', 'bx_market_cats', 'bx_market_products', 'cat', 'INNER JOIN `sys_profiles` ON (`sys_profiles`.`id` = `bx_market_products`.`author`)', 'AND `sys_profiles`.`status` = ''active''', '', '');
+
+-- STATS
+SET @iMaxOrderStats = (SELECT IFNULL(MAX(`order`), 0) FROM `sys_statistics`);
+INSERT INTO `sys_statistics` (`module`, `name`, `title`, `link`, `icon`, `query`, `order`) VALUES 
+('bx_market', 'bx_market', '_bx_market', 'page.php?i=products-home', 'shopping-cart col-green3', 'SELECT COUNT(*) FROM `bx_market_products` WHERE 1 AND `status` = ''active'' AND `status_admin` = ''active''', @iMaxOrderStats + 1);
+
+-- CHARTS
+SET @iMaxOrderCharts = (SELECT IFNULL(MAX(`order`), 0) FROM `sys_objects_chart`);
+INSERT INTO `sys_objects_chart` (`object`, `title`, `table`, `field_date_ts`, `field_date_dt`, `field_status`, `query`, `active`, `order`, `class_name`, `class_file`) VALUES
+('bx_market_growth', '_bx_market_chart_growth', 'bx_market_products', 'added', '', 'status,status_admin', '', 1, @iMaxOrderCharts + 1, 'BxDolChartGrowth', ''),
+('bx_market_growth_speed', '_bx_market_chart_growth_speed', 'bx_market_products', 'added', '', 'status,status_admin', '', 1, @iMaxOrderCharts + 2, 'BxDolChartGrowthSpeed', '');
+
+-- GRIDS: moderation tools
+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_market_administration', 'Sql', 'SELECT * FROM `bx_market_products` WHERE 1 ', 'bx_market_products', 'id', 'added', 'status_admin', '', 20, NULL, 'start', '', 'title,text', '', 'like', '', '', 192, 'BxMarketGridAdministration', 'modules/boonex/market/classes/BxMarketGridAdministration.php'),
+('bx_market_common', 'Sql', 'SELECT * FROM `bx_market_products` WHERE 1 ', 'bx_market_products', 'id', 'added', 'status', '', 20, NULL, 'start', '', 'title,text', '', 'like', '', '', 2147483647, 'BxMarketGridCommon', 'modules/boonex/market/classes/BxMarketGridCommon.php'),
+
+-- GRIDS: Licenses
+('bx_market_licenses', 'Sql', 'SELECT `tl`.`id` AS `id`, `tl`.`profile_id` AS `profile_id`, `tl`.`product_id` AS `product_id`, `tp`.`title` AS `product`, `tl`.`license` AS `license`, `tl`.`type` AS `type`, `tl`.`domain` AS `domain`, `tl`.`added` AS `added`, `tl`.`expired` AS `expired` FROM `bx_market_licenses` AS `tl` LEFT JOIN `bx_market_products` AS `tp` ON `tl`.`product_id`=`tp`.`id` WHERE 1 ', 'bx_market_licenses', 'id', 'added', '', '', 20, NULL, 'start', '', 'tp`.`title,tl`.`license,tl`.`type,tl`.`domain', '', 'like', '', '', 2147483647, 'BxMarketGridLicenses', 'modules/boonex/market/classes/BxMarketGridLicenses.php');
+
+
+INSERT INTO `sys_grid_fields` (`object`, `name`, `title`, `width`, `translatable`, `chars_limit`, `params`, `order`) VALUES
+('bx_market_administration', 'checkbox', '_sys_select', '2%', 0, '', '', 1),
+('bx_market_administration', 'switcher', '_bx_market_grid_column_title_adm_active', '8%', 0, '', '', 2),
+('bx_market_administration', 'title', '_bx_market_grid_column_title_adm_title', '25%', 0, '', '', 3),
+('bx_market_administration', 'added', '_bx_market_grid_column_title_adm_added', '20%', 1, '25', '', 4),
+('bx_market_administration', 'author', '_bx_market_grid_column_title_adm_author', '25%', 0, '25', '', 5),
+('bx_market_administration', 'actions', '', '20%', 0, '', '', 6),
+('bx_market_common', 'checkbox', '_sys_select', '2%', 0, '', '', 1),
+('bx_market_common', 'switcher', '_bx_market_grid_column_title_adm_active', '8%', 0, '', '', 2),
+('bx_market_common', 'title', '_bx_market_grid_column_title_adm_title', '40%', 0, '', '', 3),
+('bx_market_common', 'added', '_bx_market_grid_column_title_adm_added', '30%', 1, '25', '', 4),
+('bx_market_common', 'actions', '', '20%', 0, '', '', 5),
+
+('bx_market_licenses', 'product', '_bx_market_grid_column_title_lcs_product', '30%', 0, '28', '', 1),
+('bx_market_licenses', 'license', '_bx_market_grid_column_title_lcs_license', '10%', 0, '8', '', 3),
+('bx_market_licenses', 'type', '_bx_market_grid_column_title_lcs_type', '10%', 1, '12', '', 4),
+('bx_market_licenses', 'domain', '_bx_market_grid_column_title_lcs_domain', '20%', 0, '18', '', 5),
+('bx_market_licenses', 'added', '_bx_market_grid_column_title_lcs_added', '10%', 1, '25', '', 6),
+('bx_market_licenses', 'expired', '_bx_market_grid_column_title_lcs_expired', '10%', 1, '25', '', 7),
+('bx_market_licenses', 'actions', '', '10%', 0, '', '', 8);
+
+INSERT INTO `sys_grid_actions` (`object`, `type`, `name`, `title`, `icon`, `icon_only`, `confirm`, `order`) VALUES
+('bx_market_administration', 'bulk', 'delete', '_bx_market_grid_action_title_adm_delete', '', 0, 1, 1),
+('bx_market_administration', 'single', 'edit', '_bx_market_grid_action_title_adm_edit', 'pencil', 1, 0, 1),
+('bx_market_administration', 'single', 'delete', '_bx_market_grid_action_title_adm_delete', 'remove', 1, 1, 2),
+('bx_market_administration', 'single', 'settings', '_bx_market_grid_action_title_adm_more_actions', 'cog', 1, 0, 3),
+('bx_market_common', 'bulk', 'delete', '_bx_market_grid_action_title_adm_delete', '', 0, 1, 1),
+('bx_market_common', 'single', 'edit', '_bx_market_grid_action_title_adm_edit', 'pencil', 1, 0, 1),
+('bx_market_common', 'single', 'delete', '_bx_market_grid_action_title_adm_delete', 'remove', 1, 1, 2),
+('bx_market_common', 'single', 'settings', '_bx_market_grid_action_title_adm_more_actions', 'cog', 1, 0, 3),
+
+('bx_market_licenses', 'single', 'reset', '_bx_market_grid_action_title_lcs_reset', 'eraser', 1, 1, 1);
+
+
+-- UPLOADERS
+INSERT INTO `sys_objects_uploader` (`object`, `active`, `override_class_name`, `override_class_file`) VALUES
+('bx_market_simple', 1, 'BxMarketUploaderSimple', 'modules/boonex/market/classes/BxMarketUploaderSimple.php'),
+('bx_market_html5', 1, 'BxMarketUploaderHTML5', 'modules/boonex/market/classes/BxMarketUploaderHTML5.php');
+
+
+-- ALERTS
+INSERT INTO `sys_alerts_handlers` (`name`, `class`, `file`, `service_call`) VALUES 
+('bx_market', 'BxMarketAlertsResponse', 'modules/boonex/market/classes/BxMarketAlertsResponse.php', '');
+SET @iHandler := LAST_INSERT_ID();
+
+INSERT INTO `sys_alerts` (`unit`, `action`, `handler_id`) VALUES
+('system', 'save_setting', @iHandler),
+('bx_market_files', 'file_deleted', @iHandler),
+('bx_market_files', 'file_downloaded', @iHandler),
+('bx_market_photos', 'file_deleted', @iHandler),
+('profile', 'delete', @iHandler);
+
+
+-- CRON
+INSERT INTO `sys_cron_jobs` (`name`, `time`, `class`, `file`, `service_call`) VALUES
+('bx_market_pruning', '0 0 * * *', 'BxMarketCronPruning', 'modules/boonex/market/classes/BxMarketCronPruning.php', '');

+ 100 - 0
modules/boonex/market/updates/9.0.6_9.0.7/source/js/entry.js

@@ -0,0 +1,100 @@
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Market Market
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+function BxMarketEntry(oOptions) {
+	this._sActionsUri = oOptions.sActionUri;
+    this._sActionsUrl = oOptions.sActionUrl;
+    this._sObjName = oOptions.sObjName == undefined ? 'oBxMarketEntry' : oOptions.sObjName;
+    this._iOwnerId = oOptions.iOwnerId == undefined ? 0 : oOptions.iOwnerId;
+    this._sAnimationEffect = oOptions.sAnimationEffect == undefined ? 'slide' : oOptions.sAnimationEffect;
+    this._iAnimationSpeed = oOptions.iAnimationSpeed == undefined ? 'slow' : oOptions.iAnimationSpeed;
+    this._aHtmlIds = oOptions.aHtmlIds == undefined ? {} : oOptions.aHtmlIds;
+    this._oRequestParams = oOptions.oRequestParams == undefined ? {} : oOptions.oRequestParams;
+
+    var $this = this;
+    $(document).ready(function() {
+    	$this.initScreenshots();
+    });
+}
+
+BxMarketEntry.prototype.checkName = function(sTitleId, sNameId) {
+	var oDate = new Date();
+
+	var oName = jQuery("[name='" + sNameId + "']");
+	var oTitle = jQuery("[name='" + sTitleId + "']");
+
+	var sName = oName.val();
+	var sTitle = oTitle.val();	
+	if(sName.length != 0 || sTitle.length == 0)
+		return;
+
+	sName = sTitle.replace(/[^A-Za-z0-9_]/g, '-');
+	sName = sName.replace(/[-]{2,}/g, '-');
+	oName.val(sName.toLowerCase());
+
+	jQuery.get(
+		this._sActionsUrl + 'check_name',
+		{
+			title: sTitle,
+    		_t: oDate.getTime()
+    	},
+    	function(oData) {
+    		if(!oData || oData.name == undefined)
+    			return;
+
+    		oName.val(oData.name);
+    	},
+    	'json'
+	);
+};
+
+BxMarketEntry.prototype.changeFileType = function(oSelect) {
+	var sValue = jQuery(oSelect).val();
+
+	jQuery(oSelect).parents('.bx-uploader-ghost:first').find('.bx-uploader-ghost-type-rel:visible').bx_anim('hide', 'fade', 'fast', function() {
+		jQuery(this).parent().find('.bx-uploader-ghost-type-' + sValue).bx_anim('show', 'fade', 'fast');
+	});
+};
+
+BxMarketEntry.prototype.initScreenshots = function() {
+	var oItems = jQuery(".bx-market-screenshots .bx-market-ss-item");
+	if(oItems.length == 0)
+		return;
+
+	var iWidth = oItems.width();
+	var iWidthOuter = oItems.outerWidth();
+	var bBusy = false;
+
+	oItems.find('a[rel=group]').fancybox({
+		transitionIn: 'elastic',
+		transitionOut: 'elastic',
+		speedIn: 600,
+		speedOut: 200
+	});
+
+	if(oItems.length <= 2)
+		return;
+
+	$('.bx-market-screenshots').flickity({
+		cellSelector: '.bx-market-ss-item',
+		cellAlign: 'left',
+		pageDots: false,
+		imagesLoaded: true
+	});
+};
+
+/**
+ * Is used on Downloads page to show old versions. 
+ */
+BxMarketEntry.prototype.showMore = function() {
+	$('.bx-market-attachment:not(.bx-market-attachment-main)').bx_anim('toggle', this._sAnimationEffect, this._sAnimationSpeed);
+};
+
+/** @} */

+ 39 - 0
modules/boonex/market/updates/9.0.6_9.0.7/source/template/attachments.html

@@ -0,0 +1,39 @@
+<div class="bx-base-text-attachments bx-market-attachments bx-clearfix">
+    <bx_repeat:attachments>
+        <div class="bx-base-text-attachment bx-market-attachment bx-def-box bx-def-color-bg-box bx-def-gal-img-size__class__" style="float:left;">
+        	<bx_if:main>
+        		<div class="bx-market-a-main bx-def-font-h2">
+        			<i class="sys-icon check col-green3" title="<bx_text_attribute:_bx_market_txt_most_current_version />"></i>
+        		</div>
+        	</bx_if:main>
+            <bx_if:image>
+                <a target="_blank" href="javascript:void(0);" title="__attr_file_name__" onclick="$('#__popup_id__').dolPopupImage('__url_original__', $(this).parent())">
+                    <img class="bx-def-gal-img-size" src="__url_preview__" />
+                </a>
+                __popup__
+            </bx_if:image>
+            <bx_if:video>
+                __video__
+            </bx_if:video>
+            <bx_if:not_image>
+            	<div class="bx-def-padding-sec">
+	                <a target="_blank" href="__url_original__" title="__attr_file_name__">__file_name__</a>
+	                <div class="bx-def-font-grayed"><bx_text:_bx_market_form_entry_input_files_type /> __file_type__</div>
+	                <bx_if:show_version>
+	                	<div class="bx-def-font-grayed"><bx_text:_bx_market_form_entry_input_files_version /> __file_version__</div>
+	                </bx_if:show_version>
+	                <bx_if:show_update>
+	                	<div class="bx-def-font-grayed">__file_version_from_to__</div>
+	                </bx_if:show_update>
+	                
+	                
+                </div>
+            </bx_if:not_image>
+        </div>
+    </bx_repeat:attachments>
+    <script>
+        $(document).ready(function() {
+            bx_center_content('.bx-base-text-attachments', '.bx-base-text-attachment', true);
+        });
+    </script>
+</div>

+ 1 - 0
modules/boonex/market/updates/9.0.6_9.0.7/source/template/breadcrumb.html

@@ -0,0 +1 @@
+<bx_include_base:../modules/base/text/template/breadcrumb.html />

+ 38 - 0
modules/boonex/market/updates/9.0.6_9.0.7/source/template/css/forms.css

@@ -0,0 +1,38 @@
+
+@import url(../../../../base/text/template/css/forms.css);
+
+.bx-form-value .bx-form-input-autotoken b 
+{
+	padding-left:0.5rem;
+}
+
+/*--- Uploader Ghost ---*/
+.bx-uploader-ghost-header {
+	position: relative;
+	line-height: 1.5rem;
+}
+
+.bx-uploader-ghost .bx-uploader-ghost-header .sys-icon {
+    display: inline-block;
+    width: 1.5rem;
+    height: 1.5rem;
+    text-align: center;
+
+    -moz-transform: rotate(90deg);
+    -webkit-transform: rotate(90deg);
+    -ms-transform: rotate(90deg);
+    -o-transform: rotate(90deg);
+
+    -webkit-transition: all 0.5s ease;
+    -moz-transition: all 0.5s ease;
+    -ms-transition: all 0.5s ease;
+    -o-transition: all 0.5s ease;
+}
+
+.bx-uploader-ghost.closed .bx-uploader-ghost-header .sys-icon {
+    -moz-transform: rotate(0deg);
+    -webkit-transform: rotate(0deg);
+    -ms-transform: rotate(0deg);
+    -o-transform: rotate(0deg);
+}
+

+ 138 - 0
modules/boonex/market/updates/9.0.6_9.0.7/source/template/css/main.css

@@ -0,0 +1,138 @@
+
+@import url(../../../../base/text/template/css/main.css);
+
+/*--- Snippet ---*/
+div.bx-market-unit-gallery-cnt {
+	position: relative;
+	width: 100%;
+	overflow: hidden;
+}
+div.bx-market-unit-info {
+	position: relative;
+}
+
+/*+++ Item Author +++*/
+div.bx-market-unit-author {
+    position: relative;
+	text-align: left;
+}
+div.bx-market-unit-author-avatar {
+    position: absolute;
+    top: 0px;
+    left: 0px;
+}
+div.bx-market-unit-author-info {
+	display: -webkit-flex;
+    display: flex;
+    -webkit-align-items: center;
+    align-items: center;
+
+	margin-right: 32px;
+	margin-right: 2rem;
+}
+div.bx-market-unit-author-name a.bx-base-text-author {
+	padding-right: 10px;
+	padding-right: 0.625rem;
+
+    font-weight: 700;
+}
+
+/*+++ Item Actions +++*/
+div.bx-market-unit-actions {
+	position: absolute;
+	top: 0px;
+	right: 0px;	
+}
+
+/*+++ Item Info +++*/
+div.bx-market-unit-cnt {
+	text-align: left;
+}
+div.bx-market-unit-icon {
+    position: absolute;
+    top: 0px;
+    left: 0px;
+}
+div.bx-market-unit-icon-empty {
+	background-color: #ffffff;
+	text-align: center;
+	font-size: 32px;
+	font-size: 2rem;
+}
+div.bx-market-unit-icon-empty .sys-icon {
+    vertical-align: top;	
+}
+div.bx-market-unit-cover {
+	background-color: #ffffff;
+}
+div.bx-market-unit-cover div.bx-base-text-unit-no-thumb {
+	border-color: #f2f2f2;
+}
+div.bx-market-unit-cnt div.bx-market-unit-info {
+	white-space: nowrap;
+}
+div.bx-market-unit-title {
+	padding-top: 0.125rem;
+    text-overflow: ellipsis;
+    overflow: hidden;
+}
+.bx-market-ui-price {
+	float: none;
+	max-width: 80%;
+	margin-left: auto;
+	margin-right: auto;
+}
+.bx-market-fcell {
+	position: relative;
+	display: block;
+}
+.bx-market-fcell.fc-left {
+	float: left;
+}
+.bx-market-fcell.fc-right {
+    float: right;
+}
+.bx-market-fcell .bx-vote {
+	margin: 0px;
+}
+	
+/*--- Defaults ---*/
+.bx-market-thumb-size {
+    width: 148px;
+    width: 9.25rem;
+    height: 148px;
+    height: 9.25rem;
+    line-height: 148px;
+    line-height: 9.25rem;
+}
+.bx-market-thumb-size-min-height {
+    min-height: 148px;
+    min-height: 9.25rem;
+}
+.bx-market-thumb-size-left-indent {
+	margin-left: 164px;
+	margin-left: 10.25rem;
+}
+.bx-market-screenshot-size {
+    width: 200px;
+    width: 12.5rem;
+    height: 120px;
+    height: 7.5rem;
+    line-height: 120px;
+    line-height: 7.5rem;
+}
+	
+/*--- Attachments ---*/
+div.bx-market-attachment {
+	position: relative;
+	display: none;
+}
+div.bx-market-attachment.bx-market-attachment-main {
+    display: block;
+}
+div.bx-market-a-main {
+	position: absolute;
+
+	top: 5px;
+	right: 10px;
+}

+ 27 - 0
modules/boonex/market/updates/9.0.6_9.0.7/source/template/form.html

@@ -0,0 +1,27 @@
+__content__
+<script>
+    function bx_market_ghost_init(oGhost, iFileId, iThumbnailId, iCoverId) {
+    	oGhost.find('.bx-base-general-use-as-thumb input[value="' + iThumbnailId + '"]').attr('checked', true);
+    	if(iCoverId != undefined)
+    	    oGhost.find('.bx-base-general-use-as-cover input[value="' + iCoverId + '"]').attr('checked', true);
+
+    	if(typeof(tinymce) == 'object')
+            oGhost.find('.bx-base-general-intert-to-post-link').show();
+
+    	// disable images drag&drop, because resized images address can be reset after some time
+        oGhost.find(".bx-base-general-icon-" + iFileId).bind('dragstart', function() {
+            return false; 
+        });
+
+        oGhost.parent().children('.bx-uploader-ghost').each(function(iIndex, oElement) {
+        	if(iIndex > 0 && !$(oElement).hasClass('closed'))
+        		$(oElement).addClass('closed').find('.bx-uploader-ghost-header:first').addClass('bx-def-color-bg-hl').siblings('.bx-uploader-ghost-body:first').hide();
+        });
+    }
+
+    function bx_market_ghost_toggle(oLink) {
+    	$(oLink).parents('.bx-uploader-ghost:first').toggleClass('closed').find('.bx-uploader-ghost-body').bx_anim('toggle', 'slide', 'slow', function() {
+    		$(this).siblings('.bx-uploader-ghost-header').toggleClass('bx-def-color-bg-hl');
+    	});
+    }
+</script>

+ 42 - 0
modules/boonex/market/updates/9.0.6_9.0.7/source/template/form_ghost_template.html

@@ -0,0 +1,42 @@
+<div id="bx-uploader-file-{storage_object}-{file_id}" class="bx-uploader-ghost bx-market-uploader-ghost-photo bx-def-margin-sec-top bx-clearfix">
+    <div class="bx-uploader-ghost-header bx-def-padding-thd-topbottom bx-def-padding-sec-leftright">
+        <a href="javascript:void(0)" onclick="javascript:bx_market_ghost_toggle(this);"><i class="sys-icon chevron-right"></i></a> {file_name}
+    </div>
+    <div class="bx-uploader-ghost-body bx-def-padding-thd-topbottom">
+	    <input type="hidden" name="__name__" value="{file_id}" />
+	    <div class="bx-base-general-icon-wrapper bx-def-margin-sec-right">
+	        <img src="{file_icon}" class="bx-def-round-corners bx-base-general-icon bx-base-general-icon-{file_id}" />
+	    </div>
+	    <span class="bx-base-general-uploader-ghost">
+	        <b><bx_text:_sys_txt_form_entry_input_picture_pic_url /></b><br />
+	        <input class="bx-def-font-inputs bx-form-input-text bx-def-margin-sec-bottom" type="text" value="{file_url}" readonly="1" /> <br />
+	
+			<b><bx_text:_bx_market_form_entry_input_pictures_title /></b><br />
+	    	<input class="bx-def-font-inputs bx-form-input-text bx-def-margin-sec-bottom" type="text" name="title-{file_id}" value="{file_title_attr}" /><br />
+	
+	        <span class="bx-base-general-intert-to-post-link" id="bx-base-general-intert-to-post-link-{file_id}" style="display:none;">
+	            <a class="bx-btn bx-btn-small bx-def-margin-sec-right" href="javascript:void(0);" onclick="bx_base_general_insert_to_post('{file_id}', '{file_url}', '__editor_id__');"><bx_text:_sys_txt_form_entry_input_picture_insert /></a>
+	        </span>
+	        <span id="bx-base-general-delete-link-{file_id}">
+	        	<a class="bx-btn bx-btn-small bx-def-margin-sec-right" href="javascript:void(0);" onclick="bx_base_general_delete_ghost('{file_id}', '{file_url}', '{file_icon}', ['__editor_id__'], {js_instance_name});"><bx_text:_sys_txt_form_entry_input_picture_delete /></a>
+	        </span>
+	        <bx_if:set_thumb>
+	        	<br />
+	            <span class="bx-base-general-use-as-thumb">
+	                <input type="checkbox" name="__name_thumb__[]" value="{file_id}" onclick="bx_base_general_select_thumb(this)" id="__name_thumb__-{file_id}" /> 
+	                <label for="__name_thumb__-{file_id}"><bx_text:_bx_market_form_entry_input_pictures_use_as_thumb /></label>
+	            </span>
+	        </bx_if:set_thumb>
+	        <bx_if:set_cover>
+	        	<br />
+	            <span class="bx-base-general-use-as-cover">
+	                <input type="checkbox" name="__name_cover__[]" value="{file_id}" onclick="bx_base_general_select_ghost(this, '__name_cover__')" id="__name_cover__-{file_id}" /> 
+	                <label for="__name_cover__-{file_id}"><bx_text:_bx_market_form_entry_input_pictures_use_as_cover /></label>
+	            </span>
+	        </bx_if:set_cover>
+	    </span>
+    </div>
+</div>
+<script type="text/javascript" language="javascript">
+    bx_market_ghost_init($('#bx-uploader-file-{storage_object}-{file_id}'), {file_id}, __thumb_id__, __cover_id__);
+</script>

+ 49 - 0
modules/boonex/market/updates/9.0.6_9.0.7/source/template/form_ghost_template_file.html

@@ -0,0 +1,49 @@
+<div id="bx-uploader-file-{storage_object}-{file_id}" class="bx-uploader-ghost bx-market-uploader-ghost-file bx-def-margin-sec-top bx-clearfix">
+    <div class="bx-uploader-ghost-header bx-def-padding-thd-topbottom bx-def-padding-sec-leftright">
+        <a href="javascript:void(0)" onclick="javascript:bx_market_ghost_toggle(this);"><i class="sys-icon chevron-right"></i></a> {file_name}
+    </div>
+    <div class="bx-uploader-ghost-body bx-def-padding-thd-topbottom">
+	    <input type="hidden" name="__name__" value="{file_id}" />
+	    <div class="bx-base-general-icon-wrapper bx-def-margin-sec-right">
+	        <img src="{file_icon}" class="bx-def-round-corners bx-base-general-icon bx-base-general-icon-{file_id}" />
+	    </div>
+	    <span class="bx-base-general-uploader-ghost">
+			<b><bx_text:_bx_market_form_entry_input_files_name /></b><br />
+	        <input class="bx-def-font-inputs bx-form-input-text bx-def-margin-sec-bottom" type="text" value="{file_name}" readonly="1" /><br />
+	
+			<b><bx_text:_bx_market_form_entry_input_files_type /></b><br />
+			<select class="bx-def-font-inputs bx-form-input-select bx-def-margin-sec-bottom" name="type-{file_id}" onchange="javascript:oBxMarketEntry.changeFileType(this);">
+				<option value="version"{file_type_version_selected}><bx_text:_bx_market_form_entry_input_files_type_version /></option>
+				<option value="update"{file_type_update_selected}><bx_text:_bx_market_form_entry_input_files_type_update /></option>
+			</select><br />
+	
+			<span class="bx-uploader-ghost-type-rel bx-uploader-ghost-type-version"{file_type_version_elements}>
+		    	<b><bx_text:_bx_market_form_entry_input_files_version /></b><br />
+		    	<input class="bx-def-font-inputs bx-form-input-text bx-def-margin-sec-bottom" type="text" name="version-{file_id}" value="{file_version_attr}" /><br />
+			</span>
+	
+			<span class="bx-uploader-ghost-type-rel bx-uploader-ghost-type-update"{file_type_update_elements}>
+				<b><bx_text:_bx_market_form_entry_input_files_version_from /></b><br />
+		    	<select class="bx-def-font-inputs bx-form-input-select bx-def-margin-sec-bottom" name="version-from-{file_id}">{file_version_from_options}</select><br />
+				<b><bx_text:_bx_market_form_entry_input_files_version_to /></b><br />
+		    	<select class="bx-def-font-inputs bx-form-input-select bx-def-margin-sec-bottom" name="version-to-{file_id}">{file_version_to_options}</select><br />
+			</span>
+	
+	        <span class="bx-base-general-intert-to-post-link" id="bx-base-general-intert-to-post-link-{file_id}" style="display:none;">
+	            <a class="bx-btn bx-btn-small bx-def-margin-sec-right" href="javascript:void(0);" onclick="bx_base_general_insert_to_post('{file_id}', '{file_url}', '__editor_id__');"><bx_text:_sys_txt_form_entry_input_picture_insert /></a>
+	        </span>
+	        <a class="bx-btn bx-btn-small bx-def-margin-sec-right" href="javascript:void(0);" onclick="bx_base_general_delete_ghost('{file_id}', '{file_url}', '{file_icon}', ['__editor_id__'], {js_instance_name});"><bx_text:_sys_txt_form_entry_input_picture_delete /></a>
+	
+	        <bx_if:set_thumb>
+	            <span class="bx-base-general-use-as-thumb bx-uploader-ghost-type-rel bx-uploader-ghost-type-version"{file_type_version_elements}>
+	                <input type="checkbox" name="__name_thumb__[]" value="{file_id}" onclick="bx_base_general_select_thumb(this)" id="__name_thumb__-{file_id}" /> 
+	                <label for="__name_thumb__-{file_id}"><bx_text:_bx_market_form_entry_input_files_use_as_main /></label>
+	            </span>
+	        </bx_if:set_thumb>
+	
+	    </span>
+    </div>
+</div>
+<script type="text/javascript" language="javascript">
+    bx_market_ghost_init($('#bx-uploader-file-{storage_object}-{file_id}'), {file_id}, __thumb_id__);
+</script>

+ 78 - 0
modules/boonex/market/updates/9.0.6_9.0.7/source/template/unit_gallery.html

@@ -0,0 +1,78 @@
+<div class="bx-base-text-unit bx-base-text-unit-gallery bx-def-gal-unit-size bx-def-padding-sec">
+	<div class="bx-market-unit-gallery-cnt bx-def-round-corners bx-def-box bx-def-color-bg-box bx-def-shadow">
+        <!-- Author section -->
+        <bx_if:show_section_author>
+	        <div class="bx-market-unit-cnt bx-def-padding">
+	            <div class="bx-market-unit-author">
+			        <div class="bx-market-unit-author-avatar bx-def-thumb bx-def-thumb-size">__author_unit__</div>
+			        <div class="bx-market-unit-author-info bx-def-thumb-size-min-height bx-def-thumb-size-left-indent">
+			            <div class="bx-market-unit-author-name bx-def-font-middle bx-def-font-light bx-def-font-grayed">__author_width_date__</div>
+			        </div>
+			        <div class="bx-market-unit-actions">__actions__</div>
+	            </div>
+	        </div>
+        </bx_if:show_section_author>
+
+        <!-- Main section -->
+        <div class="bx-market-unit-cnt bx-market-unit-cover">
+		    <bx_if:show_cover>
+	            <a href="__content_url__" title="__summary_attr__">
+	                <div class="bx-base-text-unit-thumb bx-def-gal-div-size bx-def-font-middle" style="background-image:url(__cover_url__)">
+	                    <div class="bx-base-text-unit-strecher">__strecher__</div>
+	                </div>
+	            </a>
+	        </bx_if:show_cover>
+	        <bx_if:show_cover_empty>
+                <div class="bx-base-text-unit-no-thumb bx-def-gal-div-size bx-def-font-middle bx-def-font-grayed bx-def-padding bx-def-border bx-def-box-sizing">
+                    __summary_plain__
+                    <div class="bx-base-text-unit-strecher">__strecher__</div>
+                </div>
+	        </bx_if:show_cover_empty>
+        </div>
+		<div class="bx-market-unit-cnt bx-def-padding">
+            <div class="bx-market-unit-info">
+                <div class="bx-market-unit-icon bx-def-thumb-size bx-def-round-corners">
+                    <a href="__content_url__"> 
+		                <bx_if:show_icon>
+		                    <img class="bx-market-unit-icon bx-def-thumb-size bx-def-round-corners" src="__icon_url__" />
+		                </bx_if:show_icon>
+		                <bx_if:show_icon_empty>
+		                    <div class="bx-market-unit-icon-empty bx-def-thumb-size bx-def-round-corners">
+                                <i class="sys-icon __icon__"></i>
+                            </div>
+		                </bx_if:show_icon_empty>
+		            </a>
+                </div>
+			    <div class="bx-market-unit-title bx-def-thumb-size-min-height bx-def-thumb-size-left-indent">
+					<a class="bx-def-font-h3" href="__content_url__" title="__title_attr__">__title__</a><br />
+					<bx_if:meta><div class="bx-base-general-unit-meta">__meta__</div></bx_if:meta>
+			    </div>
+		    </div>
+		</div>
+
+        <!-- Pricing section -->
+        <bx_if:show_section_pricing>
+			<div class="bx-market-unit-cnt bx-def-padding-leftright bx-def-padding-bottom">
+	            <div class="bx-def-font-align-center">
+	                <bx_if:show_single>
+	                    <a class="bx-market-ui-price bx-btn bx-btn-small bx-def-margin-sec-top-auto" href="javascript:void(0)" onclick="javascript:__price_single_onclick__">__price_single__</a>
+	                </bx_if:show_single>
+	                <bx_if:show_recurring>
+	                    <a class="bx-market-ui-price bx-btn bx-btn-small bx-def-margin-sec-top-auto" href="javascript:void(0)" onclick="javascript:__price_recurring_onclick__">__price_recurring__</a>
+	                </bx_if:show_recurring>
+	                <bx_if:show_free>
+	                    <a class="bx-market-ui-price bx-btn bx-btn-small bx-def-margin-sec-top-auto" href="__price_free_href__"><bx_text:_bx_market_txt_get_for_free /></a>
+	                </bx_if:show_free>
+	            </div>
+			</div>
+        </bx_if:show_section_pricing>
+
+        <!-- Voting section -->
+        <bx_if:show_section_voting>
+            <div class="bx-market-unit-cnt bx-def-padding-leftright bx-def-padding-bottom bx-clearfix">
+                <div class="bx-market-fcell fc-left">__voting__</div>
+                <div class="bx-market-fcell fc-right bx-def-font-bold">__pricing__</div>
+            </div>
+        </bx_if:show_section_voting>
+	</div>
+</div>

+ 1 - 0
modules/boonex/market/updates/9.0.6_9.0.7/source/template/unit_meta_item.html

@@ -0,0 +1 @@
+<bx_include_base:../modules/base/text/template/unit_meta_item.html />

+ 109 - 0
modules/boonex/notifications/updates/9.0.5_9.0.6/source/classes/BxNtfsConfig.php

@@ -0,0 +1,109 @@
+<?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('BxDolPrivacy');
+
+class BxNtfsConfig extends BxBaseModNotificationsConfig
+{
+    protected $_iPushMaxLen;
+
+    protected $_aHandlersHiddenEmail;
+    protected $_aHandlersHiddenPush;
+
+    /**
+     * Constructor
+     */
+    public function __construct($aModule)
+    {
+        parent::__construct($aModule);
+
+        $this->CNF = array (
+        	'URL_HOME' => 'page.php?i=notifications-view',
+
+        	'OBJECT_MENU_SUBMENU' => 'bx_notifications_submenu', // main module submenu
+        );
+        
+		$this->_aPrefixes = array(
+        	'style' => 'bx-ntfs',
+        	'language' => '_bx_ntfs',
+        	'option' => 'bx_notifications_'
+        );
+
+        $this->_iPushMaxLen = 190;
+
+        $this->_aHandlerDescriptor = array('module_name' => '', 'module_method' => '', 'module_class' => '');
+        $this->_sHandlersMethod = 'get_notifications_data';
+        $this->_aHandlersHiddenEmail = array();
+        $this->_aHandlersHiddenPush = array();
+
+        $this->_aJsClasses = array(
+            'main' => 'BxNtfsMain',
+        	'view' => 'BxNtfsView',
+        );
+        $this->_aJsObjects = array(
+        	'main' => 'oBxNtfsMain',
+            'view' => 'oBxNtfsView',
+        );
+
+        $sHtmlPrefix = str_replace('_', '-', $this->_sName);
+        $this->_aHtmlIds = array(
+        	'view' => array(
+        		'block' => $sHtmlPrefix,
+        		'events' => $sHtmlPrefix . '-events',
+        		'event' => $sHtmlPrefix . '-event-'
+        	)
+        );
+    }
+
+    public function init(&$oDb)
+    {
+    	parent::init($oDb);
+
+    	$sOptionPrefix = $this->getPrefix('option');
+    	$this->_aPerPage = array(
+    		'default' => (int)getParam($sOptionPrefix . 'events_per_page')
+    	);
+
+    	$aSettings = array(
+    	    'site' => '',
+    	    'email' => 'Email',
+    	    'push' => 'Push'
+    	);
+    	foreach($aSettings as $sSetting => $sVariable) {
+    	    $sHideTimeline = getParam($sOptionPrefix . 'events_hide_' . $sSetting);
+            if(!empty($sHideTimeline))
+                $this->{'_aHandlersHidden' . $sVariable} = explode(',', $sHideTimeline);
+    	}
+    }
+
+    public function getPushMaxLen()
+    {
+        return $this->_iPushMaxLen;
+    }
+
+    public function getHandlersHidden($sType = '')
+    {
+        if(!in_array($sType, array('', 'email', 'push')))
+            return array();
+
+        return $this->{'_aHandlersHidden' . ucfirst($sType)};
+    }
+
+    /**
+     * Ancillary functions
+     */
+    public function getViewUrl()
+    {
+        return BX_DOL_URL_ROOT . BxDolPermalinks::getInstance()->permalink('page.php?i=notifications-view');
+    }
+}
+
+/** @} */

+ 108 - 0
modules/boonex/notifications/updates/9.0.5_9.0.6/source/classes/BxNtfsDb.php

@@ -0,0 +1,108 @@
+<?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
+ *
+ * @{
+ */
+
+class BxNtfsDb extends BxBaseModNotificationsDb
+{
+    protected $_sTableEvt2Usr;
+
+    /*
+     * Constructor.
+     */
+    function __construct(&$oConfig)
+    {
+        parent::__construct($oConfig);
+        $this->_sTableEvt2Usr = $this->_sPrefix . 'events2users';
+    }
+
+    public function markAsRead($iUserId, $iEventId)
+    {
+    	$sSql = $this->prepare("REPLACE `" . $this->_sTableEvt2Usr . "` SET `user_id`=?, `event_id`=?", $iUserId, $iEventId);
+    	return (int)$this->query($sSql) > 0;
+    }
+
+	protected function _getSqlPartsEventsList($aParams)
+	{
+		$sJoinClause = $sWhereClause = "";
+
+		if(isset($aParams['active']))
+			$sWhereClause .= $this->prepareAsString("AND `{$this->_sTable}`.`active`=? ", (int)$aParams['active']);
+
+		//--- Apply modules or handlers filter
+		$sWhereModuleFilter = '';
+		if(!empty($aParams['modules']) && is_array($aParams['modules']))
+			$sWhereModuleFilter = "AND `" . $this->_sTable . "`.`type` IN (" . $this->implode_escape($aParams['modules']) . ") ";
+
+		if($sWhereModuleFilter == '') {
+			$aHidden = $this->_oConfig->getHandlersHidden();
+			$sWhereModuleFilter = !empty($aHidden) && is_array($aHidden) ? "AND `" . $this->_sTableHandlers . "`.`id` NOT IN (" . $this->implode_escape($aHidden) . ") " : "";
+		}
+
+		if($sWhereModuleFilter != '')
+			$sWhereClause .= $sWhereModuleFilter;
+
+		//--- Check flag 'New'
+		if(!empty($aParams['new']) && !empty($aParams['owner_id'])) {
+			$sSql = $this->prepare("SELECT `event_id` FROM `" . $this->_sTableEvt2Usr . "` WHERE `user_id`=? LIMIT 1", (int)$aParams['owner_id']);
+			$iId = (int)$this->getOne($sSql);
+
+			$sWhereClause .= $this->prepareAsString("AND `{$this->_sTable}`.`id`>? ", $iId);
+		}
+
+		//--- Apply privacy filter
+		$aPrivacy = array(BX_DOL_PG_ALL);
+		if(isLogged())
+			$aPrivacy[] = BX_DOL_PG_MEMBERS;
+
+		$oPrivacy = BxDolPrivacy::getObjectInstance($this->_oConfig->getObject('privacy_view'));
+		$aQueryParts = $oPrivacy->getContentByGroupAsSQLPart($aPrivacy);
+		$sWhereClause .= $aQueryParts['where'] . " ";
+
+		//--- Check type
+		if(!empty($aParams['owner_id']))
+			switch($aParams['type']) {
+				case BX_BASE_MOD_NTFS_TYPE_OWNER:
+					$sWhereClause .= $this->prepareAsString("AND `{$this->_sTable}`.`owner_id`=? ", $aParams['owner_id']);
+					break;
+
+				case BX_BASE_MOD_NTFS_TYPE_OBJECT_OWNER:
+					$sWhereClause .= $this->prepareAsString("AND `{$this->_sTable}`.`owner_id`<>`{$this->_sTable}`.`object_owner_id` AND `{$this->_sTable}`.`object_owner_id`=? ", $aParams['owner_id']);
+					break;
+
+				case BX_BASE_MOD_NTFS_TYPE_CONNECTIONS:
+					$oConnection = BxDolConnection::getObjectInstance($this->_oConfig->getObject('conn_subscriptions'));
+
+					$aQueryParts = $oConnection->getConnectedContentAsSQLParts($this->_sPrefix . "events", 'owner_id', $aParams['owner_id']);
+					if(!empty($aQueryParts['join']))
+					    $sJoinClause .= ' ' . $aQueryParts['join'];
+					if(!empty($aQueryParts['fields']['added']))
+					    $sWhereClause .= "AND `{$this->_sTable}`.`date` > " . $aQueryParts['fields']['added'];
+
+					$sWhereClause .= "AND `{$this->_sTable}`.`action` <> 'replyPost' ";
+					break;
+
+                case BX_NTFS_TYPE_OBJECT_OWNER_AND_CONNECTIONS:
+                    $oConnection = BxDolConnection::getObjectInstance($this->_oConfig->getObject('conn_subscriptions'));
+
+					$aQueryParts = $oConnection->getConnectedContentAsSQLParts($this->_sPrefix . "events", 'owner_id', $aParams['owner_id']);
+					if(!empty($aQueryParts['join']))
+					    $sJoinClause .= ' ' . str_replace('INNER', 'LEFT', $aQueryParts['join']);
+                    if(!empty($aQueryParts['fields']['added']))
+					    $sWhereClause .= "AND `{$this->_sTable}`.`date` > " . $aQueryParts['fields']['added'];
+
+					$sWhereClause .= $this->prepareAsString("AND ((NOT ISNULL(`c`.`content`) AND `{$this->_sTable}`.`action` <> 'replyPost') || (`{$this->_sTable}`.`owner_id` <> `{$this->_sTable}`.`object_owner_id` AND `{$this->_sTable}`.`object_owner_id`=?)) ", $aParams['owner_id']);
+                    break;
+			}
+
+		return array($sJoinClause, $sWhereClause);
+	}
+}
+
+/** @} */

+ 267 - 0
modules/boonex/notifications/updates/9.0.5_9.0.6/source/classes/BxNtfsModule.php

@@ -0,0 +1,267 @@
+<?php use nspace\func;
+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);
+
+/**
+ * DTYPE - Delivery Type:
+ * 1. by Onsite notification,
+ * 2. by Email message,
+ * 3. by Push notification.
+ */
+define('BX_NTFS_DTYPE_SITE', 'site');
+define('BX_NTFS_DTYPE_EMAIL', 'email');
+define('BX_NTFS_DTYPE_PUSH', 'push');
+
+class BxNtfsModule extends BxBaseModNotificationsModule
+{
+    /**
+     * Constructor
+     */
+    function __construct($aModule)
+    {
+        parent::__construct($aModule);
+
+        $this->_iOwnerId = $this->getUserId();
+    }
+
+    /**
+     * ACTION METHODS
+     */
+    function actionGetPosts()
+    {
+        $aParams = $this->_prepareParamsGet();
+        $sEvents = $this->_oTemplate->getPosts($aParams);
+
+        echoJson(array('events' => $sEvents));
+    }
+
+    /**
+     * SERVICE METHODS
+     */
+
+    /**
+     * @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 = array())
+    {
+    	$aBrowseTypes = array(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)
+            return array('content' => MsgBox(_t('_bx_ntfs_txt_msg_no_results')));
+
+		$aParams = $this->_prepareParams($sType, $iOwnerId, $iStart, $iPerPage, $aModules);
+		$sContent = $this->_oTemplate->getViewBlock($aParams);
+
+		$aParams['browse'] = 'first';
+    	$aEvent = $this->_oDb->getEvents($aParams);
+    	if(!empty($aEvent))
+			$this->_oDb->markAsRead($iOwnerId, $aEvent['id']);
+
+		$sModule = $this->_oConfig->getName();
+		$sJsObject = $this->_oConfig->getJsObject('view');
+
+        return array('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_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;
+
+		$aParams = $this->_prepareParams(BX_NTFS_TYPE_DEFAULT, $iOwnerId);
+		$aParams['new'] = 1;
+
+		list($aEvent, $iCount) = $this->_oDb->getEvents($aParams, true);
+		return $iCount;
+    }
+
+    /**
+     * @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 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_DOL_URL_ROOT . 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 ---//
+    }
+
+    protected function _prepareParams($sType = '', $iOwnerId = 0, $iStart = -1, $iPerPage = -1, $aModules = array())
+    {
+        $aParams = array();
+        $aParams['browse'] = 'list';
+        $aParams['type'] = !empty($sType) ? $sType : BX_NTFS_TYPE_DEFAULT;
+        $aParams['owner_id'] = (int)$iOwnerId != 0 ? $iOwnerId : $this->getUserId();
+        $aParams['start'] = (int)$iStart > 0 ? $iStart : 0;
+        $aParams['per_page'] = (int)$iPerPage > 0 ? $iPerPage : $this->_oConfig->getPerPage();
+        $aParams['modules'] = is_array($aModules) && !empty($aModules) ? $aModules : array();
+        $aParams['active'] = 1;
+
+        return $aParams;
+    }
+
+	protected function _prepareParamsGet()
+    {
+        $aParams = array();
+        $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;
+
+        $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) : array();
+
+        $aParams['active'] = 1;
+
+        return $aParams;
+    }
+}
+
+/** @} */

+ 326 - 0
modules/boonex/notifications/updates/9.0.5_9.0.6/source/classes/BxNtfsResponse.php

@@ -0,0 +1,326 @@
+<?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
+ *
+ * @{
+ */
+
+class BxNtfsResponse extends BxBaseModNotificationsResponse
+{
+    public function __construct()
+    {
+        parent::__construct();
+
+        $this->_oModule = BxDolModule::getInstance('bx_notifications');
+    }
+
+    /**
+     * Overwritten method of parent class.
+     *
+     * @param BxDolAlerts $oAlert an instance of alert.
+     */
+    public function response($oAlert)
+    {
+    	$iObjectPrivacyView = $this->_getObjectPrivacyView($oAlert->aExtras);
+        if($iObjectPrivacyView == BX_DOL_PG_HIDDEN)
+            return;
+
+        $aHandler = $this->_oModule->_oConfig->getHandlers($oAlert->sUnit . '_' . $oAlert->sAction);
+        switch($aHandler['type']) {
+            case BX_BASE_MOD_NTFS_HANDLER_TYPE_INSERT:
+            	$sMethod = 'getInsertData' . bx_gen_method_name($oAlert->sUnit . '_' . $oAlert->sAction);           	
+            	if(!method_exists($this, $sMethod))
+            		$sMethod = 'getInsertData';
+
+                $aDataItems = $this->$sMethod($oAlert, $aHandler);
+                foreach($aDataItems as $aDataItem) {
+                    $iId = $this->_oModule->_oDb->insertEvent($aDataItem);
+                    if(!empty($iId)) {
+                        $this->sendNotifications($iId, $oAlert, $aHandler);
+
+                        $this->_oModule->onPost($iId);
+                    }
+                }
+				break;
+
+            case BX_BASE_MOD_NTFS_HANDLER_TYPE_UPDATE:
+                $this->_oModule->_oDb->updateEvent(array('object_privacy_view' => $iObjectPrivacyView), array('type' => $oAlert->sUnit, 'object_id' => $oAlert->iObject));
+                break;
+
+            case BX_BASE_MOD_NTFS_HANDLER_TYPE_DELETE:
+        		if($oAlert->sUnit == 'profile' && $oAlert->sAction == 'delete') {
+        			$this->_oModule->_oDb->deleteEvent(array('owner_id' => $oAlert->iObject));
+
+        			$this->_oModule->_oDb->deleteEvent(array('action' => 'connection_added', 'object_id' => $oAlert->iObject));
+					break;
+            	}
+
+            	$sMethod = 'getDeleteData' . bx_gen_method_name($oAlert->sUnit . '_' . $oAlert->sAction);           	
+            	if(!method_exists($this, $sMethod))
+            		$sMethod = 'getDeleteData';
+
+                $aDataItems = $this->$sMethod($oAlert, $aHandler);
+                foreach($aDataItems as $aDataItem)
+                    $this->_oModule->_oDb->deleteEvent($aDataItem);
+                break;
+        }
+    }
+
+    protected function getInsertData(&$oAlert, &$aHandler)
+    {
+    	return array(
+    	    array(
+    			'owner_id' => $oAlert->iSender,
+    			'type' => $oAlert->sUnit,
+    			'action' => $oAlert->sAction,
+    			'object_id' => $oAlert->iObject,
+    			'object_owner_id' => $this->_getObjectOwnerId($oAlert->aExtras),
+    			'object_privacy_view' => $this->_getObjectPrivacyView($oAlert->aExtras),
+    			'subobject_id' => $this->_getSubObjectId($oAlert->aExtras),
+    			'content' => '',
+        		'allow_view_event_to' => $this->_oModule->_oConfig->getPrivacyViewDefault('event'),
+    			'processed' => 0
+    	    )
+		);
+    }
+
+    protected function getDeleteData(&$oAlert, &$aHandler)
+    {
+        $aHandlers = $this->_oModule->_oDb->getHandlers(array('type' => 'by_group_key_type', 'group' => $aHandler['group']));
+
+    	return array(
+    	    array(
+            	'type' => $oAlert->sUnit, 
+            	'action' => $aHandlers[BX_BASE_MOD_NTFS_HANDLER_TYPE_INSERT]['alert_action'], 
+            	'object_id' => $oAlert->iObject,
+            	'subobject_id' => $this->_getSubObjectId($oAlert->aExtras)
+            )
+        );
+    }
+
+    protected function getDeleteDataBxTimelineDelete(&$oAlert, &$aHandler)
+    {
+        $aHandlers = $this->_oModule->_oDb->getHandlers(array('type' => 'by_group_key_type', 'group' => $aHandler['group']));
+
+    	return array(
+    	    array(
+            	'type' => $oAlert->sUnit, 
+            	'action' => $aHandlers[BX_BASE_MOD_NTFS_HANDLER_TYPE_INSERT]['alert_action'], 
+            	'object_id' => $oAlert->iObject,
+            	'subobject_id' => $this->_getSubObjectId($oAlert->aExtras)
+            ),
+            array(
+            	'action' => 'timeline_post_common', 
+            	'subobject_id' => $oAlert->iObject
+            )
+        );
+    }
+
+	/**
+     * Custom insert data getter for sys_profiles_friends -> connection_added and connection_removed alerts. 
+     */
+    protected function getInsertDataSysProfilesFriendsConnectionAdded(&$oAlert, &$aHandler)
+    {
+        if(empty($oAlert->aExtras['mutual']))
+            return array();
+
+        $iObjectPrivacyView = $this->_getObjectPrivacyView($oAlert->aExtras);
+        $iPrivacyView = $this->_oModule->_oConfig->getPrivacyViewDefault('event');
+
+    	return array(
+    	    array(
+    			'owner_id' => $oAlert->aExtras['initiator'],
+    			'type' => $oAlert->sUnit,
+    			'action' => $oAlert->sAction,
+    			'object_id' => $oAlert->aExtras['content'],
+    			'object_owner_id' => $oAlert->aExtras['content'],
+    			'object_privacy_view' => $iObjectPrivacyView,
+    			'subobject_id' => 0,
+    			'content' => '',
+        		'allow_view_event_to' => $iPrivacyView,
+    			'processed' => 0
+    	    ),
+    	    array(
+    			'owner_id' => $oAlert->aExtras['content'],
+    			'type' => $oAlert->sUnit,
+    			'action' => $oAlert->sAction,
+    			'object_id' => $oAlert->aExtras['initiator'],
+    			'object_owner_id' => $oAlert->aExtras['initiator'],
+    			'object_privacy_view' => $iObjectPrivacyView,
+    			'subobject_id' => 0,
+    			'content' => '',
+        		'allow_view_event_to' => $iPrivacyView,
+    			'processed' => 0
+    	    ),
+		);
+    }
+    
+    protected function getDeleteDataSysProfilesFriendsConnectionRemoved(&$oAlert, &$aHandler)
+    {
+        $aHandlers = $this->_oModule->_oDb->getHandlers(array('type' => 'by_group_key_type', 'group' => $aHandler['group']));
+
+        $sAction = $aHandlers[BX_BASE_MOD_NTFS_HANDLER_TYPE_INSERT]['alert_action'];
+    	return array(
+    	    array(
+    	        'owner_id' => $oAlert->aExtras['initiator'],
+            	'type' => $oAlert->sUnit, 
+            	'action' => $sAction, 
+            	'object_id' => $oAlert->aExtras['content']
+            ),
+            array(
+            	'owner_id' => $oAlert->aExtras['content'],
+            	'type' => $oAlert->sUnit, 
+            	'action' => $sAction, 
+            	'object_id' => $oAlert->aExtras['initiator']
+            )
+        );
+    }
+
+    /**
+     * Custom insert data getter for sys_profiles_subscriptions -> connection_added and connection_removed alerts. 
+     */
+    protected function getInsertDataSysProfilesSubscriptionsConnectionAdded(&$oAlert, &$aHandler)
+    {
+    	return array(
+    	    array(
+    			'owner_id' => $oAlert->aExtras['initiator'],
+    			'type' => $oAlert->sUnit,
+    			'action' => $oAlert->sAction,
+    			'object_id' => $oAlert->aExtras['content'],
+    			'object_owner_id' => $oAlert->aExtras['content'],
+    			'object_privacy_view' => $this->_getObjectPrivacyView($oAlert->aExtras),
+    			'subobject_id' => 0,
+    			'content' => '',
+        		'allow_view_event_to' => $this->_oModule->_oConfig->getPrivacyViewDefault('event'),
+    			'processed' => 0
+    	    )
+		);
+    }
+
+    protected function getDeleteDataSysProfilesSubscriptionsConnectionRemoved(&$oAlert, &$aHandler)
+    {
+        $aHandlers = $this->_oModule->_oDb->getHandlers(array('type' => 'by_group_key_type', 'group' => $aHandler['group']));
+
+    	return array(
+    	    array(
+    	        'owner_id' => $oAlert->aExtras['initiator'],
+            	'type' => $oAlert->sUnit, 
+            	'action' => $aHandlers[BX_BASE_MOD_NTFS_HANDLER_TYPE_INSERT]['alert_action'], 
+            	'object_id' => $oAlert->aExtras['content']
+            )
+        );
+    }
+
+    protected function sendNotifications($iId, &$oAlert, &$aHandler)
+    {
+        $aEvent = $this->_oModule->_oDb->getEvents(array('browse' => 'id', 'value' => $iId));
+        if(empty($aEvent) || !is_array($aEvent))
+            return;
+
+        $aTypes = array(BX_NTFS_DTYPE_EMAIL, BX_NTFS_DTYPE_PUSH);
+        $aTypesToSend = array();
+        foreach($aTypes as $sType) {
+            $aHidden = $this->_oModule->_oConfig->getHandlersHidden($sType);
+            if(in_array($aHandler['id'], $aHidden))
+                continue;
+
+            $sMethodPostfix = bx_gen_method_name($sType);
+            $sMethodGet = 'getNotification' . $sMethodPostfix;
+            $sMethodSend = 'sendNotification' . $sMethodPostfix;
+            if(!method_exists($this->_oModule->_oTemplate, $sMethodGet) || !method_exists($this, $sMethodSend))
+                continue;
+
+            //--- Get event.
+            $aTypesToSend[$sType] = array(
+            	'method' => $sMethodSend,
+                'content' => $this->_oModule->_oTemplate->$sMethodGet($aEvent)
+            );
+        }
+
+        if(empty($aTypesToSend) || !is_array($aTypesToSend))
+            return;
+
+        //--- Get subscribers.
+        $oConnection = BxDolConnection::getObjectInstance($this->_oModule->_oConfig->getObject('conn_subscriptions'));
+        $aRecipients = $oConnection->getConnectedInitiators($aEvent['owner_id']);
+
+        //--- Get content owner.
+        if((int)$aEvent['owner_id'] != (int)$aEvent['object_owner_id'] && !in_array($aEvent['object_owner_id'], $aRecipients))
+            $aRecipients[] = $aEvent['object_owner_id'];
+
+        $oPrivacyInt = BxDolPrivacy::getObjectInstance($this->_oModule->_oConfig->getObject('privacy_view'));
+        $oPrivacyExt = $this->_oModule->_oConfig->getPrivacyObject($aEvent['type'] . '_' . $aEvent['action']);
+        foreach($aRecipients as $iRecipient) {
+            $oProfile = BxDolProfile::getInstance($iRecipient);
+            if(!$oProfile)
+                continue;
+
+            if(!bx_srv($oProfile->getModule(), 'act_as_profile'))
+                continue;
+
+            if($oPrivacyExt !== false && !$oPrivacyExt->check($aEvent['id'], $iRecipient)) 
+    		    continue;
+
+            if($oPrivacyInt !== false && !$oPrivacyInt->check($aEvent['id'], $iRecipient))
+                continue;
+
+            foreach($aTypesToSend as $aType)
+                $this->{$aType['method']}($oProfile, $aType['content']);
+        }
+    }
+
+    protected function sendNotificationEmail($oProfile, $sContent)
+    {
+        sendMailTemplate('bx_notifications_new_event', $oProfile->getAccountId(), $oProfile->id(), array(
+            'content' => $sContent
+        ));
+    }
+
+    protected function sendNotificationPush($oProfile, $aContent)
+    {
+        $CNF = &$this->_oModule->_oConfig->CNF;
+
+        $sAppId = getParam('sys_push_app_id');
+        $sRestApi = getParam('sys_push_rest_api');
+        if(empty($sAppId) || empty($sRestApi))
+            return;
+
+		$sLanguage = BxDolStudioLanguagesUtils::getInstance()->getCurrentLangName(false);
+
+		$aFields = array(
+			'app_id' => $sAppId,
+			'filters' => array(
+		        array("field" => "tag", "key" => "user", "relation" => "=", "value" => $oProfile->id())
+            ),
+			'contents' => array(
+    			 $sLanguage => $aContent['message']
+    		),
+			'headings' => array(
+				 $sLanguage => _t('_bx_ntfs_push_new_event_subject', getParam('site_title'))
+			),
+			'url' => $aContent['url'],
+			'chrome_web_icon' => $aContent['icon']
+		);
+
+		$oChannel = curl_init();
+		curl_setopt($oChannel, CURLOPT_URL, "https://onesignal.com/api/v1/notifications");
+		curl_setopt($oChannel, CURLOPT_HTTPHEADER, array(
+			'Content-Type: application/json; charset=utf-8',
+			'Authorization: Basic ' . $sRestApi
+		));
+		curl_setopt($oChannel, CURLOPT_RETURNTRANSFER, true);
+		curl_setopt($oChannel, CURLOPT_HEADER, false);
+		curl_setopt($oChannel, CURLOPT_POST, true);
+		curl_setopt($oChannel, CURLOPT_POSTFIELDS, json_encode($aFields));
+		curl_setopt($oChannel, CURLOPT_SSL_VERIFYPEER, false);
+
+		$sResult = curl_exec($oChannel);
+		curl_close($oChannel);
+    }
+}
+
+/** @} */

+ 238 - 0
modules/boonex/notifications/updates/9.0.5_9.0.6/source/classes/BxNtfsTemplate.php

@@ -0,0 +1,238 @@
+<?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
+ *
+ * @{
+ */
+
+class BxNtfsTemplate extends BxBaseModNotificationsTemplate
+{
+    function __construct(&$oConfig, &$oDb)
+    {
+        parent::__construct($oConfig, $oDb);
+    }
+
+    public function getViewBlock($aParams)
+    {
+        return $this->parseHtmlByName('block_view.html', array(
+        	'html_id_view_block' => $this->_oConfig->getHtmlIds('view', 'block'),
+        	'html_id_events' => $this->_oConfig->getHtmlIds('view', 'events'),
+            'style_prefix' => $this->_oConfig->getPrefix('style'),
+            'content' => $this->getPosts($aParams),
+            'js_content' => $this->getJsCode('view', array(
+        		'oRequestParams' => array(
+	                'type' => $aParams['type'],
+	                'owner_id' => $aParams['owner_id'],
+	                'start' => $aParams['start'],
+	                'per_page' => $aParams['per_page'],
+	                'modules' => $aParams['modules']
+       			)
+            ))
+        ));
+    }
+
+    public function getPosts($aParams)
+    {
+    	$sJsObject = $this->_oConfig->getJsObject('view');
+
+    	$aParamsDb = $aParams;
+    	$aParamsDb['per_page'] = 3 * $aParamsDb['per_page'];
+
+        $aEvents = $this->_oDb->getEvents($aParamsDb);
+        if(empty($aEvents))
+        	return $this->getEmpty();
+
+        $aTmplVarsEvents = array();
+        foreach($aEvents as $aEvent) {
+            $sEvent = $this->getPost($aEvent, $aParams);
+            if(empty($sEvent))
+                continue;
+
+            $aTmplVarsEvents[] = array('event' => $sEvent);
+            if(count($aTmplVarsEvents) >= ($aParams['per_page'] + 1))
+            	break;
+        }
+
+        $oPaginate = new BxTemplPaginate(array(
+        	'start' => $aParams['start'],
+            'per_page' => $aParams['per_page'],
+        	'page_url' => $this->_oConfig->getViewUrl(),
+        	'on_change_page' => $sJsObject . ".changePage(this, {start}, {per_page})"
+        ));
+        $oPaginate->setNumFromDataArray($aTmplVarsEvents);
+
+        return $this->parseHtmlByName('events.html', array(
+        	'style_prefix' => $this->_oConfig->getPrefix('style'),
+        	'bx_repeat:events' => $aTmplVarsEvents,
+        	'paginate' => $oPaginate->getSimplePaginate()
+        ));
+    }
+
+    /**
+     * Enter description here ...
+     * @example Available keys are:
+     * 1. owner_name and owner_link
+     * 2. entry_caption and entry_url
+     * 3. subentry_url and subentry_sample
+     * 
+     */
+    public function getPost(&$aEvent, $aBrowseParams = array())
+    {
+    	$oModule = $this->getModule();
+
+    	if((int)$aEvent['processed'] == 0)
+    		$this->_processContent($aEvent);
+
+        $aEvent['content'] = unserialize($aEvent['content']);
+
+    	$oPrivacy = $oModule->_oConfig->getPrivacyObject($aEvent['type'] . '_' . $aEvent['action']);
+    	if($oPrivacy !== false && !$oPrivacy->check($aEvent['id'])) 
+    		return '';
+
+        $sService = 'check_allowed_with_content';
+        if(BxDolRequest::serviceExists($aEvent['type'], $sService) && BxDolService::call($aEvent['type'], $sService, array('view', $this->_getContentObjectId($aEvent))) !== CHECK_ACTION_RESULT_ALLOWED)
+            return '';
+
+        list($sOwnerName, $sOwnerUrl, $sOwnerIcon) = $oModule->getUserInfo($aEvent['owner_id']);
+        $bAuthorIcon = !empty($sOwnerIcon);
+
+        $aEvent['content']['owner_name'] = $sOwnerName;
+        $aEvent['content']['owner_link'] = $sOwnerUrl;
+        $aEvent['content']['owner_icon'] = $sOwnerIcon;
+        if(!empty($aEvent['content']['entry_caption']))
+            $aEvent['content']['entry_caption'] = bx_process_output($aEvent['content']['entry_caption'], BX_DATA_TEXT_MULTILINE);
+
+        foreach($aEvent['content'] as $sKey => $sValue)
+        	if(substr($sValue, 0, 1) == '_')
+        		$aEvent['content'][$sKey] = _t($sValue);        
+
+    	$aEvent['content_parsed'] = _t(!empty($aEvent['content']['lang_key']) ? $aEvent['content']['lang_key'] : $this->_getContentLangKey($aEvent));
+    	$aEvent['content_parsed'] = $this->parseHtmlByContent($aEvent['content_parsed'], $aEvent['content'], array('{', '}'));
+
+        return $this->parseHtmlByName('event.html', array (
+        	'html_id' => $this->_oConfig->getHtmlIds('view', 'event') . $aEvent['id'],
+            'style_prefix' => $this->_oConfig->getPrefix('style'),
+            'js_object' => $this->_oConfig->getJsObject('view'),
+            'id' => $aEvent['id'],
+            'bx_if:show_icon' => array(
+                'condition' => $bAuthorIcon,
+                'content' => array(
+                    'author_icon' => $sOwnerIcon
+                )
+            ),
+            'bx_if:show_icon_empty' => array(
+                'condition' => !$bAuthorIcon,
+                'content' => array()
+            ),
+            'link' => $this->_getContentLink($aEvent),
+            'content' => $aEvent['content_parsed'],
+            'date' => bx_time_js($aEvent['date']),
+        ));
+    }
+
+    public function getNotificationEmail(&$aEvent)
+    {
+        $sEvent = $this->getPost($aEvent);
+        if(empty($sEvent))
+            return;
+
+        return $this->parseHtmlByName('et_new_event.html', array(
+        	'icon_url' => !empty($aEvent['content']['owner_icon']) ? $aEvent['content']['owner_icon'] : $this->getIconUrl('std-icon.svg'),
+            'content_url' => $this->_getContentLink($aEvent),
+            'content' => $aEvent['content_parsed'],
+            'date' => bx_process_output($aEvent['date'], BX_DATA_DATETIME_TS),
+        ));
+    }
+
+    public function getNotificationPush(&$aEvent)
+    {
+        $sEvent = $this->getPost($aEvent);
+        if(empty($sEvent))
+            return;
+
+        $sMessage = preg_replace('/<\/?[a-zA-Z0-9=\'":;\(\)\s_-]+>/i', '"', $aEvent['content_parsed']);
+		if($sMessage)
+            $sMessage = BxTemplFunctions::getInstance()->getStringWithLimitedLength(html_entity_decode($sMessage), $this->_oConfig->getPushMaxLen());
+
+        return array(
+            'url' => $this->_getContentLink($aEvent),
+            'message' => $sMessage,
+            'icon' => !empty($aEvent['content']['owner_icon']) ? $aEvent['content']['owner_icon'] : ''
+        );
+    }
+
+    public function getEmpty($bVisible = true)
+    {
+        return $this->parseHtmlByName('empty.html', array(
+            'style_prefix' => $this->_oConfig->getPrefix('style'),
+            'visible' => $bVisible ? 'block' : 'none',
+            'content' => MsgBox(_t('_bx_ntfs_txt_msg_no_results'))
+        ));
+    }
+
+    protected function _processContent(&$aEvent)
+    {
+    	$aContent = $this->_getContent($aEvent);
+		if(empty($aContent) || !is_array($aContent)) 
+			return;
+
+		$aSet = array();
+		if(!empty($aContent['entry_author'])) {
+			$aSet['object_owner_id'] = (int)$aContent['entry_author'];
+			unset($aContent['entry_author']);
+		}
+
+		if(!empty($aContent['entry_privacy'])) {
+			$aSet['allow_view_event_to'] = $aContent['entry_privacy'];
+			$aEvent['allow_view_event_to'] = $aContent['entry_privacy'];
+			unset($aContent['entry_privacy']);
+		}
+
+		$aEvent['content'] = serialize($aContent);
+		$aSet = array_merge($aSet, array(
+			'content' => $aEvent['content'], 
+			'processed' => 1
+		));
+
+		$this->_oDb->updateEvent($aSet, array('id' => $aEvent['id']));
+		return;
+    }
+
+    protected function _getContent(&$aEvent)
+    {
+        $sHandler = $aEvent['type'] . '_' . $aEvent['action'];
+        if(!$this->_oConfig->isHandler($sHandler))
+            return array();
+
+        $aHandler = $this->_oConfig->getHandlers($sHandler);
+        if(!empty($aHandler['module_name']) && !empty($aHandler['module_class']) && !empty($aHandler['module_method']))
+        	return BxDolService::call($aHandler['module_name'], $aHandler['module_method'], array($aEvent), $aHandler['module_class']);
+
+        $sMethod = 'display' . bx_gen_method_name($aHandler['alert_unit'] . '_' . $aHandler['alert_action']);
+		if(!method_exists($this, $sMethod))
+        	return array();
+
+		return $this->$sMethod($aEvent);
+    }
+
+    protected function _getContentObjectId(&$aEvent)
+    {
+        return !empty($aEvent['content']['object_id']) ? (int)$aEvent['content']['object_id'] : (int)$aEvent['object_id'];
+    }
+
+    protected function _getContentLangKey(&$aEvent)
+    {
+    	return !empty($aEvent['subobject_id']) ? '_bx_ntfs_txt_subobject_added' : '_bx_ntfs_txt_object_added';
+    }
+
+    protected function _getContentLink(&$aEvent)
+    {
+        return !empty($aEvent['subobject_id']) && !empty($aEvent['content']['subentry_url']) ? $aEvent['content']['subentry_url'] : $aEvent['content']['entry_url'];
+    }
+}
+
+/** @} */

+ 82 - 0
modules/boonex/notifications/updates/9.0.5_9.0.6/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' => '9.0.6',
+    'vendor' => 'BoonEx',
+	'help_url' => 'http://feed.una.io/?section={module_name}',
+
+    'compatible_with' => array(
+        '9.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',
+    ),
+);
+
+/** @} */

+ 47 - 0
modules/boonex/notifications/updates/9.0.5_9.0.6/source/install/langs/en.xml

@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources name="en" flag="gb" title="English">
+	<string name="_bx_ntfs"><![CDATA[Notifications]]></string>
+	<string name="_bx_notifications"><![CDATA[Notifications]]></string>
+
+	<string name="_bx_ntfs_page_title_system_view"><![CDATA[Notifications]]></string>
+	<string name="_bx_ntfs_page_title_view"><![CDATA[Notifications]]></string>
+	<string name="_bx_ntfs_page_block_title_view"><![CDATA[Notifications]]></string>
+
+	<string name="_bx_ntfs_menu_title_submenu"><![CDATA[Notifications Submenu]]></string>
+	<string name="_bx_ntfs_menu_set_title_submenu"><![CDATA[Notifications Submenu]]></string>
+	<string name="_bx_ntfs_menu_item_title_system_notifications_all"><![CDATA[All Notifications]]></string>
+	<string name="_bx_ntfs_menu_item_title_notifications_all"><![CDATA[All Notifications]]></string>
+    <string name="_bx_ntfs_menu_item_title_system_notifications"><![CDATA[Notifications]]></string>
+    <string name="_bx_ntfs_menu_item_title_notifications"><![CDATA[Notifications]]></string>
+
+	<string name="_bx_ntfs_option_events_per_page"><![CDATA[Number of items per page]]></string>
+	<string name="_bx_ntfs_option_events_hide_site"><![CDATA[Onsite notifications]]></string>
+	<string name="_bx_ntfs_option_events_hide_email"><![CDATA[Email notifications]]></string>
+	<string name="_bx_ntfs_option_events_hide_push"><![CDATA[Push notifications]]></string>
+
+	<string name="_bx_ntfs_privacy_view"><![CDATA[View event]]></string>
+
+	<string name="_bx_ntfs_alert_action_added"><![CDATA[add]]></string>
+	<string name="_bx_ntfs_alert_action_commentPost"><![CDATA[add comment]]></string>
+	<string name="_bx_ntfs_alert_action_replyPost"><![CDATA[reply to own comment]]></string>
+	<string name="_bx_ntfs_alert_action_doVote"><![CDATA[add vote]]></string>
+	<string name="_bx_ntfs_alert_action_timeline_post_common"><![CDATA[post to timeline]]></string> 
+
+	<string name="_bx_ntfs_alert_module_sys_profiles_subscriptions"><![CDATA[Profiles Subscriptions]]></string>
+	<string name="_bx_ntfs_alert_module_sys_profiles_friends"><![CDATA[Profiles Friends]]></string>
+	<string name="_bx_ntfs_alert_action_connection_added"><![CDATA[add connection]]></string>
+
+	<string name="_bx_ntfs_txt_msg_no_results"><![CDATA[Empty]]></string>
+	<string name="_bx_ntfs_txt_object_added"><![CDATA[<b class="bx-ntfs-content-profile">{owner_name}</b> added a {entry_sample} <b class="bx-ntfs-content-entry">{entry_caption}</b>]]></string>
+	<string name="_bx_ntfs_txt_subobject_added"><![CDATA[<b class="bx-ntfs-content-profile">{owner_name}</b> added a {subentry_sample} <b class="bx-ntfs-content-entry">{entry_caption}</b>]]></string>
+
+    <string name="_bx_ntfs_push_new_event_subject"><![CDATA[New on "{0}"]]></string>
+
+	<string name="_bx_ntfs_email_new_event"><![CDATA[New notification]]></string>
+    <string name="_bx_ntfs_email_new_event_subject"><![CDATA[New notification on "{site_name}"]]></string>
+    <string name="_bx_ntfs_email_new_event_body"><![CDATA[{email_header}
+<p> </p>
+{content}
+<p> </p>
+{email_footer}]]></string>
+</resources>

+ 38 - 0
modules/boonex/notifications/updates/9.0.5_9.0.6/source/install/sql/disable.sql

@@ -0,0 +1,38 @@
+SET @sName = 'bx_notifications';
+
+
+-- PAGES & BLOCKS
+DELETE FROM `sys_objects_page` WHERE `module` = @sName;
+DELETE FROM `sys_pages_blocks` WHERE `module` = @sName;
+
+
+-- MENU
+DELETE FROM `sys_objects_menu` WHERE `module` = @sName;
+DELETE FROM `sys_menu_sets` WHERE `module` = @sName;
+DELETE FROM `sys_menu_items` WHERE `module` = @sName OR `set_name` IN('bx_notifications_submenu');
+
+
+-- SETTINGS
+SET @iTypeId = (SELECT `ID` FROM `sys_options_types` WHERE `name` = @sName LIMIT 1);
+SET @iCategId = (SELECT `ID` FROM `sys_options_categories` WHERE `type_id` = @iTypeId LIMIT 1);
+DELETE FROM `sys_options` WHERE `category_id` = @iCategId;
+DELETE FROM `sys_options_categories` WHERE `type_id` = @iTypeId;
+DELETE FROM `sys_options_types` WHERE `id` = @iTypeId;
+
+
+-- PRIVACY 
+DELETE FROM `sys_objects_privacy` WHERE `module` = @sName;
+
+
+-- LIVE UPDATES
+DELETE FROM `sys_objects_live_updates` WHERE `name` = @sName;
+
+
+-- ALERTS
+SET @iHandlerId = (SELECT `id` FROM `sys_alerts_handlers` WHERE `name` = @sName LIMIT 1);
+DELETE FROM `sys_alerts` WHERE `handler_id` = @iHandlerId;
+DELETE FROM `sys_alerts_handlers` WHERE `id` = @iHandlerId LIMIT 1;
+
+
+-- EMAIL TEMPLATES
+DELETE FROM `sys_email_templates` WHERE `Module` = @sName;

+ 78 - 0
modules/boonex/notifications/updates/9.0.5_9.0.6/source/install/sql/enable.sql

@@ -0,0 +1,78 @@
+SET @sName = 'bx_notifications';
+
+
+-- PAGES & BLOCKS
+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_notifications_view', '_bx_ntfs_page_title_system_view', '_bx_ntfs_page_title_view', @sName, 5, 2147483647, 1, 'notifications-view', 'page.php?i=notifications-view', '', '', '', 0, 1, 0, 'BxNtfsPageView', 'modules/boonex/notifications/classes/BxNtfsPageView.php');
+
+INSERT INTO `sys_pages_blocks` (`object`, `cell_id`, `module`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `order`) VALUES
+('bx_notifications_view', 1, @sName, '_bx_ntfs_page_block_title_view', 11, 2147483647, 'service', 'a:2:{s:6:"module";s:16:"bx_notifications";s:6:"method";s:14:"get_block_view";}', 0, 1, 1);
+
+-- PAGES: add page block on dashboard
+SET @iPBCellDashboard = 3;
+SET @iPBOrderDashboard = 4; --(SELECT IFNULL(MAX(`order`), 0) FROM `sys_pages_blocks` WHERE `object` = 'sys_dashboard' AND `cell_id` = @iPBCellDashboard LIMIT 1);
+INSERT INTO `sys_pages_blocks` (`object`, `cell_id`, `module`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `order`) VALUES
+('sys_dashboard', @iPBCellDashboard, @sName, '_bx_ntfs_page_block_title_view', 11, 2147483644, 'service', 'a:2:{s:6:"module";s:16:"bx_notifications";s:6:"method";s:14:"get_block_view";}', 0, 0, @iPBOrderDashboard);
+
+
+-- 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_notifications_submenu', '_bx_ntfs_menu_title_submenu', 'bx_notifications_submenu', @sName, 8, 0, 1, '', '');
+
+INSERT INTO `sys_menu_sets`(`set_name`, `module`, `title`, `deletable`) VALUES 
+('bx_notifications_submenu', @sName, '_bx_ntfs_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_notifications_submenu', @sName, 'notifications-all', '_bx_ntfs_menu_item_title_system_notifications_all', '_bx_ntfs_menu_item_title_notifications_all', 'page.php?i=notifications-view', '', '', '', '', 2147483647, 1, 0, 1);
+
+-- MENU: Notifications
+SET @iMIOrder = (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`, `submenu_object`, `visible_for_levels`, `active`, `copyable`, `order`) VALUES
+('sys_account_notifications', @sName, 'notifications-notifications', '_bx_ntfs_menu_item_title_system_notifications', '_bx_ntfs_menu_item_title_notifications', 'page.php?i=notifications-view', '', '', 'bell col-green3', 'a:2:{s:6:"module";s:16:"bx_notifications";s:6:"method";s:28:"get_unread_notifications_num";}', '', 2147483646, 1, 0, @iMIOrder + 1);
+
+
+-- SETTINGS
+SET @iTypeOrder = (SELECT IFNULL(MAX(`order`), 0) FROM `sys_options_types` WHERE `group` = 'modules');
+INSERT INTO `sys_options_types`(`group`, `name`, `caption`, `icon`, `order`) VALUES 
+('modules', @sName, '_bx_ntfs', 'bx_notifications@modules/boonex/notifications/|std-icon.svg', @iTypeOrder + 1);
+SET @iTypeId = LAST_INSERT_ID();
+
+INSERT INTO `sys_options_categories` (`type_id`, `name`, `caption`, `order`)
+VALUES (@iTypeId, @sName, '_bx_ntfs', 1);
+SET @iCategId = LAST_INSERT_ID();
+
+INSERT INTO `sys_options` (`name`, `value`, `category_id`, `caption`, `type`, `check`, `check_params`, `check_error`, `extra`, `order`) VALUES
+('bx_notifications_events_per_page', '10', @iCategId, '_bx_ntfs_option_events_per_page', 'digit', '', '', '', '', 1),
+('bx_notifications_events_hide_site', '', @iCategId, '_bx_ntfs_option_events_hide_site', 'rlist', '', '', '', 'a:2:{s:6:"module";s:16:"bx_notifications";s:6:"method";s:21:"get_actions_checklist";}', 10),
+('bx_notifications_events_hide_email', '', @iCategId, '_bx_ntfs_option_events_hide_email', 'rlist', '', '', '', 'a:2:{s:6:"module";s:16:"bx_notifications";s:6:"method";s:21:"get_actions_checklist";}', 11),
+('bx_notifications_events_hide_push', '', @iCategId, '_bx_ntfs_option_events_hide_push', 'rlist', '', '', '', 'a:2:{s:6:"module";s:16:"bx_notifications";s:6:"method";s:21:"get_actions_checklist";}', 12);
+
+
+-- PRIVACY 
+INSERT INTO `sys_objects_privacy` (`object`, `module`, `action`, `title`, `default_group`, `table`, `table_field_id`, `table_field_author`, `override_class_name`, `override_class_file`) VALUES
+('bx_notifications_privacy_view', @sName, 'view', '_bx_notifications_privacy_view', '3', 'bx_notifications_events', 'id', 'owner_id', 'BxNtfsPrivacy', 'modules/boonex/notifications/classes/BxNtfsPrivacy.php');
+
+
+-- LIVE UPDATES
+INSERT INTO `sys_objects_live_updates`(`name`, `frequency`, `service_call`, `active`) VALUES
+(@sName, 1, 'a:3:{s:6:"module";s:16:"bx_notifications";s:6:"method";s:16:"get_live_updates";s:6:"params";a:3:{i:0;a:2:{s:11:"menu_object";s:18:"sys_toolbar_member";s:9:"menu_item";s:7:"account";}i:1;a:2:{s:11:"menu_object";s:25:"sys_account_notifications";s:9:"menu_item";s:27:"notifications-notifications";}i:2;s:7:"{count}";}}', 1);
+
+
+-- ALERTS
+INSERT INTO `sys_alerts_handlers`(`name`, `class`, `file`, `service_call`) VALUES 
+(@sName, 'BxNtfsResponse', 'modules/boonex/notifications/classes/BxNtfsResponse.php', '');
+SET @iHandler := LAST_INSERT_ID();
+
+INSERT INTO `sys_alerts` (`unit`, `action`, `handler_id`) VALUES
+('profile', 'delete', @iHandler),
+
+('sys_profiles_friends', 'connection_added', @iHandler),
+('sys_profiles_friends', 'connection_removed', @iHandler),
+
+('sys_profiles_subscriptions', 'connection_added', @iHandler),
+('sys_profiles_subscriptions', 'connection_removed', @iHandler);
+
+
+-- EMAIL TEMPLATES
+INSERT INTO `sys_email_templates` (`Module`, `NameSystem`, `Name`, `Subject`, `Body`) VALUES
+(@sName, '_bx_ntfs_email_new_event', 'bx_notifications_new_event', '_bx_ntfs_email_new_event_subject', '_bx_ntfs_email_new_event_body');

+ 14 - 0
modules/boonex/notifications/updates/9.0.5_9.0.6/source/template/et_new_event.html

@@ -0,0 +1,14 @@
+<div style="display: inline-block;">
+	<a href="__content_url__">
+		<div style="margin: 5px; white-space: nowrap;">
+			<div style="display: inline-block; vertical-align: middle; width: 48px; height: 48px; background-clip: padding-box; border-radius: 80px; line-height: 48px;text-align: center; overflow: hidden;">
+                <img style="width: 48px; height: 48px; line-height: 48px; border-radius: 80px;" src="__icon_url__" />
+			</div><div style="display: inline-block; vertical-align: middle; min-height: 48px; margin-left: 10px;">
+			    <div style="padding: 5px 0px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;">
+                    <p style="margin: 0px;">__content__</p>
+                    <p style="margin: 5px 0px 0px 0px;">__date__</p>
+                </div>
+			</div>
+		</div>
+	</a>
+</div>

+ 20 - 0
modules/boonex/notifications/updates/9.0.5_9.0.6/source/template/event.html

@@ -0,0 +1,20 @@
+<div id="__html_id__" class="__style_prefix__-event bx-def-margin-sec-top-auto bx-def-round-corners bx-def-box bx-def-color-bg-box bx-def-color-bg-box-hover">
+    <a class="__style_prefix__-event-link bx-def-font-color" href="__link__">
+	    <div class="__style_prefix__-event-gap bx-def-padding-sec">
+	    	<div class="__style_prefix__-event-cnt">
+		       	<div class="__style_prefix__-owner-avatar bx-def-thumb bx-def-thumb-size">
+					<bx_if:show_icon>
+						<img class="bx-def-thumb bx-def-thumb-size" src="__author_icon__" />
+					</bx_if:show_icon>
+					<bx_if:show_icon_empty>
+						<i class="sys-icon user"></i>
+					</bx_if:show_icon_empty>
+				</div>
+				<div class="__style_prefix__-body bx-def-thumb-size-min-height bx-def-thumb-size-left-indent">
+					<div class="__style_prefix__-content">__content__</div>
+					<div class="__style_prefix__-date bx-def-margin-sec-top">__date__</div>
+				</div>
+			</div>
+		</div>
+	</a>
+</div>

+ 10 - 0
modules/boonex/ocean/updates/9.0.5_9.0.6/source/data/template/system/_header_js_custom.html

@@ -0,0 +1,10 @@
+
+<link href='http://fonts.googleapis.com/css?family=Source+Sans+Pro:200,400,600' rel='stylesheet' type='text/css' />
+
+<script type="text/javascript" language="javascript">
+    $(document).ready(function () {
+        bx_activate_anim_icons('#29789c');
+
+        $('#bx-toolbar').css({opacity: 0.9});
+    });
+</script>

+ 46 - 0
modules/boonex/ocean/updates/9.0.5_9.0.6/source/data/template/system/_sub_footer.html

@@ -0,0 +1,46 @@
+		
+		                <bx_injection:injection_content_after />
+		
+		                <div class="bx-clear"></div>
+		
+		            <bx_injection:banner_bottom />
+		
+		        </div> <!-- #bx-content-main -->
+		
+		        <bx_injection:injection_between_content_footer />
+		
+		    </div> <!-- #bx-content-container -->
+		
+		</div>
+	
+	</div> <!-- #bx-content-wrapper -->
+	
+	<div id="bx-footer-wrapper">
+		<div class="bx-def-centered bx-def-padding-topbottom bx-def-padding-sec-leftright bx-def-page-width bx-def-box-sizing">
+		
+		    <div id="bx-footer" class="bx-def-padding-sec-left bx-def-padding-sec-right bx-clearfix">
+		        <bx_injection:injection_footer_before />
+		
+		        <div id="bx-menu-bottom">
+		            <bx_menu:sys_footer />
+		        </div>
+		        <div id="bx-footer-copyright">
+		        	<a href="javascript:void(0)" onclick="javascript:on_copyright_click()" title="__copyright_attr__" ><i class="sys-icon copyright"></i></a>
+		        </div>
+		        <div class="bx-clear"></div>
+		        <div class="bx-menu-switch-language-inline bx-def-margin-sec-top">
+		        	<bx_menu:sys_switch_language_inline />
+		        </div>
+		
+		        <bx_injection:injection_footer_after />
+		    </div>
+		
+		</div>
+	
+	</div>
+	
+	<bx_menu:sys_site_action />
+
+</div>
+
+<bx_include_auto:_footer.html />

+ 68 - 0
modules/boonex/ocean/updates/9.0.5_9.0.6/source/data/template/system/_sub_header.html

@@ -0,0 +1,68 @@
+<bx_include_auto:_header.html />
+
+<div class="bx-main">
+
+	<bx_injection:top />
+	
+	<div id="bx-toolbar" class="bx-def-z-index-nav bx-def-shadow">
+	
+	    <div class="bx-def-centered bx-def-padding-sec-leftright bx-def-page-width bx-def-box-sizing">
+	
+	        <div id="bx-toolbar-content" class="bx-clearfix">
+	
+	            <div id="bx-menu-toolbar-1-container">
+	                <bx_menu:sys_toolbar_site />
+	            </div>
+
+	            <div id="bx-logo-container">
+	
+	                <bx_injection:injection_logo_before />
+	                    __main_logo__
+	                <bx_injection:injection_logo_after />
+	
+	            </div>
+	
+	            <div id="bx-menu-toolbar-2-container">
+	                <bx_menu:sys_toolbar_member />
+	            </div>
+	
+	        </div>
+	
+	    </div>
+	
+	</div>
+
+	<bx_injection:injection_between_cover_logo />
+
+    __cover__
+	
+	<bx_injection:injection_between_cover_top_menu />
+	
+	<div id="bx-menu-main-bar-wrapper">
+	
+	    <div id="bx-menu-main-bar" class="bx-def-padding-sec-leftright bx-def-box-sizing bx-def-color-bg-sec">
+
+            <bx_injection:injection_top_menu_before />
+
+            <bx_menu:sys_site_submenu />
+
+            <bx_injection:injection_top_menu_after />
+
+	    </div>
+	
+	</div>
+	
+	
+	<bx_injection:injection_between_content_menu />
+	
+	<div id="bx-content-wrapper">
+	
+		__informer__
+	
+		<div class="bx-page-wrapper bx-def-centered bx-def-padding-sec-leftright bx-def-page-width bx-def-box-sizing">
+		
+		    <div id="bx-content-container" class="bx-def-padding-sec-leftright">
+		
+		        <bx_injection:injection_content_before />
+		
+		        <div id="bx-content-main" class="bx-def-margin-sec-topbottom">

+ 55 - 0
modules/boonex/ocean/updates/9.0.5_9.0.6/source/data/template/system/css/general.css

@@ -0,0 +1,55 @@
+@import url(../../../../../../../template/css/general.css);
+
+/* --------------- toolbar */
+#bx-toolbar {
+	height: 64px;
+    height: 4rem;
+
+	background: -webkit-linear-gradient(#2aaadc, #0079a9);
+	background: -o-linear-gradient(#2aaadc, #0079a9);
+	background: -moz-linear-gradient(#2aaadc, #0079a9);
+	background: linear-gradient(#2aaadc, #0079a9);
+  	border-bottom: 1px solid #4c4c4c;
+	box-shadow: 0px 1px 3px #888;
+}
+#bx-logo-container {
+	height: 64px;
+    height: 4rem;
+
+	line-height: 64px;
+    line-height: 4rem;
+}
+
+/*---------------- main menu */
+#bx-menu-main-bar {
+	text-align: center;
+	overflow-x: auto;
+}
+
+/* --------------- content */
+#bx-content-wrapper {
+	background-image: url(../images/bg-page.png);
+	background-repeat: repeat-x;
+	border-top: 1px solid #3498bf;
+}
+
+/* --------------- footer */
+#bx-footer-wrapper {
+	width: 100%;
+	height: 100px;
+	height: 6.5625rem;
+	bottom: 0;
+
+	background-color: #ffffff;
+	border-top: 1px solid #93b3c3;
+}
+
+/* --------------- menu bottom */
+#bx-menu-bottom,
+#bx-footer-copyright {
+	line-height: 24px;
+	line-height: 1.5rem;
+}
+#bx-menu-bottom {
+	float: left;
+}

+ 21 - 0
modules/boonex/ocean/updates/9.0.5_9.0.6/source/data/template/system/scripts/BxTemplCaptchaReCAPTCHAInvisible.php

@@ -0,0 +1,21 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    UnaTemplate UNA Template Classes
+ * @{
+ */
+
+/**
+ * @see BxDolCaptcha
+ */
+class BxTemplCaptchaReCAPTCHAInvisible extends BxBaseCaptchaReCAPTCHAInvisible
+{
+    public function __construct ($aObject, $oTemplate = false)
+    {
+        parent::__construct ($aObject, $oTemplate);
+    }
+}
+
+/** @} */

+ 34 - 0
modules/boonex/ocean/updates/9.0.5_9.0.6/source/data/template/system/scripts/BxTemplConfig.php

@@ -0,0 +1,34 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    UnaTemplate UNA Template Classes
+ * @{
+ */
+
+class BxTemplConfig extends BxBaseConfig
+{
+    function __construct()
+    {
+        parent::__construct();
+
+        $this->_aConfig['aLessConfig'] = array_merge($this->_aConfig['aLessConfig'], array(
+        	'bx-font-family' => 'Helvetica, Arial, sans-serif',
+        
+        	'bx-color-page' => '#b9e2f6',
+        	'bx-color-block' => '#fff',
+        	'bx-color-box' => 'rgba(218, 248, 255, 1.0)',
+        	'bx-color-box-hover' => 'rgba(218, 248, 255, 0.5)',
+        	'bx-color-sec' => '#fff',
+        	'bx-color-hl' => 'rgba(202, 242, 252, 0.2)',
+        	'bx-color-active' => 'rgba(202, 242, 252, 0.4)',
+
+        	'bx-border-color' => '#00a0ce',
+        ));
+
+        $this->setPageWidth('bx_ocean_page_width');
+    }
+}
+
+/** @} */

+ 68 - 0
modules/boonex/ocean/updates/9.0.5_9.0.6/source/install/config.php

@@ -0,0 +1,68 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Ocean Ocean Template
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+$aConfig = array(
+    /**
+     * Main Section.
+     */
+    'type' => BX_DOL_MODULE_TYPE_TEMPLATE,
+    'name' => 'bx_ocean',
+    'title' => 'Ocean',
+    'note' => 'Design template',
+    'version' => '9.0.6',
+    'vendor' => 'BoonEx',
+	'help_url' => 'http://feed.una.io/?section={module_name}',
+
+    'compatible_with' => array(
+        '9.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/ocean/',
+    'home_uri' => 'ocean',
+
+    'db_prefix' => 'bx_ocean_',
+    'class_prefix' => 'BxOcean',
+
+    /**
+     * Category for language keys.
+     */
+    'language_category' => 'BoonEx Ocean',
+
+    /**
+     * 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(),
+);
+
+/** @} */

+ 44 - 0
modules/boonex/organizations/updates/9.0.5_9.0.6/source/classes/BxOrgsAlertsResponse.php

@@ -0,0 +1,44 @@
+<?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 BxOrgsAlertsResponse extends BxBaseModGroupsAlertsResponse
+{
+    public function __construct()
+    {
+    	$this->MODULE = 'bx_organizations';
+        parent::__construct();
+    }
+    
+    public function response($oAlert)
+    {
+        parent::response($oAlert);
+
+        $sMethod = 'process' . bx_gen_method_name($oAlert->sUnit . '_' . $oAlert->sAction);
+    	if(method_exists($this, $sMethod))
+    		$this->$sMethod($oAlert);
+    }
+
+    protected function processAccountCheckSwitchContext(&$oAlert)
+    {
+        $iProfile = (int)$oAlert->aExtras['switch_to_profile'];
+        $oProfile = BxDolProfile::getInstance($iProfile);
+        if(!$oProfile || $oProfile->getModule() != $this->_oModule->_oConfig->getName())
+            return;
+
+        $aDataEntry = $this->_oModule->_oDb->getContentInfoById($oProfile->getContentId());
+        if(empty($aDataEntry) || !is_array($aDataEntry))
+            return;
+
+        $oAlert->aExtras['override_result'] = $oAlert->iObject == $oAlert->aExtras['viewer_account'] || $this->_oModule->_oDb->isAdmin($iProfile, $oAlert->iSender, $aDataEntry);
+    }
+}
+
+/** @} */

+ 24 - 0
modules/boonex/organizations/updates/9.0.5_9.0.6/source/classes/BxOrgsCmtsSearchResult.php

@@ -0,0 +1,24 @@
+<?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 BxOrgsCmtsSearchResult extends BxBaseModGeneralCmtsSearchResult
+{
+    function __construct($sMode = '', $aParams = array())
+    {
+    	$this->sModule = 'bx_organizations';
+
+        parent::__construct($sMode, $aParams);
+
+        $this->aCurrent['title'] = _t('_bx_orgs_page_title_browse_by_cmts');
+    }
+}
+
+/** @} */

+ 228 - 0
modules/boonex/organizations/updates/9.0.5_9.0.6/source/classes/BxOrgsConfig.php

@@ -0,0 +1,228 @@
+<?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 BxBaseModProfileConfig
+{
+    function __construct($aModule)
+    {
+        parent::__construct($aModule);
+
+        $aMenuItems2MethodsSubmenu = array (
+        	'organization-profile-subscriptions' => 'checkAllowedSubscriptionsView'
+        );
+
+        $aMenuItems2MethodsActions = array (
+            'view-organization-profile' => 'checkAllowedView',
+            'edit-organization-profile' => 'checkAllowedEdit',
+            'edit-organization-cover' => 'checkAllowedChangeCover',
+        	'invite-to-organization' => 'checkAllowedInvite',
+            'delete-organization-profile' => 'checkAllowedDelete',
+        	'profile-fan-add' => 'checkAllowedFanAdd',
+            'profile-fan-remove' => 'checkAllowedFanRemove',
+            'profile-friend-add' => 'checkAllowedFriendAdd',
+            'profile-friend-remove' => 'checkAllowedFriendRemove',
+            'profile-subscribe-add' => 'checkAllowedSubscribeAdd',
+            'profile-subscribe-remove' => 'checkAllowedSubscribeRemove',
+            'profile-actions-more' => 'checkAllowedViewMoreMenu',
+            'profile-set-acl-level' => 'checkAllowedSetMembership',
+            'convos-compose' => 'checkAllowedCompose',
+        );
+
+        $this->CNF = array (
+
+            // module icon
+            'ICON' => 'briefcase col-red2',
+
+            // database tables
+            'TABLE_ENTRIES' => $aModule['db_prefix'] . 'data',
+            'TABLE_ENTRIES_FULLTEXT' => 'search_fields',
+        	'TABLE_ADMINS' => $aModule['db_prefix'] . 'admins',
+
+            // 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_PICTURE' => 'picture',
+            'FIELD_COVER' => 'cover',
+        	'FIELD_JOIN_CONFIRMATION' => 'join_confirmation',
+            'FIELD_ALLOW_VIEW_TO' => 'allow_view_to',
+        	'FIELD_VIEWS' => 'views',
+            'FIELD_COMMENTS' => 'comments',
+            'FIELDS_QUICK_SEARCH' => array('org_name'),
+        	'FIELD_LOCATION_PREFIX' => 'location',
+            'FIELDS_WITH_KEYWORDS' => 'auto', // can be 'auto', array of fields or comma separated string of field names, works only when OBJECT_METATAGS is specified
+
+            // 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_EDIT_COVER' => 'edit-organization-cover',
+        	'URI_JOINED_ENTRIES' => 'joined-organizations',
+        	'URI_MANAGE_COMMON' => 'organizations-manage',
+
+            'URL_HOME' => 'page.php?i=organizations-home',
+        	'URL_CREATE' => 'page.php?i=create-organization-profile',
+        	'URL_MANAGE_COMMON' => 'page.php?i=organizations-manage',
+        	'URL_MANAGE_ADMINISTRATION' => 'page.php?i=organizations-administration',
+
+            // some params
+            'PARAM_AUTOAPPROVAL' => 'bx_organizations_autoapproval',
+            '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_PUBLIC_SBSN' => 'bx_organizations_public_subscriptions',
+            'PARAM_PUBLIC_SBSD' => 'bx_organizations_public_subscribed_me',
+        	'PARAM_REDIRECT_AADD' => 'bx_organizations_redirect_aadd',
+            'PARAM_REDIRECT_AADD_CUSTOM_URL' => 'bx_organizations_redirect_aadd_custom_url',
+
+            // 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_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' => '',
+        	'OBJECT_FAVORITES' => 'bx_organizations',
+        	'OBJECT_FEATURED' => 'bx_organizations',
+            'OBJECT_COMMENTS' => 'bx_organizations',
+        	'OBJECT_REPORTS' => 'bx_organizations',
+            'OBJECT_METATAGS' => 'bx_organizations',
+            '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_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_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_COVER' => 'bx_organizations_view_submenu_cover',  // view entry submenu displayed in cover
+            'OBJECT_MENU_SUBMENU_VIEW_ENTRY_MAIN_SELECTION' => 'organizations-home', // first item in view entry submenu from main module submenu
+            '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_PRIVACY_VIEW' => 'bx_organizations_allow_view_to',
+        	'OBJECT_PRIVACY_VIEW_NOTIFICATION_EVENT' => 'bx_organizations_allow_view_notification_to',
+            'OBJECT_GRID_ADMINISTRATION' => 'bx_organizations_administration',
+            'OBJECT_GRID_COMMON' => 'bx_organizations_common',
+        	'OBJECT_GRID_CONNECTIONS' => 'bx_organizations_fans',
+        	'OBJECT_CONNECTIONS' => 'bx_organizations_fans',
+            'OBJECT_UPLOADERS_COVER' => array('bx_organizations_cover_crop'),
+            'OBJECT_UPLOADERS_PICTURE' => array('bx_organizations_picture_crop'),
+
+            '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_REMOVE' => 'bx_organizations_fan_remove',
+            'EMAIL_JOIN_REJECT' => 'bx_organizations_join_reject',
+
+            'TRIGGER_MENU_PROFILE_VIEW_SUBMENU' => 'trigger_profile_view_submenu',
+            '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' => $aMenuItems2MethodsSubmenu,
+                'bx_organizations_view_actions' => $aMenuItems2MethodsActions,
+                'bx_organizations_view_actions_more' => $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_private_group' => '_bx_orgs_txt_private_organization',
+                'txt_N_fans' => '_bx_orgs_txt_N_friends',
+            	'txt_ntfs_join_request' => '_bx_orgs_txt_ntfs_join_request',
+                'txt_ntfs_fan_added' => '_bx_orgs_txt_ntfs_fan_added',
+            	'txt_ntfs_timeline_post_common' => '_bx_orgs_txt_ntfs_timeline_post_common',
+            	'txt_all_entries_by_author' => '_bx_orgs_page_title_browse_by_author',
+                '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_become_fan_sent' => '_bx_orgs_menu_item_title_become_fan_sent',
+                'menu_item_title_leave_group_cancel_request' => '_bx_orgs_menu_item_title_leave_organization_cancel_request',
+                'menu_item_title_become_fan' => '_bx_orgs_menu_item_title_become_fan',
+                'menu_item_title_leave_group' => '_bx_orgs_menu_item_title_leave_organization',
+            	'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_select_one_filter1' => '_bx_orgs_grid_filter_item_title_adm_select_one_filter1',
+            	'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'
+            ),
+        );
+
+        $this->_aJsClasses = array(
+        	'manage_tools' => 'BxOrgsManageTools'
+        );
+
+        $this->_aJsObjects = array(
+        	'manage_tools' => 'oBxOrgsManageTools'
+        );
+
+        $this->_aGridObjects = array(
+        	'common' => $this->CNF['OBJECT_GRID_COMMON'],
+        	'administration' => $this->CNF['OBJECT_GRID_ADMINISTRATION'],
+        	
+        );
+    }
+
+}
+
+/** @} */

+ 23 - 0
modules/boonex/organizations/updates/9.0.5_9.0.6/source/classes/BxOrgsDb.php

@@ -0,0 +1,23 @@
+<?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
+ *
+ * @{
+ */
+
+/*
+ * Organizations module database queries
+ */
+class BxOrgsDb extends BxBaseModGroupsDb
+{
+    public function __construct(&$oConfig)
+    {
+        parent::__construct($oConfig);
+    }
+}
+
+/** @} */

+ 24 - 0
modules/boonex/organizations/updates/9.0.5_9.0.6/source/classes/BxOrgsFormEntry.php

@@ -0,0 +1,24 @@
+<?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
+ *
+ * @{
+ */
+
+/**
+ * Create/Edit Organization Form.
+ */
+class BxOrgsFormEntry extends BxBaseModGroupsFormEntry
+{
+    public function __construct($aInfo, $oTemplate = false)
+    {
+        $this->MODULE = 'bx_organizations';
+        parent::__construct($aInfo, $oTemplate);
+    }
+}
+
+/** @} */

+ 23 - 0
modules/boonex/organizations/updates/9.0.5_9.0.6/source/classes/BxOrgsFormsEntryHelper.php

@@ -0,0 +1,23 @@
+<?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
+ *
+ * @{
+ */
+
+/**
+ * Organization profile forms functions
+ */
+class BxOrgsFormsEntryHelper extends BxBaseModGroupsFormsEntryHelper
+{
+    public function __construct($oModule)
+    {
+        parent::__construct($oModule);
+    }
+}
+
+/** @} */

+ 21 - 0
modules/boonex/organizations/updates/9.0.5_9.0.6/source/classes/BxOrgsGridAdministration.php

@@ -0,0 +1,21 @@
+<?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 BxOrgsGridAdministration extends BxBaseModGroupsGridAdministration
+{
+    public function __construct ($aOptions, $oTemplate = false)
+    {
+    	$this->MODULE = 'bx_organizations';
+        parent::__construct ($aOptions, $oTemplate);
+    }
+}
+
+/** @} */

+ 21 - 0
modules/boonex/organizations/updates/9.0.5_9.0.6/source/classes/BxOrgsGridCommon.php

@@ -0,0 +1,21 @@
+<?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 BxOrgsGridCommon extends BxBaseModGroupsGridCommon
+{
+    public function __construct ($aOptions, $oTemplate = false)
+    {
+    	$this->MODULE = 'bx_organizations';
+        parent::__construct ($aOptions, $oTemplate);
+    }
+}
+
+/** @} */

+ 21 - 0
modules/boonex/organizations/updates/9.0.5_9.0.6/source/classes/BxOrgsGridConnections.php

@@ -0,0 +1,21 @@
+<?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 BxOrgsGridConnections extends BxBaseModGroupsGridConnections
+{
+    public function __construct ($aOptions, $oTemplate = false)
+    {
+        $this->_sContentModule = 'bx_organizations';
+        parent::__construct ($aOptions, $oTemplate);
+    }
+}
+
+/** @} */

+ 24 - 0
modules/boonex/organizations/updates/9.0.5_9.0.6/source/classes/BxOrgsMenu.php

@@ -0,0 +1,24 @@
+<?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
+ * 
+ * @{
+ */
+
+/**
+ * General class for module menu.
+ */
+class BxOrgsMenu extends BxBaseModGeneralMenuView
+{
+    public function __construct($aObject, $oTemplate = false)
+    {
+        $this->MODULE = 'bx_organizations';
+        parent::__construct($aObject, $oTemplate);
+    }
+}
+
+/** @} */

+ 25 - 0
modules/boonex/organizations/updates/9.0.5_9.0.6/source/classes/BxOrgsMenuManageTools.php

@@ -0,0 +1,25 @@
+<?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
+ *
+ * @{
+ */
+
+/**
+ * 'Organizations manage tools' menu.
+ */
+class BxOrgsMenuManageTools extends BxBaseModGroupsMenuManageTools
+{
+
+    public function __construct($aObject, $oTemplate = false)
+    {
+        $this->MODULE = 'bx_organizations';
+        parent::__construct($aObject, $oTemplate);
+    }
+}
+
+/** @} */

+ 22 - 0
modules/boonex/organizations/updates/9.0.5_9.0.6/source/classes/BxOrgsMenuSnippetMeta.php

@@ -0,0 +1,22 @@
+<?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 BxOrgsMenuSnippetMeta extends BxBaseModGroupsMenuSnippetMeta
+{
+    public function __construct($aObject, $oTemplate = false)
+    {
+        $this->_sModule = 'bx_organizations';
+
+        parent::__construct($aObject, $oTemplate);
+    }
+}
+
+/** @} */

+ 25 - 0
modules/boonex/organizations/updates/9.0.5_9.0.6/source/classes/BxOrgsMenuView.php

@@ -0,0 +1,25 @@
+<?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
+ *
+ * @{
+ */
+
+/**
+ * 'View organization' menu.
+ */
+class BxOrgsMenuView extends BxBaseModGroupsMenuView
+{
+
+    public function __construct($aObject, $oTemplate = false)
+    {
+        $this->MODULE = 'bx_organizations';
+        parent::__construct($aObject, $oTemplate);
+    }
+}
+
+/** @} */

+ 49 - 0
modules/boonex/organizations/updates/9.0.5_9.0.6/source/classes/BxOrgsModule.php

@@ -0,0 +1,49 @@
+<?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
+ *
+ * @{
+ */
+
+/**
+ * Organizations profiles module.
+ */
+class BxOrgsModule extends BxBaseModGroupsModule
+{
+    function __construct(&$aModule)
+    {
+        parent::__construct($aModule);
+
+        $CNF = &$this->_oConfig->CNF;
+
+        $this->_aSearchableNamesExcept[] = $CNF['FIELD_AUTHOR'];
+        $this->_aSearchableNamesExcept[] = $CNF['FIELD_JOIN_CONFIRMATION'];
+    }
+
+	/**
+     * Check if this module entry can be used as profile
+     */
+    public function serviceActAsProfile ()
+    {
+        return true;
+    }
+
+    public function servicePrepareFields ($aFieldsProfile)
+    {
+        return parent::_servicePrepareFields($aFieldsProfile, array('org_cat' => 35), array(
+            'org_name' => 'name',
+            'org_desc' => 'description',
+        ));
+    }
+
+    public function serviceGetTimelineData()
+    {
+    	return array();
+    }
+}
+
+/** @} */

+ 24 - 0
modules/boonex/organizations/updates/9.0.5_9.0.6/source/classes/BxOrgsPageBrowse.php

@@ -0,0 +1,24 @@
+<?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
+ *
+ * @{
+ */
+
+/**
+ * Browse entries pages.
+ */
+class BxOrgsPageBrowse extends BxBaseModGroupsPageBrowse
+{
+    public function __construct($aObject, $oTemplate = false)
+    {
+        $this->MODULE = 'bx_organizations';
+        parent::__construct($aObject, $oTemplate);
+    }
+}
+
+/** @} */

+ 27 - 0
modules/boonex/organizations/updates/9.0.5_9.0.6/source/classes/BxOrgsPageEntry.php

@@ -0,0 +1,27 @@
+<?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
+ *
+ * @{
+ */
+
+/**
+ * Profile create/edit/delete pages.
+ */
+class BxOrgsPageEntry extends BxBaseModGroupsPageEntry
+{
+    public function __construct($aObject, $oTemplate = false)
+    {
+        $this->MODULE = 'bx_organizations';
+
+        parent::__construct($aObject, $oTemplate);
+
+        $this->_sCoverClass = $this->_oModule->getName() . '_cover';
+    }
+}
+
+/** @} */

+ 24 - 0
modules/boonex/organizations/updates/9.0.5_9.0.6/source/classes/BxOrgsPageJoinedEntries.php

@@ -0,0 +1,24 @@
+<?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
+ *
+ * @{
+ */
+
+/**
+ * Entries user joined to.
+ */
+class BxOrgsPageJoinedEntries extends BxBaseModGroupsPageJoinedEntries
+{
+    public function __construct($aObject, $oTemplate = false)
+    {
+        parent::__construct($aObject, $oTemplate);
+    }
+
+}
+
+/** @} */

+ 23 - 0
modules/boonex/organizations/updates/9.0.5_9.0.6/source/classes/BxOrgsPrivacy.php

@@ -0,0 +1,23 @@
+<?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 BxOrgsPrivacy extends BxBaseModGroupsPrivacy
+{
+    function __construct($aOptions, $oTemplate = false)
+    {
+    	$this->MODULE = 'bx_organizations';
+    	$this->_aPrivacyParticallyVisible = array ('c', 5);
+
+        parent::__construct($aOptions, $oTemplate);
+    }
+}
+
+/** @} */

+ 21 - 0
modules/boonex/organizations/updates/9.0.5_9.0.6/source/classes/BxOrgsPrivacyNotifications.php

@@ -0,0 +1,21 @@
+<?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 BxOrgsPrivacyNotifications extends BxBaseModGroupsPrivacyNotifications
+{
+    function __construct($aOptions, $oTemplate = false)
+    {
+    	$this->MODULE = 'bx_organizations';
+        parent::__construct($aOptions, $oTemplate);
+    }
+}
+
+/** @} */

+ 224 - 0
modules/boonex/organizations/updates/9.0.5_9.0.6/source/classes/BxOrgsSearchResult.php

@@ -0,0 +1,224 @@
+<?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 BxOrgsSearchResult extends BxBaseModGroupsSearchResult
+{
+    function __construct($sMode = '', $aParams = false)
+    {
+        parent::__construct($sMode, $aParams);
+
+        $this->sUnitTemplate = 'unit_with_cover.html';
+
+        $this->aCurrent =  array(
+            'name' => 'bx_organizations',
+            'module_name' => 'bx_organizations',
+            'object_metatags' => 'bx_organizations',
+            'title' => _t('_bx_orgs_page_title_browse'),
+            'table' => 'sys_profiles',
+            'tableSearch' => 'bx_organizations_data',
+            'ownFields' => array(),
+            'searchFields' => array(),
+            'restriction' => array(
+        		'account_id' => array('value' => '', 'field' => 'account_id', 'operator' => '='),
+                'perofileStatus' => array('value' => 'active', 'field' => 'status', 'operator' => '='),
+                'perofileType' => array('value' => 'bx_organizations', 'field' => 'type', 'operator' => '='),
+                'owner' => array('value' => '', 'field' => 'author', 'operator' => '=', 'table' => 'bx_organizations_data'),
+        		'featured' => array('value' => '', 'field' => 'featured', 'operator' => '<>', 'table' => 'bx_organizations_data'),
+        		'online' => array('value' => '', 'field' => 'date', 'operator' => '>', 'table' => 'sys_sessions'),
+            ),
+            'join' => array (
+                'profile' => array(
+                    'type' => 'INNER',
+                    'table' => 'bx_organizations_data',
+                    'mainField' => 'content_id',
+                    'onField' => 'id',
+                    'joinFields' => array('id', 'org_name', 'picture', 'cover', 'added', 'author', 'allow_view_to'),
+                ),
+                'account' => array(
+                    'type' => 'INNER',
+                    'table' => 'sys_accounts',
+                    'mainField' => 'account_id',
+                    'onField' => 'id',
+                    'joinFields' => array(),
+                ),
+            ),
+            'paginate' => array('perPage' => getParam('bx_organizations_per_page_browse'), 'start' => 0),
+            'sorting' => 'none',
+            'rss' => array(
+                'title' => '',
+                'link' => '',
+                'image' => '',
+                'profile' => 0,
+                'fields' => array (
+                    'Guid' => 'link',
+                    'Link' => 'link',
+                    'Title' => 'org_name',
+                    'DateTimeUTS' => 'added',
+                    'Desc' => 'org_name',
+                    'Picture' => 'picture',
+                ),
+            ),
+            'ident' => 'id'
+        );
+
+        $this->sFilterName = 'bx_organizations_data_filter';
+        $this->oModule = $this->getMain();
+
+        $CNF = &$this->oModule->_oConfig->CNF;
+
+        $sSearchFields = getParam($CNF['PARAM_SEARCHABLE_FIELDS']);
+        $this->aCurrent['searchFields'] = !empty($sSearchFields) ? explode(',', $sSearchFields) : '';
+
+        $oJoinedProfile = null;
+        $bProcessConditionsForPrivateContent = true;
+
+        switch ($sMode) {
+
+            case 'joined_entries':
+                $oJoinedProfile = BxDolProfile::getInstance((int)$aParams['joined_profile']);
+                if (!$oJoinedProfile) {
+                    $this->isError = true;
+                    break;
+                }
+
+                $bProcessConditionsForPrivateContent = false;
+
+                $this->aCurrent['join']['fans'] = array(
+                    'type' => 'INNER',
+                    'table' => 'bx_organizations_fans',
+                    'mainField' => 'id',
+                    'onField' => 'content',
+                    'joinFields' => array('initiator'),
+                );
+
+                $this->aCurrent['restriction']['fans'] = array('value' => $oJoinedProfile->id(), 'field' => 'initiator', 'operator' => '=', 'table' => 'bx_organizations_fans');
+
+                $this->sBrowseUrl = 'page.php?i=' . $CNF['URI_JOINED_ENTRIES'] . '&profile_id={profile_id}';
+                $this->aCurrent['title'] = _t('_bx_orgs_page_title_joined_entries');
+                $this->aCurrent['rss']['link'] = 'modules/?r=orgs/rss/' . $sMode . '/' . $oJoinedProfile->id();
+                break;
+
+            case 'connections':
+                if ($this->_setConnectionsConditions($aParams)) {
+                    $bProcessConditionsForPrivateContent = false;
+                    $oProfile = BxDolProfile::getInstance($aParams['profile']);
+                    $oProfile2 = isset($aParams['profile2']) ? BxDolProfile::getInstance($aParams['profile2']) : null;
+
+                    if (isset($aParams['type']) && $aParams['type'] == 'common' && $oProfile && $oProfile2)
+                        $this->aCurrent['title'] = _t('_bx_orgs_page_title_browse_connections_mutual', $oProfile->getDisplayName(), $oProfile2->getDisplayName());
+                    elseif ((!isset($aParams['type']) || $aParams['type'] != 'common') && $oProfile)
+                        $this->aCurrent['title'] = _t('_bx_orgs_page_title_browse_connections', $oProfile->getDisplayName());
+
+                    $this->aCurrent['rss']['link'] = 'modules/?r=orgs/rss/' . $sMode . '/' . $aParams['object'] . '/' . $aParams['type'] . '/' . (int)$aParams['profile'] . '/' . (int)$aParams['profile2'] . '/' . (int)$aParams['mutual'];
+                }
+                break;
+
+			case 'acl':
+                if ($this->_setAclConditions($aParams)) {
+					$this->aCurrent['title'] = _t('_bx_orgs_page_title_browse_by_acl', implode(', ', $this->aCurrent['title']));
+                    unset($this->aCurrent['rss']);
+                }
+                break;
+
+            case 'favorite':
+                $oProfileAuthor = null;
+                if(!$this->_setFavoriteConditions($sMode, $aParams, $oProfileAuthor)) {
+                    $this->isError = true;
+                    break;
+                }
+                break;
+
+            case 'recent':
+                $this->aCurrent['rss']['link'] = 'modules/?r=orgs/rss/' . $sMode;
+                $this->aCurrent['title'] = _t('_bx_orgs_page_title_browse_recent');
+                $this->aCurrent['sorting'] = 'last';
+                $this->sBrowseUrl = 'page.php?i=organizations-home';
+                break;
+
+            case 'featured':
+                $this->sBrowseUrl = BxDolPermalinks::getInstance()->permalink($CNF['URL_HOME']);
+                $this->aCurrent['title'] = _t('_bx_orgs_page_title_browse_featured');
+                $this->aCurrent['restriction']['featured']['value'] = '0';
+                $this->aCurrent['rss']['link'] = 'modules/?r=orgs/rss/' . $sMode;
+                $this->aCurrent['sorting'] = 'featured';
+                break;
+
+            case 'active':
+                $this->aCurrent['rss']['link'] = 'modules/?r=orgs/rss/' . $sMode;
+                $this->aCurrent['title'] = _t('_bx_orgs_page_title_browse_active');
+                $this->aCurrent['sorting'] = 'active';
+                $this->sBrowseUrl = 'page.php?i=organizations-active';
+                break;
+
+			case 'online':
+                $this->aCurrent['rss']['link'] = 'modules/?r=orgs/rss/' . $sMode;
+                $this->aCurrent['title'] = _t('_bx_orgs_page_title_browse_online');
+                $this->aCurrent['restriction']['online']['value'] = time() - 60 * (int)getParam('sys_account_online_time');
+                $this->aCurrent['restriction_sql'] = ' AND `sys_accounts`.`profile_id`=`sys_profiles`.`id`';
+                $this->aCurrent['join']['session'] = array(
+                    'type' => 'INNER',
+                    'table' => 'sys_sessions',
+                    'mainField' => 'account_id',
+                    'onField' => 'user_id',
+                    'joinFields' => array('date'),
+                    'groupTable' => $this->aCurrent['table'],
+                    'groupField' => 'id'
+                );
+                $this->aCurrent['sorting'] = 'online';
+                $this->sBrowseUrl = 'page.php?i=organizations-online';
+                break;
+
+            case '': // search results
+                $this->sBrowseUrl = BX_DOL_SEARCH_KEYWORD_PAGE;
+                $this->aCurrent['title'] = _t('_bx_orgs');
+                unset($this->aCurrent['paginate']['perPage'], $this->aCurrent['rss']);
+                break;
+
+            default:
+                $this->isError = true;
+        }
+
+        if ($bProcessConditionsForPrivateContent)
+            $this->addConditionsForPrivateContent($CNF, $oJoinedProfile);
+
+        $this->sCenterContentUnitSelector = false;
+    }
+
+    function getAlterOrder()
+    {
+        switch ($this->aCurrent['sorting']) {
+            case 'featured':
+                return array('order' => ' ORDER BY `bx_organizations_data`.`featured` DESC ');
+	        case 'none':
+	            return array('order' => ' ORDER BY `sys_accounts`.`logged` DESC ');
+			case 'active':
+	            return array('order' => ' ORDER BY `sys_accounts`.`logged` DESC ');
+			case 'online':
+	            return array('order' => ' ORDER BY `sys_sessions`.`date` DESC ');
+	        case 'last':
+	        default:                        
+	            return array('order' => ' ORDER BY `bx_organizations_data`.`added` DESC ');
+        }
+    }
+
+    function _getPseud ()
+    {
+        return array(
+            'id' => 'id',
+            'org_name' => 'org_name',
+            'added' => 'added',
+            'author' => 'author',
+            'picture' => 'picture',
+        );
+    }
+}
+
+/** @} */

+ 34 - 0
modules/boonex/organizations/updates/9.0.5_9.0.6/source/classes/BxOrgsTemplate.php

@@ -0,0 +1,34 @@
+<?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
+ *
+ * @{
+ */
+
+/*
+ * Organizations module representation.
+ */
+class BxOrgsTemplate extends BxBaseModGroupsTemplate
+{
+    function __construct(&$oConfig, &$oDb)
+    {
+        $this->MODULE = 'bx_organizations';
+
+        parent::__construct($oConfig, $oDb);
+
+        $this->_sUnitClass = 'bx-base-pofile-unit';
+        $this->_sUnitClassWithCover = 'bx-base-pofile-unit-with-cover';
+        $this->_sUnitClassWoInfo = 'bx-base-pofile-unit-wo-info';
+    }
+
+    protected function _getUnitClass($aData, $sTemplateName = 'unit.html')
+    {
+        return BxBaseModProfileTemplate::_getUnitClass($aData, $sTemplateName);
+    }
+}
+
+/** @} */

+ 21 - 0
modules/boonex/organizations/updates/9.0.5_9.0.6/source/classes/BxOrgsUploaderCoverCrop.php

@@ -0,0 +1,21 @@
+<?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 BxOrgsUploaderCoverCrop extends BxBaseModGroupsUploaderCoverCrop
+{
+    public function __construct ($aObject, $sStorageObject, $sUniqId, $oTemplate)
+    {
+        $this->_oModule = BxDolModule::getInstance('bx_organizations');
+        parent::__construct($aObject, $sStorageObject, $sUniqId, $oTemplate);
+    }
+}
+
+/** @} */

+ 21 - 0
modules/boonex/organizations/updates/9.0.5_9.0.6/source/classes/BxOrgsUploaderPictureCrop.php

@@ -0,0 +1,21 @@
+<?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 BxOrgsUploaderPictureCrop extends BxBaseModGroupsUploaderPictureCrop
+{
+    public function __construct ($aObject, $sStorageObject, $sUniqId, $oTemplate)
+    {
+        $this->_oModule = BxDolModule::getInstance('bx_organizations');
+        parent::__construct($aObject, $sStorageObject, $sUniqId, $oTemplate);
+    }
+}
+
+/** @} */

+ 148 - 0
modules/boonex/organizations/updates/9.0.5_9.0.6/source/install/config.php

@@ -0,0 +1,148 @@
+<?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' => '9.0.6',
+    'vendor' => 'BoonEx',
+	'help_url' => 'http://feed.una.io/?section={module_name}',
+
+    'compatible_with' => array(
+        '9.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'),
+    ),
+
+    /**
+     * Menu triggers.
+     */
+    'menu_triggers' => array(
+    	'trigger_profile_view_submenu',
+        '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_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_notifications',
+    ),
+);
+
+/** @} */

+ 392 - 0
modules/boonex/organizations/updates/9.0.5_9.0.6/source/install/langs/en.xml

@@ -0,0 +1,392 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources name="en" flag="gb" title="English">
+	<string name="_bx_orgs"><![CDATA[Organizations]]></string>
+	<string name="_bx_organizations"><![CDATA[Organizations]]></string>
+	<string name="_bx_orgs_cmts"><![CDATA[Organizations' Comments]]></string>
+
+	<string name="_bx_orgs_option_autoapproval"><![CDATA[Activate all organizations after creation automatically]]></string>
+	<string name="_bx_orgs_option_default_acl_level"><![CDATA[Default level to assign after organizations's profile creation]]></string>
+	<string name="_bx_orgs_option_redirect_aadd"><![CDATA[Redirect after organizations's profile creation to]]></string>
+    <string name="_bx_orgs_option_redirect_aadd_profile"><![CDATA[Profile Page]]></string>
+    <string name="_bx_orgs_option_redirect_aadd_last"><![CDATA[Last Page]]></string>
+    <string name="_bx_orgs_option_redirect_aadd_custom"><![CDATA[Custom Page]]></string>
+    <string name="_bx_orgs_option_redirect_aadd_custom_url"><![CDATA[URL for 'Custom Page' redirect]]></string>
+	<string name="_bx_orgs_option_num_connections_quick"><![CDATA[Number of items in friends block]]></string>
+	<string name="_bx_orgs_option_per_page_browse"><![CDATA[Number of items per page]]></string>
+    <string name="_bx_orgs_option_num_rss"><![CDATA[Number of items in RSS feed]]></string>
+    <string name="_bx_orgs_option_searchable_fields"><![CDATA[Searchable fields for keyword search]]></string>
+    <string name="_bx_orgs_option_public_subscriptions"><![CDATA[Public following list]]></string>
+    <string name="_bx_orgs_option_public_subscribed_me"><![CDATA[Public followers list]]></string>
+
+	<string name="_bx_orgs_form_profile"><![CDATA[Organizations]]></string>
+	<string name="_bx_orgs_form_profile_display_add"><![CDATA[Add Organization]]></string>
+	<string name="_bx_orgs_form_profile_display_edit"><![CDATA[Edit Organization]]></string>
+	<string name="_bx_orgs_form_profile_display_edit_cover"><![CDATA[Edit Cover]]></string>
+	<string name="_bx_orgs_form_profile_display_delete"><![CDATA[Delete Organization]]></string>
+	<string name="_bx_orgs_form_profile_display_view"><![CDATA[View Organization]]></string>
+	<string name="_bx_orgs_form_profile_display_view_full"><![CDATA[Full View Organization]]></string>
+	<string name="_bx_orgs_form_profile_display_invite"><![CDATA[Invite to Organization]]></string>
+    <string name="_bx_orgs_form_profile_input_sys_do_submit"><![CDATA[Submit]]></string>
+    <string name="_bx_orgs_form_profile_input_sys_join_confirm"><![CDATA[Join confirmation]]></string>
+    <string name="_bx_orgs_form_profile_input_join_confirm"><![CDATA[Join confirmation]]></string>
+    <string name="_bx_orgs_form_profile_input_sys_allow_view_to"><![CDATA[Visible to]]></string>
+    <string name="_bx_orgs_form_profile_input_allow_view_to"><![CDATA[Visible to]]></string>
+    <string name="_bx_orgs_form_profile_input_allow_view_to_info"><![CDATA[Closed - anyone can find the organization and see who's in it, only members can see posts. Secret - only members can find the organization and see posts.]]></string>
+    <string name="_bx_orgs_form_profile_input_allow_view_notification_to"><![CDATA[Show notifications to]]></string>
+    <string name="_bx_orgs_form_profile_input_sys_initial_members"><![CDATA[Invite Members]]></string>
+    <string name="_bx_orgs_form_profile_input_initial_members"><![CDATA[Invite Members]]></string>
+    <string name="_bx_orgs_form_profile_input_sys_org_name"><![CDATA[Organization Name]]></string>
+    <string name="_bx_orgs_form_profile_input_org_name"><![CDATA[Organization Name]]></string>
+    <string name="_bx_orgs_form_profile_input_org_name_err"><![CDATA[This information is essential. Please, fill in this field.]]></string>
+    <string name="_bx_orgs_form_profile_input_sys_org_desc"><![CDATA[Description]]></string>
+    <string name="_bx_orgs_form_profile_input_org_desc"><![CDATA[Description]]></string>
+    <string name="_bx_orgs_form_profile_input_sys_org_cat"><![CDATA[Category]]></string>
+	<string name="_bx_orgs_form_profile_input_org_cat"><![CDATA[Category]]></string>
+    <string name="_bx_orgs_form_profile_input_org_cat_err"><![CDATA[Category field is mandatory]]></string>
+	<string name="_bx_orgs_form_profile_input_sys_picture"><![CDATA[Profile Picture]]></string>
+	<string name="_bx_orgs_form_profile_input_picture"><![CDATA[Upload a profile picture]]></string>
+	<string name="_bx_orgs_form_profile_input_picture_err"><![CDATA[Profile picture is mandatory.]]></string>
+	<string name="_bx_orgs_form_profile_input_sys_cover"><![CDATA[Cover Picture]]></string>
+	<string name="_bx_orgs_form_profile_input_cover"><![CDATA[Upload New Cover Picture]]></string>
+	<string name="_bx_orgs_form_profile_input_sys_delete_confirm"><![CDATA[Delete confirmation]]></string>
+	<string name="_bx_orgs_form_profile_input_delete_confirm"><![CDATA[I am sure I want to delete this profile]]></string>
+	<string name="_bx_orgs_form_profile_input_delete_confirm_info"><![CDATA[This action can not be undone.]]></string>
+	<string name="_bx_orgs_form_profile_input_delete_confirm_error"><![CDATA[Please check this checkbox if you really want to delete your profile.]]></string>
+	<string name="_bx_orgs_form_profile_input_sys_profile_email"><![CDATA[Email]]></string>
+    <string name="_bx_orgs_form_profile_input_profile_email"><![CDATA[Email]]></string>
+    <string name="_bx_orgs_form_profile_input_sys_profile_status"><![CDATA[Status]]></string>
+    <string name="_bx_orgs_form_profile_input_profile_status"><![CDATA[Status]]></string>
+
+	<string name="_bx_orgs_acl_action_create_profile"><![CDATA[Create Organization's Profile]]></string>
+	<string name="_bx_orgs_acl_action_delete_profile"><![CDATA[Delete Organization's Profile]]></string>
+	<string name="_bx_orgs_acl_action_view_profile"><![CDATA[View Organization's Profile]]></string>
+	<string name="_bx_orgs_acl_action_edit_any_profile"><![CDATA[Edit Any Organization's Profile]]></string>
+
+	<string name="_bx_orgs_page_title_sys_create_profile"><![CDATA[Create a Profile - Organization]]></string>
+	<string name="_bx_orgs_page_title_create_profile"><![CDATA[Create a Profile - Organization]]></string>
+	<string name="_bx_orgs_page_title_sys_edit_profile"><![CDATA[Edit Profile]]></string>
+	<string name="_bx_orgs_page_title_edit_profile"><![CDATA[Edit Profile]]></string>
+	<string name="_bx_orgs_page_title_sys_edit_profile_cover"><![CDATA[Edit Profile Cover]]></string>
+	<string name="_bx_orgs_page_title_edit_profile_cover"><![CDATA[Edit Cover]]></string>
+	<string name="_bx_orgs_page_title_sys_delete_profile"><![CDATA[Delete Profile]]></string>
+	<string name="_bx_orgs_page_title_delete_profile"><![CDATA[Delete Profile]]></string>
+	<string name="_bx_orgs_page_title_sys_view_profile"><![CDATA[View Profile]]></string>
+	<string name="_bx_orgs_page_title_sys_view_profile_closed"><![CDATA[View Profile with Limited Visibility]]></string>
+	<string name="_bx_orgs_page_title_view_profile"><![CDATA[{display_name}]]></string>
+	<string name="_bx_orgs_page_title_browse"><![CDATA[Organizations]]></string>
+	<string name="_bx_orgs_page_title_browse_by_author"><![CDATA[Organizations of {display_name}]]></string>
+	<string name="_bx_orgs_page_title_browse_featured"><![CDATA[Featured Organizations]]></string>
+	<string name="_bx_orgs_page_title_browse_active"><![CDATA[Active Organizations]]></string>
+	<string name="_bx_orgs_page_title_browse_online"><![CDATA[Online Organizations]]></string>
+	<string name="_bx_orgs_page_title_browse_recent"><![CDATA[New Organizations]]></string>
+	<string name="_bx_orgs_page_title_browse_connections"><![CDATA[{0} connections]]></string>
+	<string name="_bx_orgs_page_title_browse_connections_mutual"><![CDATA[{0} and {1} mutual connections]]></string>
+	<string name="_bx_orgs_page_title_browse_favorites"><![CDATA[{0} favorites]]></string>
+	<string name="_bx_orgs_page_title_browse_by_acl"><![CDATA[{0} Organizations]]></string>
+	<string name="_bx_orgs_page_title_browse_by_cmts"><![CDATA[Organizations' Comments]]></string>
+	<string name="_bx_orgs_page_title_sys_profile_favorites"><![CDATA[Favorite Organizations]]></string>
+	<string name="_bx_orgs_page_title_profile_favorites"><![CDATA[Favorite Organizations]]></string>
+	<string name="_bx_orgs_page_title_sys_profile_friends"><![CDATA[Friends]]></string>
+	<string name="_bx_orgs_page_title_profile_friends"><![CDATA[Friends]]></string>
+	<string name="_bx_orgs_page_title_sys_friend_requests"><![CDATA[Friend Requests]]></string>
+    <string name="_bx_orgs_page_title_friend_requests"><![CDATA[Friend Requests]]></string>
+	<string name="_bx_orgs_page_title_sys_profile_subscriptions"><![CDATA[Following]]></string>
+    <string name="_bx_orgs_page_title_profile_subscriptions"><![CDATA[Following & Followers]]></string>
+    <string name="_bx_orgs_page_title_sys_fans"><![CDATA[Members]]></string>
+    <string name="_bx_orgs_page_title_fans"><![CDATA[Members]]></string>
+    <string name="_bx_orgs_page_title_sys_profile_comments"><![CDATA[Comments]]></string>
+    <string name="_bx_orgs_page_title_profile_comments"><![CDATA[Comments]]></string>
+	<string name="_bx_orgs_page_title_sys_profile_info"><![CDATA[Profile Info]]></string>
+	<string name="_bx_orgs_page_title_profile_info"><![CDATA[Info about {display_name}]]></string>
+	<string name="_bx_orgs_page_title_sys_recent"><![CDATA[New Organizations]]></string>
+	<string name="_bx_orgs_page_title_recent"><![CDATA[New Organizations]]></string>
+	<string name="_bx_orgs_page_title_sys_manage"><![CDATA[Manage Own Organizations]]></string>
+	<string name="_bx_orgs_page_title_sys_manage_administration"><![CDATA[Manage All Organizations]]></string>
+	<string name="_bx_orgs_page_title_manage"><![CDATA[Manage Organizations]]></string>
+	<string name="_bx_orgs_page_title_sys_active"><![CDATA[Active Organizations]]></string>
+	<string name="_bx_orgs_page_title_active"><![CDATA[Active Organizations]]></string>
+	<string name="_bx_orgs_page_title_sys_online"><![CDATA[Online Organizations]]></string>
+	<string name="_bx_orgs_page_title_online"><![CDATA[Online Organizations]]></string>
+	<string name="_bx_orgs_page_title_sys_invite_to_organization"><![CDATA[Invite Members to the Organization]]></string>
+    <string name="_bx_orgs_page_title_invite_to_organization"><![CDATA[Invite Members to the Organization]]></string>
+	<string name="_bx_orgs_page_title_sys_entries_search"><![CDATA[Search]]></string>
+    <string name="_bx_orgs_page_title_entries_search"><![CDATA[Search]]></string>
+    <string name="_bx_orgs_page_title_sys_joined_entries"><![CDATA[Joined Organizations]]></string>
+    <string name="_bx_orgs_page_title_joined_entries"><![CDATA[Joined Organizations]]></string>
+
+    <string name="_bx_orgs_page_block_title_profile_private"><![CDATA[Private Profile]]></string>
+    <string name="_bx_orgs_page_block_title_choose_type"><![CDATA[Choose Profile Type]]></string>
+	<string name="_bx_orgs_page_block_title_create_profile"><![CDATA[Create a Profile - Organization]]></string>
+	<string name="_bx_orgs_page_block_title_edit_profile"><![CDATA[Edit Profile]]></string>
+	<string name="_bx_orgs_page_block_title_edit_profile_cover"><![CDATA[Edit Cover]]></string>
+	<string name="_bx_orgs_page_block_title_delete_profile"><![CDATA[Delete Profile]]></string>
+	<string name="_bx_orgs_page_block_title_profile_all_actions"><![CDATA[All Actions]]></string>
+	<string name="_bx_orgs_page_block_title_profile_info_link"><![CDATA[About <a href="{profile_link}">{display_name}</a>]]></string>
+	<string name="_bx_orgs_page_block_title_profile_info"><![CDATA[Info]]></string>
+	<string name="_bx_orgs_page_block_title_system_profile_info"><![CDATA[Info]]></string>
+	<string name="_bx_orgs_page_block_title_profile_membership"><![CDATA[Membership]]></string>
+	<string name="_bx_orgs_page_block_title_system_profile_membership"><![CDATA[Membership]]></string>
+	<string name="_bx_orgs_page_block_title_profile_description"><![CDATA[Description]]></string>
+	<string name="_bx_orgs_page_block_title_profile_favorites"><![CDATA[Favorite Organizations]]></string>
+	<string name="_bx_orgs_page_block_title_system_profile_favorites"><![CDATA[Favorite Organizations]]></string>
+	<string name="_bx_orgs_page_block_title_profile_friends_link"><![CDATA[Friends of <a href="{profile_link}">{display_name}</a>]]></string>
+	<string name="_bx_orgs_page_block_title_profile_friends"><![CDATA[Friends]]></string>
+	<string name="_bx_orgs_page_block_title_system_profile_friends"><![CDATA[Friends]]></string>
+	<string name="_bx_orgs_page_block_title_friend_requests_link"><![CDATA[Friend Requests for <a href="{profile_link}">{display_name}</a>]]></string>
+    <string name="_bx_orgs_page_block_title_system_friend_requests"><![CDATA[Friend Requests]]></string>
+    <string name="_bx_orgs_page_block_title_admins"><![CDATA[Administrators]]></string>
+    <string name="_bx_orgs_page_block_title_fans_link"><![CDATA[Members of <a href="{profile_link}">{display_name}</a>]]></string>
+    <string name="_bx_orgs_page_block_title_fans"><![CDATA[Members]]></string>
+    <string name="_bx_orgs_page_block_title_system_fans"><![CDATA[Members]]></string>
+	<string name="_bx_orgs_page_block_title_profile_location"><![CDATA[Location]]></string>
+	<string name="_bx_orgs_page_block_title_system_profile_subscriptions"><![CDATA[Following]]></string>
+    <string name="_bx_orgs_page_block_title_profile_subscriptions"><![CDATA[Following]]></string>
+    <string name="_bx_orgs_page_block_title_system_profile_subscribed_me"><![CDATA[Followers]]></string>
+    <string name="_bx_orgs_page_block_title_profile_subscribed_me"><![CDATA[Followers]]></string>
+    <string name="_bx_orgs_page_block_title_profile_comments"><![CDATA[Comments]]></string>
+    <string name="_bx_orgs_page_block_title_profile_comments_link"><![CDATA[Comments to <a href="{entry_link}">{title}</a>]]></string>
+	<string name="_bx_orgs_page_block_title_profile_actions"><![CDATA[Actions]]></string>
+	<string name="_bx_orgs_page_block_title_featured_profiles"><![CDATA[Featured Organizations]]></string>
+	<string name="_bx_orgs_page_block_title_latest_profiles"><![CDATA[New Organizations]]></string>
+	<string name="_bx_orgs_page_block_title_system_manage"><![CDATA[Manage Own Organizations]]></string>
+	<string name="_bx_orgs_page_block_title_system_manage_administration"><![CDATA[Manage All Organizations]]></string>
+	<string name="_bx_orgs_page_block_title_manage"><![CDATA[Manage Organizations]]></string>
+    <string name="_bx_orgs_page_block_title_active_profiles"><![CDATA[Active Organizations]]></string>
+    <string name="_bx_orgs_page_block_title_online_profiles"><![CDATA[Online Organizations]]></string>
+    <string name="_bx_orgs_page_block_title_categories"><![CDATA[Organization categories]]></string>
+    <string name="_bx_orgs_page_block_title_invite_to_organization"><![CDATA[Invite Members to the Organization]]></string>
+    <string name="_bx_orgs_page_block_title_search_form"><![CDATA[Search Form]]></string>
+    <string name="_bx_orgs_page_block_title_search_results"><![CDATA[Search Results]]></string>
+    <string name="_bx_orgs_page_block_title_search_form_cmts"><![CDATA[Comments Search Form]]></string>
+    <string name="_bx_orgs_page_block_title_search_results_cmts"><![CDATA[Comments Search Results]]></string>
+    <string name="_bx_orgs_page_block_title_favorites_of_author"><![CDATA[Favorite Organizations]]></string>
+    <string name="_bx_orgs_page_block_title_sys_favorites_of_author"><![CDATA[Favorite Organizations]]></string>
+    <string name="_bx_orgs_page_block_title_sys_joined_entries"><![CDATA[Joined Organizations]]></string>
+    <string name="_bx_orgs_page_block_title_joined_entries"><![CDATA[Joined Organizations]]></string>
+    <string name="_bx_orgs_page_block_title_sys_entries_actions"><![CDATA[Organizations actions]]></string>
+    <string name="_bx_orgs_page_block_title_entries_actions"><![CDATA[Organizations actions]]></string>
+
+    <string name="_bx_orgs_menu_title_submenu"><![CDATA[Organizations Submenu]]></string>
+    <string name="_bx_orgs_menu_set_title_submenu"><![CDATA[Organizations Submenu]]></string>
+    <string name="_bx_orgs_menu_set_title_view_profile_actions"><![CDATA[Organization Actions]]></string>
+    <string name="_bx_orgs_menu_title_view_profile_actions"><![CDATA[Organization Actions]]></string>
+    <string name="_bx_orgs_menu_set_title_view_profile_actions_more"><![CDATA[Organization More Actions]]></string>
+    <string name="_bx_orgs_menu_title_view_profile_actions_more"><![CDATA[Organization More Actions]]></string>
+    <string name="_bx_orgs_menu_set_title_view_profile_submenu"><![CDATA[View Organization Submenu]]></string>
+    <string name="_bx_orgs_menu_title_view_profile_submenu"><![CDATA[View Organization Submenu]]></string>
+    <string name="_bx_orgs_menu_title_view_profile_submenu_cover"><![CDATA[Organization Cover Submenu]]></string>
+    <string name="_bx_orgs_menu_title_entries_my"><![CDATA[Profile Organizations Action Menu]]></string>
+    <string name="_bx_orgs_menu_set_title_entries_my"><![CDATA[Profile Organizations Menu]]></string>
+	<string name="_bx_orgs_menu_set_title_manage_tools"><![CDATA[Manage Tools Submenu]]></string>
+    <string name="_bx_orgs_menu_title_manage_tools"><![CDATA[Manage Tools Submenu]]></string>
+    <string name="_bx_orgs_menu_item_title_system_delete"><![CDATA[Delete]]></string>
+    <string name="_bx_orgs_menu_item_title_delete"><![CDATA[Delete]]></string>
+    <string name="_bx_orgs_menu_item_title_system_delete_with_content"><![CDATA[Delete With Content]]></string>
+    <string name="_bx_orgs_menu_item_title_delete_with_content"><![CDATA[Delete With Content]]></string>
+    <string name="_bx_orgs_menu_item_title_system_edit_cover"><![CDATA[Edit Cover]]></string>
+    <string name="_bx_orgs_menu_item_title_edit_cover"><![CDATA[Edit Cover]]></string>
+    <string name="_bx_orgs_menu_item_title_system_edit_profile"><![CDATA[Edit Organization]]></string>
+    <string name="_bx_orgs_menu_item_title_edit_profile"><![CDATA[Edit Profile]]></string>
+    <string name="_bx_orgs_menu_item_title_system_delete_profile"><![CDATA[Delete Organization]]></string>
+    <string name="_bx_orgs_menu_item_title_delete_profile"><![CDATA[Delete Profile]]></string>
+    <string name="_bx_orgs_menu_item_title_system_delete_account"><![CDATA[Delete Account]]></string>
+    <string name="_bx_orgs_menu_item_title_delete_account"><![CDATA[Delete Account]]></string>
+    <string name="_bx_orgs_menu_item_title_system_delete_account_content"><![CDATA[Delete Account with Content]]></string>
+    <string name="_bx_orgs_menu_item_title_delete_account_content"><![CDATA[Delete Account with Content]]></string>
+    <string name="_bx_orgs_menu_item_title_system_profile_type"><![CDATA[Organization]]></string>
+    <string name="_bx_orgs_menu_item_title_profile_type"><![CDATA[Organization]]></string>
+    <string name="_bx_orgs_menu_item_title_system_create_profile"><![CDATA[Organization]]></string>
+    <string name="_bx_orgs_menu_item_title_create_profile"><![CDATA[Organization]]></string>
+    <string name="_bx_orgs_menu_item_title_system_new_profile"><![CDATA[New Organization]]></string>
+    <string name="_bx_orgs_menu_item_title_new_profile"><![CDATA[New Organization]]></string>
+    <string name="_bx_orgs_menu_item_title_system_view_profile_fans"><![CDATA[Members]]></string>
+    <string name="_bx_orgs_menu_item_title_view_profile_fans"><![CDATA[Members]]></string>
+    <string name="_bx_orgs_menu_item_title_system_view_profile_friends"><![CDATA[Friends]]></string>
+    <string name="_bx_orgs_menu_item_title_view_profile_friends"><![CDATA[Friends]]></string>
+    <string name="_bx_orgs_menu_item_title_system_view_profile_subscriptions"><![CDATA[Following]]></string>
+    <string name="_bx_orgs_menu_item_title_view_profile_subscriptions"><![CDATA[Following]]></string>
+    <string name="_bx_orgs_menu_item_title_system_view_profile_comments"><![CDATA[Comments]]></string>
+    <string name="_bx_orgs_menu_item_title_view_profile_comments"><![CDATA[Comments]]></string>
+    <string name="_bx_orgs_menu_item_title_system_view_profile_info"><![CDATA[Info]]></string>
+    <string name="_bx_orgs_menu_item_title_view_profile_info"><![CDATA[Info]]></string>
+    <string name="_bx_orgs_menu_item_title_system_view_profile_view"><![CDATA[Organization]]></string>
+    <string name="_bx_orgs_menu_item_title_view_profile_view"><![CDATA[Organization]]></string>
+    <string name="_bx_orgs_menu_item_title_system_view_joined_groups"><![CDATA[Organizations]]></string>
+    <string name="_bx_orgs_menu_item_title_view_joined_groups"><![CDATA[Organizations]]></string>
+    <string name="_bx_orgs_menu_item_title_system_invite"><![CDATA[Invite]]></string>
+    <string name="_bx_orgs_menu_item_title_invite"><![CDATA[Invite]]></string>
+    <string name="_bx_orgs_menu_item_title_system_befriend"><![CDATA[Add friend]]></string>
+    <string name="_bx_orgs_menu_item_title_befriend"><![CDATA[Add friend]]></string>
+    <string name="_bx_orgs_menu_item_title_befriend_sent"><![CDATA[Add friend (requested)]]></string>
+    <string name="_bx_orgs_menu_item_title_befriend_confirm"><![CDATA[Accept friend request]]></string>
+    <string name="_bx_orgs_menu_item_title_system_unfriend"><![CDATA[Unfriend]]></string>
+    <string name="_bx_orgs_menu_item_title_unfriend"><![CDATA[Unfriend]]></string>
+    <string name="_bx_orgs_menu_item_title_unfriend_cancel_request"><![CDATA[Cancel friend request]]></string>
+    <string name="_bx_orgs_menu_item_title_unfriend_reject_request"><![CDATA[Reject friend request]]></string>
+    <string name="_bx_orgs_menu_item_title_system_become_fan"><![CDATA[Join Organization]]></string>
+    <string name="_bx_orgs_menu_item_title_become_fan"><![CDATA[Join Organization]]></string>
+    <string name="_bx_orgs_menu_item_title_become_fan_sent"><![CDATA[Join Organization (requested)]]></string>
+    <string name="_bx_orgs_menu_item_title_become_fan_confirm"><![CDATA[Accept Request]]></string>
+    <string name="_bx_orgs_menu_item_title_system_leave_organization"><![CDATA[Leave Organization]]></string>
+    <string name="_bx_orgs_menu_item_title_leave_organization"><![CDATA[Leave Organization]]></string>
+    <string name="_bx_orgs_menu_item_title_leave_organization_cancel_request"><![CDATA[Cancel Request]]></string>
+    <string name="_bx_orgs_menu_item_title_leave_organization_reject_request"><![CDATA[Reject Request]]></string>
+    <string name="_bx_orgs_menu_item_title_system_subscribe"><![CDATA[Follow]]></string>
+    <string name="_bx_orgs_menu_item_title_subscribe"><![CDATA[Follow]]></string>
+    <string name="_bx_orgs_menu_item_title_system_unsubscribe"><![CDATA[Unfollow]]></string>
+    <string name="_bx_orgs_menu_item_title_unsubscribe"><![CDATA[Unfollow]]></string>
+    <string name="_bx_orgs_menu_item_title_system_more_actions"><![CDATA[More Actions]]></string>
+    <string name="_bx_orgs_menu_item_title_more_actions"><![CDATA[]]></string>
+    <string name="_bx_orgs_menu_item_title_system_friends"><![CDATA[Friends]]></string>
+    <string name="_bx_orgs_menu_item_title_friends"><![CDATA[Friends]]></string>
+    <string name="_bx_orgs_menu_item_title_system_friend_requests"><![CDATA[Friend requests number]]></string>
+    <string name="_bx_orgs_menu_item_title_friend_requests"><![CDATA[{addon} friend requests]]></string>
+    <string name="_bx_orgs_menu_item_title_system_manage_my_organizations"><![CDATA[My organizations]]></string>
+    <string name="_bx_orgs_menu_item_title_manage_my_organizations"><![CDATA[{addon} organizations]]></string>
+    <string name="_bx_orgs_menu_item_title_system_favorites"><![CDATA[Favorite Organizations]]></string>
+    <string name="_bx_orgs_menu_item_title_favorites"><![CDATA[{addon} favorite organizations]]></string>
+    <string name="_bx_orgs_menu_item_title_system_subscriptions"><![CDATA[Following]]></string>
+    <string name="_bx_orgs_menu_item_title_subscriptions"><![CDATA[{addon} following]]></string>
+    <string name="_bx_orgs_menu_item_title_system_subscribed_me"><![CDATA[Followers]]></string>
+    <string name="_bx_orgs_menu_item_title_subscribed_me"><![CDATA[{addon} followers]]></string>
+    <string name="_bx_orgs_menu_item_title_system_entries_recent"><![CDATA[New]]></string>
+    <string name="_bx_orgs_menu_item_title_entries_recent"><![CDATA[New]]></string>
+    <string name="_bx_orgs_menu_item_title_system_entries_search"><![CDATA[Search]]></string>
+    <string name="_bx_orgs_menu_item_title_entries_search"><![CDATA[Search]]></string>
+    <string name="_bx_orgs_menu_item_title_system_entries_manage"><![CDATA[Manage]]></string>
+    <string name="_bx_orgs_menu_item_title_entries_manage"><![CDATA[Manage]]></string>
+    <string name="_bx_orgs_menu_item_title_system_entries_home"><![CDATA[Orgs]]></string>
+    <string name="_bx_orgs_menu_item_title_entries_home"><![CDATA[Orgs]]></string>
+    <string name="_bx_orgs_menu_item_title_system_admt_organizations"><![CDATA[Organizations]]></string>
+	<string name="_bx_orgs_menu_item_title_admt_organizations"><![CDATA[Organizations - {addon} unapproved]]></string>
+	<string name="_bx_orgs_menu_item_title_manage_my"><![CDATA[My Organizations]]></string>
+	<string name="_bx_orgs_menu_item_title_manage_all"><![CDATA[All Organizations]]></string>
+	<string name="_bx_orgs_menu_item_title_system_entries_active"><![CDATA[Active]]></string>
+	<string name="_bx_orgs_menu_item_title_entries_active"><![CDATA[Active]]></string>
+	<string name="_bx_orgs_menu_item_title_system_entries_online"><![CDATA[Online]]></string>
+	<string name="_bx_orgs_menu_item_title_entries_online"><![CDATA[Online]]></string>
+
+	<string name="_bx_orgs_grid_filter_item_title_adm_select_one_filter1"><![CDATA[All Statuses]]></string>
+	<string name="_bx_orgs_grid_filter_item_title_adm_active"><![CDATA[Active]]></string>
+	<string name="_bx_orgs_grid_filter_item_title_adm_pending"><![CDATA[Pending]]></string>
+	<string name="_bx_orgs_grid_filter_item_title_adm_suspended"><![CDATA[Suspended]]></string>
+	<string name="_bx_orgs_grid_column_title_adm_active"><![CDATA[Active]]></string>
+    <string name="_bx_orgs_grid_column_title_adm_fullname"><![CDATA[Name]]></string>
+    <string name="_bx_orgs_grid_column_title_adm_last_online"><![CDATA[Last Online]]></string>
+    <string name="_bx_orgs_grid_column_title_adm_account"><![CDATA[Account]]></string>
+    <string name="_bx_orgs_grid_action_title_adm_delete"><![CDATA[Delete]]></string>
+    <string name="_bx_orgs_grid_action_title_adm_delete_with_content"><![CDATA[Delete With Content]]></string>
+    <string name="_bx_orgs_grid_action_title_adm_set_acl_level"><![CDATA[Set Membership]]></string>
+    <string name="_bx_orgs_grid_action_title_adm_more_actions"><![CDATA[More Actions]]></string>
+	<string name="_bx_orgs_grid_action_err_delete"><![CDATA[Cannot delete the selected organization(s).]]></string>
+	<string name="_bx_orgs_grid_txt_account_manager"><![CDATA[Redirect to manage account.]]></string>
+
+    <string name="_bx_orgs_chart_growth"><![CDATA[Organizations: Growth]]></string>
+    <string name="_bx_orgs_chart_growth_speed"><![CDATA[Organizations: Growth Speed]]></string>
+
+    <string name="_bx_orgs_search_extended"><![CDATA[Organizations Search]]></string>
+    <string name="_bx_orgs_search_extended_cmts"><![CDATA[Organizations Comments Search]]></string>
+
+    <string name="_bx_orgs_txt_account_pending"><![CDATA[This profile is pending approval, please wait until it is activated.]]></string>
+    <string name="_bx_orgs_txt_account_pending_moderation"><![CDATA[This <a href="{0}">profile</a> is pending approval.]]></string>
+    <string name="_bx_orgs_txt_account_suspended"><![CDATA[This profile is suspended.]]></string>
+    <string name="_bx_orgs_txt_account_suspended_moderation"><![CDATA[This <a href="{0}">profile</a> is suspended.]]></string>
+
+    <string name="_bx_orgs_pre_lists_cats"><![CDATA[Organization categories]]></string>
+    <string name="_bx_orgs_cat_Agriculture"><![CDATA[Agriculture]]></string>
+    <string name="_bx_orgs_cat_Financial"><![CDATA[Financial]]></string>
+    <string name="_bx_orgs_cat_Biotech"><![CDATA[Biotech]]></string>
+    <string name="_bx_orgs_cat_Cause"><![CDATA[Cause]]></string>
+    <string name="_bx_orgs_cat_Chemical"><![CDATA[Chemical]]></string>
+    <string name="_bx_orgs_cat_Religious"><![CDATA[Religious]]></string>
+    <string name="_bx_orgs_cat_Community"><![CDATA[Community]]></string>
+    <string name="_bx_orgs_cat_Company"><![CDATA[Company]]></string>
+    <string name="_bx_orgs_cat_Entertainment"><![CDATA[Entertainment]]></string>
+    <string name="_bx_orgs_cat_Technology"><![CDATA[Technology]]></string>
+    <string name="_bx_orgs_cat_Consulting"><![CDATA[Consulting]]></string>
+    <string name="_bx_orgs_cat_Education"><![CDATA[Education]]></string>
+    <string name="_bx_orgs_cat_Energy"><![CDATA[Energy]]></string>
+    <string name="_bx_orgs_cat_Engineering"><![CDATA[Engineering]]></string>
+    <string name="_bx_orgs_cat_Food"><![CDATA[Food]]></string>
+    <string name="_bx_orgs_cat_Government"><![CDATA[Government]]></string>
+    <string name="_bx_orgs_cat_Health"><![CDATA[Health]]></string>
+    <string name="_bx_orgs_cat_Medical"><![CDATA[Medical]]></string>
+    <string name="_bx_orgs_cat_Industrial"><![CDATA[Industrial]]></string>
+    <string name="_bx_orgs_cat_Insurance"><![CDATA[Insurance]]></string>
+    <string name="_bx_orgs_cat_Internet"><![CDATA[Internet]]></string>
+    <string name="_bx_orgs_cat_Software"><![CDATA[Software]]></string>
+    <string name="_bx_orgs_cat_Legal"><![CDATA[Legal]]></string>
+    <string name="_bx_orgs_cat_Media"><![CDATA[Media]]></string>
+    <string name="_bx_orgs_cat_School"><![CDATA[School]]></string>
+    <string name="_bx_orgs_cat_NGO"><![CDATA[NGO]]></string>
+    <string name="_bx_orgs_cat_NPO"><![CDATA[NPO]]></string>
+    <string name="_bx_orgs_cat_Political"><![CDATA[Political]]></string>
+    <string name="_bx_orgs_cat_Retail"><![CDATA[Retail]]></string>
+    <string name="_bx_orgs_cat_Small_Business"><![CDATA[Small Business]]></string>
+    <string name="_bx_orgs_cat_Telecommunication"><![CDATA[Telecommunication]]></string>
+    <string name="_bx_orgs_cat_Transport"><![CDATA[Transport]]></string>
+    <string name="_bx_orgs_cat_Travel"><![CDATA[Travel]]></string>
+    <string name="_bx_orgs_cat_University"><![CDATA[University]]></string>
+    <string name="_bx_orgs_cat_Other"><![CDATA[Other]]></string>
+
+    <string name="_bx_organizations_alert_action_fan_added"><![CDATA[member joined]]></string>
+    <string name="_bx_organizations_alert_action_join_request"><![CDATA[join request]]></string>
+    <string name="_bx_orgs_txt_ntfs_fan_added"><![CDATA[Organization <b class="bx-ntfs-content-profile">{owner_name}</b> has got a member <b class="bx-ntfs-content-entry">{subentry_sample}</b>]]></string>
+    <string name="_bx_orgs_txt_ntfs_join_request"><![CDATA[Organization <b class="bx-ntfs-content-profile">{owner_name}</b> has a join request from <b class="bx-ntfs-content-entry">{subentry_sample}</b>]]></string>
+    <string name="_bx_orgs_txt_ntfs_timeline_post_common"><![CDATA[New post <b class="bx-ntfs-content-entry">{subentry_sample}</b> in <b class="bx-ntfs-content-profile">{owner_name}</b> organization timeline]]></string>
+
+    <string name="_bx_orgs_txt_sample_single"><![CDATA[organization]]></string>
+    <string name="_bx_orgs_txt_sample_comment_single"><![CDATA[comment to organization]]></string>
+    <string name="_bx_orgs_txt_N_friends"><![CDATA[{0} friends]]></string>
+    <string name="_bx_orgs_txt_to_admins"><![CDATA[To Admins]]></string>
+    <string name="_bx_orgs_txt_from_admins"><![CDATA[From Admins]]></string>
+    <string name="_bx_orgs_txt_private_organization"><![CDATA[Private organization]]></string>
+
+    <string name="_bx_orgs_email_friend_request"><![CDATA[Friend request]]></string>
+    <string name="_bx_orgs_email_friend_request_subject"><![CDATA[Friendship Request]]></string>
+    <string name="_bx_orgs_email_friend_request_body"><![CDATA[{email_header}
+<p><a href="{SenderUrl}">{SenderDisplayName}</a> wants to be friends with you. <a href="{FriendsLink}">Respond</a>.</p>
+{email_footer}]]></string>
+
+    <string name="_bx_orgs_email_join_request"><![CDATA[Organization join request]]></string>
+    <string name="_bx_orgs_email_join_request_subject"><![CDATA[Request to join your organization]]></string>
+    <string name="_bx_orgs_email_join_request_body"><![CDATA[{email_header}
+<p>New request to join <a href="{EntryUrl}">{EntryTitle}</a> organization from <a href="{NewMemberUrl}">{NewMemberDisplayName}</a></p>
+{email_footer}]]></string>
+
+    <string name="_bx_orgs_email_join_reject"><![CDATA[Organization join request was rejected]]></string>
+    <string name="_bx_orgs_email_join_reject_subject"><![CDATA[Request to join an organization was rejected]]></string>
+    <string name="_bx_orgs_email_join_reject_body"><![CDATA[{email_header}
+<p>Your request to join <a href="{EntryUrl}">{EntryTitle}</a> organization was rejected by the organization admin.</p>
+{email_footer}]]></string>
+
+    <string name="_bx_orgs_email_join_confirm"><![CDATA[Organization join request was confirmed]]></string>
+    <string name="_bx_orgs_email_join_confirm_subject"><![CDATA[Your request to join an organization was confirmed]]></string>
+    <string name="_bx_orgs_email_join_confirm_body"><![CDATA[{email_header}
+<p>Your request to join <a href="{EntryUrl}">{EntryTitle}</a> organization was confirmed by the organization admin.</p>
+{email_footer}]]></string>
+
+    <string name="_bx_orgs_email_fan_remove"><![CDATA[Profile was removed from organization members]]></string>
+    <string name="_bx_orgs_email_fan_remove_subject"><![CDATA[Your profile was removed from the organization]]></string>
+    <string name="_bx_orgs_email_fan_remove_body"><![CDATA[{email_header}
+<p>Your profile was removed from <a href="{EntryUrl}">{EntryTitle}</a> organization by the organization admin.</p>
+{email_footer}]]></string>
+
+    <string name="_bx_orgs_email_fan_become_admin"><![CDATA[Organization admin status was granted]]></string>
+    <string name="_bx_orgs_email_fan_become_admin_subject"><![CDATA[You are an organization admin now]]></string>
+    <string name="_bx_orgs_email_fan_become_admin_body"><![CDATA[{email_header}
+<p>You are an admin of <a href="{EntryUrl}">{EntryTitle}</a> organization now.</p>
+{email_footer}]]></string>
+
+    <string name="_bx_orgs_email_admin_become_fan"><![CDATA[Organization admin status was revoked]]></string>
+    <string name="_bx_orgs_email_admin_become_fan_subject"><![CDATA[Your organization admin status was revoked]]></string>
+    <string name="_bx_orgs_email_admin_become_fan_body"><![CDATA[{email_header}
+<p>Your admin status was revoked from <a href="{EntryUrl}">{EntryTitle}</a> organization.</p>
+{email_footer}]]></string>
+
+    <string name="_bx_orgs_email_invitation"><![CDATA[Invitation to organization]]></string>
+    <string name="_bx_orgs_email_invitation_subject"><![CDATA[Invitation to "{EntryTitle}" organization]]></string>
+    <string name="_bx_orgs_email_invitation_body"><![CDATA[{email_header}
+<p><a href="{InviterUrl}">{InviterDisplayName}</a> invited you to <a href="{EntryUrl}">{EntryTitle}</a> organization.</p>
+{email_footer}]]></string>
+</resources>

+ 75 - 0
modules/boonex/organizations/updates/9.0.5_9.0.6/source/install/sql/disable.sql

@@ -0,0 +1,75 @@
+
+-- SETTINGS
+SET @iTypeId = (SELECT `ID` FROM `sys_options_types` WHERE `name` = 'bx_organizations' LIMIT 1);
+SET @iCategId = (SELECT `ID` FROM `sys_options_categories` WHERE `type_id` = @iTypeId LIMIT 1);
+DELETE FROM `sys_options` WHERE `category_id` = @iCategId;
+DELETE FROM `sys_options_categories` WHERE `type_id` = @iTypeId;
+DELETE FROM `sys_options_types` WHERE `id` = @iTypeId;
+
+-- PAGES
+DELETE FROM `sys_objects_page` WHERE `module` = 'bx_organizations';
+DELETE FROM `sys_pages_blocks` WHERE `module` = 'bx_organizations' OR `object` IN('bx_organizations_create_profile', 'bx_organizations_delete_profile', 'bx_organizations_edit_profile', 'bx_organizations_edit_profile_cover', 'bx_organizations_invite', 'bx_organizations_view_profile', 'bx_organizations_view_profile_closed', 'bx_organizations_profile_info', 'bx_organizations_fans', 'bx_organizations_profile_friends', 'bx_organizations_friend_requests', 'bx_organizations_profile_favorites', 'bx_organizations_profile_subscriptions', 'bx_organizations_profile_comments', 'bx_organizations_home', 'bx_organizations_search', 'bx_organizations_manage', 'bx_organizations_joined');
+
+-- MENU
+DELETE FROM `sys_objects_menu` WHERE `module` = 'bx_organizations';
+DELETE FROM `sys_menu_sets` WHERE `module` = 'bx_organizations';
+DELETE FROM `sys_menu_items` WHERE `module` = 'bx_organizations' OR `set_name` IN('bx_organizations_view_submenu', 'bx_organizations_submenu', 'bx_organizations_view_actions', 'bx_organizations_view_actions_more', 'bx_organizations_my', 'bx_organizations_snippet_meta', 'bx_organizations_menu_manage_tools');
+
+-- ACL
+DELETE `sys_acl_actions`, `sys_acl_matrix` FROM `sys_acl_actions`, `sys_acl_matrix` WHERE `sys_acl_matrix`.`IDAction` = `sys_acl_actions`.`ID` AND `sys_acl_actions`.`Module` = 'bx_organizations';
+DELETE FROM `sys_acl_actions` WHERE `Module` = 'bx_organizations';
+
+-- COMMENTS
+DELETE FROM `sys_objects_cmts` WHERE `Name` = 'bx_organizations';
+
+-- VIEWS
+DELETE FROM `sys_objects_view` WHERE `name` = 'bx_organizations';
+
+-- REPORTS
+DELETE FROM `sys_objects_report` WHERE `name` = 'bx_organizations';
+
+-- FAFORITES
+DELETE FROM `sys_objects_favorite` WHERE `name` = 'bx_organizations';
+
+-- FEATURED
+DELETE FROM `sys_objects_feature` WHERE `name` = 'bx_organizations';
+
+-- METATAGS
+DELETE FROM `sys_objects_metatags` WHERE `object` = 'bx_organizations';
+
+-- CATEGORY
+DELETE FROM `sys_objects_category` WHERE `object` = 'bx_organizations_cats';
+
+-- SEARCH
+DELETE FROM `sys_objects_search` WHERE `ObjectName` IN ('bx_organizations', 'bx_organizations_cmts');
+
+-- CONNECTIONS
+DELETE FROM `sys_objects_connection` WHERE `object` = 'bx_organizations_fans';
+
+-- STATS
+DELETE FROM `sys_statistics` WHERE `name` LIKE 'bx_organizations%';
+
+-- CHARTS
+DELETE FROM `sys_objects_chart` WHERE `object` LIKE 'bx_organizations%';
+
+-- GRIDS
+DELETE FROM `sys_objects_grid` WHERE `object` LIKE 'bx_organizations%';
+DELETE FROM `sys_grid_fields` WHERE `object` LIKE 'bx_organizations%';
+DELETE FROM `sys_grid_actions` WHERE `object` LIKE 'bx_organizations%';
+
+-- LIVE UPDATES
+DELETE FROM `sys_objects_live_updates` WHERE `name` = 'bx_organizations_friend_requests';
+
+-- ALERTS
+SET @iHandler := (SELECT `id` FROM `sys_alerts_handlers` WHERE `name` = 'bx_organizations' LIMIT 1);
+DELETE FROM `sys_alerts` WHERE `handler_id` = @iHandler;
+DELETE FROM `sys_alerts_handlers` WHERE `id` = @iHandler;
+
+-- PRIVACY 
+DELETE FROM `sys_objects_privacy` WHERE `object` IN('bx_organizations_allow_view_to', 'bx_organizations_allow_view_notification_to');
+
+-- EMAIL TEMPLATES
+DELETE FROM `sys_email_templates` WHERE `Module` = 'bx_organizations';
+
+-- UPLOADERS
+DELETE FROM `sys_objects_uploader` WHERE `object` IN('bx_organizations_cover_crop', 'bx_organizations_picture_crop');

+ 579 - 0
modules/boonex/organizations/updates/9.0.5_9.0.6/source/install/sql/enable.sql

@@ -0,0 +1,579 @@
+
+-- 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_organizations', '_bx_orgs', 'bx_organizations@modules/boonex/organizations/|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_organizations', '_bx_orgs', 1);
+SET @iCategId = LAST_INSERT_ID();
+
+INSERT INTO `sys_options` (`name`, `value`, `category_id`, `caption`, `type`, `extra`, `check`, `check_error`, `order`) VALUES
+('bx_organizations_autoapproval', 'on', @iCategId, '_bx_orgs_option_autoapproval', 'checkbox', '', '', '', 1),
+('bx_organizations_default_acl_level', '3', @iCategId, '_bx_orgs_option_default_acl_level', 'select', 'a:4:{s:6:"module";s:6:"system";s:6:"method";s:15:"get_memberships";s:6:"params";a:2:{i:0;b:0;i:1;b:1;}s:5:"class";s:16:"TemplAclServices";}', '', '', 2),
+('bx_organizations_redirect_aadd', 'profile', @iCategId, '_bx_orgs_option_redirect_aadd', 'select', 'a:2:{s:6:"module";s:16:"bx_organizations";s:6:"method";s:30:"get_options_redirect_after_add";}', '', '', 3),
+('bx_organizations_redirect_aadd_custom_url', '', @iCategId, '_bx_orgs_option_redirect_aadd_custom_url', 'digit', '', '', '', 4),
+('bx_organizations_num_connections_quick', '4', @iCategId, '_bx_orgs_option_num_connections_quick', 'digit', '', '', '', 10),
+('bx_organizations_per_page_browse', '20', @iCategId, '_bx_orgs_option_per_page_browse', 'digit', '', '', '', 11),
+('bx_organizations_num_rss', '10', @iCategId, '_bx_orgs_option_num_rss', 'digit', '', '', '', 12),
+('bx_organizations_searchable_fields', 'org_name,org_desc', @iCategId, '_bx_orgs_option_searchable_fields', 'list', 'a:2:{s:6:"module";s:16:"bx_organizations";s:6:"method";s:21:"get_searchable_fields";}', '', '', 20),
+('bx_organizations_public_subscriptions', '', @iCategId, '_bx_orgs_option_public_subscriptions', 'checkbox', '', '', '', 30),
+('bx_organizations_public_subscribed_me', '', @iCategId, '_bx_orgs_option_public_subscribed_me', 'checkbox', '', '', '', 31);
+
+-- PAGES
+
+-- PAGE: create profile
+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_organizations_create_profile', 'create-organization-profile', '_bx_orgs_page_title_sys_create_profile', '_bx_orgs_page_title_create_profile', 'bx_organizations', 5, 2147483647, 1, 'page.php?i=create-organization-profile', '', '', '', 0, 1, 0, '', '');
+
+INSERT INTO `sys_pages_blocks`(`object`, `cell_id`, `module`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `active`, `order`) VALUES
+('bx_organizations_create_profile', 1, 'bx_organizations', '_bx_orgs_page_block_title_choose_type', 11, 2147483647, 'menu', 'sys_add_profile_vertical', 0, 1, 0, 0),
+('bx_organizations_create_profile', 1, 'bx_organizations', '_bx_orgs_page_block_title_create_profile', 11, 2147483647, 'service', 'a:2:{s:6:\"module\";s:16:\"bx_organizations\";s:6:\"method\";s:13:\"entity_create\";}', 0, 1, 1, 1);
+
+-- PAGE: view profile
+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_organizations_view_profile', 'view-organization-profile', '_bx_orgs_page_title_sys_view_profile', '_bx_orgs_page_title_view_profile', 'bx_organizations', 7, 2147483647, 1, 'page.php?i=view-organization-profile', '', '', '', 0, 1, 0, 'BxOrgsPageEntry', 'modules/boonex/organizations/classes/BxOrgsPageEntry.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_organizations_view_profile', 2, 'bx_organizations', '', '_bx_orgs_page_block_title_profile_subscriptions', 11, 2147483647, 'service', 'a:2:{s:6:\"module\";s:16:\"bx_organizations\";s:6:\"method\";s:21:\"profile_subscriptions\";}', 0, 1, 0, 0),
+('bx_organizations_view_profile', 2, 'bx_organizations', '', '_bx_orgs_page_block_title_profile_subscribed_me', 11, 2147483647, 'service', 'a:2:{s:6:\"module\";s:16:\"bx_organizations\";s:6:\"method\";s:21:\"profile_subscribed_me\";}', 0, 1, 0, 0),
+('bx_organizations_view_profile', 2, 'bx_organizations', '', '_bx_orgs_page_block_title_profile_comments', 11, 2147483647, 'service', 'a:2:{s:6:\"module\";s:16:\"bx_organizations\";s:6:\"method\";s:15:\"entity_comments\";}', 0, 0, 0, 0),
+('bx_organizations_view_profile', 2, 'bx_organizations', '', '_bx_orgs_page_block_title_profile_description', 13, 2147483647, 'service', 'a:2:{s:6:\"module\";s:16:\"bx_organizations\";s:6:\"method\";s:17:\"entity_text_block\";}', 0, 0, 1, 1),
+('bx_organizations_view_profile', 2, 'bx_organizations', '', '_bx_orgs_page_block_title_fans', 11, 2147483647, 'service', 'a:2:{s:6:\"module\";s:16:\"bx_organizations\";s:6:\"method\";s:4:\"fans\";}', 0, 0, 1, 2),
+('bx_organizations_view_profile', 2, 'bx_organizations', '', '_bx_orgs_page_block_title_profile_friends', 11, 2147483647, 'service', 'a:2:{s:6:\"module\";s:16:\"bx_organizations\";s:6:\"method\";s:15:\"profile_friends\";}', 0, 1, 1, 3),
+('bx_organizations_view_profile', 3, 'bx_organizations', '', '_bx_orgs_page_block_title_profile_location', 13, 2147483647, 'service', 'a:2:{s:6:\"module\";s:16:\"bx_organizations\";s:6:\"method\";s:15:\"entity_location\";}', 0, 0, 0, 0),
+('bx_organizations_view_profile', 3, 'bx_organizations', '', '_bx_orgs_page_block_title_profile_info', 11, 2147483647, 'service', 'a:2:{s:6:\"module\";s:16:\"bx_organizations\";s:6:\"method\";s:11:\"entity_info\";}', 0, 0, 1, 0),
+('bx_organizations_view_profile', 3, 'bx_organizations', '', '_bx_orgs_page_block_title_profile_all_actions', 13, 2147483647, 'service', 'a:2:{s:6:"module";s:16:"bx_organizations";s:6:"method";s:18:"entity_all_actions";}', 0, 0, 1, 1),
+('bx_organizations_view_profile', 3, 'bx_organizations', '', '_bx_orgs_page_block_title_profile_membership', 11, 2147483647, 'service', 'a:2:{s:6:\"module\";s:16:\"bx_organizations\";s:6:\"method\";s:18:\"profile_membership\";}', 0, 0, 1, 2),
+('bx_organizations_view_profile', 3, 'bx_organizations', '', '_bx_orgs_page_block_title_admins', 11, 2147483647, 'service', 'a:2:{s:6:\"module\";s:16:\"bx_organizations\";s:6:\"method\";s:6:\"admins\";}', 0, 0, 1, 3),
+('bx_organizations_view_profile', 3, 'bx_organizations', '', '_bx_orgs_page_block_title_profile_location', 3, 2147483647, 'service', 'a:4:{s:6:\"module\";s:6:\"system\";s:6:\"method\";s:13:\"locations_map\";s:6:\"params\";a:2:{i:0;s:16:\"bx_organizations\";i:1;s:12:\"{content_id}\";}s:5:\"class\";s:20:\"TemplServiceMetatags\";}', 0, 0, 1, 4);
+
+-- PAGE: view closed profile 
+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_organizations_view_profile_closed', 'view-organization-profile-closed', '_bx_orgs_page_title_sys_view_profile_closed', '_bx_orgs_page_title_view_profile', 'bx_organizations', 10, 2147483647, 1, 'page.php?i=view-organization-profile', '', '', '', 0, 1, 0, 'BxOrgsPageEntry', 'modules/boonex/organizations/classes/BxOrgsPageEntry.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_organizations_view_profile_closed', 2, 'bx_organizations', '', '_bx_orgs_page_block_title_profile_info', 11, 2147483647, 'service', 'a:2:{s:6:\"module\";s:16:\"bx_organizations\";s:6:\"method\";s:11:\"entity_info\";}', 0, 0, 1, 0),
+('bx_organizations_view_profile_closed', 3, 'bx_organizations', '', '_bx_orgs_page_block_title_fans', 11, 2147483647, 'service', 'a:2:{s:6:\"module\";s:16:\"bx_organizations\";s:6:\"method\";s:4:\"fans\";}', 0, 0, 1, 0);
+
+-- PAGE: edit profile
+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_organizations_edit_profile', 'edit-organization-profile', '_bx_orgs_page_title_sys_edit_profile', '_bx_orgs_page_title_edit_profile', 'bx_organizations', 5, 2147483647, 1, 'page.php?i=edit-organization-profile', '', '', '', 0, 1, 0, 'BxOrgsPageEntry', 'modules/boonex/organizations/classes/BxOrgsPageEntry.php');
+
+INSERT INTO `sys_pages_blocks`(`object`, `cell_id`, `module`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `order`) VALUES 
+('bx_organizations_edit_profile', 1, 'bx_organizations', '_bx_orgs_page_block_title_edit_profile', 11, 2147483647, 'service', 'a:2:{s:6:\"module\";s:16:\"bx_organizations\";s:6:\"method\";s:11:\"entity_edit\";}', 0, 0, 0);
+
+-- PAGE: edit profile cover
+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_organizations_edit_profile_cover', 'edit-organization-cover', '_bx_orgs_page_title_sys_edit_profile_cover', '_bx_orgs_page_title_edit_profile_cover', 'bx_organizations', 5, 2147483647, 1, 'page.php?i=edit-organization-cover', '', '', '', 0, 1, 0, 'BxOrgsPageEntry', 'modules/boonex/organizations/classes/BxOrgsPageEntry.php');
+
+INSERT INTO `sys_pages_blocks`(`object`, `cell_id`, `module`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `order`) VALUES 
+('bx_organizations_edit_profile_cover', 1, 'bx_organizations', '_bx_orgs_page_block_title_edit_profile_cover', 11, 2147483647, 'service', 'a:2:{s:6:\"module\";s:16:\"bx_organizations\";s:6:\"method\";s:17:\"entity_edit_cover\";}', 0, 0, 0);
+
+-- PAGE: invite members
+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_organizations_invite', 'invite-to-organization', '_bx_orgs_page_title_sys_invite_to_organization', '_bx_orgs_page_title_invite_to_organization', 'bx_organizations', 5, 2147483647, 1, 'page.php?i=invite-to-organization', '', '', '', 0, 1, 0, 'BxOrgsPageEntry', 'modules/boonex/organizations/classes/BxOrgsPageEntry.php');
+
+INSERT INTO `sys_pages_blocks`(`object`, `cell_id`, `module`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `order`) VALUES 
+('bx_organizations_invite', 1, 'bx_organizations', '_bx_orgs_page_block_title_invite_to_organization', 11, 2147483647, 'service', 'a:2:{s:6:\"module\";s:16:\"bx_organizations\";s:6:\"method\";s:13:\"entity_invite\";}', 0, 0, 0);
+
+-- PAGE: delete profile
+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_organizations_delete_profile', 'delete-organization-profile', '_bx_orgs_page_title_sys_delete_profile', '_bx_orgs_page_title_delete_profile', 'bx_organizations', 5, 2147483647, 1, 'page.php?i=delete-organization-profile', '', '', '', 0, 1, 0, 'BxOrgsPageEntry', 'modules/boonex/organizations/classes/BxOrgsPageEntry.php');
+
+INSERT INTO `sys_pages_blocks`(`object`, `cell_id`, `module`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `order`) VALUES 
+('bx_organizations_delete_profile', 1, 'bx_organizations', '_bx_orgs_page_block_title_delete_profile', 11, 2147483647, 'service', 'a:2:{s:6:\"module\";s:16:\"bx_organizations\";s:6:\"method\";s:13:\"entity_delete\";}', 0, 0, 0);
+
+-- PAGE: profile info
+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_organizations_profile_info', 'organization-profile-info', '_bx_orgs_page_title_sys_profile_info', '_bx_orgs_page_title_profile_info', 'bx_organizations', 5, 2147483647, 1, 'page.php?i=organization-profile-info', '', '', '', 0, 1, 0, 'BxOrgsPageEntry', 'modules/boonex/organizations/classes/BxOrgsPageEntry.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_organizations_profile_info', 1, 'bx_organizations', '_bx_orgs_page_block_title_system_profile_info', '_bx_orgs_page_block_title_profile_info_link', 11, 2147483647, 'service', 'a:2:{s:6:\"module\";s:16:\"bx_organizations\";s:6:\"method\";s:16:\"entity_info_full\";}', 0, 0, 1, 1),
+('bx_organizations_profile_info', 1, 'bx_organizations', '', '_bx_orgs_page_block_title_profile_description', 13, 2147483647, 'service', 'a:2:{s:6:\"module\";s:16:\"bx_organizations\";s:6:\"method\";s:17:\"entity_text_block\";}', 0, 0, 1, 2);
+
+-- PAGE: group fans
+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_organizations_fans', 'organization-profile-fans', '_bx_orgs_page_title_sys_fans', '_bx_orgs_page_title_fans', 'bx_organizations', 5, 2147483647, 1, 'page.php?i=organization-profile-fans', '', '', '', 0, 1, 0, 'BxOrgsPageEntry', 'modules/boonex/organizations/classes/BxOrgsPageEntry.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_organizations_fans', 1, 'bx_organizations', '_bx_orgs_page_block_title_system_fans', '_bx_orgs_page_block_title_fans_link', 11, 2147483647, 'service', 'a:2:{s:6:"module";s:16:"bx_organizations";s:6:"method";s:10:"fans_table";}', 0, 0, 1, 1);
+
+-- PAGE: profile friends
+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_organizations_profile_friends', 'organization-profile-friends', '_bx_orgs_page_title_sys_profile_friends', '_bx_orgs_page_title_profile_friends', 'bx_organizations', 5, 2147483647, 1, 'page.php?i=organization-profile-friends', '', '', '', 0, 1, 0, 'BxOrgsPageEntry', 'modules/boonex/organizations/classes/BxOrgsPageEntry.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_organizations_profile_friends', 1, 'bx_organizations', '_bx_orgs_page_block_title_system_profile_friends', '_bx_orgs_page_block_title_profile_friends_link', 11, 2147483647, 'service', 'a:3:{s:6:\"module\";s:6:\"system\";s:6:\"method\";s:17:\"connections_table\";s:5:\"class\";s:23:\"TemplServiceConnections\";}', 0, 0, 1, 1);
+
+-- PAGE: profile friend requests
+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_organizations_friend_requests', 'organization-friend-requests', '_bx_orgs_page_title_sys_friend_requests', '_bx_orgs_page_title_friend_requests', 'bx_organizations', 5, 2147483647, 1, 'page.php?i=organization-friend-requests', '', '', '', 0, 1, 0, 'BxOrgsPageEntry', 'modules/boonex/organizations/classes/BxOrgsPageEntry.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_organizations_friend_requests', 1, 'bx_organizations', '_bx_orgs_page_block_title_system_friend_requests', '_bx_orgs_page_block_title_friend_requests_link', 11, 2147483647, 'service', 'a:3:{s:6:\"module\";s:6:\"system\";s:6:\"method\";s:25:\"connections_request_table\";s:5:\"class\";s:23:\"TemplServiceConnections\";}', 0, 0, 1, 1);
+
+-- PAGE: profile favorites
+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_organizations_profile_favorites', 'organization-profile-favorites', '_bx_orgs_page_title_sys_profile_favorites', '_bx_orgs_page_title_profile_favorites', 'bx_organizations', 5, 2147483647, 1, 'page.php?i=organization-profile-favorites', '', '', '', 0, 1, 0, 'BxOrgsPageBrowse', 'modules/boonex/organizations/classes/BxOrgsPageBrowse.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_organizations_profile_favorites', 1, 'bx_organizations', '_bx_orgs_page_block_title_system_profile_favorites', '_bx_orgs_page_block_title_profile_favorites', 11, 2147483647, 'service', 'a:2:{s:6:"module";s:16:"bx_organizations";s:6:"method";s:15:"browse_favorite";}', 0, 1, 1, 1);
+
+-- PAGE: profile subscriptions
+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_organizations_profile_subscriptions', 'organization-profile-subscriptions', '_bx_orgs_page_title_sys_profile_subscriptions', '_bx_orgs_page_title_profile_subscriptions', 'bx_organizations', 5, 2147483647, 1, 'page.php?i=organization-profile-subscriptions', '', '', '', 0, 1, 0, 'BxOrgsPageEntry', 'modules/boonex/organizations/classes/BxOrgsPageEntry.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_organizations_profile_subscriptions', 1, 'bx_organizations', '_bx_orgs_page_block_title_system_profile_subscriptions', '_bx_orgs_page_block_title_profile_subscriptions', 11, 2147483647, 'service', 'a:3:{s:6:\"module\";s:6:\"system\";s:6:\"method\";s:19:\"subscriptions_table\";s:5:\"class\";s:23:\"TemplServiceConnections\";}', 0, 0, 1, 1),
+('bx_organizations_profile_subscriptions', 1, 'bx_organizations', '_bx_orgs_page_block_title_system_profile_subscribed_me', '_bx_orgs_page_block_title_profile_subscribed_me', 11, 2147483647, 'service', 'a:3:{s:6:\"module\";s:6:\"system\";s:6:\"method\";s:19:\"subscribed_me_table\";s:5:\"class\";s:23:\"TemplServiceConnections\";}', 0, 0, 1, 2);
+
+-- PAGE: view entry comments
+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_organizations_profile_comments', '_bx_orgs_page_title_sys_profile_comments', '_bx_orgs_page_title_profile_comments', 'bx_organizations', 5, 2147483647, 1, 'organization-profile-comments', '', '', '', '', 0, 1, 0, 'BxOrgsPageEntry', 'modules/boonex/organizations/classes/BxOrgsPageEntry.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_organizations_profile_comments', 1, 'bx_organizations', '_bx_orgs_page_block_title_profile_comments', '_bx_orgs_page_block_title_profile_comments_link', 11, 2147483647, 'service', 'a:2:{s:6:\"module\";s:16:\"bx_organizations\";s:6:\"method\";s:15:\"entity_comments\";}', 0, 0, 0, 1);
+
+-- PAGE: module home
+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_organizations_home', '_bx_orgs_page_title_sys_recent', '_bx_orgs_page_title_recent', 'bx_organizations', 5, 2147483647, 1, 'organizations-home', 'page.php?i=organizations-home', '', '', '', 0, 1, 0, 'BxOrgsPageBrowse', 'modules/boonex/organizations/classes/BxOrgsPageBrowse.php');
+
+INSERT INTO `sys_pages_blocks`(`object`, `cell_id`, `module`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `order`) VALUES
+('bx_organizations_home', 1, 'bx_organizations', '_bx_orgs_page_block_title_featured_profiles', 11, 2147483647, 'service', 'a:3:{s:6:"module";s:16:"bx_organizations";s:6:"method";s:15:"browse_featured";s:6:"params";a:1:{i:0;s:7:"gallery";}}', 0, 1, 0),
+('bx_organizations_home', 1, 'bx_organizations', '_bx_orgs_page_block_title_latest_profiles', 11, 2147483647, 'service', 'a:3:{s:6:\"module\";s:16:\"bx_organizations\";s:6:\"method\";s:22:\"browse_recent_profiles\";s:6:"params";a:1:{i:0;b:1;}}', 0, 1, 1);
+
+-- PAGE: active profiles
+
+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_organizations_active', '_bx_orgs_page_title_sys_active', '_bx_orgs_page_title_active', 'bx_organizations', 5, 2147483647, 1, 'organizations-active', 'page.php?i=organizations-active', '', '', '', 0, 1, 0, 'BxOrgsPageBrowse', 'modules/boonex/organizations/classes/BxOrgsPageBrowse.php');
+
+INSERT INTO `sys_pages_blocks`(`object`, `cell_id`, `module`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `order`) VALUES 
+('bx_organizations_active', 1, 'bx_organizations', '_bx_orgs_page_block_title_active_profiles', 11, 2147483647, 'service', 'a:3:{s:6:\"module\";s:16:\"bx_organizations\";s:6:\"method\";s:22:\"browse_active_profiles\";s:6:"params";a:1:{i:0;b:1;}}', 0, 1, 0);
+
+-- PAGE: online profiles
+
+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_organizations_online', '_bx_orgs_page_title_sys_online', '_bx_orgs_page_title_online', 'bx_organizations', 5, 2147483647, 1, 'organizations-online', 'page.php?i=organizations-online', '', '', '', 0, 1, 0, 'BxOrgsPageBrowse', 'modules/boonex/organizations/classes/BxOrgsPageBrowse.php');
+
+INSERT INTO `sys_pages_blocks`(`object`, `cell_id`, `module`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `order`) VALUES 
+('bx_organizations_online', 1, 'bx_organizations', '_bx_orgs_page_block_title_online_profiles', 11, 2147483647, 'service', 'a:3:{s:6:\"module\";s:16:\"bx_organizations\";s:6:\"method\";s:22:\"browse_online_profiles\";s:6:"params";a:1:{i:0;b:1;}}', 0, 1, 0);
+
+-- PAGE: search for entries
+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_organizations_search', '_bx_orgs_page_title_sys_entries_search', '_bx_orgs_page_title_entries_search', 'bx_organizations', 5, 2147483647, 1, 'organizations-search', 'page.php?i=organizations-search', '', '', '', 0, 1, 0, 'BxOrgsPageBrowse', 'modules/boonex/organizations/classes/BxOrgsPageBrowse.php');
+
+INSERT INTO `sys_pages_blocks`(`object`, `cell_id`, `module`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `active`, `order`) VALUES 
+('bx_organizations_search', 1, 'bx_organizations', '_bx_orgs_page_block_title_search_form', 11, 2147483647, 'service', 'a:4:{s:6:"module";s:6:"system";s:6:"method";s:8:"get_form";s:6:"params";a:1:{i:0;a:1:{s:6:"object";s:16:"bx_organizations";}}s:5:"class";s:27:"TemplSearchExtendedServices";}', 0, 1, 1, 1),
+('bx_organizations_search', 1, 'bx_organizations', '_bx_orgs_page_block_title_search_results', 11, 2147483647, 'service', 'a:4:{s:6:"module";s:6:"system";s:6:"method";s:11:"get_results";s:6:"params";a:1:{i:0;a:2:{s:6:"object";s:16:"bx_organizations";s:10:"show_empty";b:1;}}s:5:"class";s:27:"TemplSearchExtendedServices";}', 0, 1, 1, 2),
+('bx_organizations_search', 1, 'bx_organizations', '_bx_orgs_page_block_title_search_form_cmts', 11, 2147483647, 'service', 'a:4:{s:6:"module";s:6:"system";s:6:"method";s:8:"get_form";s:6:"params";a:1:{i:0;a:1:{s:6:"object";s:21:"bx_organizations_cmts";}}s:5:"class";s:27:"TemplSearchExtendedServices";}', 0, 1, 0, 3),
+('bx_organizations_search', 1, 'bx_organizations', '_bx_orgs_page_block_title_search_results_cmts', 11, 2147483647, 'service', 'a:4:{s:6:"module";s:6:"system";s:6:"method";s:11:"get_results";s:6:"params";a:1:{i:0;a:2:{s:6:"object";s:21:"bx_organizations_cmts";s:10:"show_empty";b:1;}}s:5:"class";s:27:"TemplSearchExtendedServices";}', 0, 1, 0, 4);
+
+-- PAGE: module manage own
+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_organizations_manage', '_bx_orgs_page_title_sys_manage', '_bx_orgs_page_title_manage', 'bx_organizations', 5, 2147483647, 1, 'organizations-manage', 'page.php?i=organizations-manage', '', '', '', 0, 1, 0, 'BxOrgsPageBrowse', 'modules/boonex/organizations/classes/BxOrgsPageBrowse.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_organizations_manage', 1, 'bx_organizations', '_bx_orgs_page_block_title_system_manage', '_bx_orgs_page_block_title_manage', 11, 2147483647, 'service', 'a:2:{s:6:\"module\";s:16:\"bx_organizations\";s:6:\"method\";s:12:\"manage_tools\";}}', 0, 1, 0);
+
+-- PAGE: module manage all
+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_organizations_administration', '_bx_orgs_page_title_sys_manage_administration', '_bx_orgs_page_title_manage', 'bx_organizations', 5, 192, 1, 'organizations-administration', 'page.php?i=organizations-administration', '', '', '', 0, 1, 0, 'BxOrgsPageBrowse', 'modules/boonex/organizations/classes/BxOrgsPageBrowse.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_organizations_administration', 1, 'bx_organizations', '_bx_orgs_page_block_title_system_manage_administration', '_bx_orgs_page_block_title_manage', 11, 192, 'service', 'a:3:{s:6:\"module\";s:16:\"bx_organizations\";s:6:\"method\";s:12:\"manage_tools\";s:6:\"params\";a:1:{i:0;s:14:\"administration\";}}', 0, 1, 0);
+
+-- PAGE: user's organizations
+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_organizations_joined', 'joined-organizations', '_bx_orgs_page_title_sys_joined_entries', '_bx_orgs_page_title_joined_entries', 'bx_organizations', 5, 2147483647, 1, '', '', '', '', 0, 1, 0, 'BxOrgsPageJoinedEntries', 'modules/boonex/organizations/classes/BxOrgsPageJoinedEntries.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_organizations_joined', 1, 'bx_organizations', '_bx_orgs_page_block_title_sys_entries_actions', '_bx_orgs_page_block_title_entries_actions', 13, 2147483647, 'service', 'a:2:{s:6:"module";s:16:"bx_organizations";s:6:"method";s:18:"my_entries_actions";}', 0, 0, 1, 1),
+('bx_organizations_joined', 1, 'bx_organizations', '_bx_orgs_page_block_title_sys_favorites_of_author', '_bx_orgs_page_block_title_favorites_of_author', 11, 2147483647, 'service', 'a:3:{s:6:"module";s:16:"bx_organizations";s:6:"method";s:15:"browse_favorite";s:6:"params";a:1:{i:0;s:12:"{profile_id}";}}', 0, 1, 1, 1),
+('bx_organizations_joined', 1, 'bx_organizations', '_bx_orgs_page_block_title_sys_joined_entries', '_bx_orgs_page_block_title_joined_entries', 11, 2147483647, 'service', 'a:3:{s:6:"module";s:16:"bx_organizations";s:6:"method";s:21:"browse_joined_entries";s:6:"params";a:2:{i:0;i:0;i:1;b:1;}}', 0, 0, 1, 2);
+
+-- PAGE: add block to homepage
+SET @iBlockOrder = (SELECT `order` FROM `sys_pages_blocks` WHERE `object` = 'sys_home' AND `cell_id` = 1 ORDER BY `order` DESC LIMIT 1);
+INSERT INTO `sys_pages_blocks` (`object`, `cell_id`, `module`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `active`, `order`) VALUES
+('sys_home', 1, 'bx_organizations', '_bx_orgs_page_block_title_latest_profiles', 11, 2147483647, 'service', 'a:2:{s:6:"module";s:16:"bx_organizations";s:6:"method";s:22:"browse_recent_profiles";}', 1, 0, 0, IFNULL(@iBlockOrder, 0) + 1);
+
+-- PAGES: add page block to profiles modules (trigger* page objects are processed separately upon modules enable/disable)
+SET @iPBCellProfile = 2;
+INSERT INTO `sys_pages_blocks` (`object`, `cell_id`, `module`, `title_system`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `active`, `order`) VALUES
+('trigger_page_profile_view_entry', @iPBCellProfile, 'bx_organizations', '_bx_orgs_page_block_title_sys_joined_entries', '_bx_orgs_page_block_title_joined_entries', 11, 2147483647, 'service', 'a:3:{s:6:"module";s:16:"bx_organizations";s:6:"method";s:21:"browse_joined_entries";s:6:"params";a:2:{i:0;s:12:"{profile_id}";i:1;b:0;}}', 0, 0, 1, 0);
+
+-- PAGE: service blocks
+SET @iBlockOrder = (SELECT `order` FROM `sys_pages_blocks` WHERE `object` = '' AND `cell_id` = 0 ORDER BY `order` DESC LIMIT 1);
+INSERT INTO `sys_pages_blocks` (`object`, `cell_id`, `module`, `title_system`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `active`, `order`) VALUES
+('', 0, 'bx_organizations', '', '_bx_orgs_page_block_title_categories', 11, 2147483647, 'service', 'a:4:{s:6:"module";s:6:"system";s:6:"method";s:15:"categories_list";s:6:"params";a:2:{i:0;s:21:"bx_organizations_cats";i:1;a:2:{s:10:\"show_empty\";b:1;s:21:\"show_empty_categories\";b:1;}}s:5:"class";s:20:"TemplServiceCategory";}', 1, 1, 1, IFNULL(@iBlockOrder, 0) + 1);
+
+
+-- MENU
+
+-- MENU: add to site menu
+SET @iSiteMenuOrder = (SELECT `order` FROM `sys_menu_items` WHERE `set_name` = 'sys_site' 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_site', 'bx_organizations', 'organizations-home', '_bx_orgs_menu_item_title_system_entries_home', '_bx_orgs_menu_item_title_entries_home', 'page.php?i=organizations-home', '', '', 'briefcase col-red2', 'bx_organizations_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_organizations', 'organizations-home', '_bx_orgs_menu_item_title_system_entries_home', '_bx_orgs_menu_item_title_entries_home', 'page.php?i=organizations-home', '', '', 'briefcase col-red2', 'bx_organizations_submenu', 2147483647, 1, 1, IFNULL(@iHomepageMenuOrder, 0) + 1);
+
+--SET @iCreateProfileMenuOrder = (SELECT `order` FROM `sys_menu_items` WHERE `set_name` = 'sys_profiles_create' 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_profiles_create', 'bx_organizations', 'create-organization-profile', '_bx_orgs_menu_item_title_system_profile_type', '_bx_orgs_menu_item_title_profile_type', 'page.php?i=create-organization-profile', '', '', 'briefcase', '', 2147483647, 1, 1, IFNULL(@iCreateProfileMenuOrder, 0) + 1);
+
+-- MENU: add to create profile menu
+SET @iAddMenuOrder = (SELECT `order` FROM `sys_menu_items` WHERE `set_name` = 'sys_add_profile_links' 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_add_profile_links', 'bx_organizations', 'create-organization-profile', '_bx_orgs_menu_item_title_system_create_profile', '_bx_orgs_menu_item_title_create_profile', 'page.php?i=create-organization-profile', '', '', 'briefcase col-red2', '', 2147483647, 1, 1, IFNULL(@iAddMenuOrder, 0) + 1);
+
+-- MENU: view actions
+INSERT INTO `sys_objects_menu`(`object`, `title`, `set_name`, `module`, `template_id`, `deletable`, `active`, `override_class_name`, `override_class_file`) VALUES 
+('bx_organizations_view_actions', '_bx_orgs_menu_title_view_profile_actions', 'bx_organizations_view_actions', 'bx_organizations', 9, 0, 1, 'BxOrgsMenuView', 'modules/boonex/organizations/classes/BxOrgsMenuView.php');
+
+INSERT INTO `sys_menu_sets`(`set_name`, `module`, `title`, `deletable`) VALUES 
+('bx_organizations_view_actions', 'bx_organizations', '_bx_orgs_menu_set_title_view_profile_actions', 0);
+
+INSERT INTO `sys_menu_items`(`set_name`, `module`, `name`, `title_system`, `title`, `link`, `onclick`, `target`, `icon`, `submenu_object`, `submenu_popup`, `visible_for_levels`, `active`, `copyable`, `editable`, `order`) VALUES 
+('bx_organizations_view_actions', 'bx_organizations', 'profile-friend-add', '_bx_orgs_menu_item_title_system_befriend', '{title_add_friend}', 'javascript:void(0)', 'bx_conn_action(this, \'sys_profiles_friends\', \'add\', \'{profile_id}\')', '', 'user-plus', '', 0, 2147483647, 1, 0, 1, 10),
+('bx_organizations_view_actions', 'bx_organizations', 'profile-subscribe-add', '_bx_orgs_menu_item_title_system_subscribe', '_bx_orgs_menu_item_title_subscribe', 'javascript:void(0)', 'bx_conn_action(this, \'sys_profiles_subscriptions\', \'add\', \'{profile_id}\')', '', 'check', '', 0, 2147483647, 1, 0, 1, 20),
+('bx_organizations_view_actions', 'bx_organizations', 'profile-set-acl-level', '_sys_menu_item_title_system_set_acl_level', '_sys_menu_item_title_set_acl_level', 'javascript:void(0)', 'bx_menu_popup(''sys_set_acl_level'', window, {}, {profile_id: {profile_id}});', '', 'certificate', '', 0, 192, 1, 0, 1, 30),
+('bx_organizations_view_actions', 'bx_organizations', 'profile-actions-more', '_bx_orgs_menu_item_title_system_more_actions', '_bx_orgs_menu_item_title_more_actions', 'javascript:void(0)', 'bx_menu_popup(''bx_organizations_view_actions_more'', this, {}, {profile_id:{profile_id}});', '', 'cog', 'bx_organizations_view_actions_more', 1, 2147483647, 1, 0, 1, 9999);
+
+-- MENU: view actions more
+INSERT INTO `sys_objects_menu`(`object`, `title`, `set_name`, `module`, `template_id`, `deletable`, `active`, `override_class_name`, `override_class_file`) VALUES 
+('bx_organizations_view_actions_more', '_bx_orgs_menu_title_view_profile_actions_more', 'bx_organizations_view_actions_more', 'bx_organizations', 6, 0, 1, 'BxOrgsMenuView', 'modules/boonex/organizations/classes/BxOrgsMenuView.php');
+
+INSERT INTO `sys_menu_sets`(`set_name`, `module`, `title`, `deletable`) VALUES 
+('bx_organizations_view_actions_more', 'bx_organizations', '_bx_orgs_menu_set_title_view_profile_actions_more', 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_organizations_view_actions_more', 'bx_organizations', 'profile-fan-remove', '_bx_orgs_menu_item_title_system_leave_organization', '{title_remove_fan}', 'javascript:void(0)', 'bx_conn_action(this, \'bx_organizations_fans\', \'remove\', \'{profile_id}\')', '', 'user-times', '', 2147483647, 1, 0, 10),
+('bx_organizations_view_actions_more', 'bx_organizations', 'profile-friend-remove', '_bx_orgs_menu_item_title_system_unfriend', '{title_remove_friend}', 'javascript:void(0)', 'bx_conn_action(this, \'sys_profiles_friends\', \'remove\', \'{profile_id}\')', '', 'user-times', '', 2147483647, 1, 0, 10),
+('bx_organizations_view_actions_more', 'bx_organizations', 'profile-subscribe-remove', '_bx_orgs_menu_item_title_system_unsubscribe', '_bx_orgs_menu_item_title_unsubscribe', 'javascript:void(0)', 'bx_conn_action(this, \'sys_profiles_subscriptions\', \'remove\', \'{profile_id}\')', '', 'check', '', 2147483647, 1, 0, 20),
+('bx_organizations_view_actions_more', 'bx_organizations', 'edit-organization-cover', '_bx_orgs_menu_item_title_system_edit_cover', '_bx_orgs_menu_item_title_edit_cover', 'page.php?i=edit-organization-cover&id={content_id}', '', '', 'pencil', '', 2147483647, 1, 0, 25),
+('bx_organizations_view_actions_more', 'bx_organizations', 'edit-organization-profile', '_bx_orgs_menu_item_title_system_edit_profile', '_bx_orgs_menu_item_title_edit_profile', 'page.php?i=edit-organization-profile&id={content_id}', '', '', 'pencil', '', 2147483647, 1, 0, 30),
+('bx_organizations_view_actions_more', 'bx_organizations', 'invite-to-organization', '_bx_orgs_menu_item_title_system_invite', '_bx_orgs_menu_item_title_invite', 'page.php?i=invite-to-organization&id={content_id}', '', '', 'user-plus', '', 2147483647, 1, 0, 32),
+('bx_organizations_view_actions_more', 'bx_organizations', 'delete-organization-profile', '_bx_orgs_menu_item_title_system_delete_profile', '_bx_orgs_menu_item_title_delete_profile', 'page.php?i=delete-organization-profile&id={content_id}', '', '', 'remove', '', 2147483647, 1, 0, 40),
+('bx_organizations_view_actions_more', 'bx_organizations', 'delete-organization-account', '_bx_orgs_menu_item_title_system_delete_account', '_bx_orgs_menu_item_title_delete_account', 'page.php?i=account-settings-delete&id={account_id}', '', '', 'remove', '', 128, 1, 0, 50),
+('bx_organizations_view_actions_more', 'bx_organizations', 'delete-organization-account-content', '_bx_orgs_menu_item_title_system_delete_account_content', '_bx_orgs_menu_item_title_delete_account_content', 'page.php?i=account-settings-delete&id={account_id}&content=1', '', '', 'remove', '', 128, 1, 0, 60);
+
+-- MENU: actions menu for my entries
+
+INSERT INTO `sys_objects_menu`(`object`, `title`, `set_name`, `module`, `template_id`, `deletable`, `active`, `override_class_name`, `override_class_file`) VALUES 
+('bx_organizations_my', '_bx_orgs_menu_title_entries_my', 'bx_organizations_my', 'bx_organizations', 9, 0, 1, 'BxOrgsMenu', 'modules/boonex/organizations/classes/BxOrgsMenu.php');
+
+INSERT INTO `sys_menu_sets`(`set_name`, `module`, `title`, `deletable`) VALUES 
+('bx_organizations_my', 'bx_organizations', '_bx_orgs_menu_set_title_entries_my', 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_organizations_my', 'bx_organizations', 'create-organization-profile', '_bx_orgs_menu_item_title_system_new_profile', '_bx_orgs_menu_item_title_new_profile', 'page.php?i=create-organization-profile', '', '', 'plus', '', 2147483647, 1, 0, 0);
+
+-- 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_organizations_submenu', '_bx_orgs_menu_title_submenu', 'bx_organizations_submenu', 'bx_organizations', 8, 0, 1, '', '');
+
+INSERT INTO `sys_menu_sets`(`set_name`, `module`, `title`, `deletable`) VALUES 
+('bx_organizations_submenu', 'bx_organizations', '_bx_orgs_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_organizations_submenu', 'bx_organizations', 'organizations-home', '_bx_orgs_menu_item_title_system_entries_recent', '_bx_orgs_menu_item_title_entries_recent', 'page.php?i=organizations-home', '', '', '', '', 2147483647, 1, 1, 1),
+('bx_organizations_submenu', 'bx_organizations', 'organizations-active', '_bx_orgs_menu_item_title_system_entries_active', '_bx_orgs_menu_item_title_entries_active', 'page.php?i=organizations-active', '', '', '', '', 2147483647, 1, 1, 2),
+('bx_organizations_submenu', 'bx_organizations', 'organizations-online', '_bx_orgs_menu_item_title_system_entries_online', '_bx_orgs_menu_item_title_entries_online', 'page.php?i=organizations-online', '', '', '', '', 2147483647, 1, 1, 3),
+('bx_organizations_submenu', 'bx_organizations', 'organizations-search', '_bx_orgs_menu_item_title_system_entries_search', '_bx_orgs_menu_item_title_entries_search', 'page.php?i=organizations-search', '', '', '', '', 2147483647, 1, 1, 4),
+('bx_organizations_submenu', 'bx_organizations', 'organizations-manage', '_bx_orgs_menu_item_title_system_entries_manage', '_bx_orgs_menu_item_title_entries_manage', 'page.php?i=organizations-manage', '', '', '', '', 2147483646, 1, 1, 5);
+
+-- MENU: view submenu
+INSERT INTO `sys_objects_menu`(`object`, `title`, `set_name`, `module`, `template_id`, `deletable`, `active`, `override_class_name`, `override_class_file`) VALUES 
+('bx_organizations_view_submenu', '_bx_orgs_menu_title_view_profile_submenu', 'bx_organizations_view_submenu', 'bx_organizations', 8, 0, 1, 'BxOrgsMenuView', 'modules/boonex/organizations/classes/BxOrgsMenuView.php'),
+('bx_organizations_view_submenu_cover', '_bx_orgs_menu_title_view_profile_submenu_cover', 'bx_organizations_view_submenu', 'bx_organizations', 7, 0, 1, 'BxOrgsMenuView', 'modules/boonex/organizations/classes/BxOrgsMenuView.php');
+
+INSERT INTO `sys_menu_sets`(`set_name`, `module`, `title`, `deletable`) VALUES 
+('bx_organizations_view_submenu', 'bx_organizations', '_bx_orgs_menu_set_title_view_profile_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_organizations_view_submenu', 'bx_organizations', 'view-organization-profile', '_bx_orgs_menu_item_title_system_view_profile_view', '_bx_orgs_menu_item_title_view_profile_view', 'page.php?i=view-organization-profile&id={content_id}', '', '', 'briefcase col-red2', '', 2147483647, 1, 0, 1),
+('bx_organizations_view_submenu', 'bx_organizations', 'organization-profile-info', '_bx_orgs_menu_item_title_system_view_profile_info', '_bx_orgs_menu_item_title_view_profile_info', 'page.php?i=organization-profile-info&id={content_id}', '', '', 'info-circle col-gray', '', 2147483647, 1, 0, 2),
+('bx_organizations_view_submenu', 'bx_organizations', 'organization-profile-fans', '_bx_orgs_menu_item_title_system_view_profile_fans', '_bx_orgs_menu_item_title_view_profile_fans', 'page.php?i=organization-profile-fans&profile_id={profile_id}', '', '', 'group col-blue3', '', 2147483647, 1, 0, 3),
+('bx_organizations_view_submenu', 'bx_organizations', 'organization-profile-friends', '_bx_orgs_menu_item_title_system_view_profile_friends', '_bx_orgs_menu_item_title_view_profile_friends', 'page.php?i=organization-profile-friends&profile_id={profile_id}', '', '', 'group col-blue3', '', 2147483647, 1, 0, 4),
+('bx_organizations_view_submenu', 'bx_organizations', 'organization-profile-subscriptions', '_bx_orgs_menu_item_title_system_view_profile_subscriptions', '_bx_orgs_menu_item_title_view_profile_subscriptions', 'page.php?i=organization-profile-subscriptions&profile_id={profile_id}', '', '', 'check col-blue3', '', 2147483647, 1, 0, 5),
+('bx_organizations_view_submenu', 'bx_organizations', 'organization-profile-comments', '_bx_orgs_menu_item_title_system_view_profile_comments', '_bx_orgs_menu_item_title_view_profile_comments', 'page.php?i=organization-profile-comments&id={content_id}', '', '', '', '', 2147483647, 0, 0, 6);
+
+-- MENU: custom menu for snippet meta info
+INSERT INTO `sys_objects_menu`(`object`, `title`, `set_name`, `module`, `template_id`, `deletable`, `active`, `override_class_name`, `override_class_file`) VALUES 
+('bx_organizations_snippet_meta', '_sys_menu_title_snippet_meta', 'bx_organizations_snippet_meta', 'bx_organizations', 15, 0, 1, 'BxOrgsMenuSnippetMeta', 'modules/boonex/organizations/classes/BxOrgsMenuSnippetMeta.php');
+
+INSERT INTO `sys_menu_sets`(`set_name`, `module`, `title`, `deletable`) VALUES 
+('bx_organizations_snippet_meta', 'bx_organizations', '_sys_menu_set_title_snippet_meta', 0);
+
+INSERT INTO `sys_menu_items`(`set_name`, `module`, `name`, `title_system`, `title`, `link`, `onclick`, `target`, `icon`, `submenu_object`, `visible_for_levels`, `active`, `copyable`, `editable`, `order`) VALUES
+('bx_organizations_snippet_meta', 'bx_organizations', 'join', '_sys_menu_item_title_system_sm_join', '_sys_menu_item_title_sm_join', '', '', '', '', '', 2147483647, 1, 0, 1, 1),
+('bx_organizations_snippet_meta', 'bx_organizations', 'leave', '_sys_menu_item_title_system_sm_leave', '_sys_menu_item_title_sm_leave', '', '', '', '', '', 2147483647, 0, 0, 1, 2),
+('bx_organizations_snippet_meta', 'bx_organizations', 'befriend', '_sys_menu_item_title_system_sm_befriend', '_sys_menu_item_title_sm_befriend', '', '', '', '', '', 2147483647, 0, 0, 1, 3),
+('bx_organizations_snippet_meta', 'bx_organizations', 'unfriend', '_sys_menu_item_title_system_sm_unfriend', '_sys_menu_item_title_sm_unfriend', '', '', '', '', '', 2147483647, 0, 0, 1, 4),
+('bx_organizations_snippet_meta', 'bx_organizations', 'subscribe', '_sys_menu_item_title_system_sm_subscribe', '_sys_menu_item_title_sm_subscribe', '', '', '', '', '', 2147483647, 0, 0, 1, 5),
+('bx_organizations_snippet_meta', 'bx_organizations', 'unsubscribe', '_sys_menu_item_title_system_sm_unsubscribe', '_sys_menu_item_title_sm_unsubscribe', '', '', '', '', '', 2147483647, 0, 0, 1, 6),
+('bx_organizations_snippet_meta', 'bx_organizations', 'date', '_sys_menu_item_title_system_sm_date', '_sys_menu_item_title_sm_date', '', '', '', '', '', 2147483647, 0, 0, 1, 7),
+('bx_organizations_snippet_meta', 'bx_organizations', 'tags', '_sys_menu_item_title_system_sm_tags', '_sys_menu_item_title_sm_tags', '', '', '', '', '', 2147483647, 0, 0, 1, 8),
+('bx_organizations_snippet_meta', 'bx_organizations', 'views', '_sys_menu_item_title_system_sm_views', '_sys_menu_item_title_sm_views', '', '', '', '', '', 2147483647, 0, 0, 1, 9),
+('bx_organizations_snippet_meta', 'bx_organizations', 'comments', '_sys_menu_item_title_system_sm_comments', '_sys_menu_item_title_sm_comments', '', '', '', '', '', 2147483647, 0, 0, 1, 10),
+('bx_organizations_snippet_meta', 'bx_organizations', 'members', '_sys_menu_item_title_system_sm_members', '_sys_menu_item_title_sm_members', '', '', '', '', '', 2147483647, 1, 0, 1, 11),
+('bx_organizations_snippet_meta', 'bx_organizations', 'friends', '_sys_menu_item_title_system_sm_friends', '_sys_menu_item_title_sm_friends', '', '', '', '', '', 2147483647, 0, 0, 1, 12),
+('bx_organizations_snippet_meta', 'bx_organizations', 'subscribers', '_sys_menu_item_title_system_sm_subscribers', '_sys_menu_item_title_sm_subscribers', '', '', '', '', '', 2147483647, 0, 0, 1, 13);
+
+-- MENU: notifications menu in account popup
+SET @iNotifMenuOrder = (SELECT `order` FROM `sys_menu_items` WHERE `set_name` = 'sys_account_notifications' 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`, `addon`, `submenu_object`, `visible_for_levels`, `active`, `copyable`, `order`) VALUES
+('sys_account_notifications', 'bx_organizations', 'notifications-friend-requests', '_bx_orgs_menu_item_title_system_friends', '_bx_orgs_menu_item_title_friends', 'page.php?i=organization-profile-friends&profile_id={member_id}', '', '', 'group col-red2', 'a:4:{s:6:"module";s:6:"system";s:6:"method";s:31:"get_unconfirmed_connections_num";s:6:"params";a:1:{i:0;s:20:"sys_profiles_friends";}s:5:"class";s:23:"TemplServiceConnections";}', '', 2147483646, 1, 0, IFNULL(@iNotifMenuOrder, 0) + 1);
+
+-- MENU: profile stats
+SET @iNotifMenuOrder = (SELECT IFNULL(MAX(`order`), 0) FROM `sys_menu_items` WHERE `set_name` = 'sys_profile_stats' AND `active` = 1 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_profile_stats', 'bx_organizations', 'profile-stats-friend-requests', '_bx_orgs_menu_item_title_system_friend_requests', '_bx_orgs_menu_item_title_friend_requests', 'page.php?i=organization-profile-friends&profile_id={member_id}', '', '', 'briefcase col-red2', 'a:4:{s:6:"module";s:6:"system";s:6:"method";s:31:"get_unconfirmed_connections_num";s:6:"params";a:1:{i:0;s:20:"sys_profiles_friends";}s:5:"class";s:23:"TemplServiceConnections";}', '', 2147483646, 1, 0, @iNotifMenuOrder + 1),
+('sys_profile_stats', 'bx_organizations', 'profile-stats-manage-organizations', '_bx_orgs_menu_item_title_system_manage_my_organizations', '_bx_orgs_menu_item_title_manage_my_organizations', 'page.php?i=organizations-manage', '', '_self', 'briefcase col-red2', 'a:2:{s:6:"module";s:16:"bx_organizations";s:6:"method";s:41:"get_menu_addon_manage_tools_profile_stats";}', '', 2147483646, 1, 0, @iNotifMenuOrder + 2),
+('sys_profile_stats', 'bx_organizations', 'profile-stats-favorite-organizations', '_bx_orgs_menu_item_title_system_favorites', '_bx_orgs_menu_item_title_favorites', 'page.php?i=organization-profile-favorites&profile_id={member_id}', '', '', 'star col-red2', 'a:2:{s:6:"module";s:16:"bx_organizations";s:6:"method";s:38:"get_menu_addon_favorites_profile_stats";}', '', 2147483646, 1, 0, @iNotifMenuOrder + 3),
+('sys_profile_stats', 'bx_organizations', 'profile-stats-subscriptions', '_bx_orgs_menu_item_title_system_subscriptions', '_bx_orgs_menu_item_title_subscriptions', 'page.php?i=organization-profile-subscriptions&profile_id={member_id}#subscriptions', '', '_self', 'rss col-red2', 'a:4:{s:6:"module";s:6:"system";s:6:"method";s:25:"get_connected_content_num";s:6:"params";a:1:{i:0;s:26:"sys_profiles_subscriptions";}s:5:"class";s:23:"TemplServiceConnections";}', '', 2147483646, 1, 0, @iNotifMenuOrder + 4),
+('sys_profile_stats', 'bx_organizations', 'profile-stats-subscribed-me', '_bx_orgs_menu_item_title_system_subscribed_me', '_bx_orgs_menu_item_title_subscribed_me', 'page.php?i=organization-profile-subscribed-me&profile_id={member_id}#subscribers', '', '_self', 'rss col-red2', 'a:4:{s:6:"module";s:6:"system";s:6:"method";s:28:"get_connected_initiators_num";s:6:"params";a:1:{i:0;s:26:"sys_profiles_subscriptions";}s:5:"class";s:23:"TemplServiceConnections";}', '', 2147483646, 1, 0, @iNotifMenuOrder + 5);
+
+-- MENU: manage tools submenu
+INSERT INTO `sys_objects_menu`(`object`, `title`, `set_name`, `module`, `template_id`, `deletable`, `active`, `override_class_name`, `override_class_file`) VALUES 
+('bx_organizations_menu_manage_tools', '_bx_orgs_menu_title_manage_tools', 'bx_organizations_menu_manage_tools', 'bx_organizations', 6, 0, 1, 'BxOrgsMenuManageTools', 'modules/boonex/organizations/classes/BxOrgsMenuManageTools.php');
+
+INSERT INTO `sys_menu_sets`(`set_name`, `module`, `title`, `deletable`) VALUES 
+('bx_organizations_menu_manage_tools', 'bx_organizations', '_bx_orgs_menu_set_title_manage_tools', 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_organizations_menu_manage_tools', 'bx_organizations', 'delete', '_bx_orgs_menu_item_title_system_delete', '_bx_orgs_menu_item_title_delete', 'javascript:void(0)', 'javascript:{js_object}.onClickDelete({content_id});', '_self', 'trash-o', '', 2147483647, 1, 0, 1),
+('bx_organizations_menu_manage_tools', 'bx_organizations', 'delete-with-content', '_bx_orgs_menu_item_title_system_delete_with_content', '_bx_orgs_menu_item_title_delete_with_content', 'javascript:void(0)', 'javascript:{js_object}.onClickDeleteWithContent({content_id});', '_self', 'trash-o', '', 2147483647, 1, 0, 2);
+
+-- 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_organizations', 'organizations-administration', '_bx_orgs_menu_item_title_system_admt_organizations', '_bx_orgs_menu_item_title_admt_organizations', 'page.php?i=organizations-administration', '', '_self', '', 'a:2:{s:6:"module";s:16:"bx_organizations";s:6:"method";s:27:"get_menu_addon_manage_tools";}', '', 192, 1, 0, @iManageMenuOrder + 1);
+
+-- MENU: add menu item to profiles modules (trigger* menu sets are processed separately upon modules enable/disable)
+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 
+('trigger_profile_view_submenu', 'bx_organizations', 'joined-organizations', '_bx_orgs_menu_item_title_system_view_joined_groups', '_bx_orgs_menu_item_title_view_joined_groups', 'page.php?i=joined-organizations&profile_id={profile_id}', '', '', 'briefcase col-red2', '', 2147483647, 1, 0, 0);
+
+
+-- ACL
+INSERT INTO `sys_acl_actions` (`Module`, `Name`, `AdditionalParamName`, `Title`, `Desc`, `Countable`, `DisabledForLevels`) VALUES
+('bx_organizations', 'create entry', NULL, '_bx_orgs_acl_action_create_profile', '', 1, 1);
+SET @iIdActionProfileCreate = LAST_INSERT_ID();
+
+INSERT INTO `sys_acl_actions` (`Module`, `Name`, `AdditionalParamName`, `Title`, `Desc`, `Countable`, `DisabledForLevels`) VALUES
+('bx_organizations', 'delete entry', NULL, '_bx_orgs_acl_action_delete_profile', '', 1, 1);
+SET @iIdActionProfileDelete = LAST_INSERT_ID();
+
+INSERT INTO `sys_acl_actions` (`Module`, `Name`, `AdditionalParamName`, `Title`, `Desc`, `Countable`, `DisabledForLevels`) VALUES
+('bx_organizations', 'view entry', NULL, '_bx_orgs_acl_action_view_profile', '', 1, 0);
+SET @iIdActionProfileView = LAST_INSERT_ID();
+
+INSERT INTO `sys_acl_actions` (`Module`, `Name`, `AdditionalParamName`, `Title`, `Desc`, `Countable`, `DisabledForLevels`) VALUES
+('bx_organizations', 'edit any entry', NULL, '_bx_orgs_acl_action_edit_any_profile', '', 1, 3);
+SET @iIdActionProfileEditAny = LAST_INSERT_ID();
+
+SET @iUnauthenticated = 1;
+SET @iAccount = 2;
+SET @iStandard = 3;
+SET @iUnconfirmed = 4;
+SET @iPending = 5;
+SET @iSuspended = 6;
+SET @iModerator = 7;
+SET @iAdministrator = 8;
+SET @iPremium = 9;
+
+INSERT INTO `sys_acl_matrix` (`IDLevel`, `IDAction`) VALUES
+
+-- profile create
+(@iAccount, @iIdActionProfileCreate),
+(@iStandard, @iIdActionProfileCreate),
+(@iUnconfirmed, @iIdActionProfileCreate),
+(@iPending, @iIdActionProfileCreate),
+(@iModerator, @iIdActionProfileCreate),
+(@iAdministrator, @iIdActionProfileCreate),
+(@iPremium, @iIdActionProfileCreate),
+
+-- profile delete
+(@iAccount, @iIdActionProfileDelete),
+(@iStandard, @iIdActionProfileDelete),
+(@iUnconfirmed, @iIdActionProfileDelete),
+(@iPending, @iIdActionProfileDelete),
+(@iModerator, @iIdActionProfileDelete),
+(@iAdministrator, @iIdActionProfileDelete),
+(@iPremium, @iIdActionProfileDelete),
+
+-- profile view
+(@iUnauthenticated, @iIdActionProfileView),
+(@iAccount, @iIdActionProfileView),
+(@iStandard, @iIdActionProfileView),
+(@iUnconfirmed, @iIdActionProfileView),
+(@iPending, @iIdActionProfileView),
+(@iModerator, @iIdActionProfileView),
+(@iAdministrator, @iIdActionProfileView),
+(@iPremium, @iIdActionProfileView),
+
+-- any profile edit
+(@iModerator, @iIdActionProfileEditAny),
+(@iAdministrator, @iIdActionProfileEditAny);
+
+
+-- COMMENTS
+INSERT INTO `sys_objects_cmts` (`Name`, `Module`, `Table`, `CharsPostMin`, `CharsPostMax`, `CharsDisplayMax`, `Nl2br`, `PerView`, `PerViewReplies`, `BrowseType`, `IsBrowseSwitch`, `PostFormPosition`, `NumberOfLevels`, `IsDisplaySwitch`, `IsRatable`, `ViewingThreshold`, `IsOn`, `RootStylePrefix`, `BaseUrl`, `ObjectVote`, `TriggerTable`, `TriggerFieldId`, `TriggerFieldAuthor`, `TriggerFieldTitle`, `TriggerFieldComments`, `ClassName`, `ClassFile`) VALUES
+('bx_organizations', 'bx_organizations', 'bx_organizations_cmts', 1, 5000, 1000, 1, 5, 3, 'tail', 1, 'bottom', 1, 1, 1, -3, 1, 'cmt', 'page.php?i=view-organization-profile&id={object_id}', '', 'bx_organizations_data', 'id', 'author', 'org_name', 'comments', '', '');
+
+
+-- VIEWS
+INSERT INTO `sys_objects_view` (`name`, `table_track`, `period`, `is_on`, `trigger_table`, `trigger_field_id`, `trigger_field_author`, `trigger_field_count`, `class_name`, `class_file`) VALUES 
+('bx_organizations', 'bx_organizations_views_track', '86400', '1', 'bx_organizations_data', 'id', 'author', 'views', '', '');
+
+
+-- FAFORITES
+INSERT INTO `sys_objects_favorite` (`name`, `table_track`, `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_organizations', 'bx_organizations_favorites_track', '1', '1', '0', 'page.php?i=view-organization-profile&id={object_id}', 'bx_organizations_data', 'id', 'author', 'favorites', 'BxOrgsFavorite', 'modules/boonex/organizations/classes/BxOrgsFavorite.php');
+
+
+-- FEATURED
+INSERT INTO `sys_objects_feature` (`name`, `is_on`, `is_undo`, `base_url`, `trigger_table`, `trigger_field_id`, `trigger_field_author`, `trigger_field_flag`, `class_name`, `class_file`) VALUES 
+('bx_organizations', '1', '1', 'page.php?i=view-organization-profile&id={object_id}', 'bx_organizations_data', 'id', 'author', 'featured', '', '');
+
+
+-- REPORTS
+INSERT INTO `sys_objects_report` (`name`, `table_main`, `table_track`, `is_on`, `base_url`, `trigger_table`, `trigger_field_id`, `trigger_field_author`, `trigger_field_count`, `class_name`, `class_file`) VALUES 
+('bx_organizations', 'bx_organizations_reports', 'bx_organizations_reports_track', '1', 'page.php?i=view-organization-profile&id={object_id}', 'bx_organizations_data', 'id', 'author', 'reports', 'BxOrgsReport', 'modules/boonex/organizations/classes/BxOrgsReport.php');
+
+
+-- METATAGS
+INSERT INTO `sys_objects_metatags` (`object`, `table_keywords`, `table_locations`, `table_mentions`, `override_class_name`, `override_class_file`) VALUES
+('bx_organizations', 'bx_organizations_meta_keywords', 'bx_organizations_meta_locations', '', '', '');
+
+
+-- CATEGORY
+INSERT INTO `sys_objects_category` (`object`, `search_object`, `form_object`, `list_name`, `table`, `field`, `join`, `where`, `override_class_name`, `override_class_file`) VALUES
+('bx_organizations_cats', 'bx_organizations', 'bx_organization', 'bx_organizations_cats', 'bx_organizations_data', 'org_cat', 'INNER JOIN `sys_profiles` ON (`sys_profiles`.`content_id` = `bx_organizations_data`.`id` AND `sys_profiles`.`type` = ''bx_organizations'')', 'AND `sys_profiles`.`status` = ''active''', '', '');
+
+
+-- SEARCH
+SET @iSearchOrder = (SELECT IFNULL(MAX(`Order`), 0) FROM `sys_objects_search`);
+INSERT INTO `sys_objects_search` (`ObjectName`, `Title`, `Order`, `ClassName`, `ClassPath`) VALUES
+('bx_organizations', '_bx_orgs', @iSearchOrder + 1, 'BxOrgsSearchResult', 'modules/boonex/organizations/classes/BxOrgsSearchResult.php'),
+('bx_organizations_cmts', '_bx_orgs_cmts', @iSearchOrder + 2, 'BxOrgsCmtsSearchResult', 'modules/boonex/organizations/classes/BxOrgsCmtsSearchResult.php');
+
+
+-- CONNECTIONS
+INSERT INTO `sys_objects_connection` (`object`, `table`, `type`, `override_class_name`, `override_class_file`) VALUES
+('bx_organizations_fans', 'bx_organizations_fans', 'mutual', '', '');
+
+
+-- STATS
+SET @iMaxOrderStats = (SELECT IFNULL(MAX(`order`), 0) FROM `sys_statistics`);
+INSERT INTO `sys_statistics` (`module`, `name`, `title`, `link`, `icon`, `query`, `order`) VALUES 
+('bx_organizations', 'bx_organizations', '_bx_orgs', 'page.php?i=organizations-home', 'briefcase col-red2', 'SELECT COUNT(*) FROM `bx_organizations_data` AS `td` LEFT JOIN `sys_profiles` AS `tp` ON `td`.`id` = `tp`.`content_id` AND `tp`.`type`=''bx_organizations'' WHERE 1 AND `tp`.`status`=''active''', @iMaxOrderStats + 1);
+
+
+-- CHARTS
+SET @iMaxOrderCharts = (SELECT IFNULL(MAX(`order`), 0) FROM `sys_objects_chart`);
+INSERT INTO `sys_objects_chart` (`object`, `title`, `table`, `field_date_ts`, `field_date_dt`, `field_status`, `query`, `active`, `order`, `class_name`, `class_file`) VALUES
+('bx_organizations_growth', '_bx_orgs_chart_growth', 'bx_organizations_data', 'added', '', '', 'SELECT {field_date_formatted} AS `period`, COUNT(*) AS {object} FROM {table} LEFT JOIN `sys_profiles` AS `tp` ON {table}.`id` = `tp`.`content_id` AND `tp`.`type`=''bx_organizations'' WHERE 1 AND `tp`.`status`=''active'' {where_inteval} GROUP BY `period` ORDER BY {table}.{field_date} ASC', 1, @iMaxOrderCharts + 1, 'BxDolChartGrowth', ''),
+('bx_organizations_growth_speed', '_bx_orgs_chart_growth_speed', 'bx_organizations_data', 'added', '', '', 'SELECT {field_date_formatted} AS `period`, COUNT(*) AS {object} FROM {table} LEFT JOIN `sys_profiles` AS `tp` ON {table}.`id` = `tp`.`content_id` AND `tp`.`type`=''bx_organizations'' WHERE 1 AND `tp`.`status`=''active'' {where_inteval} GROUP BY `period` ORDER BY {table}.{field_date} ASC', 1, @iMaxOrderCharts + 2, 'BxDolChartGrowthSpeed', '');
+
+
+-- GRID: connections
+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_organizations_fans', 'Sql', 'SELECT `p`.`id`, `c`.`added`, `c`.`mutual` FROM `sys_profiles` AS `p` INNER JOIN `sys_accounts` AS `a` ON (`a`.`id` = `p`.`account_id`) {join_connections}', 'sys_profiles', 'id', 'c`.`added', '', '', 10, NULL, 'start', '', 'name,email', '', 'auto', '', '', 2147483647, 'BxOrgsGridConnections', 'modules/boonex/organizations/classes/BxOrgsGridConnections.php');
+
+INSERT INTO `sys_grid_fields` (`object`, `name`, `title`, `width`, `params`, `order`) VALUES
+('bx_organizations_fans', 'name', '_sys_name', '50%', '', 10),
+('bx_organizations_fans', 'actions', '', '50%', '', 20);
+
+INSERT INTO `sys_grid_actions` (`object`, `type`, `name`, `title`, `icon`, `confirm`, `order`) VALUES
+('bx_organizations_fans', 'single', 'accept', '_sys_accept', '', 0, 10),
+('bx_organizations_fans', 'single', 'to_admins', '_bx_orgs_txt_to_admins', '', 0, 20),
+('bx_organizations_fans', 'single', 'from_admins', '_bx_orgs_txt_from_admins', '', 0, 30),
+('bx_organizations_fans', 'single', 'delete', '', 'remove', 1, 40);
+
+-- GRIDS: administration
+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_organizations_administration', 'Sql', 'SELECT `td`.*, `td`.`org_name` AS `fullname`, `ta`.`email` AS `account`, `ta`.`logged` AS `last_online`, `tp`.`status` AS `status` FROM `bx_organizations_data` AS `td` LEFT JOIN `sys_profiles` AS `tp` ON `td`.`id`=`tp`.`content_id` AND `tp`.`type`=''bx_organizations'' LEFT JOIN `sys_accounts` AS `ta` ON `tp`.`account_id`=`ta`.`id` WHERE 1 ', 'bx_organizations_data', 'id', 'last_online', 'status', '', 20, NULL, 'start', '', 'org_name', '', 'like', '', '', 192, 'BxOrgsGridAdministration', 'modules/boonex/organizations/classes/BxOrgsGridAdministration.php'),
+('bx_organizations_common', 'Sql', 'SELECT `td`.*, `td`.`org_name` AS `fullname`, `ta`.`email` AS `account`, `ta`.`logged` AS `last_online`, `tp`.`status` AS `status` FROM `bx_organizations_data` AS `td` LEFT JOIN `sys_profiles` AS `tp` ON `td`.`id`=`tp`.`content_id` AND `tp`.`type`=''bx_organizations'' LEFT JOIN `sys_accounts` AS `ta` ON `tp`.`account_id`=`ta`.`id` WHERE 1 ', 'bx_organizations_data', 'id', 'last_online', 'status', '', 20, NULL, 'start', '', 'org_name', '', 'like', '', '', 2147483647, 'BxOrgsGridCommon', 'modules/boonex/organizations/classes/BxOrgsGridCommon.php');
+
+INSERT INTO `sys_grid_fields` (`object`, `name`, `title`, `width`, `translatable`, `chars_limit`, `params`, `order`) VALUES
+('bx_organizations_administration', 'checkbox', '_sys_select', '2%', 0, '', '', 1),
+('bx_organizations_administration', 'switcher', '_bx_orgs_grid_column_title_adm_active', '8%', 0, '', '', 2),
+('bx_organizations_administration', 'fullname', '_bx_orgs_grid_column_title_adm_fullname', '25%', 0, '', '', 3),
+('bx_organizations_administration', 'last_online', '_bx_orgs_grid_column_title_adm_last_online', '20%', 1, '25', '', 4),
+('bx_organizations_administration', 'account', '_bx_orgs_grid_column_title_adm_account', '25%', 0, '25', '', 5),
+('bx_organizations_administration', 'actions', '', '20%', 0, '', '', 6),
+('bx_organizations_common', 'checkbox', '_sys_select', '2%', 0, '', '', 1),
+('bx_organizations_common', 'fullname', '_bx_orgs_grid_column_title_adm_fullname', '48%', 0, '', '', 2),
+('bx_organizations_common', 'last_online', '_bx_orgs_grid_column_title_adm_last_online', '30%', 1, '25', '', 3),
+('bx_organizations_common', 'actions', '', '20%', 0, '', '', 4);
+
+INSERT INTO `sys_grid_actions` (`object`, `type`, `name`, `title`, `icon`, `icon_only`, `confirm`, `order`) VALUES
+('bx_organizations_administration', 'bulk', 'set_acl_level', '_bx_orgs_grid_action_title_adm_set_acl_level', '', 0, 0, 1),
+('bx_organizations_administration', 'bulk', 'delete', '_bx_orgs_grid_action_title_adm_delete', '', 0, 1, 2),
+('bx_organizations_administration', 'bulk', 'delete_with_content', '_bx_orgs_grid_action_title_adm_delete_with_content', '', 0, 1, 3),
+('bx_organizations_administration', 'single', 'set_acl_level', '_bx_orgs_grid_action_title_adm_set_acl_level', 'certificate', 1, 0, 1),
+('bx_organizations_administration', 'single', 'settings', '_bx_orgs_grid_action_title_adm_more_actions', 'cog', 1, 0, 2),
+('bx_organizations_common', 'bulk', 'delete', '_bx_orgs_grid_action_title_adm_delete', '', 0, 1, 1),
+('bx_organizations_common', 'bulk', 'delete_with_content', '_bx_orgs_grid_action_title_adm_delete_with_content', '', 0, 1, 2),
+('bx_organizations_common', 'single', 'settings', '_bx_orgs_grid_action_title_adm_more_actions', 'cog', 1, 0, 1);
+
+
+-- LIVE UPDATES
+INSERT INTO `sys_objects_live_updates`(`name`, `frequency`, `service_call`, `active`) VALUES
+('bx_organizations_friend_requests', 1, 'a:4:{s:6:"module";s:6:"system";s:6:"method";s:40:"get_live_updates_unconfirmed_connections";s:6:"params";a:5:{i:0;s:16:"bx_organizations";i:1;s:20:"sys_profiles_friends";i:2;a:2:{s:11:"menu_object";s:18:"sys_toolbar_member";s:9:"menu_item";s:7:"account";}i:3;a:2:{s:11:"menu_object";s:25:"sys_account_notifications";s:9:"menu_item";s:29:"notifications-friend-requests";}i:4;s:7:"{count}";}s:5:"class";s:23:"TemplServiceConnections";}', 1);
+
+
+-- ALERTS
+INSERT INTO `sys_alerts_handlers` (`name`, `class`, `file`, `service_call`) VALUES 
+('bx_organizations', 'BxOrgsAlertsResponse', 'modules/boonex/organizations/classes/BxOrgsAlertsResponse.php', '');
+SET @iHandler := LAST_INSERT_ID();
+
+INSERT INTO `sys_alerts` (`unit`, `action`, `handler_id`) VALUES
+('system', 'save_setting', @iHandler),
+('account', 'check_switch_context', @iHandler),
+('sys_profiles_friends', 'connection_added', @iHandler),
+('bx_timeline', 'post_common', @iHandler),
+('bx_organizations_pics', 'file_deleted', @iHandler),
+('bx_organizations_fans', 'connection_added', @iHandler),
+('bx_organizations_fans', 'connection_removed', @iHandler),
+('bx_organizations', 'fan_added', @iHandler),
+('bx_organizations', 'join_invitation', @iHandler),
+('bx_organizations', 'join_request', @iHandler),
+('bx_organizations', 'join_request_accepted', @iHandler),
+('bx_organizations', 'timeline_view', @iHandler),
+('bx_organizations', 'timeline_post', @iHandler),
+('bx_organizations', 'timeline_delete', @iHandler),
+('bx_organizations', 'timeline_comment', @iHandler),
+('bx_organizations', 'timeline_vote', @iHandler),
+('bx_organizations', 'timeline_report', @iHandler),
+('bx_organizations', 'timeline_repost', @iHandler);
+
+
+-- PRIVACY 
+INSERT INTO `sys_objects_privacy` (`object`, `module`, `action`, `title`, `default_group`, `table`, `table_field_id`, `table_field_author`, `override_class_name`, `override_class_file`) VALUES
+('bx_organizations_allow_view_to', 'bx_organizations', 'view', '_bx_orgs_form_profile_input_allow_view_to', '3', 'bx_organizations_data', 'id', 'author', 'BxOrgsPrivacy', 'modules/boonex/organizations/classes/BxOrgsPrivacy.php'),
+('bx_organizations_allow_view_notification_to', 'bx_organizations', 'view_event', '_bx_orgs_form_profile_input_allow_view_notification_to', '3', 'bx_notifications_events', 'id', 'object_owner_id', 'BxOrgsPrivacyNotifications', 'modules/boonex/organizations/classes/BxOrgsPrivacyNotifications.php');
+
+
+-- EMAIL TEMPLATES
+INSERT INTO `sys_email_templates` (`Module`, `NameSystem`, `Name`, `Subject`, `Body`) VALUES
+('bx_organizations', '_bx_organizations_email_friend_request', 'bx_organizations_friend_request', '_bx_organizations_email_friend_request_subject', '_bx_organizations_email_friend_request_body'),
+('bx_organizations', '_bx_orgs_email_join_request', 'bx_organizations_join_request', '_bx_orgs_email_join_request_subject', '_bx_orgs_email_join_request_body'),
+('bx_organizations', '_bx_orgs_email_join_reject', 'bx_organizations_join_reject', '_bx_orgs_email_join_reject_subject', '_bx_orgs_email_join_reject_body'),
+('bx_organizations', '_bx_orgs_email_join_confirm', 'bx_organizations_join_confirm', '_bx_orgs_email_join_confirm_subject', '_bx_orgs_email_join_confirm_body'),
+('bx_organizations', '_bx_orgs_email_fan_remove', 'bx_organizations_fan_remove', '_bx_orgs_email_fan_remove_subject', '_bx_orgs_email_fan_remove_body'),
+('bx_organizations', '_bx_orgs_email_fan_become_admin', 'bx_organizations_fan_become_admin', '_bx_orgs_email_fan_become_admin_subject', '_bx_orgs_email_fan_become_admin_body'),
+('bx_organizations', '_bx_orgs_email_admin_become_fan', 'bx_organizations_admin_become_fan', '_bx_orgs_email_admin_become_fan_subject', '_bx_orgs_email_admin_become_fan_body'),
+('bx_organizations', '_bx_orgs_email_invitation', 'bx_organizations_invitation', '_bx_orgs_email_invitation_subject', '_bx_orgs_email_invitation_body');
+
+
+-- UPLOADERS
+INSERT INTO `sys_objects_uploader` (`object`, `active`, `override_class_name`, `override_class_file`) VALUES
+('bx_organizations_cover_crop', 1, 'BxOrgsUploaderCoverCrop', 'modules/boonex/organizations/classes/BxOrgsUploaderCoverCrop.php'),
+('bx_organizations_picture_crop', 1, 'BxOrgsUploaderPictureCrop', 'modules/boonex/organizations/classes/BxOrgsUploaderPictureCrop.php');

+ 320 - 0
modules/boonex/organizations/updates/9.0.5_9.0.6/source/install/sql/install.sql

@@ -0,0 +1,320 @@
+
+SET @sStorageEngine = (SELECT `value` FROM `sys_options` WHERE `name` = 'sys_storage_default');
+
+-- TABLE: PROFILES
+CREATE TABLE IF NOT EXISTS `bx_organizations_data` (
+  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
+  `author` int(10) unsigned NOT NULL,
+  `added` int(11) NOT NULL,
+  `changed` int(11) NOT NULL,
+  `picture` int(11) NOT NULL,
+  `cover` int(11) NOT NULL,
+  `org_name` varchar(255) NOT NULL,
+  `org_cat` int(11) NOT NULL,
+  `org_desc` text NOT NULL,
+  `views` 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',
+  `allow_view_to` varchar(16) NOT NULL DEFAULT '3',
+  PRIMARY KEY (`id`),
+  FULLTEXT KEY `search_fields` (`org_name`,`org_desc`)
+);
+
+-- TABLE: STORAGES & TRANSCODERS
+CREATE TABLE IF NOT EXISTS `bx_organizations_pics` (
+  `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` int(11) 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_organizations_pics_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` int(11) 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_organizations_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(10) unsigned 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',
+  PRIMARY KEY (`cmt_id`),
+  KEY `cmt_object_id` (`cmt_object_id`,`cmt_parent_id`),
+  FULLTEXT KEY `search_fields` (`cmt_text`)
+);
+
+-- TABLE: VIEWS
+CREATE TABLE IF NOT EXISTS `bx_organizations_views_track` (
+  `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',
+  KEY `id` (`object_id`,`viewer_id`,`viewer_nip`)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8;
+
+-- TABLE: favorites
+CREATE TABLE IF NOT EXISTS `bx_organizations_favorites_track` (
+  `object_id` int(11) NOT NULL default '0',
+  `author_id` int(11) NOT NULL default '0',
+  `date` int(11) NOT NULL default '0',
+  KEY `id` (`object_id`,`author_id`)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8;
+
+-- TABLE: reports
+CREATE TABLE IF NOT EXISTS `bx_organizations_reports` (
+  `object_id` int(11) NOT NULL default '0',
+  `count` int(11) NOT NULL default '0',
+  UNIQUE KEY `object_id` (`object_id`)
+) ENGINE=MYISAM DEFAULT CHARSET=utf8;
+
+CREATE TABLE IF NOT EXISTS `bx_organizations_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',
+  PRIMARY KEY (`id`),
+  KEY `report` (`object_id`, `author_nip`)
+) ENGINE=MYISAM DEFAULT CHARSET=utf8;
+
+-- TABLE: metas
+CREATE TABLE IF NOT EXISTS `bx_organizations_meta_keywords` (
+  `object_id` int(10) unsigned NOT NULL,
+  `keyword` varchar(255) NOT NULL,
+  KEY `object_id` (`object_id`),
+  KEY `keyword` (`keyword`)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8;
+
+CREATE TABLE IF NOT EXISTS `bx_organizations_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))
+) ENGINE=MyISAM DEFAULT CHARSET=utf8;
+
+-- TABLE: fans
+CREATE TABLE IF NOT EXISTS `bx_organizations_fans` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `initiator` int(11) NOT NULL,
+  `content` int(11) NOT NULL,
+  `mutual` tinyint(4) NOT NULL,
+  `added` int(10) unsigned NOT NULL,
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `initiator` (`initiator`,`content`),
+  KEY `content` (`content`)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8;
+
+-- TABLE: admins
+CREATE TABLE IF NOT EXISTS `bx_organizations_admins` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `group_profile_id` int(10) unsigned NOT NULL,
+  `fan_id` int(10) unsigned NOT NULL,
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `admin` (`group_profile_id`,`fan_id`)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8;
+
+
+-- 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_organizations_pics', @sStorageEngine, '', 360, 2592000, 3, 'bx_organizations_pics', 'allow-deny', 'jpg,jpeg,jpe,gif,png', '', 0, 0, 0, 0, 0, 0),
+('bx_organizations_pics_resized', @sStorageEngine, '', 360, 2592000, 3, 'bx_organizations_pics_resized', 'allow-deny', 'jpg,jpeg,jpe,gif,png', '', 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_organizations_icon', 'bx_organizations_pics_resized', 'Storage', 'a:1:{s:6:"object";s:21:"bx_organizations_pics";}', 'no', '1', '2592000', '0'),
+('bx_organizations_thumb', 'bx_organizations_pics_resized', 'Storage', 'a:1:{s:6:"object";s:21:"bx_organizations_pics";}', 'no', '1', '2592000', '0'),
+('bx_organizations_avatar', 'bx_organizations_pics_resized', 'Storage', 'a:1:{s:6:"object";s:21:"bx_organizations_pics";}', 'no', '1', '2592000', '0'),
+('bx_organizations_picture', 'bx_organizations_pics_resized', 'Storage', 'a:1:{s:6:"object";s:21:"bx_organizations_pics";}', 'no', '1', '2592000', '0'),
+('bx_organizations_cover', 'bx_organizations_pics_resized', 'Storage', 'a:1:{s:6:"object";s:21:"bx_organizations_pics";}', 'no', '1', '2592000', '0'),
+('bx_organizations_cover_thumb', 'bx_organizations_pics_resized', 'Storage', 'a:1:{s:6:"object";s:21:"bx_organizations_pics";}', 'no', '1', '2592000', '0'),
+('bx_organizations_gallery', 'bx_organizations_pics_resized', 'Storage', 'a:1:{s:6:"object";s:21:"bx_organizations_pics";}', 'no', '1', '2592000', '0');
+
+INSERT INTO `sys_transcoder_filters` (`transcoder_object`, `filter`, `filter_params`, `order`) VALUES 
+('bx_organizations_icon', 'Resize', 'a:3:{s:1:"w";s:2:"32";s:1:"h";s:2:"32";s:13:"square_resize";s:1:"1";}', '0'),
+('bx_organizations_thumb', 'Resize', 'a:3:{s:1:"w";s:2:"48";s:1:"h";s:2:"48";s:13:"square_resize";s:1:"1";}', '0'),
+('bx_organizations_avatar', 'Resize', 'a:3:{s:1:"w";s:2:"96";s:1:"h";s:2:"96";s:13:"square_resize";s:1:"1";}', '0'),
+('bx_organizations_picture', 'Resize', 'a:3:{s:1:"w";s:4:"1024";s:1:"h";s:4:"1024";s:13:"square_resize";s:1:"0";}', '0'),
+('bx_organizations_cover', 'Resize', 'a:1:{s:1:"w";s:4:"2000";}', '0'),
+('bx_organizations_cover_thumb', 'Resize', 'a:3:{s:1:"w";s:2:"48";s:1:"h";s:2:"48";s:13:"square_resize";s:1:"1";}', '0'),
+('bx_organizations_gallery', 'Resize', 'a:1:{s:1:"w";s:3:"500";}', '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_organization', 'bx_organizations', '_bx_orgs_form_profile', '', 'a:1:{s:7:\"enctype\";s:19:\"multipart/form-data\";}', 'bx_organizations_data', 'id', '', '', 'do_submit', '', 0, 1, 'BxOrgsFormEntry', 'modules/boonex/organizations/classes/BxOrgsFormEntry.php');
+
+INSERT INTO `sys_form_displays`(`object`, `display_name`, `module`, `view_mode`, `title`) VALUES 
+('bx_organization', 'bx_organization_add', 'bx_organizations', 0, '_bx_orgs_form_profile_display_add'),
+('bx_organization', 'bx_organization_delete', 'bx_organizations', 0, '_bx_orgs_form_profile_display_delete'),
+('bx_organization', 'bx_organization_edit', 'bx_organizations', 0, '_bx_orgs_form_profile_display_edit'),
+('bx_organization', 'bx_organization_edit_cover', 'bx_organizations', 0, '_bx_orgs_form_profile_display_edit_cover'),
+('bx_organization', 'bx_organization_view', 'bx_organizations', 1, '_bx_orgs_form_profile_display_view'),
+('bx_organization', 'bx_organization_view_full', 'bx_organizations', 1, '_bx_orgs_form_profile_display_view_full'),
+('bx_organization', 'bx_organization_invite', 'bx_organizations', 0, '_bx_orgs_form_profile_display_invite');
+
+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_organization', 'bx_organizations', 'allow_view_to', 3, '', 0, 'custom', '_bx_orgs_form_profile_input_sys_allow_view_to', '_bx_orgs_form_profile_input_allow_view_to', '_bx_orgs_form_profile_input_allow_view_to_info', 0, 0, 0, '', '', '', '', '', '', '', '', 1, 0),
+('bx_organization', 'bx_organizations', 'delete_confirm', 1, '', 0, 'checkbox', '_bx_orgs_form_profile_input_sys_delete_confirm', '_bx_orgs_form_profile_input_delete_confirm', '_bx_orgs_form_profile_input_delete_confirm_info', 1, 0, 0, '', '', '', 'avail', '', '_bx_orgs_form_profile_input_delete_confirm_error', '', '', 1, 0),
+('bx_organization', 'bx_organizations', 'do_submit', '_sys_form_account_input_submit', '', 0, 'submit', '_bx_orgs_form_profile_input_sys_do_submit', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 1, 0),
+('bx_organization', 'bx_organizations', 'org_desc', '', '', 0, 'textarea', '_bx_orgs_form_profile_input_sys_org_desc', '_bx_orgs_form_profile_input_org_desc', '', 0, 0, 0, '', '', '', '', '', '', 'XssMultiline', '', 1, 1),
+('bx_organization', 'bx_organizations', 'org_cat', '', '#!bx_organizations_cats', 0, 'select', '_bx_orgs_form_profile_input_sys_org_cat', '_bx_orgs_form_profile_input_org_cat', '', 1, 0, 0, '', '', '', 'avail', '', '_bx_orgs_form_profile_input_org_cat_err', 'Xss', '', 1, 1),
+('bx_organization', 'bx_organizations', 'org_name', '', '', 0, 'text', '_bx_orgs_form_profile_input_sys_org_name', '_bx_orgs_form_profile_input_org_name', '', 1, 0, 0, '', '', '', 'avail', '', '_bx_orgs_form_profile_input_org_name_err', 'Xss', '', 1, 0),
+('bx_organization', 'bx_organizations', 'initial_members', '', '', 0, 'custom', '_bx_orgs_form_profile_input_sys_initial_members', '_bx_orgs_form_profile_input_initial_members', '', 0, 0, 0, '', '', '', '', '', '', '', '', 1, 1),
+('bx_organization', 'bx_organizations', 'join_confirmation', 1, '', 1, 'switcher', '_bx_orgs_form_profile_input_sys_join_confirm', '_bx_orgs_form_profile_input_join_confirm', '', 0, 0, 0, '', '', '', '', '', '', 'Xss', '', 1, 0),
+('bx_organization', 'bx_organizations', 'cover', 'a:1:{i:0;s:27:"bx_organizations_cover_crop";}', 'a:1:{s:27:"bx_organizations_cover_crop";s:24:"_sys_uploader_crop_title";}', 0, 'files', '_bx_orgs_form_profile_input_sys_cover', '_bx_orgs_form_profile_input_cover', '', 0, 0, 0, '', '', '', '', '', '', '', '', 1, 0),
+('bx_organization', 'bx_organizations', 'picture', 'a:1:{i:0;s:29:"bx_organizations_picture_crop";}', 'a:1:{s:29:"bx_organizations_picture_crop";s:24:"_sys_uploader_crop_title";}', 0, 'files', '_bx_orgs_form_profile_input_sys_picture', '_bx_orgs_form_profile_input_picture', '', 0, 0, 0, '', '', '', '', '', '_bx_orgs_form_profile_input_picture_err', '', '', 1, 0),
+('bx_organization', 'bx_organizations', 'location', '', '', 0, 'location', '_sys_form_input_sys_location', '_sys_form_input_location', '', 0, 0, 0, '', '', '', '', '', '', '', '', 1, 0),
+('bx_organization', 'bx_organizations', 'profile_email', '', '', 0, 'text', '_bx_orgs_form_profile_input_sys_profile_email', '_bx_orgs_form_profile_input_profile_email', '', 0, 0, 0, '', '', '', '', '', '', 'Xss', '', 1, 0),
+('bx_organization', 'bx_organizations', 'profile_status', '', '', 0, 'custom', '_bx_orgs_form_profile_input_sys_profile_status', '_bx_orgs_form_profile_input_profile_status', '', 0, 0, 0, '', '', '', '', '', '', 'Xss', '', 1, 0);
+
+
+INSERT INTO `sys_form_display_inputs`(`display_name`, `input_name`, `visible_for_levels`, `active`, `order`) VALUES
+('bx_organization_add', 'initial_members', 2147483647, 1, 1),
+('bx_organization_add', 'picture', 2147483647, 1, 2),
+('bx_organization_add', 'org_name', 2147483647, 1, 3),
+('bx_organization_add', 'org_cat', 2147483647, 1, 4),
+('bx_organization_add', 'org_desc', 2147483647, 1, 5),
+('bx_organization_add', 'location', 2147483647, 1, 6),
+('bx_organization_add', 'join_confirmation', 2147483647, 1, 7),
+('bx_organization_add', 'allow_view_to', 2147483647, 1, 8),
+('bx_organization_add', 'do_submit', 2147483647, 1, 9),
+
+('bx_organization_invite', 'initial_members', 2147483647, 1, 1),
+('bx_organization_invite', 'do_submit', 2147483647, 1, 2),
+
+('bx_organization_delete', 'delete_confirm', 2147483647, 1, 1),
+('bx_organization_delete', 'do_submit', 2147483647, 1, 2),
+
+('bx_organization_edit', 'picture', 2147483647, 1, 1),
+('bx_organization_edit', 'org_name', 2147483647, 1, 2),
+('bx_organization_edit', 'org_cat', 2147483647, 1, 3),
+('bx_organization_edit', 'org_desc', 2147483647, 1, 4),
+('bx_organization_edit', 'location', 2147483647, 1, 5),
+('bx_organization_edit', 'join_confirmation', 2147483647, 1, 6),
+('bx_organization_edit', 'allow_view_to', 2147483647, 1, 7),
+('bx_organization_edit', 'do_submit', 2147483647, 1, 8),
+
+('bx_organization_edit_cover', 'cover', 2147483647, 1, 1),
+('bx_organization_edit_cover', 'do_submit', 2147483647, 1, 2),
+
+('bx_organization_view', 'org_name', 2147483647, 1, 1),
+('bx_organization_view', 'org_cat', 2147483647, 1, 2),
+('bx_organization_view', 'profile_email', 192, 1, 3),
+('bx_organization_view', 'profile_status', 192, 1, 4),
+
+('bx_organization_view_full', 'org_name', 2147483647, 1, 1),
+('bx_organization_view_full', 'org_cat', 2147483647, 1, 2),
+('bx_organization_view_full', 'org_desc', 2147483647, 1, 3),
+('bx_organization_view_full', 'profile_email', 192, 1, 4),
+('bx_organization_view_full', 'profile_status', 192, 1, 5);
+
+
+-- PRE-VALUES
+INSERT INTO `sys_form_pre_lists`(`key`, `title`, `module`, `use_for_sets`) VALUES
+('bx_organizations_cats', '_bx_orgs_pre_lists_cats', 'bx_organizations', '0');
+
+INSERT INTO `sys_form_pre_values`(`Key`, `Value`, `Order`, `LKey`, `LKey2`) VALUES
+('bx_organizations_cats', '', 0, '_sys_please_select', ''),
+('bx_organizations_cats', '1', 1, '_bx_orgs_cat_Agriculture', ''),
+('bx_organizations_cats', '2', 2, '_bx_orgs_cat_Financial', ''),
+('bx_organizations_cats', '3', 3, '_bx_orgs_cat_Biotech', ''),
+('bx_organizations_cats', '4', 4, '_bx_orgs_cat_Cause', ''),
+('bx_organizations_cats', '5', 5, '_bx_orgs_cat_Chemical', ''),
+('bx_organizations_cats', '6', 6, '_bx_orgs_cat_Religious', ''),
+('bx_organizations_cats', '7', 7, '_bx_orgs_cat_Community', ''),
+('bx_organizations_cats', '8', 8, '_bx_orgs_cat_Company', ''),
+('bx_organizations_cats', '9', 9, '_bx_orgs_cat_Entertainment', ''),
+('bx_organizations_cats', '10', 10, '_bx_orgs_cat_Technology', ''),
+('bx_organizations_cats', '11', 11, '_bx_orgs_cat_Consulting', ''),
+('bx_organizations_cats', '12', 12, '_bx_orgs_cat_Education', ''),
+('bx_organizations_cats', '13', 13, '_bx_orgs_cat_Energy', ''),
+('bx_organizations_cats', '14', 14, '_bx_orgs_cat_Engineering', ''),
+('bx_organizations_cats', '15', 15, '_bx_orgs_cat_Food', ''),
+('bx_organizations_cats', '16', 16, '_bx_orgs_cat_Government', ''),
+('bx_organizations_cats', '17', 17, '_bx_orgs_cat_Health', ''),
+('bx_organizations_cats', '18', 18, '_bx_orgs_cat_Medical', ''),
+('bx_organizations_cats', '19', 19, '_bx_orgs_cat_Industrial', ''),
+('bx_organizations_cats', '20', 20, '_bx_orgs_cat_Insurance', ''),
+('bx_organizations_cats', '21', 21, '_bx_orgs_cat_Internet', ''),
+('bx_organizations_cats', '22', 22, '_bx_orgs_cat_Software', ''),
+('bx_organizations_cats', '23', 23, '_bx_orgs_cat_Legal', ''),
+('bx_organizations_cats', '24', 24, '_bx_orgs_cat_Media', ''),
+('bx_organizations_cats', '25', 25, '_bx_orgs_cat_School', ''),
+('bx_organizations_cats', '26', 26, '_bx_orgs_cat_NGO', ''),
+('bx_organizations_cats', '27', 27, '_bx_orgs_cat_NPO', ''),
+('bx_organizations_cats', '28', 28, '_bx_orgs_cat_Political', ''),
+('bx_organizations_cats', '29', 29, '_bx_orgs_cat_Retail', ''),
+('bx_organizations_cats', '30', 30, '_bx_orgs_cat_Small_Business', ''),
+('bx_organizations_cats', '31', 31, '_bx_orgs_cat_Telecommunication', ''),
+('bx_organizations_cats', '32', 32, '_bx_orgs_cat_Transport', ''),
+('bx_organizations_cats', '33', 33, '_bx_orgs_cat_Travel', ''),
+('bx_organizations_cats', '34', 34, '_bx_orgs_cat_University', ''),
+('bx_organizations_cats', '35', 35, '_bx_orgs_cat_Other', '');
+
+
+-- 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_organizations', '_bx_orgs', 'bx_organizations', 'added', 'edited', 'deleted', '', ''),
+('bx_organizations_cmts', '_bx_orgs_cmts', 'bx_organizations', 'commentPost', 'commentUpdated', 'commentRemoved', 'BxDolContentInfoCmts', '');
+
+INSERT INTO `sys_content_info_grids` (`object`, `grid_object`, `grid_field_id`, `condition`, `selection`) VALUES
+('bx_organizations', 'bx_organizations_administration', 'td`.`id', '', ''),
+('bx_organizations', 'bx_organizations_common', 'td`.`id', '', '');
+
+
+-- SEARCH EXTENDED
+INSERT INTO `sys_objects_search_extended` (`object`, `object_content_info`, `module`, `title`, `active`, `class_name`, `class_file`) VALUES
+('bx_organizations', 'bx_organizations', 'bx_organizations', '_bx_orgs_search_extended', 1, '', ''),
+('bx_organizations_cmts', 'bx_organizations_cmts', 'bx_organizations', '_bx_orgs_search_extended_cmts', 1, 'BxTemplSearchExtendedCmts', '');
+
+
+-- STUDIO PAGE & WIDGET
+INSERT INTO `sys_std_pages`(`index`, `name`, `header`, `caption`, `icon`) VALUES
+(3, 'bx_organizations', '_bx_orgs', '_bx_orgs', 'bx_organizations@modules/boonex/organizations/|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`, `url`, `click`, `icon`, `caption`, `cnt_notices`, `cnt_actions`) VALUES
+(@iPageId, 'bx_organizations', '{url_studio}module.php?name=bx_organizations', '', 'bx_organizations@modules/boonex/organizations/|std-icon.svg', '_bx_orgs', '', '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));

+ 38 - 0
modules/boonex/organizations/updates/9.0.5_9.0.6/source/install/sql/uninstall.sql

@@ -0,0 +1,38 @@
+
+-- TABLES
+DROP TABLE IF EXISTS `bx_organizations_data`, `bx_organizations_pics`, `bx_organizations_pics_resized`, `bx_organizations_cmts`, `bx_organizations_views_track`, `bx_organizations_favorites_track`, `bx_organizations_reports`, `bx_organizations_reports_track`, `bx_organizations_meta_keywords`, `bx_organizations_meta_locations`, `bx_organizations_fans`, `bx_organizations_admins`;
+
+-- PROFILES
+DELETE FROM sys_profiles WHERE `type` = 'bx_organizations';
+
+-- STORAGES & TRANSCODERS
+DELETE FROM `sys_objects_storage` WHERE `object` IN('bx_organizations_pics', 'bx_organizations_pics_resized');
+DELETE FROM `sys_storage_tokens` WHERE `object` IN('bx_organizations_pics', 'bx_organizations_pics_resized');
+
+DELETE FROM `sys_objects_transcoder` WHERE `object` IN('bx_organizations_icon', 'bx_organizations_thumb', 'bx_organizations_avatar', 'bx_organizations_picture', 'bx_organizations_cover', 'bx_organizations_cover_thumb', 'bx_organizations_gallery');
+DELETE FROM `sys_transcoder_filters` WHERE `transcoder_object` IN('bx_organizations_icon', 'bx_organizations_thumb', 'bx_organizations_avatar', 'bx_organizations_picture', 'bx_organizations_cover', 'bx_organizations_cover_thumb', 'bx_organizations_gallery');
+DELETE FROM `sys_transcoder_images_files` WHERE `transcoder_object` IN('bx_organizations_icon', 'bx_organizations_thumb', 'bx_organizations_avatar', 'bx_organizations_picture', 'bx_organizations_cover', 'bx_organizations_cover_thumb', 'bx_organizations_gallery');
+
+-- FORMS
+DELETE FROM `sys_objects_form` WHERE `module` = 'bx_organizations';
+DELETE FROM `sys_form_displays` WHERE `module` = 'bx_organizations';
+DELETE FROM `sys_form_inputs` WHERE `module` = 'bx_organizations';
+DELETE FROM `sys_form_display_inputs` WHERE `display_name` IN('bx_organization_add', 'bx_organization_delete', 'bx_organization_edit', 'bx_organization_edit_cover', 'bx_organization_view', 'bx_organization_view_full', 'bx_organization_invite');
+
+-- PRE-VALUES
+DELETE FROM `sys_form_pre_lists` WHERE `module` = 'bx_organizations';
+
+DELETE FROM `sys_form_pre_values` WHERE `Key` IN('bx_organizations_cats');
+
+-- CONTENT INFO
+DELETE FROM `sys_objects_content_info` WHERE `name` IN ('bx_organizations', 'bx_organizations_cmts');
+
+DELETE FROM `sys_content_info_grids` WHERE `object` IN ('bx_organizations');
+
+-- SEARCH EXTENDED
+DELETE FROM `sys_objects_search_extended` WHERE `module` = 'bx_organizations';
+
+-- STUDIO PAGE & WIDGET
+DELETE FROM `tp`, `tw`, `tpw`
+USING `sys_std_pages` AS `tp`, `sys_std_widgets` AS `tw`, `sys_std_pages_widgets` AS `tpw`
+WHERE `tp`.`id` = `tw`.`page_id` AND `tw`.`id` = `tpw`.`widget_id` AND `tp`.`name` = 'bx_organizations';

+ 1 - 0
modules/boonex/organizations/updates/9.0.5_9.0.6/source/template/unit_live_search.html

@@ -0,0 +1 @@
+<bx_include_base:../modules/base/profile/template/unit_live_search.html />

+ 1 - 0
modules/boonex/organizations/updates/9.0.5_9.0.6/source/template/unit_meta_item.html

@@ -0,0 +1 @@
+<bx_include_base:../modules/base/profile/template/unit_meta_item.html />

+ 1 - 0
modules/boonex/organizations/updates/9.0.5_9.0.6/source/template/unit_wo_info_links.html

@@ -0,0 +1 @@
+<bx_include_base:../modules/base/profile/template/unit_wo_info_links.html />

+ 339 - 0
modules/boonex/payment/updates/9.0.5_9.0.6/source/classes/BxPaymentCart.php

@@ -0,0 +1,339 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Payment Payment
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+class BxPaymentCart extends BxBaseModPaymentCart
+{
+    function __construct()
+    {
+    	$this->MODULE = 'bx_payment';
+
+    	parent::__construct();
+    }
+
+    /*
+     * Service methods
+     */
+    
+    /**
+     * @page service Service Calls
+     * @section bx_payment Payment
+     * @subsection bx_payment-page_blocks Page Blocks
+     * @subsubsection bx_payment-get_block_carts get_block_carts
+     * 
+     * @code bx_srv('bx_payment', 'get_block_carts', [...], 'Cart'); @endcode
+     * 
+     * Get page block with shopping carts by vendors.
+     *
+     * @return an array describing a block to display on the site or an empty string if something is wrong. All necessary CSS and JS files are automatically added to the HEAD section of the site HTML.
+     * 
+     * @see BxPaymentCart::serviceGetBlockCarts
+     */
+    /** 
+     * @ref bx_payment-get_block_carts "get_block_carts"
+     */
+	public function serviceGetBlockCarts()
+    {
+    	$CNF = &$this->_oModule->_oConfig->CNF;
+
+    	if(bx_get('seller_id') !== false)
+    		return '';
+
+    	$iUserId = $this->_oModule->getProfileId();
+        if(empty($iUserId))
+            return MsgBox(_t($CNF['T']['ERR_REQUIRED_LOGIN']));
+
+        return array(
+        	'content' => $this->_oModule->_oTemplate->displayBlockCarts($iUserId)
+        );
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_payment Payment
+     * @subsection bx_payment-page_blocks Page Blocks
+     * @subsubsection bx_payment-get_block_cart get_block_cart
+     * 
+     * @code bx_srv('bx_payment', 'get_block_cart', [...], 'Cart'); @endcode
+     * 
+     * Get page block with content of selected shopping cart.
+     *
+     * @return an array describing a block to display on the site or an empty string if something is wrong. All necessary CSS and JS files are automatically added to the HEAD section of the site HTML.
+     * 
+     * @see BxPaymentCart::serviceGetBlockCart
+     */
+    /** 
+     * @ref bx_payment-get_block_cart "get_block_cart"
+     */
+	public function serviceGetBlockCart()
+    {
+    	// Don't show the block at all if 'seller_id' not exists.
+    	if(bx_get('seller_id') === false)
+    		return '';
+
+    	$CNF = &$this->_oModule->_oConfig->CNF;
+
+    	$iUserId = $this->_oModule->getProfileId();
+        if(empty($iUserId))
+            return array(
+            	'content' => MsgBox(_t($CNF['T']['ERR_REQUIRED_LOGIN']))
+            );
+
+    	$iSellerId = bx_process_input(bx_get('seller_id'), BX_DATA_INT);
+    	if(empty($iSellerId))
+    		return array(
+            	'content' => MsgBox(_t($CNF['T']['ERR_UNKNOWN_VENDOR']))
+    		);
+
+		$aSeller = $this->_oModule->getProfileInfo($iSellerId);
+        return array(
+        	'title' => _t($CNF['T']['BLOCK_TITLE_CART'], $aSeller['name']),
+        	'content' => $this->_oModule->_oTemplate->displayBlockCart($iUserId, $iSellerId)
+        );
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_payment Payment
+     * @subsection bx_payment-page_blocks Page Blocks
+     * @subsubsection bx_payment-get_block_cart_history get_block_cart_history
+     * 
+     * @code bx_srv('bx_payment', 'get_block_cart_history', [...], 'Cart'); @endcode
+     * 
+     * Get page block with shopping cart history.
+     *
+     * @return an array describing a block to display on the site or an empty string if something is wrong. All necessary CSS and JS files are automatically added to the HEAD section of the site HTML.
+     * 
+     * @see BxPaymentCart::serviceGetBlockCartHistory
+     */
+    /** 
+     * @ref bx_payment-get_block_cart_history "get_block_cart_history"
+     */
+    public function serviceGetBlockCartHistory()
+    {
+    	$CNF = &$this->_oModule->_oConfig->CNF;
+
+		$iSellerId = bx_get('vendor') !== false ? (int)bx_get('vendor') : 0;
+
+    	$iUserId = $this->_oModule->getProfileId();
+        if(empty($iUserId))
+            return array(
+            	'content' => MsgBox(_t($CNF['T']['ERR_REQUIRED_LOGIN']))
+            );
+
+        return array(
+        	'content' => $this->_oModule->_oTemplate->displayBlockHistory($iUserId, $iSellerId),
+		);
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_payment Payment
+     * @subsection bx_payment-purchase_processing Purchase Processing
+     * @subsubsection bx_payment-add_to_cart add_to_cart
+     * 
+     * @code bx_srv('bx_payment', 'add_to_cart', [...], 'Cart'); @endcode
+     * 
+     * Add an item described with method's params to shopping cart.
+     *
+     * @param $iSellerId integer value with seller ID.
+     * @param $mixedModuleId mixed value (ID, Name or URI) determining a module from which the action was initiated.
+     * @param $iItemId integer value with item ID.
+     * @param $iItemCount integer value with a number of items for purchasing.
+     * @param $aCustom array with custom data.
+     * @return an array with special format which describes the result of operation.
+     * 
+     * @see BxPaymentCart::serviceAddToCart
+     */
+    /** 
+     * @ref bx_payment-add_to_cart "add_to_cart"
+     */
+    public function serviceAddToCart($iSellerId, $mixedModuleId, $iItemId, $iItemCount, $aCustom = array())
+    {
+    	$CNF = &$this->_oModule->_oConfig->CNF;
+
+    	$iModuleId = $this->_oModule->_oConfig->getModuleId($mixedModuleId);
+    	$iClientId = $this->_oModule->getProfileId();
+
+    	$mixedResult = $this->_oModule->checkData($iClientId, $iSellerId, $iModuleId, $iItemId, $iItemCount);
+    	if($mixedResult !== true)
+    		return $mixedResult;
+
+        $aSellerProviders = $this->_oModule->_oDb->getVendorInfoProvidersSingle($iSellerId);
+        if(empty($aSellerProviders))
+            return array('code' => 5, 'message' => _t($CNF['T']['ERR_NOT_ACCEPT_PAYMENTS']));
+
+        $aCart = $this->_oModule->_oDb->getCartContent($iClientId);
+        $sCartItems = !empty($aCart['items']) ? $aCart['items'] : '';
+
+        $sCiDsc = $this->_oModule->_oConfig->descriptorA2S(array($iSellerId, $iModuleId, $iItemId));
+        if(strpos($sCartItems, $sCiDsc) !== false)
+            $sCartItems = preg_replace_callback(
+            	"/" . $this->_oModule->_oConfig->descriptorA2S(array($iSellerId, $iModuleId, $iItemId, '([0-9])+')) . "/", 
+            	create_function('$aMatches', 'return ' . $this->_oModule->_oConfig->descriptorA2S(array("'" . $iSellerId, $iModuleId, $iItemId, "' . (\$aMatches[1] + " . $iItemCount . ")")) . ';'),
+            	$sCartItems
+			);
+        else {
+            $sCartItem = $this->_oModule->_oConfig->descriptorA2S(array($iSellerId, $iModuleId, $iItemId, $iItemCount));
+            $sCartItems = empty($sCartItems) ? $sCartItem : $sCartItems . $this->_oModule->_oConfig->getDivider('DIVIDER_DESCRIPTORS') . $sCartItem;
+        }
+
+        $aCartCustom = array();
+        if(!empty($aCart['customs']))
+            $aCartCustom = unserialize($aCart['customs']);
+
+        if(!empty($aCustom) && is_array($aCustom))
+            $aCartCustom[$sCiDsc] = !empty($aCartCustom[$sCiDsc]) && is_array($aCartCustom[$sCiDsc]) ? array_merge($aCartCustom[$sCiDsc], $aCustom) : $aCustom;
+
+        $this->_oModule->_oDb->setCartItems($iClientId, $sCartItems, $aCartCustom);
+
+        $aInfo = $this->getInfo(BX_PAYMENT_TYPE_SINGLE, $iClientId);
+        $iTotalQuantity = 0;
+        foreach($aInfo as $aCart)
+           $iTotalQuantity += $aCart['items_count'];
+
+        return array(
+        	'code' => 0, 
+        	'message' => _t($CNF['T']['MSG_ITEM_ADDED']), 
+        	'total_quantity' => $iTotalQuantity,
+	        //TODO: Update account submenu if it's needed.  
+        	'content' => '' //$this->_oModule->_oTemplate->displayToolbarSubmenu($aInfo)
+        );
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_payment Payment
+     * @subsection bx_payment-purchase_processing Purchase Processing
+     * @subsubsection bx_payment-delete_from_cart delete_from_cart
+     * 
+     * @code bx_srv('bx_payment', 'delete_from_cart', [...], 'Cart'); @endcode
+     * 
+     * Delete an item(s) from shopping cart.
+     *
+     * @param $iSellerId integer value with seller ID. The items owned by this seller will be removed only.
+     * @param $iModuleId (optional) integer value with module ID. If specified, the items related to this module will be removed only.
+     * @param $iItemId (optional) integer value with item ID. If specified, the item with this ID will be removed only.
+     * @return an array with special format which describes the result of operation.
+     * 
+     * @see BxPaymentCart::serviceDeleteFromCart
+     */
+    /** 
+     * @ref bx_payment-delete_from_cart "delete_from_cart"
+     */
+    public function serviceDeleteFromCart($iSellerId, $iModuleId = 0, $iItemId = 0)
+    {
+    	$CNF = &$this->_oModule->_oConfig->CNF;
+
+        if($iSellerId == BX_PAYMENT_EMPTY_ID)
+            return array('code' => 1, 'message' => _t($CNF['T']['ERR_WRONG_DATA']));
+
+		$iClientId = $this->_oModule->getProfileId();
+        if(empty($iClientId))
+            return array('code' => 2, 'message' => _t($CNF['T']['ERR_REQUIRED_LOGIN']));
+
+        $aCart = $this->_oModule->_oDb->getCartContent($iClientId);
+
+        $aCartCustom = array();
+        if(!empty($aCart['customs']))
+            $aCartCustom = unserialize($aCart['customs']);
+
+        if(!empty($iModuleId) && !empty($iItemId)) {
+            $sCiDsc = $this->_oModule->_oConfig->descriptorA2S(array($iSellerId, $iModuleId, $iItemId));
+            if(!empty($aCartCustom[$sCiDsc]))
+                unset($aCartCustom[$sCiDsc]);
+        }
+        else {
+            $aCiDscs = array_keys($aCartCustom);
+            foreach($aCiDscs as $sCiDsc)
+                if(strpos($sCiDsc, $iSellerId . '_') === 0)
+                    unset($aCartCustom[$sCiDsc]);
+
+            $iModuleId = $iItemId = '[0-9]+';
+        }
+
+        $aCart['items'] = trim(preg_replace("'" . $this->_oModule->_oConfig->descriptorA2S(array($iSellerId, $iModuleId, $iItemId, '[0-9]+:?')) . "'", "", $aCart['items']), ":");
+        $this->_oModule->_oDb->setCartItems($iClientId, $aCart['items'], $aCartCustom);
+
+        return array('code' => 0, 'message' => _t($CNF['T']['MSG_ITEM_DELETED']));
+    }
+
+    public function getInfo($sType, $iUserId, $iSellerId = BX_PAYMENT_EMPTY_ID, $aItems = array())
+    {
+        if($iSellerId != BX_PAYMENT_EMPTY_ID && !empty($aItems))
+            return $this->_getInfo($sType, $iUserId, $iSellerId, $this->_oModule->_oConfig->descriptorsM2A($aItems));
+
+        $aContent = $this->_parseByVendor($iUserId);
+
+        if($iSellerId != BX_PAYMENT_EMPTY_ID)
+            return isset($aContent[$iSellerId]) ? $this->_getInfo($sType, $iUserId, $iSellerId, $aContent[$iSellerId]) : array();
+
+        $aResult = array();
+        foreach($aContent as $iSellerId => $aSellerItems)
+            $aResult[$iSellerId] = $this->_getInfo($sType, $iUserId, $iSellerId, $aSellerItems);
+
+        return $aResult;
+    }
+
+    /**
+     * Enter description here...
+     *
+     * @param  integer $iClientId client's ID
+     * @param  integer $iSellerId vendor's ID
+     * @param  array   $aItems    item descriptors(quaternions) from shopping cart.
+     * @return array   with full info about vendor and items.
+     */
+    protected function _getInfo($sType, $iClientId, $iSellerId, $aItems)
+    {
+        $bTypeSingle = $sType == BX_PAYMENT_TYPE_SINGLE;
+
+        $iItemsCount = 0;
+        $fItemsPrice = 0;
+        $aItemsInfo = array();
+        foreach($aItems as $aItem) {
+            $aItemInfo = $this->_oModule->callGetCartItem((int)$aItem['module_id'], array($aItem['item_id']));
+            if(empty($aItemInfo) || !is_array($aItemInfo)) {
+                if($bTypeSingle) {
+                    $sCartItems = $this->_oModule->_oDb->getCartItems($iClientId);
+                    $sCartItems = trim(preg_replace("'" . $this->_oModule->_oConfig->descriptorA2S($aItem) . ":?'", "", $sCartItems), ":");
+                    $this->_oModule->_oDb->setCartItems($iClientId, $sCartItems);
+                }
+
+                continue;
+            }
+
+            $aItemInfo['module_id'] = (int)$aItem['module_id'];
+            $aItemInfo['quantity'] = (int)$aItem['item_count'];
+
+            $iItemsCount += $aItem['item_count'];
+            $fItemsPrice += $aItem['item_count'] * $this->_oModule->_oConfig->getPrice($sType, $aItemInfo);
+            $aItemsInfo[] = $aItemInfo;
+        }
+
+        $aSeller = $this->_oModule->getVendorInfo((int)$iSellerId);
+        return array(
+        	'client_id' => $iClientId,
+            'vendor_id' => $aSeller['id'],
+            'vendor_name' => $aSeller['name'],
+        	'vendor_link' => $aSeller['link'],
+            'vendor_icon' => $aSeller['icon'],
+        	'vendor_thumb' => $aSeller['thumb'],
+        	'vendor_avatar' => $aSeller['avatar'],
+        	'vendor_unit' => $aSeller['unit'],
+            'vendor_currency_code' => $aSeller['currency_code'],
+            'vendor_currency_sign' => $aSeller['currency_sign'],
+            'items_count' => $iItemsCount,
+            'items_price' => $fItemsPrice,
+            'items' => $aItemsInfo
+        );
+    }
+}
+
+/** @} */

+ 273 - 0
modules/boonex/payment/updates/9.0.5_9.0.6/source/classes/BxPaymentConfig.php

@@ -0,0 +1,273 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Payment Payment
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+class BxPaymentConfig extends BxBaseModPaymentConfig
+{
+    function __construct($aModule)
+    {
+        parent::__construct($aModule);
+
+        $sBaseUrl = BX_DOL_URL_ROOT . $this->getBaseUri();
+
+        $this->CNF = array_merge($this->CNF, array(
+        	'URL_JOIN' => 'page.php?i=payment-join',
+        	'URL_CARTS' => 'page.php?i=payment-carts',
+        	'URL_CART' => 'page.php?i=payment-cart',
+        	'URL_CART_CHECKOUT' => $sBaseUrl . 'initialize_checkout/' . BX_PAYMENT_TYPE_SINGLE . '/',
+        	'URL_SUBSCRIBE' => $sBaseUrl . 'subscribe/',
+        	'URL_SUBSCRIPTIONS' => 'page.php?i=payment-sbs-list-my',
+        	'URL_HISTORY' => 'page.php?i=payment-history',
+        	'URL_ORDERS' => 'page.php?i=payment-orders',
+        	'URL_DETAILS' => 'page.php?i=payment-details',
+        	'URL_RETURN' => 'page.php?i=payment-cart-thank-you',
+        	'URL_RETURN_DATA' => $sBaseUrl . 'finalize_checkout/',
+        	'URL_NOTIFY' => $sBaseUrl . 'notify/',
+
+        	'KEY_ARRAY_PRICE_SINGLE' => 'price_single',
+        	'KEY_ARRAY_PRICE_RECURRING' => 'price_recurring',
+        	'KEY_ARRAY_TRIAL_RECURRING' => 'trial_recurring',
+
+            'OBJECT_FORM_PRELISTS_CURRENCIES' => 'bx_payment_currencies',
+
+	        // some language keys
+        	'T' => array(
+        		'MSG_ITEM_ADDED' => '_bx_payment_msg_item_added',
+        		'MSG_ITEM_DELETED' => '_bx_payment_msg_item_deleted',
+        		'ERR_WRONG_DATA' => '_bx_payment_err_wrong_data',
+        		'ERR_REQUIRED_LOGIN' => '_bx_payment_err_required_login',
+        		'ERR_NOT_ACCEPT_PAYMENTS' => '_bx_payment_err_not_accept_payments',
+        		'ERR_SELF_PURCHASE' => '_bx_payment_err_self_purchase',
+        		'ERR_INACTIVE_VENDOR' => '_bx_payment_err_inactive_vendor',
+        		'ERR_UNKNOWN_VENDOR' => '_bx_payment_err_unknown_vendor',
+
+				'BLOCK_TITLE_CART' => '_bx_payment_page_block_title_cart',
+
+        		'POPUP_PROVIDERS_SELECT' => '_bx_payment_popup_title_crd_providers_select', 
+
+        		'TXT_CART_PROVIDER' => '_bx_payment_txt_cart_'
+        	)
+        ));
+
+        $this->_aHtmlIds = array(
+        	'cart' => array(
+        		'providers_select' => $this->_sName . '-cart-providers-select-',
+        	),
+        	'history' => array(
+        		'order_history_view' => $this->_sName . '-order-view-history',
+        	),
+        	'subscription' => array(
+        		'order_subscription_view' => $this->_sName . '-order-view-subscription',
+        		'order_subscription_get_details' => $this->_sName . '-order-get-details-subscription',
+        	    'order_subscription_change_details' => $this->_sName . '-order-change-details-subscription',
+        		'order_subscription_get_billing' => $this->_sName . '-order-get-billing-subscription',
+        		'order_subscription_change_billing' => $this->_sName . '-order-change-billing-subscription',
+        		'form_subscription_change_billing' => $this->_sName . '-form-change-billing-subscription',
+        	    'form_subscription_change_details' => $this->_sName . '-form-change-details-subscription',
+        	),
+        	'pending' => array(
+        		'order_pending_view' => $this->_sName . '-order-view-pending',
+        		'order_pending_process' => $this->_sName . '-order-process',
+        	),
+        	'processed' => array(
+        		'order_processed_view' => $this->_sName . '-order-view-processed',
+        		'order_processed_add' => $this->_sName . '-order-add',
+        		'order_processed_client_id' => $this->_sName . '-oa-client-id',
+        		'order_processed_client' => $this->_sName . '-oa-client',
+        		'order_processed_items' => $this->_sName . '-oa-items',	
+        	),
+        );
+
+        $this->_aPerPage = array(
+        	'orders' => 10,
+        	'history' => 10
+        );
+        $this->_aHandlers = array();
+
+        $this->_aJsClasses = array(
+        	'cart' => 'BxPaymentCart',
+        	'history' => 'BxPaymentOrders',
+        	'subscription' => 'BxPaymentSubscriptions',
+        	'pending' => 'BxPaymentOrders',
+        	'processed' => 'BxPaymentOrders',
+        	'stripe' => 'BxPaymentProviderStripe'
+        );
+
+        $this->_aJsObjects = array(
+        	'cart' => 'oPaymentCart',
+        	'history' => 'oPaymentOrders',
+        	'subscription' => 'oBxPaymentSubscriptions',
+        	'pending' => 'oPaymentOrders',
+        	'processed' => 'oPaymentOrders',
+        	'stripe' => 'oPaymentProviderStripe'
+        );
+    }
+
+    public function init(&$oDb)
+    {
+        parent::init($oDb);
+
+        $sPrefix = $this->getPrefix('options');
+
+        $aCurrencies = BxDolForm::getDataItems($this->CNF['OBJECT_FORM_PRELISTS_CURRENCIES'], false, BX_DATA_VALUES_ADDITIONAL);
+        $this->_sCurrencyCode = $this->_oDb->getParam($sPrefix . 'default_currency_code');
+        $this->_sCurrencySign = $aCurrencies[$this->_sCurrencyCode];
+    }
+
+	public function getLicense()
+    {
+        list($fMilliSec, $iSec) = explode(' ', microtime());
+        $fSeed = (float)$iSec + ((float)$fMilliSec * 100000);
+        srand($fSeed);
+
+        $sResult = '';
+        for($i=0; $i < 16; ++$i) {
+            switch(rand(1,2)) {
+                case 1:
+                    $c = chr(rand(ord('A'),ord('Z')));
+                    break;
+                case 2:
+                    $c = chr(rand(ord('0'),ord('9')));
+                    break;
+            }
+            $sResult .= $c;
+        }
+
+        return $sResult;
+    }
+
+    public function getPrice($sType, $aItem)
+    {
+    	$fPrice = 0;
+
+		switch($sType) {
+			case BX_PAYMENT_TYPE_SINGLE:
+				$fPrice = $aItem[$this->getKey('KEY_ARRAY_PRICE_SINGLE')];
+				break;
+
+			case BX_PAYMENT_TYPE_RECURRING:
+				$fPrice = $aItem[$this->getKey('KEY_ARRAY_PRICE_RECURRING')];
+				break;
+		}
+
+		return (float)$fPrice;
+    }
+
+    public function getTrial($sType, $aItem)
+    {
+        $iTrial = 0;
+
+		switch($sType) {
+			case BX_PAYMENT_TYPE_RECURRING:
+				$iTrial = $aItem[$this->getKey('KEY_ARRAY_TRIAL_RECURRING')];
+				break;
+		}
+
+		return (int)$iTrial;
+    }
+
+    public function getModuleId($mixedId)
+    {
+    	if(is_numeric($mixedId))
+    		return (int)$mixedId;
+
+		if(is_string($mixedId)) {
+            $aInfo = $this->_oDb->getModuleByName($mixedId);
+            if(!is_array($aInfo) || empty($aInfo['id']))
+            	$aInfo = $this->_oDb->getModuleByUri($mixedId);
+
+            if(is_array($aInfo) && !empty($aInfo['id']))
+            	return (int)$aInfo['id'];
+        } 
+
+        return 0;
+    }
+
+    public function descriptorA2S($a) 
+    {
+    	return implode($this->getDivider('DIVIDER_DESCRIPTOR'), $a);
+    }
+
+	public function descriptorS2A($s) 
+    {
+    	return explode($this->getDivider('DIVIDER_DESCRIPTOR'), $s);
+    }
+
+	/**
+     * Conver items to array with necessary structure.
+     *
+     * @param  string/array $mixed - string with cart items divided with (:) or an array of cart items.
+     * @return array        with items.
+     */
+    public function descriptorsM2A($mixed)
+    {
+        $aResult = array();
+
+        if(is_string($mixed))
+           $aItems = explode($this->getDivider('DIVIDER_DESCRIPTORS'), $mixed);
+        else if(is_array($mixed))
+           $aItems = $mixed;
+        else
+            $aItems = array();
+
+        foreach($aItems as $sItem) {
+            $aItem = $this->descriptorS2A($sItem);
+            $aResult[] = array('vendor_id' => $aItem[0], 'module_id' => $aItem[1], 'item_id' => $aItem[2], 'item_count' => $aItem[3]);
+        }
+
+        return $aResult;
+    }
+
+    public function putCustom($mDsc, $aCustom, &$aCustoms)
+    {
+        if(empty($aCustom) || !is_array($aCustom))
+            return;
+
+        if(is_array($mDsc))
+            $mDsc = $this->descriptorA2S(array_slice($mDsc, 0, 3));
+
+        $aCustoms[$mDsc] = !empty($aCustoms[$mDsc]) && is_array($aCustoms[$mDsc]) ? array_merge($aCustoms[$mDsc], $aCustom) : $aCustom;
+    }
+
+    public function getCustom($mDsc, &$aCustoms)
+    {
+        if(is_array($mDsc))
+            $mDsc = $this->descriptorA2S(array_slice($mDsc, 0, 3));
+
+        if(empty($aCustoms) || !is_array($aCustoms) || empty($aCustoms[$mDsc]))
+            return array();
+
+        return $aCustoms[$mDsc];
+    }
+
+    public function pullCustom($mDsc, &$aCustoms)
+    {
+        if(is_array($mDsc))
+            $mDsc = $this->descriptorA2S(array_slice($mDsc, 0, 3));
+
+        if(empty($aCustoms) || !is_array($aCustoms) || empty($aCustoms[$mDsc]))
+            return array();
+
+        $aResult = $aCustoms[$mDsc];
+        unset($aCustoms[$mDsc]);           
+
+        return $aResult;
+    }
+
+	public function http2https($s)
+    {
+    	if(strncmp($s, 'https://', 8) === 0)
+    		return $s;
+
+        return 'https://' . bx_ltrim_str($s, 'http://');
+    }
+}
+
+/** @} */

+ 465 - 0
modules/boonex/payment/updates/9.0.5_9.0.6/source/classes/BxPaymentDb.php

@@ -0,0 +1,465 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Payment Payment
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+class BxPaymentDb extends BxBaseModPaymentDb
+{
+    function __construct(&$oConfig)
+    {
+        parent::__construct($oConfig);
+    }
+
+    /**
+     * Payment details methods
+     */
+    public function getForm()
+    {
+        $sQuery = "SELECT
+                `tp`.`id` AS `provider_id`,
+                `tp`.`name` AS `provider_name`,
+                `tp`.`caption` AS `provider_caption`,
+                `tp`.`description` AS `provider_description`,
+                `tp`.`option_prefix` AS `provider_option_prefix`,
+                `tpo`.`id` AS `id`,
+                `tpo`.`name` AS `name`,
+                `tpo`.`type` AS `type`,
+                `tpo`.`caption` AS `caption`,
+                `tpo`.`description` AS `description`,
+                `tpo`.`extra` AS `extra`,
+                `tpo`.`check_type` AS `check_type`,
+                `tpo`.`check_params` AS `check_params`,
+                `tpo`.`check_error` AS `check_error`
+            FROM `" . $this->_sPrefix . "providers` AS `tp`
+            LEFT JOIN `" . $this->_sPrefix . "providers_options` AS `tpo` ON `tp`.`id`=`tpo`.`provider_id`
+            ORDER BY `tp`.`id` ASC, `tpo`.`order` ASC";
+
+        return $this->getAll($sQuery);
+    }
+
+	public function getProviders($aParams = array())
+    {
+    	$aMethod = array('name' => 'getAll', 'params' => array(0 => 'query'));
+
+        $sWhereClause = "";
+        if(!empty($aParams['type']))
+	        switch($aParams['type']) {
+	        	case 'by_name':
+	        		$aMethod['name'] = 'getRow';
+	        		$aMethod['params'][1] = array(
+	                	'name' => $aParams['name']
+	                );
+	
+	        		$sWhereClause = " AND `tp`.`name`=:name";
+	        		break;
+	
+				case 'for_single':
+					$aMethod['name'] = 'getAllWithKey';
+					$aMethod['params'][1] = 'name';
+	
+					$sWhereClause = " AND `tp`.`for_single`='1'";
+	        		break;
+	
+				case 'for_recurring':
+					$aMethod['name'] = 'getAllWithKey';
+					$aMethod['params'][1] = 'name';
+	
+					$sWhereClause = " AND `tp`.`for_recurring`='1'";
+	        		break;
+
+	        	case 'all':
+					$aMethod['name'] = 'getAllWithKey';
+					$aMethod['params'][1] = 'name';
+	        		break;
+	        }          
+
+        $aMethod['params'][0] = "SELECT
+                `tp`.`id` AS `id`,
+                `tp`.`name` AS `name`,
+                `tp`.`caption` AS `caption`,
+                `tp`.`description` AS `description`,
+                `tp`.`option_prefix` AS `option_prefix`,
+                `tp`.`for_visitor` AS `for_visitor`,
+                `tp`.`for_single` AS `for_single`,
+                `tp`.`for_recurring` AS `for_recurring`,
+                `tp`.`class_name` AS `class_name`,
+                `tp`.`class_file` AS `class_file`
+            FROM `" . $this->_sPrefix . "providers` AS `tp`
+            WHERE 1" . $sWhereClause;
+
+        return call_user_func_array(array($this, $aMethod['name']), $aMethod['params']);
+    }
+
+    public function getOptions($iUserId = BX_PAYMENT_EMPTY_ID, $iProviderId = 0)
+    {
+    	$aBinding = array(
+    		'user_id' => $iUserId
+    	);
+
+        if($iUserId == BX_PAYMENT_EMPTY_ID && empty($iProviderId))
+           return $this->getAll("SELECT `id`, `name`, `type` FROM `" . $this->_sPrefix . "providers_options`");
+
+        $sWhereAddon = "";
+        if(!empty($iProviderId)) {
+        	$aBinding['provider_id'] = $iProviderId;
+
+            $sWhereAddon = " AND `tpo`.`provider_id`=:provider_id";
+        }
+
+        $sQuery = "SELECT
+               `tpo`.`name` AS `name`,
+               `tuv`.`value` AS `value`
+            FROM `" . $this->_sPrefix . "providers_options` AS `tpo`
+            LEFT JOIN `" . $this->_sPrefix . "user_values` AS `tuv` ON `tpo`.`id`=`tuv`.`option_id`
+            WHERE 1" . $sWhereAddon . " AND `tuv`.`user_id`=:user_id";
+
+        return $this->getAllWithKey($sQuery, 'name', $aBinding);
+    }
+
+    public function updateOption($iUserId, $iOptionId, $sValue)
+    {
+        $sQuery = $this->prepare("REPLACE INTO `" . $this->_sPrefix . "user_values` SET `user_id`=?, `option_id`=?, `value`=?", $iUserId, $iOptionId, $sValue);
+        return $this->query($sQuery);
+    }
+
+
+    /**
+     * Shopping cart methods.
+     */
+    public function getCartItems($iId)
+    {
+    	$sQuery = $this->prepare("SELECT `items` FROM `" . $this->_sPrefix . "cart` WHERE `client_id`=? LIMIT 1", $iId);
+        return $this->getOne($sQuery);
+    }
+
+    public function getCartContent($iId)
+    {
+    	return $this->getRow("SELECT * FROM `" . $this->_sPrefix . "cart` WHERE `client_id`=:client_id LIMIT 1", array(
+    		'client_id' => $iId
+    	));
+    }
+
+    public function setCartItems($iId, $sItems, $aCustoms = array())
+    {
+        $sItems = trim($sItems, ":");
+        if(empty($sItems))
+            return $this->query("DELETE FROM `" . $this->_sPrefix . "cart` WHERE `client_id`=:client_id LIMIT 1", array(
+                'client_id' => $iId
+            ));
+
+        return $this->query("REPLACE INTO `" . $this->_sPrefix . "cart` SET `client_id`=:client_id, `items`=:items, `customs`=:customs", array(
+            'client_id' => $iId,
+            'items' => $sItems,
+            'customs' => !empty($aCustoms) && is_array($aCustoms) ? serialize($aCustoms) : ''
+        ));
+    }
+
+	public function getVendorInfoProvidersSingle($iVendorId)
+    {
+    	return $this->getVendorInfoProviders($iVendorId, array('type' => 'for_single'));
+    }
+
+	public function getVendorInfoProvidersRecurring($iVendorId)
+    {
+    	return $this->getVendorInfoProviders($iVendorId, array('type' => 'for_recurring'));
+    }
+
+    public function getVendorInfoProviders($iVendorId, $aParams = array())
+    {
+    	if(empty($aParams))
+    		$aParams = array('type' => 'all');
+
+		$aProviders = $this->getProviders($aParams);
+		$aOptions = $this->getOptions($iVendorId);
+
+		$aResult = array();
+		foreach($aProviders as $sProvider => $aProvider)
+			if(isset($aOptions[$aProvider['option_prefix'] . 'active']) && $aOptions[$aProvider['option_prefix'] . 'active']['value'] == 'on') {
+				foreach($aOptions as $sName => $aOption)
+					if(strpos($sName, $aProvider['option_prefix']) !== false)
+						$aProvider['options'][$sName] = $aOption;
+				$aResult[$sProvider] = $aProvider;
+			}
+
+		return $aResult;
+	}
+
+    public function getAdminsIds()
+    {
+        $sQuery = "SELECT 
+        		`tp`.`id` AS `id`,
+        		`tp`.`type` AS `type`  
+        	FROM `sys_profiles` AS `tp` 
+        	INNER JOIN `sys_accounts` AS `ta` ON `tp`.`account_id`=`ta`.`id` AND `ta`.`role`&" . BX_DOL_ROLE_ADMIN . " 
+        	WHERE 
+        		`tp`.`type`<>'system' AND `tp`.`status`='active' 
+        	ORDER BY `tp`.`id` ASC";
+
+        $aAdmins = $this->getAllWithKey($sQuery, 'id');
+        foreach($aAdmins as $iId => $aAdmin)
+            if(!BxDolService::call($aAdmin['type'], 'act_as_profile'))
+                unset($aAdmins[$iId]);
+
+        return array_keys($aAdmins);
+    }
+
+
+	/*
+     * Pending Orders methods
+     */
+    public function getOrderPending($aParams)
+    {
+    	$aMethod = array('name' => 'getRow', 'params' => array(0 => 'query'));
+
+    	$sWhereClause = $sLimitClause = '';
+        switch($aParams['type']) {
+            case 'id':
+            	$aMethod['params'][1] = array(
+                	'id' => $aParams['id']
+                );
+
+                $sWhereClause = " AND `id`=:id";
+                $sLimitClause = " LIMIT 1";
+                break;
+
+            case 'order':
+            	$aMethod['params'][1] = array(
+                	'order' => $aParams['order']
+                );
+
+            	$sWhereClause = " AND `order`=:order";
+                $sLimitClause = " LIMIT 1";
+                break;
+
+            case 'mixed':
+                $aMethod['name'] = 'getAll';
+
+                $sWhereClause = ' AND ' . $this->arrayToSQL($aParams['conditions'], ' AND ');
+                break;
+        }
+
+        $aMethod['params'][0] = "SELECT * FROM `" . $this->_sPrefix . "transactions_pending` WHERE 1 " . $sWhereClause . $sLimitClause;
+        return call_user_func_array(array($this, $aMethod['name']), $aMethod['params']);
+    }
+
+    public function insertOrderPending($iClientId, $sType, $sProvider, $aCartInfo, $aCustom = array())
+    {
+        $sItems = "";
+        foreach($aCartInfo['items'] as $aItem)
+            $sItems .= $this->_oConfig->descriptorA2S(array($aCartInfo['vendor_id'], $aItem['module_id'], $aItem['id'], $aItem['quantity'])) . ':';
+
+        return (int)$this->query("INSERT INTO `" . $this->_sPrefix . "transactions_pending` SET `client_id`=:client_id, `seller_id`=:seller_id, `type`=:type, `provider`=:provider, `items`=:items, `customs`=:customs, `amount`=:amount, `date`=UNIX_TIMESTAMP()", array(
+            'client_id' => $iClientId,
+            'seller_id' => $aCartInfo['vendor_id'],
+            'type' => $sType, 
+            'provider' => $sProvider,
+            'items' => trim($sItems, ':'),
+            'customs' => !empty($aCustom) && is_array($aCustom) ? serialize($aCustom) : '',
+            'amount' => $aCartInfo['items_price']
+        )) > 0 ? $this->lastId() : 0;
+    }
+
+    public function updateOrderPending($iId, $aValues)
+    {
+        $sQuery = $this->prepare("UPDATE `" . $this->_sPrefix . "transactions_pending` SET " . $this->arrayToSQL($aValues) . " WHERE `id`=?", $iId);
+        return (int)$this->query($sQuery) > 0;
+    }
+
+    public function deleteOrderPending($mixedId)
+    {
+    	if(!is_array($mixedId))
+    		$mixedId = array($mixedId);
+
+        return (int)$this->query("DELETE FROM `" . $this->_sPrefix . "transactions_pending` WHERE `id` IN (" . $this->implode_escape($mixedId) . ")") > 0;
+    }
+
+    /*
+     * Processed Orders
+     */
+    public function getOrderProcessed($aParams)
+    {
+    	$aMethod = array('name' => 'getRow', 'params' => array(0 => 'query'));
+
+        $sWhereClause = "";
+        switch($aParams['type']) {
+            case 'id':
+            	$aMethod['params'][1] = array(
+                	'id' => $aParams['id']
+                );
+
+                $sWhereClause = " AND `tt`.`id`=:id";
+                break;
+
+            case 'new':
+                $aMethod['name'] = 'getAll';
+                $aMethod['params'][1] = array(
+                	'seller_id' => $aParams['seller_id']
+                );
+
+                $sWhereClause = " AND `tt`.`seller_id`=:seller_id AND `tt`.`new`='1'";
+                break;
+
+			case 'pending_id':
+                if(empty($aParams['with_key'])) {
+                	$aMethod['name'] = 'getAll';
+                	$aMethod['params'][1] = array(
+						'pending_id' => $aParams['pending_id']
+					);
+                }
+                else {
+                	$aMethod['name'] = 'getAllWithKey';
+					$aMethod['params'][1] = $aParams['with_key'];
+					$aMethod['params'][2] = array(
+						'pending_id' => $aParams['pending_id']
+					);
+                }
+
+                $sWhereClause = " AND `tt`.`pending_id`=:pending_id";
+                break;
+
+            case 'license':
+                $aMethod['name'] = 'getAll';
+                $aMethod['params'][1] = array(
+                	'license' => $aParams['license']
+                );
+
+                $sWhereClause = " AND `tt`.`license`=:license";
+                break;
+
+            case 'mixed':
+                $aMethod['name'] = 'getAll';
+
+                $sWhereClause = ' AND ' . $this->arrayToSQL($aParams['conditions'], ' AND ');
+                break;
+
+        }
+
+        $aMethod['params'][0] = "SELECT
+        		`tt`.`id`,
+                `tt`.`license`,
+                `ttp`.`type`,
+                `tt`.`client_id`,
+                `tt`.`seller_id`,
+                `tt`.`module_id`,
+                `tt`.`item_id`,
+                `tt`.`item_count`,
+                `tt`.`amount`,
+                `tt`.`date`,
+                `ttp`.`order`,
+                `ttp`.`error_msg`,
+                `ttp`.`provider`
+            FROM `" . $this->_sPrefix . "transactions` AS `tt`
+            LEFT JOIN `" . $this->_sPrefix . "transactions_pending` AS `ttp` ON `tt`.`pending_id`=`ttp`.`id`
+            WHERE 1" . $sWhereClause;
+
+        return call_user_func_array(array($this, $aMethod['name']), $aMethod['params']);
+    }
+
+    public function insertOrderProcessed($aValues)
+    {
+        return $this->query("INSERT INTO `" . $this->_sPrefix . "transactions` SET " . $this->arrayToSQL($aValues) . ", `date`=UNIX_TIMESTAMP()");
+    }
+
+	public function updateOrderProcessed($iId, $aValues)
+    {        
+        return $this->updateOrdersProcessed($aValues, array('id' => $iId));
+    }
+
+    public function updateOrdersProcessed($aValues, $aWhere)
+    {
+        if(empty($aValues) || !is_array($aValues) || empty($aWhere) || !is_array($aWhere))
+            return false;
+
+        return (int)$this->query("UPDATE `" . $this->_sPrefix . "transactions` SET " . $this->arrayToSQL($aValues) . " WHERE " . $this->arrayToSQL($aWhere, ' AND ')) > 0;
+    }
+
+    public function deleteOrderProcessed($mixedId)
+    {
+    	if(!is_array($mixedId))
+    		$mixedId = array($mixedId);
+
+        return (int)$this->query("DELETE FROM `" . $this->_sPrefix . "transactions` WHERE `id` IN (" . $this->implode_escape($mixedId) . ")") > 0;
+    }
+
+    public function getOrderHistory($aParams)
+    {
+        return $this->getOrderProcessed($aParams);
+    }
+
+	/*
+     * Subscriptions methods
+     */
+    public function getOrderSubscription($aParams)
+    {
+        return $this->getOrderPending($aParams);
+    }
+
+    public function getSubscription($aParams)
+    {
+    	$aMethod = array('name' => 'getAll', 'params' => array(0 => 'query'));
+
+    	$sWhereClause = $sLimitClause = '';
+        switch($aParams['type']) {
+            case 'pending_id':
+                $aMethod['name'] = 'getRow';
+            	$aMethod['params'][1] = array(
+                	'pending_id' => $aParams['pending_id']
+                );
+
+                $sWhereClause = " AND `pending_id`=:pending_id";
+                $sLimitClause = " LIMIT 1";
+                break;
+        }
+
+        $aMethod['params'][0] = "SELECT * FROM `" . $this->_sPrefix . "subscriptions` WHERE 1 " . $sWhereClause . $sLimitClause;
+        return call_user_func_array(array($this, $aMethod['name']), $aMethod['params']);
+    }
+
+    public function insertSubscription($aValues)
+    {
+        if(empty($aValues) || !is_array($aValues))
+            return false;
+
+        return $this->query("INSERT INTO `" . $this->_sPrefix . "subscriptions` SET " . $this->arrayToSQL($aValues) . ", `date`=UNIX_TIMESTAMP()");
+    }
+
+	public function updateSubscription($aValues, $aWhere)
+    {
+        if(empty($aValues) || !is_array($aValues) || empty($aWhere) || !is_array($aWhere))
+            return false;
+
+        return (int)$this->query("UPDATE `" . $this->_sPrefix . "subscriptions` SET " . $this->arrayToSQL($aValues) . " WHERE " . $this->arrayToSQL($aWhere, ' AND ')) > 0;
+    }
+
+    public function deleteSubscription($mixedId, $sReason)
+    {
+    	if(!is_array($mixedId))
+    		$mixedId = array($mixedId);
+
+        //--- Move to deleted subscriptions table.   
+    	$sQuery = "INSERT IGNORE INTO `" . $this->_sPrefix . "subscriptions_deleted` SELECT *, :reason AS `reason`, UNIX_TIMESTAMP() AS `deleted` FROM `" . $this->_sPrefix . "subscriptions` WHERE `id` IN (" . $this->implode_escape($mixedId) . ")";
+		$this->query($sQuery, array(
+		    'reason' => $sReason
+		));
+
+        return (int)$this->query("DELETE FROM `" . $this->_sPrefix . "subscriptions` WHERE `id` IN (" . $this->implode_escape($mixedId) . ")") > 0;
+    }
+
+    //--- Order Administration ---//
+    public function onProfileDelete($iId)
+    {
+    	$sQuery = $this->prepare("DELETE FROM `" . $this->_sPrefix . "cart` WHERE `client_id`=?", $iId);
+    	$this->query($sQuery);
+
+    	$sQuery = $this->prepare("DELETE FROM `" . $this->_sPrefix . "user_values` WHERE `user_id`=?", $iId);
+    	$this->query($sQuery);
+    }
+}
+
+/** @} */

+ 210 - 0
modules/boonex/payment/updates/9.0.5_9.0.6/source/classes/BxPaymentDetails.php

@@ -0,0 +1,210 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Payment Payment
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+bx_import('BxDolForm');
+
+class BxPaymentDetailsFormCheckerHelper extends BxDolFormCheckerHelper
+{
+	function checkHttps ($s)
+    {
+        return empty($s) || substr(BX_DOL_URL_ROOT, 0, 5) == 'https';
+    }
+}
+
+class BxPaymentDetails extends BxBaseModPaymentDetails
+{
+	protected $_sLangsPrefix;
+    protected $_bCollapseFirst;
+
+    function __construct()
+    {
+    	$this->MODULE = 'bx_payment';
+
+    	parent::__construct();
+
+    	$this->_sLangsPrefix = $this->_oModule->_oConfig->getPrefix('langs');
+        $this->_bCollapseFirst = true;
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_payment Payment
+     * @subsection bx_payment-page_blocks Page Blocks
+     * @subsubsection bx_payment-get_block_details get_block_details
+     * 
+     * @code bx_srv('bx_payment', 'get_block_details', [...], 'Details'); @endcode
+     * 
+     * Get page block with payment providers' configuration settings represented as subforms.
+     *
+     * @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 BxPaymentDetails::serviceGetBlockDetails
+     */
+    /** 
+     * @ref bx_payment-get_block_details "get_block_details"
+     */
+    public function serviceGetBlockDetails($iUserId = BX_PAYMENT_EMPTY_ID)
+    {
+        if(!$this->_oModule->isLogged())
+			return array(
+        		'content' => MsgBox(_t($this->_sLangsPrefix . 'err_required_login'))
+			);
+
+        $iUserId = $iUserId != BX_PAYMENT_EMPTY_ID ? $iUserId : $this->_oModule->getProfileId();
+
+		$sContent = $this->getForm($iUserId);
+		if(empty($sContent))
+			$sContent = MsgBox(_t($this->_sLangsPrefix . 'msg_no_results'));
+
+        return array(
+        	'content' => $sContent
+        );
+    }
+
+    public function getForm($iUserId)
+    {
+        $aInputs = $this->_oModule->_oDb->getForm();
+        if(empty($aInputs))
+            return '';
+
+		$aForm = array(
+            'form_attrs' => array(
+                'id' => 'pmt_details',
+                'name' => 'pmt_details',
+                'action' => BX_DOL_URL_ROOT . BxDolPermalinks::getInstance()->permalink('page.php?i=payment-details'),
+                'method' => 'post',
+                'enctype' => 'multipart/form-data'
+            ),
+            'params' => array(
+                'db' => array(
+                    'table' => '',
+                    'key' => 'id',
+                    'uri' => '',
+                    'uri_title' => '',
+                    'submit_name' => 'submit'
+                ),
+                'checker_helper' => 'BxPaymentDetailsFormCheckerHelper'
+            ),
+            'inputs' => array (
+            )
+        );
+
+        $bCollapsed = $this->_bCollapseFirst;
+        $iProvider = 0;
+        $sProvider = "";
+        $oProvider = null;
+        foreach($aInputs as $aInput) {
+            if($iProvider != $aInput['provider_id']) {
+                if(!empty($iProvider))
+                    $aForm['inputs']['provider_' . $iProvider . '_end'] = array(
+                        'type' => 'block_end'
+                    );
+
+                $aForm['inputs']['provider_' . $aInput['provider_id'] . '_begin'] = array(
+                    'type' => 'block_header',
+                    'caption' => _t($aInput['provider_caption']),
+                    'collapsable' => true,
+                    'collapsed' => $bCollapsed
+                );
+
+                $iProvider = $aInput['provider_id'];
+                $sProvider = $aInput['provider_name'];
+                $oProvider = $this->_oModule->getObjectProvider($sProvider, $iUserId);
+                $bCollapsed = true;
+            }
+
+            $aForm['inputs'][$aInput['name']] = array(
+				'type' => $aInput['type'],
+                'name' => $aInput['name'],
+                'caption' => _t($aInput['caption']),
+                'value' => $oProvider->getOption($aInput['name']),
+                'info' => _t($aInput['description']),
+            	'attrs' => array(
+            		'bx-data-provider' => $iProvider
+            	),
+                'checker' => array (
+                    'func' => $aInput['check_type'],
+                    'params' => $aInput['check_params'],
+                    'error' => _t($aInput['check_error']),
+                )
+            );
+
+            //--- Make some field dependent actions ---//
+            switch($aInput['type']) {
+                case 'select':
+                    if(empty($aInput['extra']))
+                       break;
+
+                    $aAddon = array('values' => array());
+
+                    $aPairs = explode(',', $aInput['extra']);
+                    foreach($aPairs as $sPair) {
+                        $aPair = explode('|', $sPair);
+                        $aAddon['values'][] = array('key' => $aPair[0], 'value' => _t($aPair[1]));
+                    }
+                    break;
+
+                case 'checkbox':
+                    $aForm['inputs'][$aInput['name']]['value'] = 'on';
+                    $aAddon = array('checked' => $oProvider->getOption($aInput['name']) == 'on');
+                    break;
+
+				 case 'value':
+				 	$sName = str_replace($aInput['provider_option_prefix'], '', $aInput['name']);
+				 	if(!in_array($sName, array('return_data_url', 'notify_url')))
+				 		break;
+
+				 	$sMethod = 'get' . bx_gen_method_name($sName);
+				 	if(method_exists($oProvider, $sMethod))
+						$aForm['inputs'][$aInput['name']]['value'] = $oProvider->$sMethod($iUserId);
+				 	break;
+            }
+
+            if(!empty($aAddon) && is_array($aAddon))
+                $aForm['inputs'][$aInput['name']] = array_merge($aForm['inputs'][$aInput['name']], $aAddon);
+        }
+
+        $aForm['inputs']['provider_' . $iProvider . '_end'] = array(
+            'type' => 'block_end'
+        );
+        $aForm['inputs']['submit'] = array(
+            'type' => 'submit',
+            'name' => 'submit',
+            'value' => _t($this->_sLangsPrefix . 'form_details_input_do_submit'),
+        );
+
+        bx_import('BxTemplFormView');
+        $oForm = new BxTemplFormView($aForm);
+        $oForm->initChecker();
+
+        if($oForm->isSubmittedAndValid()) {
+            $aOptions = $this->_oModule->_oDb->getOptions();
+            foreach($aOptions as $aOption) {
+            	$sValue = bx_get($aOption['name']) !== false ? bx_get($aOption['name']) : '';
+                $this->_oModule->_oDb->updateOption($iUserId, $aOption['id'], bx_process_input($sValue));
+            }
+
+            header('Location: ' . $oForm->aFormAttrs['action']);
+        }
+        else {
+        	foreach($oForm->aInputs as $aInput)
+        		if(!empty($aInput['error']) && !empty($aInput['attrs']['bx-data-provider'])) {
+        			$sProviderBlock = 'provider_' . (int)$aInput['attrs']['bx-data-provider'] . '_begin';
+        			if(!empty($oForm->aInputs[$sProviderBlock]))
+        				$oForm->aInputs[$sProviderBlock]['collapsed'] = false;
+        		}
+
+			return $oForm->getCode();
+        }
+    }
+}
+
+/** @} */

+ 25 - 0
modules/boonex/payment/updates/9.0.5_9.0.6/source/classes/BxPaymentFormView.php

@@ -0,0 +1,25 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Payment Payment
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+class BxPaymentFormView extends BxTemplStudioFormView
+{
+	function __construct($aInfo, $oTemplate = false)
+    {
+        parent::__construct($aInfo, $oTemplate);
+    }
+	
+	protected function genCustomInputClient ($aInput)
+	{
+		return parent::genCustomInputUsernamesSuggestions ($aInput);
+	}
+}
+
+/** @} */

+ 139 - 0
modules/boonex/payment/updates/9.0.5_9.0.6/source/classes/BxPaymentGridProcessed.php

@@ -0,0 +1,139 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Payment Payment
+ * @ingroup     UnaModules
+ * 
+ * @{
+ */
+
+
+class BxPaymentGridProcessed extends BxBaseModPaymentGridOrders
+{
+    public function __construct ($aOptions, $oTemplate = false)
+    {
+    	$this->MODULE = 'bx_payment';
+
+        parent::__construct ($aOptions, $oTemplate);
+
+        $this->_sOrdersType = 'processed';
+    }
+
+    public function performActionAdd()
+    {
+    	$sType = BX_PAYMENT_TYPE_SINGLE;
+    	$sAction = 'add';
+    	$sJsObject = $this->_oModule->_oConfig->getJsObject('processed');
+
+        $sFormObject = $this->_oModule->_oConfig->getObject('form_processed');
+        $sFormDisplay = $this->_oModule->_oConfig->getObject('display_processed_add');
+
+        $oForm = BxDolForm::getObjectInstance($sFormObject, $sFormDisplay, $this->_oModule->_oTemplate);
+        $oForm->aFormAttrs['action'] = BX_DOL_URL_ROOT . 'grid.php?o=' . $this->_sObject . '&a=' . $sAction;
+
+        $oForm->aInputs['seller_id']['value'] = $this->_aQueryAppend['seller_id'];
+
+        $oForm->aInputs['client_id']['attrs'] = array(
+        	'id' => $this->_oModule->_oConfig->getHtmlIds('processed', 'order_processed_client_id'),
+        );
+
+		$oForm->aInputs['client']['attrs'] = array(
+        	'id' => $this->_oModule->_oConfig->getHtmlIds('processed', 'order_processed_client')			
+        );
+
+		$oForm->aInputs['client']['ajax_get_suggestions'] = BX_DOL_URL_ROOT . 'modules/?r=' . $this->_oModule->_oConfig->getUri() . '/get_clients';
+
+		$oForm->aInputs['client']['custom'] = array(
+			'only_once' => true,
+			'on_select' => "function(oObject){{$sJsObject}.showPopup(oObject);}"
+		);
+
+        $oForm->aInputs['module_id']['attrs'] = array(
+			'onchange' => 'javascript:' . $sJsObject . '.selectModule(this);'
+		);
+        $oForm->aInputs['module_id']['values'] = array(
+            array('key' => '0', 'value' => _t('_Select_one'))
+        );
+
+        $aModules = $this->_oModule->_oDb->getModules();
+        foreach($aModules as $aModule)
+           $oForm->aInputs['module_id']['values'][] = array('key' => $aModule['id'], 'value' => $aModule['title']);
+
+		$oForm->aInputs['items']['content'] = $this->_oModule->_oTemplate->displayItems($sType);
+
+        $oForm->initChecker();
+        if($oForm->isSubmittedAndValid()) {
+        	$sFormMethod = $oForm->aFormAttrs['method'];
+
+        	$aItemIds = $oForm->getSubmittedValue('items', $sFormMethod);
+        	if(empty($aItemIds) || !is_array($aItemIds))
+            	return echoJson(array('msg' => $this->_sLangsPrefix . 'err_empty_items'));
+
+			$aItems = array();
+			$sPriceKey = $this->_oModule->_oConfig->getKey('KEY_ARRAY_PRICE_SINGLE');
+			foreach($aItemIds as $iItemId) {
+	            $iItemId = (int)$iItemId;
+	            $fItemPrice = (float)$oForm->getSubmittedValue('item-price-' . $iItemId, $sFormMethod);
+	            $iItemQuantity = (int)$oForm->getSubmittedValue('item-quantity-' . $iItemId, $sFormMethod);
+
+	            if($iItemQuantity <= 0)
+	                return echoJson(array('msg' => $this->_sLangsPrefix . 'err_wrong_quantity'));
+
+				$aItems[] = array(
+					'id' => $iItemId, 
+					 $sPriceKey => $fItemPrice, 
+					'quantity' => $iItemQuantity
+				);
+			}
+
+        	$mixedResult = $this->_oModule->getObjectOrders()->addOrder(array(
+        		'client_id' => $oForm->getCleanValue('client_id'),
+        		'seller_id' => $oForm->getCleanValue('seller_id'),
+        		'provider' => 'manual',
+        		'type' => $sType,
+        		'order' => $oForm->getCleanValue('order'),
+        		'error_code' => 0,
+        		'error_msg' => 'Manually processed',        		
+        		'module_id' => $oForm->getCleanValue('module_id'),
+        		'items' => $aItems
+        	));
+        	if(is_array($mixedResult))
+        		return echoJson($mixedResult);
+
+			$iPendingId = (int)$mixedResult;
+        	if(!$this->_oModule->registerPayment($iPendingId))
+        		return echoJson(array('msg' => _t($this->_sLangsPrefix . 'err_cannot_perform')));
+
+			$aOrders = $this->_oModule->_oDb->getOrderProcessed(array('type' => 'pending_id', 'pending_id' => $iPendingId, 'with_key' => 'id'));
+            return echoJson(array('grid' => $this->getCode(false), 'blink' => array_keys($aOrders)));
+        }
+
+        $sKey = 'order_' . $this->_sOrdersType . '_add';
+        $sId = $this->_oModule->_oConfig->getHtmlIds('processed', $sKey);
+    	$sTitle = _t($this->_sLangsPrefix . 'popup_title_ods_' . $sKey);
+
+		$sContent = BxTemplStudioFunctions::getInstance()->popupBox($sId, $sTitle, $this->_oModule->_oTemplate->parseHtmlByName('order_processed_add.html', array(
+			'js_object' => $sJsObject,
+			'form_id' => $oForm->aFormAttrs['id'],
+			'form' => $oForm->getCode(true),
+			'object' => $this->_sObject,
+			'action' => $sAction
+		)));
+
+		echoJson(array('popup' => array('html' => $sContent, 'options' => array('closeOnOuterClick' => false))));
+    }
+
+	protected function _getDataSql($sFilter, $sOrderField, $sOrderDir, $iStart, $iPerPage)
+    {
+    	if(empty($this->_aQueryAppend['seller_id']))
+    		return array();
+
+		$this->_aOptions['source'] .= $this->_oModule->_oDb->prepareAsString(" AND `tt`.`seller_id`=?", $this->_aQueryAppend['seller_id']);
+
+        return parent::_getDataSql($sFilter, $sOrderField, $sOrderDir, $iStart, $iPerPage);
+    }
+}
+
+/** @} */

+ 136 - 0
modules/boonex/payment/updates/9.0.5_9.0.6/source/classes/BxPaymentJoin.php

@@ -0,0 +1,136 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Payment Payment
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+class BxPaymentJoin extends BxBaseModPaymentJoin
+{
+    protected $_sLangsPrefix;
+
+    function __construct()
+    {
+    	$this->MODULE = 'bx_payment';
+
+    	parent::__construct();
+
+        $this->_sLangsPrefix = $this->_oModule->_oConfig->getPrefix('langs');
+    }
+
+    /*
+     * Service methods
+     */
+
+    /**
+     * @page service Service Calls
+     * @section bx_payment Payment
+     * @subsection bx_payment-page_blocks Page Blocks
+     * @subsubsection bx_payment-get_block_join get_block_join
+     * 
+     * @code bx_srv('bx_payment', 'get_block_join', [...], 'Join'); @endcode
+     * 
+     * Get page block with join form to complete the payment.
+     * TODO: Should be tested when paid memberships with "Paid Before Join" or some similar feature will appear.
+     *
+     * @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 BxPaymentJoin::serviceGetBlockJoin
+     */
+    /** 
+     * @ref bx_payment-get_block_join "get_block_join"
+     */
+	public function serviceGetBlockJoin()
+    {
+    	$sSessionKeyPending = $this->_oModule->_oConfig->getKey('KEY_SESSION_PENDING');
+    	$sRequestKeyPending = $this->_oModule->_oConfig->getKey('KEY_REQUEST_PENDING');
+
+    	$oSession = BxDolSession::getInstance();
+    	$iPendingId = (int)$oSession->getValue($sSessionKeyPending);
+
+    	if(empty($iPendingId) && bx_get($sRequestKeyPending) !== false) {
+    		$iPendingId = (int)bx_get($sRequestKeyPending);
+
+    		$oSession->setValue($sSessionKeyPending, $iPendingId);
+    	}
+
+		if(empty($iPendingId))
+			return array(
+        		'content' => MsgBox(_t($this->_sLangsPrefix . 'err_not_allowed'))
+			);
+
+		$aPending = $this->_oModule->_oDb->getOrderPending(array('type' => 'id', 'id' => $iPendingId));
+	    if(empty($aPending['order']) || (int)$aPending['error_code'] != 1)
+			return array(
+        		'content' => MsgBox(_t($this->_sLangsPrefix . 'err_not_processed'))
+			);
+
+		if((int)$aPending['processed'] == 1)
+			return array(
+        		'content' => MsgBox(_t($this->_sLangsPrefix . 'err_already_processed'))
+			);
+
+		//--- 'System' -> 'Join after Payment' for Alerts Engine ---//
+		$bOverride = false;
+		$sOverrideError = '';
+
+		bx_alert('system', 'join_after_payment', 0, 0, array('override' => &$bOverride, 'override_error' => &$sOverrideError));
+
+        if($bOverride)
+        	return;
+		//--- 'System' -> 'Join after Payment' for Alerts Engine ---//
+
+    	$sContent = BxDolService::call('system', 'create_account_form', array(array('action' => $this->_oModule->_oConfig->getUrl('URL_JOIN'))), 'TemplServiceAccount');
+    	if(!empty($sOverrideError))
+    		$sContent = MsgBox(_t($sOverrideError)) . $sContent;
+
+		return array(
+        	'content' => $sContent
+		);
+    }
+
+	public function performJoin($iPendingId, $sClientName = '', $sClientEmail = '')
+    {
+		BxDolSession::getInstance()->setValue($this->_oModule->_oConfig->getKey('KEY_SESSION_PENDING'), (int)$iPendingId);
+
+		if(!empty($sClientName) && !empty($sClientEmail)) {
+			$aTemplate = BxDolEmailTemplates::getInstance()->parseTemplate($this->_oModule->_oConfig->getPrefix('general') . 'paid_need_join', array(
+				'RealName' => $sClientName,
+				'JoinLink' => $this->_oModule->_oConfig->getUrl('URL_JOIN', array($this->_oModule->_oConfig->getKey('KEY_REQUEST_PENDING') => (int)$iPendingId))
+			));
+
+			sendMail($sClientEmail, $aTemplate['Subject'], $aTemplate['Body'], 0, array(), BX_EMAIL_SYSTEM);
+		}
+
+		header('Location: ' . $this->_oModule->_oConfig->getUrl('URL_JOIN'));
+		exit;
+	}
+
+	public function onProfileJoin($iProfileId)
+    {
+    	$sSessionKeyPending = $this->_oModule->_oConfig->getKey('KEY_SESSION_PENDING');
+
+    	$oSession = BxDolSession::getInstance();
+		$iPendingId = (int)$oSession->getValue($sSessionKeyPending);
+
+        if(empty($iProfileId) || empty($iPendingId))
+        	return;
+ 
+		$aPending = $this->_oModule->_oDb->getOrderPending(array('type' => 'id', 'id' => $iPendingId));
+		if(empty($aPending) || (isset($aPending['client_id']) && (int)$aPending['client_id'] != 0))
+			return;
+
+		if(!$this->_oModule->_oDb->updateOrderPending($iPendingId, array('client_id' => $iProfileId)))
+			return;
+
+		$this->_oModule->registerPayment($iPendingId);
+
+		$oSession->unsetValue($sSessionKeyPending);
+    }
+}
+
+/** @} */

+ 954 - 0
modules/boonex/payment/updates/9.0.5_9.0.6/source/classes/BxPaymentModule.php

@@ -0,0 +1,954 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Payment Payment
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+define('BX_PAYMENT_ORDERS_TYPE_PENDING', 'pending');
+define('BX_PAYMENT_ORDERS_TYPE_PROCESSED', 'processed');
+define('BX_PAYMENT_ORDERS_TYPE_SUBSCRIPTION', 'subscription');
+define('BX_PAYMENT_ORDERS_TYPE_HISTORY', 'history');
+
+define('BX_PAYMENT_EMPTY_ID', 0);
+
+define('BX_PAYMENT_RESULT_SUCCESS', 0);
+
+/**
+ * Payment module by BoonEx
+ *
+ * This module is needed to work with payment providers and organize the process
+ * of some item purchasing. Shopping Cart and Orders Manager are included.
+ *
+ * Integration notes:
+ * To integrate your module with this one, you need:
+ * 1. Get 'Add To Cart' button using serviceGetAddToCartLink service.
+ * 2. Add info about your module in the 'bx_pmt_modules' table.
+ * 3. Realize the following service methods in your Module class.
+ *   a. serviceGetItems($iSellerId) - Is used in Orders Administration to get all products of the requested seller(vendor).
+ *   b. serviceGetCartItem($iClientId, $iItemId) - Is used in Shopping Cart to get one product by specified id.
+ *   c. serviceRegisterCartItem($iClientId, $iSellerId, $iItemId, $iItemCount, $sOrderId) - Register purchased product.
+ *   d. serviceUnregisterCartItem($iClientId, $iSellerId, $iItemId, $iItemCount, $sOrderId) - Unregister the product purchased earlier.
+ * @see You may see an example of integration in Membership module.
+ *
+ *
+ * Profile's Wall:
+ * no spy events
+ *
+ *
+ *
+ * Spy:
+ * no spy events
+ *
+ *
+ *
+ * Memberships/ACL:
+ * Doesn't depend on user's membership.
+ *
+ *
+ *
+ * Service methods:
+ *
+ * Is used to get "Add to cart" link for some item(s) in your module.
+ * @see BxPmtModule::serviceGetAddToCartLink
+ * BxDolService::call('payment', 'get_add_to_cart_link', array($iSellerId, $mixedModuleId, $iItemId, $iItemCount));
+ *
+ * Check transaction(s) in database which satisty all conditions.
+ * @see BxPmtModule::serviceGetOrdersInfo
+ * BxDolService::call('payment', 'get_orders_info', array($aConditions), 'Orders');
+ *
+ * Get total count of items in Shopping Cart.
+ * @see BxPmtModule::serviceGetCartItemsCount
+ * BxDolService::call('payment', 'get_cart_items_count', array($iUserId, $iOldCount));
+ * @note is needed for internal usage(integration with member tool bar).
+ *
+ * Get Shopping cart content.
+ * @see BxPmtModule::serviceGetCartItems
+ * BxDolService::call('payment', 'get_cart_items');
+ * @note is needed for internal usage(integration with member tool bar).
+ *
+ *
+ * Alerts:
+ * no alerts available
+ *
+ */
+class BxPaymentModule extends BxBaseModPaymentModule
+{
+    protected $_iUserId;
+
+    protected $_aOrderTypes;
+
+    function __construct($aModule)
+    {
+        parent::__construct($aModule);
+
+        $this->_iUserId = $this->getProfileId();
+
+        $this->_aOrderTypes = array(
+        	BX_PAYMENT_ORDERS_TYPE_PENDING, 
+        	BX_PAYMENT_ORDERS_TYPE_PROCESSED, 
+        	BX_PAYMENT_ORDERS_TYPE_SUBSCRIPTION, 
+        	BX_PAYMENT_ORDERS_TYPE_HISTORY
+        );
+    }
+
+    /**
+     * Manage Orders Methods
+     */
+	public function actionGetClients()
+    {
+        $sTerm = bx_get('term');
+
+        $aResult = BxDolService::call('system', 'profiles_search', array($sTerm), 'TemplServiceProfiles');
+
+        echoJson($aResult);
+    }
+
+    public function actionGetItems($sType, $iModuleId)
+    {
+    	$iSellerId = $this->getProfileId();
+        $aItems = $this->callGetCartItems((int)$iModuleId, array($iSellerId));
+
+		echoJson(array(
+			'code' => 0, 
+		 	'eval' => $this->_oConfig->getJsObject('processed') . '.onSelectModule(oData);', 
+			'data' => $this->_oTemplate->displayItems($sType, $aItems)
+		));
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_payment Payment
+     * @subsection bx_payment-purchase_processing Purchase Processing
+     * @subsubsection bx_payment-is_accepting_payments is_accepting_payments
+     * 
+     * @code bx_srv('bx_payment', 'is_accepting_payments', [...]); @endcode
+     * 
+     * Check whether the specified vendor has a configured payment provider or not.
+     *
+     * @param $iVendorId integer value with vendor ID.
+     * @param $sPaymentType (optional) string value with payment type. If specified then the vendor will be checked for having the payment provider of the requested type.
+     * @return boolean value determining the result of checking.
+     * 
+     * @see BxPaymentModule::serviceIsAcceptingPayments
+     */
+    /** 
+     * @ref bx_payment-is_accepting_payments "is_accepting_payments"
+     */
+    public function serviceIsAcceptingPayments($iVendorId, $sPaymentType = '')
+    {
+    	$bResult = false;
+
+    	switch($sPaymentType) {
+    		case BX_PAYMENT_TYPE_SINGLE:
+    			$aProvidersCart = $this->_oDb->getVendorInfoProvidersSingle($iVendorId);
+    			$bResult = !empty($aProvidersCart);
+    			break;
+
+    		case BX_PAYMENT_TYPE_RECURRING:
+    			$aProvidersSubscription = $this->_oDb->getVendorInfoProvidersRecurring($iVendorId);
+    			$bResult = !empty($aProvidersSubscription);
+    			break;
+
+    		default:
+    			$aProviders = $this->_oDb->getVendorInfoProviders($iVendorId);
+    			$bResult = !empty($aProviders);
+    	}
+
+		return $bResult;
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_payment Payment
+     * @subsection bx_payment-purchase_processing Purchase Processing
+     * @subsubsection bx_payment-is_payment_provider is_payment_provider
+     * 
+     * @code bx_srv('bx_payment', 'is_payment_provider', [...]); @endcode
+     * 
+     * Check whether the specified vendor has configured the specified payment provider or not.
+     *
+     * @param $iVendorId integer value with vendor ID.
+     * @param $sVendorProvider string value with payment provider name.
+     * @param $sPaymentType (optional) string value with payment type. If specified then the vendor will be checked for having the payment provider of the requested type.
+     * @return boolean value determining the result of checking.
+     * 
+     * @see BxPaymentModule::serviceIsPaymentProvider
+     */
+    /** 
+     * @ref bx_payment-is_payment_provider "is_payment_provider"
+     */
+    public function serviceIsPaymentProvider($iVendorId, $sVendorProvider, $sPaymentType = '')
+    {
+    	$aProvider = $this->serviceGetPaymentProvider($iVendorId, $sVendorProvider, $sPaymentType);
+    	return $aProvider !== false;
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_payment Payment
+     * @subsection bx_payment-purchase_processing Purchase Processing
+     * @subsubsection bx_payment-get_payment_provider get_payment_provider
+     * 
+     * @code bx_srv('bx_payment', 'is_payment_provider', [...]); @endcode
+     * 
+     * Get configuration settings for the payment provider entered by the specified vendor.
+     *
+     * @param $iVendorId integer value with vendor ID.
+     * @param $sVendorProvider string value with payment provider name.
+     * @param $sPaymentType (optional) string value with payment type. If specified then the vendor will be checked for having the payment provider of the requested type.
+     * @return an array with special format describing the payment provider or false value if something is wrong.
+     * 
+     * @see BxPaymentModule::serviceGetPaymentProvider
+     */
+    /** 
+     * @ref bx_payment-get_payment_provider "get_payment_provider"
+     */
+    public function serviceGetPaymentProvider($iVendorId, $sVendorProvider, $sPaymentType = '')
+    {
+    	$aProviders = array();
+    	switch($sPaymentType) {
+    		case BX_PAYMENT_TYPE_SINGLE:
+    			$aProviders = $this->_oDb->getVendorInfoProvidersSingle($iVendorId);
+    			break;
+
+    		case BX_PAYMENT_TYPE_RECURRING:
+    			$aProviders = $this->_oDb->getVendorInfoProvidersRecurring($iVendorId);
+    			break;
+
+    		default:
+    			$aProviders = $this->_oDb->getVendorInfoProviders($iVendorId);
+    	}
+
+    	return !empty($aProviders) && !empty($aProviders[$sVendorProvider]) && is_array(($aProviders[$sVendorProvider])) ? $aProviders[$sVendorProvider] : false;
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_payment Payment
+     * @subsection bx_payment-other Other
+     * @subsubsection bx_payment-get_options_default_currency_code get_options_default_currency_code
+     * 
+     * @code bx_srv('bx_payment', 'get_options_default_currency_code', [...]); @endcode
+     * 
+     * Get an array with available currencies. Is used in forms.
+     *
+     * @return an array with available currencies represented as key => value pairs.
+     * 
+     * @see BxPaymentModule::serviceGetOptionsDefaultCurrencyCode
+     */
+    /** 
+     * @ref bx_payment-get_options_default_currency_code "get_options_default_currency_code"
+     */
+    public function serviceGetOptionsDefaultCurrencyCode()
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        $aCurrencies = BxDolForm::getDataItems($CNF['OBJECT_FORM_PRELISTS_CURRENCIES']);
+
+        $aResult = array();
+        foreach($aCurrencies as $sKey => $sValue)
+            $aResult[] = array(
+                'key' => $sKey,
+                'value' => $sValue
+            );
+
+        return $aResult;
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_payment Payment
+     * @subsection bx_payment-other Other
+     * @subsubsection bx_payment-get_options_site_admin get_options_site_admin
+     * 
+     * @code bx_srv('bx_payment', 'get_options_site_admin', [...]); @endcode
+     * 
+     * Get an array with profiles which can be used as 'Site Admin (Owner)'. 'Site Admin' is a person who will be displayed to buyers when something is selling on behalf of the site.
+     *
+     * @return an array with profiles represented as key => value pairs.
+     * 
+     * @see BxPaymentModule::serviceGetOptionsSiteAdmin
+     */
+    /** 
+     * @ref bx_payment-get_options_site_admin "get_options_site_admin"
+     */
+    public function serviceGetOptionsSiteAdmin()
+    {
+        $aResult = array(
+            array('key' => '', 'value' => _t('_Select_one'))
+        );
+
+        $aIds = $this->_oDb->getAdminsIds();
+        foreach($aIds as $iId) {
+        	$aUser = $this->getProfileInfo($iId);
+
+            $aResult[] = array(
+                'key' => $iId,
+                'value' => $aUser['name']
+            );
+        }
+
+        return $aResult;
+    }
+
+    /**
+     * Cart Processing Methods
+     */
+    public function actionAddToCart($iSellerId, $iModuleId, $iItemId, $iItemCount, $sCustom = '')
+    {
+        if(empty($sCustom) && bx_get('custom') !== false)
+            $sCustom = bx_process_input(bx_get('custom'));
+
+        $aCustom = array();
+        if(!empty($sCustom)) {
+            $aCustom = unserialize(base64_decode($sCustom));
+            if(empty($aCustom) || !is_array($aCustom))
+                $aCustom = array();
+        }
+
+        $aResult = $this->getObjectCart()->serviceAddToCart($iSellerId, $iModuleId, $iItemId, $iItemCount, $aCustom);
+		echoJson($aResult);
+    }
+
+    /**
+     * Isn't used yet.
+     */
+    public function actionDeleteFromCart($iSellerId, $iModuleId, $iItemId)
+    {
+        $aResult = $this->getObjectCart()->serviceDeleteFromCart($iSellerId, $iModuleId, $iItemId);
+        echoJson($aResult);
+    }
+
+    /**
+     * Isn't used yet.
+     */
+    public function actionEmptyCart($iSellerId)
+    {
+        $aResult = $this->getObjectCart()->serviceDeleteFromCart($iSellerId);
+		echoJson($aResult);
+    }
+
+	public function actionSubscribe()
+    {
+    	$iSellerId = bx_process_input(bx_get('seller_id'), BX_DATA_INT);
+    	$sSellerProvider = bx_process_input(bx_get('seller_provider'));
+    	$iModuleId = bx_process_input(bx_get('module_id'), BX_DATA_INT);
+    	$iItemId = bx_process_input(bx_get('item_id'), BX_DATA_INT);
+    	$iItemCount = bx_process_input(bx_get('item_count'), BX_DATA_INT);
+    	if(empty($iItemCount))
+    		$iItemCount = 1;
+
+        $sRedirect = bx_process_input(bx_get('redirect'));
+        $sCustom = bx_process_input(bx_get('custom'));
+
+        $aCustom = array();
+        if(!empty($sCustom)) {
+            $aCustom = unserialize(base64_decode($sCustom));
+            if(empty($aCustom) || !is_array($aCustom))
+                $aCustom = array();
+        }
+
+        $aResult = $this->getObjectSubscriptions()->serviceSubscribe($iSellerId, $sSellerProvider, $iModuleId, $iItemId, $iItemCount, $sRedirect, $aCustom);
+        $bRedirect = !empty($aResult['redirect']);
+
+        if(!empty($aResult['popup'])) {
+            $sContent = '';
+            $sContent .= $this->_oTemplate->displayCartJs(BX_PAYMENT_TYPE_RECURRING, $iSellerId);
+            $sContent .= !empty($aResult['popup']['html']) ? $aResult['popup']['html'] : $aResult['popup'];
+
+			return $this->_oTemplate->displayPageCodeResponse($sContent, false, true);
+        }
+
+		if(!empty($aResult['code']))
+			return $this->_oTemplate->displayPageCodeError($aResult['message']);
+
+		if(!empty($aResult['message']) && !$bRedirect)
+			return $this->_oTemplate->displayPageCodeResponse($aResult['message']);
+
+        if($bRedirect) {
+    		header('Location: ' . $aResult['redirect']);
+            exit;
+        }
+    }
+
+    public function actionSubscribeJson()
+    {
+    	$iSellerId = bx_process_input(bx_get('seller_id'), BX_DATA_INT);
+    	$sSellerProvider = bx_process_input(bx_get('seller_provider'));
+    	$iModuleId = bx_process_input(bx_get('module_id'), BX_DATA_INT);
+    	$iItemId = bx_process_input(bx_get('item_id'), BX_DATA_INT);
+
+    	$iItemCount = bx_process_input(bx_get('item_count'), BX_DATA_INT);
+    	if(empty($iItemCount))
+    		$iItemCount = 1;
+
+        $sRedirect = bx_process_input(bx_get('redirect'));
+        $sCustom = bx_process_input(bx_get('custom'));
+
+        $aCustom = array();
+        if(!empty($sCustom)) {
+            $aCustom = unserialize(base64_decode($sCustom));
+            if(empty($aCustom) || !is_array($aCustom))
+                $aCustom = array();
+        }
+
+        $aResult = $this->getObjectSubscriptions()->serviceSubscribe($iSellerId, $sSellerProvider, $iModuleId, $iItemId, $iItemCount, $sRedirect, $aCustom);
+		echoJson($aResult);
+    }
+
+    public function actionSubscriptionGetDetails($iId)
+    {
+        $aResult = $this->_oTemplate->displaySubscriptionGetDetails($iId);
+		echoJson($aResult);
+    }
+
+    public function actionSubscriptionChangeDetails($iId)
+    {
+        $aResult = $this->_oTemplate->displaySubscriptionChangeDetails($iId);
+		echoJson($aResult);
+    }
+
+    public function actionSubscriptionGetBilling($iId)
+    {
+        $aResult = $this->_oTemplate->displaySubscriptionGetBilling($iId);
+		echoJson($aResult);
+    }
+
+    public function actionSubscriptionChangeBilling($iId)
+    {
+        $aResult = $this->_oTemplate->displaySubscriptionChangeBilling($iId);
+		echoJson($aResult);
+    }
+
+    public function actionSubscriptionCancelation($iId)
+    {
+        $aResult = array('code' => 1, 'message' => _t('_bx_payment_err_cannot_perform'));
+
+        $aPending = $this->_oDb->getOrderPending(array('type' => 'id', 'id' => $iId));
+        if(empty($aPending) && !is_array($aPending))
+            return echoJson($aResult);
+
+        $aSubscription = $this->_oDb->getSubscription(array('type' => 'pending_id', 'pending_id' => $iId));
+        if(empty($aSubscription) && !is_array($aSubscription))
+            return echoJson($aResult);
+
+        $oRecipient = BxDolProfile::getInstance((int)$aPending['seller_id']);
+        if(!$oRecipient)
+            return echoJson($aResult);
+
+		$aTemplate = BxDolEmailTemplates::getInstance()->parseTemplate($this->_oConfig->getPrefix('general') . 'cancelation_request', array(
+			'sibscription_id' => $aSubscription['subscription_id'],
+			'sibscription_customer' => $aSubscription['customer_id'],
+		    'sibscription_date' => bx_time_js($aSubscription['date'], BX_FORMAT_DATE, true)
+		), 0, (int)$aPending['client_id']);
+
+		$sEmail = '';
+		$oProvider = $this->getObjectProvider($aPending['provider'], $aPending['seller_id']);
+		if($oProvider !== false && $oProvider->isActive())
+		    $sEmail = $oProvider->getOption('cancellation_email');
+
+		if(empty($sEmail))
+		    $sEmail = $oRecipient->getAccountObject()->getEmail();
+
+		if(!sendMail($sEmail, $aTemplate['Subject'], $aTemplate['Body'], 0, array(), BX_EMAIL_SYSTEM))
+		    return echoJson($aResult);
+
+        echoJson(array('code' => 0, 'message' => _t('_bx_payment_msg_cancelation_request_sent')));
+    }
+
+
+    /**
+     * Payment Processing Methods
+     */
+	public function actionInitializeCheckout($sType)
+    {
+    	if(!$this->isLogged())
+            return $this->_oTemplate->displayPageCodeError($this->_sLangsPrefix . 'err_required_login');
+
+		if(bx_get('seller_id') !== false && bx_get('provider') !== false && bx_get('items') !== false) {
+			$iSellerId = bx_process_input(bx_get('seller_id'), BX_DATA_INT);
+			$sProvider = bx_process_input(bx_get('provider'));
+			$aItems = bx_process_input(bx_get('items'));
+
+			$mixedResult = $this->serviceInitializeCheckout(BX_PAYMENT_TYPE_SINGLE, $iSellerId, $sProvider, $aItems);
+			if($mixedResult !== true)
+	    		return $this->_oTemplate->displayPageCodeError($mixedResult);
+		}
+
+        header('Location: ' . $this->_oConfig->getUrl('URL_CART'));
+        exit;
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_payment Payment
+     * @subsection bx_payment-purchase_processing Purchase Processing
+     * @subsubsection bx_payment-initialize_checkout initialize_checkout
+     * 
+     * @code bx_srv('bx_payment', 'initialize_checkout', [...]); @endcode
+     * 
+     * Initialize the checkout process.
+     * 
+     * @param $sType string value with payment type (single or recurring). 
+     * @param $iSellerId integer value with seller ID. 
+     * @param $sProvider string value with payment provider name. 
+     * @param $aItems (optional) an array with items to be purchased. 
+     * @param $sRedirect (optional) string value with redirect URL if it's needed.
+     * @param $aCustom (optional) array with custom data to attach to a payment.
+     * @return the result depends on the payment provider which is used for processing or represented as string value with error message if something is wrong.
+     * 
+     * @see BxPaymentModule::serviceInitializeCheckout
+     */
+    /** 
+     * @ref bx_payment-initialize_checkout "initialize_checkout"
+     */
+	public function serviceInitializeCheckout($sType, $iSellerId, $sProvider, $aItems = array(), $sRedirect = '', $aCustoms = array())
+	{
+	    $bTypeSingle = $sType == BX_PAYMENT_TYPE_SINGLE;
+	    $bTypeRecurring = $sType == BX_PAYMENT_TYPE_RECURRING;
+
+		if(!is_array($aItems))
+			$aItems = array($aItems);
+
+		$iSellerId = (int)$iSellerId;
+        if($iSellerId == BX_PAYMENT_EMPTY_ID)
+            return $this->_sLangsPrefix . 'err_unknown_vendor';
+
+		$oProvider = $this->getObjectProvider($sProvider, $iSellerId);
+        if($oProvider === false || !$oProvider->isActive())
+        	return $this->_sLangsPrefix . 'err_incorrect_provider';
+
+        $aInfo = $this->getObjectCart()->getInfo($sType, $this->_iUserId, $iSellerId, $aItems);
+        if(empty($aInfo) || $aInfo['vendor_id'] == BX_PAYMENT_EMPTY_ID || empty($aInfo['items']))
+            return $this->_sLangsPrefix . 'err_empty_order';
+            
+		/*
+		 * Process FREE (price = 0) items for LOGGED IN members
+		 * WITHOUT processing via payment provider.
+		 * Note. This section isn't used for now!
+		 */
+		$bProcessedFree = false;
+		$sKeyPriceSingle = $this->_oConfig->getKey('KEY_ARRAY_PRICE_SINGLE');
+		$sKeyPriceRecurring = $this->_oConfig->getKey('KEY_ARRAY_PRICE_RECURRING');
+		foreach($aInfo['items'] as $iIndex => $aItem) {
+		    if((int)$aInfo['client_id'] == 0)
+		        continue;
+
+            //--- For Single time payments.
+			if($bTypeSingle && (float)$aItem[$sKeyPriceSingle] == 0) {
+			    $aCart = $this->_oDb->getCartContent($aInfo['client_id']);
+			    $aCartCustoms = !empty($aCart['customs']) ? unserialize($aCart['customs']) : array();
+
+			    $aCartItem = array($aInfo['vendor_id'], $aItem['module_id'], $aItem['id'], $aItem['quantity']);
+			    $aCartItemCustom = $this->_oConfig->pullCustom($aCartItem, $aCartCustoms);
+
+				$aItemInfo = $this->callRegisterCartItem((int)$aItem['module_id'], array($aInfo['client_id'], $aInfo['vendor_id'], $aItem['id'], $aItem['quantity'], $this->_oConfig->getLicense(), $aCartItemCustom));
+	            if(is_array($aItemInfo) && !empty($aItemInfo))
+	            	$bProcessedFree = true;
+
+	            $aInfo['items_count'] -= 1;
+	            unset($aInfo['items'][$iIndex]);
+
+	            $aCart['items'] = trim(preg_replace("'" . $this->_oConfig->descriptorA2S($aCartItem) . ":?'", "", $aCart['items']), ":");
+	            $this->_oDb->setCartItems($aInfo['client_id'], $aCart['items'], $aCartCustoms);
+			}
+
+			//--- For Recurring payments.
+			if($bTypeRecurring && (float)$aItem[$sKeyPriceRecurring] == 0) {
+			    //TODO: Process FREE subscription here, if such situation will be possible.
+			}
+		}
+
+		if(empty($aInfo['items']))
+            return $this->_sLangsPrefix . ($bProcessedFree ? 'msg_successfully_processed_free' : 'err_empty_order');
+
+        if($bTypeSingle && (empty($aCustoms) || !is_array($aCustoms))) {
+            $aCart = $this->_oDb->getCartContent($aInfo['client_id']);
+            $aCartCustoms = !empty($aCart['customs']) ? unserialize($aCart['customs']) : array();
+
+            $aCustoms = array();
+            foreach($aInfo['items'] as $aItem) {
+                $sCartItem = $this->_oConfig->descriptorA2S(array($aInfo['vendor_id'], $aItem['module_id'], $aItem['id']));
+                $aCartItemCustom = $this->_oConfig->getCustom($sCartItem, $aCartCustoms);
+                $this->_oConfig->putCustom($sCartItem, $aCartItemCustom, $aCustoms);
+            }
+        }
+
+        $iPendingId = $this->_oDb->insertOrderPending($this->_iUserId, $sType, $sProvider, $aInfo, $aCustoms);
+        if(empty($iPendingId))
+            return $this->_sLangsPrefix . 'err_access_db';
+
+		/*
+		 * Perform Join WITHOUT processing via payment provider
+		 * if a client ISN'T logged in and has only ONE FREE item in the card.
+		 * Note. This section isn't used for now because only a member can purchase!
+		 */
+		if((int)$aInfo['client_id'] == 0 && (int)$aInfo['items_count'] == 1) {
+			reset($aInfo['items']);
+			$aItem = current($aInfo['items']);
+
+			if(!empty($aItem) && $this->_oConfig->getPrice($sType, $aItem)) {
+				$this->_oDb->updateOrderPending($iPendingId, array(
+		            'order' => $this->_oConfig->getLicense(),
+		            'error_code' => '1',
+		            'error_msg' => ''
+		        ));
+
+				$this->getObjectJoin()->performJoin($iPendingId);
+			}
+		}
+
+		return $oProvider->initializeCheckout($iPendingId, $aInfo, $sRedirect);
+	}
+
+    public function actionFinalizeCheckout($sProvider, $mixedVendorId = "")
+    {
+        $aData = &$_REQUEST;
+
+        $oProvider = $this->getObjectProvider($sProvider, $mixedVendorId);
+        if($oProvider === false || !$oProvider->isActive())
+        	return $this->_oTemplate->displayPageCodeError($this->_sLangsPrefix . 'err_incorrect_provider');
+
+        $aResult = $oProvider->finalizeCheckout($aData);
+        if((int)$aResult['code'] != BX_PAYMENT_RESULT_SUCCESS) 
+        	return $this->_oTemplate->displayPageCodeError($aResult['message']);
+
+		$aPending = $this->_oDb->getOrderPending(array('type' => 'id', 'id' => (int)$aResult['pending_id']));
+		$bTypeRecurring = $aPending['type'] == BX_PAYMENT_TYPE_RECURRING;
+		if($bTypeRecurring)
+		    $this->registerSubscription($aPending, array(
+		        'customer_id' => $aResult['customer_id'], 
+		    	'subscription_id' => $aResult['subscription_id']
+		    ));
+
+		$this->onPaymentRegisterBefore($aPending);
+
+		//--- Check "Pay Before Join" situation
+		if((int)$aPending['client_id'] == 0)
+			$this->getObjectJoin()->performJoin((int)$aPending['id'], isset($aResult['client_name']) ? $aResult['client_name'] : '', isset($aResult['client_email']) ? $aResult['client_email'] : '');
+
+		//--- Register payment for purchased items in associated modules 
+		if(!empty($aResult['paid']) || ($bTypeRecurring && !empty($aResult['trial'])))
+			$this->registerPayment($aPending);
+
+        bx_alert($this->getName(), 'finalize_checkout', 0, bx_get_logged_profile_id(), array(
+            'pending' => $aPending,
+            'transactions' => $this->_oDb->getOrderProcessed(array('type' => 'pending_id', 'pending_id' => (int)$aPending['id'])),
+            'provider' => $oProvider,
+            'message' => &$aResult['message'],
+        ));
+
+        if($oProvider->needRedirect()) {
+			header('Location: ' . $oProvider->getReturnUrl());
+			exit;
+		}
+
+		if(!empty($aResult['redirect'])) {
+			header('Location: ' . base64_decode(urldecode($aResult['redirect'])));
+			exit;
+		}
+
+		$this->_oTemplate->displayPageCodeResponse($aResult['message']);
+    }
+
+    public function actionFinalizedCheckout($sProvider, $mixedVendorId = "")
+    {
+        $oProvider = $this->getObjectProvider($sProvider, $mixedVendorId);
+        if($oProvider === false || !$oProvider->isActive())
+        	return $this->_oTemplate->displayPageCodeError($this->_sLangsPrefix . 'err_incorrect_provider');
+
+        $aResult = $oProvider->finalizedCheckout();
+        $this->_oTemplate->displayPageCodeResponse($aResult['message']);
+    }
+
+    public function actionNotify($sProvider, $mixedVendorId = "")
+    {
+    	$oProvider = $this->getObjectProvider($sProvider, $mixedVendorId);
+        if($oProvider === false || !$oProvider->isActive())
+        	return $this->_oTemplate->displayPageCodeError($this->_sLangsPrefix . 'err_incorrect_provider');
+
+		$oProvider->notify();
+    }
+
+    public function onProfileJoin($iProfileId)
+    {
+    	$this->getObjectJoin()->onProfileJoin($iProfileId);
+    }
+
+    public function onProfileDelete($iProfileId)
+    {
+		$this->_oDb->onProfileDelete($iProfileId);
+    }
+
+    public function isAllowedPurchase($aItem, $bPerform = false)
+    {
+        $iUserId = (int)$this->getProfileId();
+
+        $aItemInfo = $this->callGetCartItem($aItem['module_id'], array($aItem['item_id']));
+		if(empty($aItemInfo))
+			return false;
+
+        if(isAdmin())
+            return true;
+
+        $aCheckResult = checkActionModule($iUserId, 'purchase', $this->getName(), $bPerform);
+        if($aCheckResult[CHECK_ACTION_RESULT] == CHECK_ACTION_RESULT_ALLOWED)
+			return true;
+
+        return $aCheckResult[CHECK_ACTION_MESSAGE];
+    }
+
+    public function isAllowedSell($aItem, $bPerform = false)
+    {
+		$iUserId = (int)$this->getProfileId();
+        if(!$iUserId)
+        	return false;
+
+		$aItemInfo = $this->callGetCartItem($aItem['module_id'], array($aItem['item_id']));
+		if(empty($aItemInfo))
+			return false;
+
+        if(isAdmin())
+            return true;
+
+        $aCheckResult = checkActionModule($iUserId, 'sell', $this->getName(), $bPerform);
+        if((int)$aItemInfo['author_id'] == $iUserId && $aCheckResult[CHECK_ACTION_RESULT] == CHECK_ACTION_RESULT_ALLOWED)
+			return true;
+
+        return $aCheckResult[CHECK_ACTION_MESSAGE];
+    }
+
+    public function checkData($iClientId, $iSellerId, $iModuleId, $iItemId, $iItemCount)
+    {
+    	$CNF = &$this->_oConfig->CNF;
+
+		if($iSellerId == BX_PAYMENT_EMPTY_ID || empty($iModuleId) || empty($iItemId) || empty($iItemCount))
+            return array('code' => 1, 'message' => _t($CNF['T']['ERR_WRONG_DATA']));
+
+		$iClientId = $this->getProfileId();
+        if(empty($iClientId)) {
+        	$sLoginUrl = BxDolPermalinks::getInstance()->permalink('page.php?i=login');
+            return array('code' => 2, 'eval' => 'window.open("' . $sLoginUrl . '", "_self");');
+        }
+
+        $mixedResult = $this->isAllowedPurchase(array('module_id' => $iModuleId, 'item_id' => $iItemId));
+        if($mixedResult !== true) {
+            if(is_string($mixedResult) && !empty($mixedResult))
+                return array('code' => 2, 'message' => $mixedResult);
+            else 
+                return array('code' => 1, 'message' => _t($CNF['T']['ERR_WRONG_DATA']));
+        }
+
+        if($iClientId == $iSellerId)
+            return array('code' => 3, 'message' => _t($CNF['T']['ERR_SELF_PURCHASE']));
+
+        $aSeller = $this->getVendorInfo($iSellerId);
+        if(!$aSeller['active'])
+            return array('code' => 4, 'message' => _t($CNF['T']['ERR_INACTIVE_VENDOR']));
+
+		return true;
+    }
+
+	public function registerPayment($mixedPending)
+    {
+    	$aPending = is_array($mixedPending) ? $mixedPending : $this->_oDb->getOrderPending(array('type' => 'id', 'id' => (int)$mixedPending));
+    	if(empty($aPending) || !is_array($aPending))
+    		return false;
+
+		$sType = $aPending['type'];
+		$bTypeSingle = $sType == BX_PAYMENT_TYPE_SINGLE;
+
+		if($bTypeSingle && (int)$aPending['processed'] == 1)
+			return true;
+
+		$iClientId = (int)$aPending['client_id'];
+		$sLicense = $this->_oConfig->getLicense();
+		$aCustoms = !empty($aPending['customs']) ? unserialize($aPending['customs']) : array();
+
+		$aCart = array();
+		if($bTypeSingle) {
+			$aCart = $this->_oDb->getCartContent($iClientId);
+			$aCart['customs'] = !empty($aCart['customs']) ? unserialize($aCart['customs']) : array();
+		}
+
+		$bResult = false;
+        $aItems = $this->_oConfig->descriptorsM2A($aPending['items']);
+        foreach($aItems as $aItem) {
+            $sItem = $this->_oConfig->descriptorA2S(array($aItem['vendor_id'], $aItem['module_id'], $aItem['item_id']));
+		    $aItemCustom = $this->_oConfig->getCustom($sItem, $aCustoms);
+
+        	$sMethod = $bTypeSingle ? 'callRegisterCartItem' : 'callRegisterSubscriptionItem';
+        	$aItemInfo = $this->$sMethod((int)$aItem['module_id'], array($aPending['client_id'], $aPending['seller_id'], $aItem['item_id'], $aItem['item_count'], $aPending['order'], $sLicense, $aItemCustom));
+            if(empty($aItemInfo) || !is_array($aItemInfo))
+                continue;
+
+            $this->_oDb->insertOrderProcessed(array(
+                'pending_id' => $aPending['id'],
+                'client_id' => $aPending['client_id'],
+                'seller_id' => $aPending['seller_id'],
+                'module_id' => (int)$aItem['module_id'],
+                'item_id' => (int)$aItem['item_id'],
+                'item_count' => (int)$aItem['item_count'],
+                'amount' => (int)$aItem['item_count'] * $this->_oConfig->getPrice($sType, $aItemInfo),
+            	'license' => $sLicense,
+            ));
+
+            if($bTypeSingle) {
+                $this->_oConfig->pullCustom($sItem, $aCart['customs']);
+
+            	$aCart['items'] = trim(preg_replace("'" . $this->_oConfig->descriptorA2S($aItem) . ":?'", "", $aCart['items']), ":");
+            }
+
+			$bResult = true;
+        }
+
+        if($bTypeSingle)
+			$this->_oDb->setCartItems($iClientId, $aCart['items'], $aCart['customs']);
+
+        if($bResult) {
+        	$this->_oDb->updateOrderPending($aPending['id'], array('processed' => 1));
+
+        	$this->onPaymentRegister($aPending);
+        }
+
+        return $bResult;
+    }
+
+	public function refundPayment($mixedPending)
+	{
+		$aPending = is_array($mixedPending) ? $mixedPending : $this->_oDb->getOrderPending(array('type' => 'id', 'id' => (int)$mixedPending));
+    	if(empty($aPending) || !is_array($aPending))
+    		return false;
+
+		$bTypeSingle = $aPending['type'] == BX_PAYMENT_TYPE_SINGLE;
+
+		$iCanceled = 0;
+		$aOrders = $this->_oDb->getOrderProcessed(array('type' => 'pending_id', 'pending_id' => (int)$aPending['id']));
+		foreach($aOrders as $aOrder) {
+			$sMethod = $bTypeSingle ? 'callUnregisterCartItem' : 'callUnregisterSubscriptionItem';
+			$bResult = $this->$sMethod((int)$aOrder['module_id'], array($aOrder['client_id'], $aOrder['seller_id'], $aOrder['item_id'], $aOrder['item_count'], $aPending['order'], $aOrder['license']));
+			if(!$bResult)
+                continue;
+
+            if($this->_oDb->deleteOrderProcessed($aOrder['id']))
+            	$iCanceled++;
+		}
+
+		if($iCanceled != count($aOrders))
+			return false;
+
+		$bResult = $this->_oDb->deleteOrderPending($aPending['id']);
+		if($bResult)
+			$this->onPaymentRefund($aPending);
+
+		return $bResult;
+	}
+
+	public function registerSubscription($aPending, $aParams = array())
+	{
+	    $this->_oDb->insertSubscription(array(
+	        'pending_id' => $aPending['id'],
+	        'customer_id' => $aParams['customer_id'],
+	        'subscription_id' => $aParams['subscription_id']
+	    ));
+
+	    $this->onSubscriptionCreate($aPending);
+	}
+
+	public function updateSubscription($aPending, $aParams = array())
+	{
+	    $this->_oDb->updateSubscription($aParams, array(
+	        'pending_id' => $aPending['id']
+	    ));
+
+	    $this->onSubscriptionUpdate($aPending);
+	}
+
+	public function cancelSubscription($mixedPending)
+	{
+		$aPending = is_array($mixedPending) ? $mixedPending : $this->_oDb->getOrderPending(array('type' => 'id', 'id' => (int)$mixedPending));
+    	if(empty($aPending) || !is_array($aPending) || $aPending['type'] != BX_PAYMENT_TYPE_RECURRING)
+    		return false;
+
+		$aItems = $this->_oConfig->descriptorsM2A($aPending['items']);
+        foreach($aItems as $aItem)
+			$this->callCancelSubscriptionItem((int)$aItem['module_id'], array($aPending['client_id'], $aPending['seller_id'], $aItem['item_id'], $aItem['item_count'], $aPending['order']));
+
+		$this->onSubscriptionCancel($aPending);
+	}
+
+	public function onPaymentRegisterBefore($aPending, $aResult = array())
+	{
+		//--- 'System' -> 'Before Register Payment' for Alerts Engine ---//
+		bx_alert('system', 'before_register_payment', 0, $aPending['client_id'], array('pending' => $aPending));
+		//--- 'System' -> 'Before Register Payment' for Alerts Engine ---//
+	}
+
+	public function onPaymentRegister($aPending, $aResult = array())
+	{
+	    $bTypeSingle = $aPending['type'] == BX_PAYMENT_TYPE_SINGLE;
+
+	    if($bTypeSingle) {
+    	    $aItems = $this->_oConfig->descriptorsM2A($aPending['items']);
+            foreach($aItems as $aItem)
+                $this->isAllowedPurchase(array('module_id' => $aItem['module_id'], 'item_id' => $aItem['item_id']), true);
+	    }
+
+		//--- 'System' -> 'Register Payment' for Alerts Engine ---//
+		bx_alert('system', 'register_payment', 0, $aPending['client_id'], array('pending' => $aPending));
+		//--- 'System' -> 'Register Payment' for Alerts Engine ---//
+	}
+
+	public function onPaymentRefund($aPending, $aResult = array())
+	{
+		//--- 'System' -> 'Refund Payment' for Alerts Engine ---//
+		bx_alert('system', 'refund_payment', 0, $aPending['client_id'], array('pending' => $aPending));
+		//--- 'System' -> 'Refund Payment' for Alerts Engine ---//
+	}
+
+	public function onSubscriptionCreate($aPending, $aResult = array())
+	{
+	    $aItems = $this->_oConfig->descriptorsM2A($aPending['items']);
+	    $this->isAllowedPurchase(array('module_id' => $aItems[0]['module_id'], 'item_id' => $aItems[0]['item_id']), true);
+
+		//--- 'System' -> 'Create Subscription' for Alerts Engine ---//
+		bx_alert('system', 'create_subscription', 0, $aPending['client_id'], array('pending' => $aPending));
+		//--- 'System' -> 'Create Subscription' for Alerts Engine ---//
+	}
+
+	public function onSubscriptionUpdate($aPending, $aResult = array())
+	{
+	    //--- 'System' -> 'Update Subscription' for Alerts Engine ---//
+		bx_alert('system', 'update_subscription', 0, $aPending['client_id'], array('pending' => $aPending));
+		//--- 'System' -> 'Update Subscription' for Alerts Engine ---//
+	}
+	
+	public function onSubscriptionCancel($aPending, $aResult = array())
+	{
+		//--- 'System' -> 'Cancel Subscription' for Alerts Engine ---//
+		bx_alert('system', 'cancel_subscription', 0, $aPending['client_id'], array('pending' => $aPending));
+		//--- 'System' -> 'Cancel Subscription' for Alerts Engine ---//
+	}
+
+    public function setSiteSubmenu($sSubmenu, $sSelModule, $sSelName)
+    {
+        $oSiteSubmenu = BxDolMenu::getObjectInstance('sys_site_submenu');
+        if(!$oSiteSubmenu)
+            return;
+
+        $sModuleSubmenu = $this->_oConfig->getObject($sSubmenu);
+        $oModuleSubmenu = BxDolMenu::getObjectInstance($sModuleSubmenu);
+        if(!$oModuleSubmenu) 
+            return;
+
+        $oSiteSubmenu->setObjectSubmenu($sModuleSubmenu);
+        $oModuleSubmenu->setSelected($sSelModule, $sSelName);
+    }
+}
+
+/** @} */

+ 200 - 0
modules/boonex/payment/updates/9.0.5_9.0.6/source/classes/BxPaymentOrders.php

@@ -0,0 +1,200 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Payment Payment
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+class BxPaymentOrders extends BxBaseModPaymentOrders
+{
+    protected $_sLangsPrefix;
+
+    function __construct()
+    {
+    	$this->MODULE = 'bx_payment';
+
+    	parent::__construct();
+
+        $this->_sLangsPrefix = $this->_oModule->_oConfig->getPrefix('langs');
+    }
+
+	/*
+     * Service methods
+     */
+    
+    /**
+     * @page service Service Calls
+     * @section bx_payment Payment
+     * @subsection bx_payment-page_blocks Page Blocks
+     * @subsubsection bx_payment-get_block_orders get_block_orders
+     * 
+     * @code bx_srv('bx_payment', 'get_block_orders', [...], 'Orders'); @endcode
+     * 
+     * Get page block with a list of orders represented as table.
+     *
+     * @param $sType string value with order type (processed or pending).
+     * @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 BxPaymentOrders::serviceGetBlockOrders
+     */
+    /** 
+     * @ref bx_payment-get_block_orders "get_block_orders"
+     */
+	public function serviceGetBlockOrders($sType = '', $iUserId = BX_PAYMENT_EMPTY_ID)
+    {
+        $CNF = &$this->_oModule->_oConfig->CNF;
+
+    	if(empty($sType))
+    		$sType = bx_get('type') !== false ? bx_process_input(bx_get('type')) : BX_PAYMENT_ORDERS_TYPE_PROCESSED;
+
+    	if(!$this->_oModule->isLogged())
+            return array(
+            	'content' => MsgBox(_t($this->_sLangsPrefix . 'err_required_login'))
+            );
+
+        $iUserId = $iUserId != BX_PAYMENT_EMPTY_ID ? $iUserId : $this->_oModule->getProfileId();
+        if($sType == BX_PAYMENT_ORDERS_TYPE_PROCESSED)
+            $this->_oModule->_oDb->updateOrdersProcessed(array('new' => 0), array('seller_id' => $iUserId, 'new' => 1));
+
+        $this->_oModule->setSiteSubmenu('menu_dashboard', 'system', 'dashboard-orders');
+
+        $sBlockSubmenu = $this->_oModule->_oConfig->getObject('menu_orders_submenu');
+        $oBlockSubmenu = BxDolMenu::getObjectInstance($sBlockSubmenu);
+        if($oBlockSubmenu)
+            $oBlockSubmenu->setSelected($this->MODULE, 'orders-' . $sType);
+
+        return array(
+        	'title' => _t($this->_sLangsPrefix . 'page_block_title_orders_' . $sType),
+        	'content' => $this->_oModule->_oTemplate->displayBlockOrders($sType, $iUserId),
+            'menu' => $oBlockSubmenu
+        );
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_payment Payment
+     * @subsection bx_payment-other Other
+     * @subsubsection bx_payment-get_orders_info get_orders_info
+     * 
+     * @code bx_srv('bx_payment', 'get_orders_info', [...], 'Orders'); @endcode
+     * 
+     * Get transaction(s) which meets all requirements.
+     *
+     * @param $aConditions an array of pears('key' => 'value'). Available keys are the following:
+     * a. license - internal license (string)
+     * b. client_id - client's ID (integer)
+     * c. seller_id - seller's ID (integer)
+     * d. module_id - modules's where the purchased product is located. (integer)
+     * e. item_id - item id in the database. (integer)
+     * f. date - the date when the payment was processed(UNIXTIME STAMP)
+     * @return an array of transactions. Each transaction has full info(client ID, seller ID, external transaction ID, date and so on)
+     * 
+     * @see BxPaymentOrders::serviceGetOrdersInfo
+     */
+    /** 
+     * @ref bx_payment-get_orders_info "get_orders_info"
+     */
+    public function serviceGetOrdersInfo($aConditions)
+    {
+        if(empty($aConditions) || !is_array($aConditions))
+            return array();
+
+        return $this->_oModule->_oDb->getOrderProcessed(array('type' => 'mixed', 'conditions' => $aConditions));
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_payment Payment
+     * @subsection bx_payment-other Other
+     * @subsubsection bx_payment-get_pending_orders_info get_pending_orders_info
+     * 
+     * @code bx_srv('bx_payment', 'get_pending_orders_info', [...], 'Orders'); @endcode
+     * 
+     * Get pending transaction(s) which meets all requirements.
+     *
+     * @param $aConditions an array of pears('key' => 'value'). The most useful keys are the following:
+     * a. client_id - client's ID (integer)
+     * b. seller_id - seller's ID (integer)
+     * c. type - transaction type: single or recurring (string)
+     * d. amount - transaction amount (float)
+     * e. order - order ID received from payment provider (string)
+     * f. provider - payment provider name (string)
+     * g. date - the date when the payment was established(UNIXTIME STAMP)
+     * h. processed - whether the payment was processed or not (integer, 0 or 1)
+     * @return an array of pending transactions. Each transaction has full info(client ID, seller ID, type, date and so on)
+     * 
+     * @see BxPaymentOrders::serviceGetPendingOrdersInfo
+     */
+    /** 
+     * @ref bx_payment-get_pending_orders_info "get_pending_orders_info"
+     */
+    public function serviceGetPendingOrdersInfo($aConditions)
+    {
+        if(empty($aConditions) || !is_array($aConditions))
+            return array();
+
+        return $this->_oModule->_oDb->getOrderPending(array('type' => 'mixed', 'conditions' => $aConditions));
+    }
+
+	public function addOrder($aData)
+    {
+        $iSellerId = isset($aData['seller_id']) ? (int)$aData['seller_id'] : $this->_oModule->getProfileId();
+        if($iSellerId == $aData['client_id'])
+            return array('msg' => $this->_sLangsPrefix . 'err_self_purchase');
+
+        $sOrder = trim($aData['order']);
+        if(empty($sOrder))
+            return array('msg' => $this->_sLangsPrefix . 'form_processed_input_order_err');
+
+        $aCartInfo = array('vendor_id' => $iSellerId, 'items_price' => 0, 'items' => array());
+        foreach($aData['items'] as $aItem) {
+        	if(!$this->_oModule->isAllowedSell(array('module_id' => $aData['module_id'], 'item_id' => $aItem['id']), true))
+        		continue;
+
+            $aCartInfo['items_price'] += $this->_oModule->_oConfig->getPrice($aData['type'], $aItem) * $aItem['quantity'];
+            $aCartInfo['items'][] = array(
+                'vendor_id' => $iSellerId,
+                'module_id' => $aData['module_id'],
+                'id' => $aItem['id'],
+                'quantity' => $aItem['quantity']
+            );
+        }
+
+        $iPendingId = $this->_oModule->_oDb->insertOrderPending($aData['client_id'], $aData['type'], $aData['provider'], $aCartInfo);
+        $this->_oModule->_oDb->updateOrderPending($iPendingId, array(
+            'order' => $sOrder,
+            'error_code' => $aData['error_code'],
+            'error_msg' => $aData['error_msg']
+        ));
+
+        return (int)$iPendingId;
+    }
+
+    public function getOrder($sType, $iId)
+    {
+        return $this->_oModule->_oTemplate->displayOrder($sType, $iId);
+    }
+
+    public function cancel($sType, $iOrderId)
+    {
+    	$sMethodName = 'getOrder' . bx_gen_method_name($sType);
+    	$aOrder = $this->_oModule->_oDb->$sMethodName(array('type' => 'id', 'id' => $iOrderId));
+		if(empty($aOrder) || !is_array($aOrder))
+	    	return true;
+
+		if($sType == BX_PAYMENT_ORDERS_TYPE_PROCESSED && !$this->_oModule->callUnregisterCartItem((int)$aOrder['module_id'], array($aOrder['client_id'], $aOrder['seller_id'], $aOrder['item_id'], $aOrder['item_count'], $aOrder['order'], $aOrder['license'])))
+			return false;
+
+		$sMethodName = 'deleteOrder' . bx_gen_method_name($sType);
+		if(!$this->_oModule->_oDb->$sMethodName($iOrderId))
+			return false;
+
+        return true;
+    }
+}
+
+/** @} */

+ 314 - 0
modules/boonex/payment/updates/9.0.5_9.0.6/source/classes/BxPaymentProviderPayPal.php

@@ -0,0 +1,314 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Payment Payment
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+/**
+ * Usefull links related to the integration:
+ * 
+ * HTML Form Basics for PayPal Payments Standard
+ * https://developer.paypal.com/docs/classic/paypal-payments-standard/integration-guide/formbasics/
+ * 
+ * HTML Variables for PayPal Payments Standard
+ * https://developer.paypal.com/docs/classic/paypal-payments-standard/integration-guide/Appx_websitestandard_htmlvariables/
+ * 
+ */
+
+define('PP_MODE_LIVE', 1);
+define('PP_MODE_TEST', 2);
+
+define('PP_PRC_TYPE_DIRECT', 1);
+define('PP_PRC_TYPE_PDT', 2);
+define('PP_PRC_TYPE_IPN', 3);
+
+class BxPaymentProviderPayPal extends BxBaseModPaymentProvider implements iBxBaseModPaymentProvider
+{
+    function __construct($aConfig)
+    {
+    	$this->MODULE = 'bx_payment';
+
+        parent::__construct($aConfig);
+
+        $this->_bRedirectOnResult = false;
+        $this->_sLogFile = BX_DIRECTORY_PATH_LOGS . 'bx_pp_' . $this->_sName . '.log';
+    }
+
+    public function initializeCheckout($iPendingId, $aCartInfo, $bRecurring = false, $iRecurringDays = 0)
+    {
+        $iMode = (int)$this->getOption('mode');
+        $sItemName = _t($this->_sLangsPrefix . 'txt_payment_to_for', $aCartInfo['vendor_name']);
+        $sActionURL = $iMode == PP_MODE_LIVE ? 'https://www.paypal.com/cgi-bin/webscr' : 'https://www.sandbox.paypal.com/cgi-bin/webscr';
+
+        if($bRecurring) {
+            $aFormData = array(
+                'cmd' => '_xclick-subscriptions',
+                'a3' => sprintf("%.2f", (float)$aCartInfo['items_price']),
+                'p3' => $iRecurringDays,
+                't3' => 'D',
+                'src' => '1', // repeat billings unles member cancels subscription
+                'sra' => '1' // reattempt on failure
+            );
+
+            foreach($aCartInfo['items'] as $aItem)
+                $sItemName .= ' ' . $aItem['title'] . ',';
+		    $sItemName = trim($sItemName, ', ');
+        }
+        else {
+            $aFormData = array(
+                'cmd' => '_cart',
+                'upload' => '1',
+                'item_name' => $sItemName,
+                'amount' => sprintf( "%.2f", (float)$aCartInfo['items_price'])
+            );
+
+            foreach($aCartInfo['items'] as $iIndex => $aItem) {
+                $i = $iIndex + 1; 
+
+                $aFormData['item_name_' . $i] = bx_process_output($aItem['title']);
+			    $aFormData['quantity_' . $i] = $aItem['quantity'];
+			    $aFormData['amount_' . $i] = $this->_oModule->_oConfig->getPrice(BX_PAYMENT_TYPE_SINGLE, $aItem);
+            }
+        }
+
+        $aFormData = array_merge($aFormData, array(
+            'business' => $iMode == PP_MODE_LIVE ? $this->getOption('business') : $this->getOption('sandbox'),
+            'currency_code' => $aCartInfo['vendor_currency_code'],
+            'no_note' => '1',
+            'no_shipping' => '1',
+            'custom' => $this->_constructCustomData($aCartInfo['vendor_id'], $iPendingId),
+        	'item_name' => $sItemName,
+            'item_number' => $iPendingId,
+        ));
+
+        switch($this->getOption('prc_type')) {
+            case PP_PRC_TYPE_PDT:
+            case PP_PRC_TYPE_DIRECT:
+                $aFormData = array_merge($aFormData, array(
+                    'return' => $this->getReturnDataUrl($aCartInfo['vendor_id']),
+                    'rm' => '2'
+                ));
+                break;
+            case PP_PRC_TYPE_IPN:
+                $aFormData = array_merge($aFormData, array(
+                    'return' => $this->getReturnUrl(),
+                    'notify_url' => $this->getReturnDataUrl($aCartInfo['vendor_id']),
+                    'rm' => '1'
+                ));
+                break;
+        }
+
+        $this->log('Initialize Checkout:');
+        $this->log($aFormData);
+
+        $this->_oModule->_oTemplate->displayPageCodeRedirect($sActionURL, $aFormData);
+        exit;
+    }
+
+    public function finalizeCheckout(&$aData)
+    {
+        $aResult = $this->_registerCheckout($aData);
+        if(!isset($aResult['code']) || (int)$aResult['code'] != BX_PAYMENT_RESULT_SUCCESS) {
+            $this->log('Finalize Checkout: Failed');
+            $this->log($aData);
+            $this->log($aResult);
+        }
+
+        return $aResult;
+    }
+
+    /**
+     *
+     * @param $aData - data from payment provider.
+     * @return array with results.
+     */
+    protected function _registerCheckout(&$aData)
+    {
+        if(empty($this->_aOptions) && !empty($aData['item_number']))
+            $this->_aOptions = $this->getOptionsByPending((int)$aData['item_number']);
+
+        if(empty($this->_aOptions))
+            return array('code' => 1, 'message' => $this->_sLangsPrefix . 'err_incorrect_provider');
+
+        $iPrcType = (int)$this->getOption('prc_type');
+        if((in_array($iPrcType, array(PP_PRC_TYPE_DIRECT, PP_PRC_TYPE_IPN)) && !isset($aData['txn_id'])) || ($iPrcType == PP_PRC_TYPE_PDT && !isset($aData['tx'])))
+            return array('code' => 2, 'message' => $this->_sLangsPrefix . 'pp_err_no_data_given');
+
+        $aPending = array();
+        $aResult = $this->_validateCheckout($aData, $aPending);
+
+        if(empty($aPending) || !is_array($aPending))
+            return $aResult;
+
+        if(!empty($aPending['order']) || !empty($aPending['error_code']) || !empty($aPending['error_msg']) || (int)$aPending['processed'] != 0)
+            return array('code' => 11, 'message' => $this->_sLangsPrefix . 'err_already_processed');
+
+        //--- Update pending transaction
+        $this->_oModule->_oDb->updateOrderPending($aPending['id'], array(
+            'order' => $aData['txn_id'],
+            'error_code' => $aResult['code'],
+            'error_msg' => _t($aResult['message'])
+        ));
+
+        $aResult['pending_id'] = $aPending['id'];
+        $aResult['client_name'] = _t($this->_sLangsPrefix . 'txt_buyer_name_mask', bx_process_input($aData['first_name']), bx_process_input($aData['last_name'])); 
+		$aResult['client_email'] = bx_process_input($aData['payer_email']);
+		$aResult['paid'] = true;
+        return $aResult;
+    }
+
+    protected function _validateCheckout(&$aData, &$aPending)
+    {
+        $iMode = (int)$this->getOption('mode');
+        if($iMode == PP_MODE_LIVE) {
+           $sBusiness = $this->getOption('business');
+           $sConnectionUrl = 'www.paypal.com';
+        } else {
+            $sBusiness = $this->getOption('sandbox');
+            $sConnectionUrl = 'www.sandbox.paypal.com';
+        }
+
+        $iPrcType = $this->getOption('prc_type');
+        if($iPrcType == PP_PRC_TYPE_DIRECT || $iPrcType == PP_PRC_TYPE_IPN) {
+            if($aData['payment_status'] != 'Completed' )
+                return array('code' => 3, 'message' => $this->_sLangsPrefix . 'pp_err_not_completed');
+
+            if($aData['business'] != $sBusiness)
+                return array('code' => 4, 'message' => $this->_sLangsPrefix . 'pp_err_wrong_business');
+
+            $sRequest = 'cmd=_notify-validate';
+            foreach($aData as $sKey => $sValue) {
+                if(in_array($sKey, array('cmd', 'r')))
+                    continue;
+
+                $sRequest .= '&' . urlencode($sKey) . '=' . urlencode(bx_process_pass($sValue));
+            }
+
+            $aResponse = $this->_readValidationData($sConnectionUrl, $sRequest);
+            if((int)$aResponse['code'] !== 0)
+               return $aResponse;
+
+            array_walk($aResponse['content'], create_function('&$arg', "\$arg = trim(\$arg);"));
+            if(strcmp($aResponse['content'][0], "INVALID") === 0)
+                return array('code' => 6, 'message' => $this->_sLangsPrefix . 'pp_err_wrong_transaction');
+            else if(strcmp($aResponse['content'][0], "VERIFIED") !== 0)
+                return array('code' => 7, 'message' => $this->_sLangsPrefix . 'pp_err_wrong_verification_status');
+        }
+         else if($iPrcType == PP_PRC_TYPE_PDT) {
+            $sRequest = "cmd=_notify-synch&tx=" . $aData['tx'] . "&at=" . $this->getOption('token');
+            $aResponse = $this->_readValidationData($sConnectionUrl, $sRequest);
+
+            if((int)$aResponse['code'] !== 0)
+               return $aResponse;
+
+            if(strcmp($aResponse['content'][0], "FAIL") === 0)
+                return array('code' => 6, 'message' => $this->_sLangsPrefix . 'pp_err_wrong_transaction');
+            else if(strcmp($aResponse['content'][0], "SUCCESS") !== 0)
+                return array('code' => 7, 'message' => $this->_sLangsPrefix . 'pp_err_wrong_verification_status');
+
+            $aKeys = array();
+            foreach($aResponse['content'] as $sLine) 
+                if(strpos($sLine, '=') !== false) {
+                    list($sKey, $sValue) = explode('=', $sLine);
+                    $aKeys[urldecode($sKey)] = urldecode($sValue);
+                }
+
+            $aData = array_merge($aData, $aKeys);
+
+            if($aData['payment_status'] != 'Completed' )
+                return array('code' => 3, 'message' => $this->_sLangsPrefix . 'pp_err_not_completed');
+
+            if($aData['business'] != $sBusiness)
+                return array('code' => 4, 'message' => $this->_sLangsPrefix . 'pp_err_wrong_business');
+        }
+
+        if(empty($aData['custom']))
+            return array('code' => 8, 'message' => $this->_sLangsPrefix . 'pp_err_wrong_custom_data');
+
+        list($iVendorId, $iPendingId) = $this->_deconstructCustomData($aData['custom']);
+        if(empty($iVendorId) || empty($iPendingId))
+            return array('code' => 8, 'message' => $this->_sLangsPrefix . 'pp_err_wrong_custom_data');
+
+        $aPending = $this->_oModule->_oDb->getOrderPending(array('type' => 'id', 'id' => $iPendingId));
+        if((int)$iVendorId != (int)$aPending['seller_id'])
+            return array('code' => 9, 'message' => $this->_sLangsPrefix . 'pp_err_wrong_vendor');
+
+        $aVendor = $this->_oModule->getVendorInfo($iVendorId);
+        $fAmount = (float)$this->_getReceivedAmount($aVendor['currency_code'], $aData);
+        if($fAmount != (float)$aPending['amount'])
+            return array('code' => 10, 'message' => $this->_sLangsPrefix . 'pp_err_wrong_amount');
+
+        return array('code' => BX_PAYMENT_RESULT_SUCCESS, 'message' => $this->_sLangsPrefix . 'pp_msg_verified');
+    }
+
+    protected function _readValidationData($sConnectionUrl, $sRequest)
+    {
+        $this->log('Validation Request: ');
+        $this->log($sRequest);
+
+		$rConnect = curl_init('https://' . $sConnectionUrl . '/cgi-bin/webscr');
+		curl_setopt($rConnect, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
+		curl_setopt($rConnect, CURLOPT_POST, 1);
+		curl_setopt($rConnect, CURLOPT_RETURNTRANSFER,1);
+		curl_setopt($rConnect, CURLOPT_POSTFIELDS, $sRequest);
+		curl_setopt($rConnect, CURLOPT_SSL_VERIFYPEER, 1);
+		curl_setopt($rConnect, CURLOPT_SSL_VERIFYHOST, 2);
+		curl_setopt($rConnect, CURLOPT_FORBID_REUSE, 1);
+		curl_setopt($rConnect, CURLOPT_HTTPHEADER, array('Connection: Close'));
+
+		$sResponse = curl_exec($rConnect);
+    	if(curl_errno($rConnect) == 60) { // CURLE_SSL_CACERT
+            curl_setopt($rConnect, CURLOPT_CAINFO, BX_DIRECTORY_PATH_PLUGINS . 'curl/cacert.pem');
+            $sResponse = curl_exec($rConnect);
+        }
+
+		if(!$sResponse) {
+		    $this->log('Validation Data: ' . curl_error($rConnect));
+            $this->log($sResponse);
+			curl_close($rConnect);
+
+			return array('code' => 5, 'message' => $this->_sLangsPrefix . 'err_cannot_validate');
+		}
+
+		curl_close($rConnect);
+
+		$aResponse = explode("\n", $sResponse);
+
+		$this->log('Validation Response: ');
+        $this->log($aResponse);
+		return array('code' => 0, 'content' => $aResponse);
+    }
+
+    protected function _getReceivedAmount($sCurrencyCode, &$aResultData)
+    {
+        $fAmount = 0.00;
+        $fTax = isset($aResultData['tax']) ? (float)$aResultData['tax'] : 0.00;
+
+        if($aResultData['mc_currency'] == $sCurrencyCode && isset($aResultData['payment_gross']) && !empty($aResultData['payment_gross']))
+            $fAmount = (float)$aResultData['payment_gross'] - $fTax;
+        else if($aResultData['mc_currency'] == $sCurrencyCode && isset($aResultData['mc_gross']) && !empty($aResultData['mc_gross']))
+            $fAmount = (float)$aResultData['mc_gross'] - $fTax;
+        else if($aResultData['settle_currency'] == $sCurrencyCode && isset($aResultData['settle_amount']) && !empty($aResultData['settle_amount']))
+            $fAmount = (float)$aResultData['settle_amount'] - $fTax;
+
+        return $fAmount;
+    }
+
+	protected function _constructCustomData()
+	{
+		$aParams = func_get_args();
+		return urlencode(base64_encode(implode('|', $aParams)));
+	}
+
+	protected function _deconstructCustomData($data)
+	{
+		return explode('|', base64_decode(urldecode($data)));
+	}
+}
+
+/** @} */

+ 869 - 0
modules/boonex/payment/updates/9.0.5_9.0.6/source/classes/BxPaymentProviderStripe.php

@@ -0,0 +1,869 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Payment Payment
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+require_once(BX_DIRECTORY_PATH_PLUGINS . 'stripe/init.php');
+
+define('STRP_MODE_LIVE', 1);
+define('STRP_MODE_TEST', 2);
+
+class BxPaymentProviderStripe extends BxBaseModPaymentProvider implements iBxBaseModPaymentProvider
+{
+	protected $_aIncludeJs;
+	protected $_aIncludeCss;
+
+	protected $_sFormDetails;
+	protected $_sFormDisplayDetailsEdit;
+
+    protected $_sFormCard;
+	protected $_sFormDisplayCardAdd;
+
+	protected $_iMode;
+	protected $_bCheckAmount;
+	protected $_bProrate;
+
+	protected $_oCustomer;
+
+
+    function __construct($aConfig)
+    {
+    	$this->MODULE = 'bx_payment';
+
+        parent::__construct($aConfig);
+
+        $this->_sFormDetails = 'bx_payment_form_strp_details';
+        $this->_sFormDisplayDetailsEdit = 'bx_payment_form_strp_details_edit';
+
+        $this->_sFormCard = 'bx_payment_form_strp_card';
+        $this->_sFormDisplayCardAdd = 'bx_payment_form_strp_card_add';
+
+        $this->_bRedirectOnResult = false;
+        $this->_iMode = (int)$this->getOption('mode');
+        $this->_bCheckAmount = $this->getOption('check_amount') == 'on'; 
+        $this->_bUseSsl = $this->getOption('ssl') == 'on';
+        $this->_bProrate = false;
+        $this->_sLogFile = BX_DIRECTORY_PATH_LOGS . 'bx_pp_' . $this->_sName . '.log';
+
+        $this->_aIncludeJs = array(
+        	'https://checkout.stripe.com/checkout.js',
+        	'main.js',
+        	'stripe.js'
+        );
+        $this->_aIncludeCss = array(
+        	'stripe.css'
+        );
+
+        $this->_oCustomer = null;
+
+        \Stripe\Stripe::setApiKey($this->_getSecretKey());
+    }
+
+	public function addJsCss()
+    {
+    	if(!$this->isActive())
+    		return;
+
+        $this->_oModule->_oTemplate->addJs($this->_aIncludeJs);
+        $this->_oModule->_oTemplate->addCss($this->_aIncludeCss);
+    }
+
+    public function initializeCheckout($iPendingId, $aCartInfo, $sRedirect = '')
+    {
+    	$sToken = bx_process_input(bx_get('token'));
+
+    	if(empty($aCartInfo['items']) || !is_array($aCartInfo['items']))
+    		return $this->_sLangsPrefix . 'err_empty_items';
+
+		$aClient = $this->_oModule->getProfileInfo();
+		$aVendor = $this->_oModule->getProfileInfo($aCartInfo['vendor_id']);
+
+		$aPending = $this->_oModule->_oDb->getOrderPending(array('type' => 'id', 'id' => $iPendingId));
+		if(!empty($aPending['order']) || !empty($aPending['error_code']) || !empty($aPending['error_msg']) || (int)$aPending['processed'] != 0)
+            return $this->_sLangsPrefix . 'err_already_processed';
+
+		switch($aPending['type']) {
+			case BX_PAYMENT_TYPE_SINGLE:
+				$aCartInfo['items_title'] = '';
+				foreach($aCartInfo['items'] as $aItem)
+		            $aCartInfo['items_title'] .= ' ' . $aItem['title'] . ',';
+				$aCartInfo['items_title'] = trim($aCartInfo['items_title'], ', ');
+
+				$mixedResult = $this->_createCharge($sToken, $iPendingId, $aClient, $aCartInfo);
+				if($mixedResult === false)
+					return $this->_sLangsPrefix . 'err_cannot_perform';
+
+				header("Location: " . $this->getReturnDataUrl($aVendor['id'], array(
+					'order_id' => $mixedResult['order'],
+					'customer_id' => $mixedResult['customer'], 
+					'pending_id' => $aPending['id'],
+				    'redirect' => $sRedirect
+				)));
+				exit;
+
+			case BX_PAYMENT_TYPE_RECURRING:
+				$mixedResult = $this->_createSubscription($sToken, $iPendingId, $aClient, $aCartInfo);
+				if($mixedResult === false)
+					return $this->_sLangsPrefix . 'err_cannot_perform';
+
+				return array(
+					'code' => 0,
+					'eval' => $this->_oModule->_oConfig->getJsObject('cart') . '.onSubscribeSubmit(oData);',
+					'redirect' => $this->getReturnDataUrl($aVendor['id'], array(
+						'order_id' => $mixedResult['order'],
+						'customer_id' => $mixedResult['customer'],
+						'pending_id' => $aPending['id'],
+						'redirect' => $sRedirect
+					))
+				);
+		}
+    }
+
+    public function finalizeCheckout(&$aData)
+    {
+    	$sOrderId = bx_process_input($aData['order_id']);
+    	$sCustomerId = bx_process_input($aData['customer_id']);
+		$iPendingId = bx_process_input($aData['pending_id'], BX_DATA_INT);
+        if(empty($iPendingId))
+        	return array('code' => 1, 'message' => $this->_sLangsPrefix . 'err_wrong_data');
+
+        $sRedirect = bx_process_input($aData['redirect']);
+
+		$aPending = $this->_oModule->_oDb->getOrderPending(array('type' => 'id', 'id' => $iPendingId));
+        if(!empty($aPending['order']) || !empty($aPending['error_code']) || !empty($aPending['error_msg']) || (int)$aPending['processed'] != 0)
+            return array('code' => 3, 'message' => $this->_sLangsPrefix . 'err_already_processed');
+
+		$aResult = array(
+			'code' => BX_PAYMENT_RESULT_SUCCESS,
+        	'message' => '',
+			'pending_id' => $iPendingId,
+		    'customer_id' => '',
+		    'subscription_id' => '',
+			'client_name' => '',
+			'client_email' => '',
+			'paid' => false,
+			'trial' => false,
+		    'redirect' => $sRedirect
+		);
+
+		switch($aPending['type']) {
+			case BX_PAYMENT_TYPE_SINGLE:
+			    $oCustomer = $this->_retrieveCustomer(BX_PAYMENT_TYPE_SINGLE, $sCustomerId);
+				$oCharge = $this->_retrieveCharge($sOrderId);
+				if($oCustomer === false || $oCharge === false)
+				    return array('code' => 4, 'message' => $this->_sLangsPrefix . 'err_cannot_perform');
+				
+				$aCustomer = $oCustomer->jsonSerialize();
+				$aCharge = $oCharge->jsonSerialize();
+				if(empty($aCustomer) || !is_array($aCustomer) || empty($aCharge) || !is_array($aCharge))
+					return array('code' => 4, 'message' => $this->_sLangsPrefix . 'err_cannot_perform');
+
+				$aResult = array_merge($aResult, array(
+					'message' => $this->_sLangsPrefix . 'strp_msg_charged',
+					'client_email' => $aCustomer['email'],
+					'paid' => (bool)$aCharge['paid']
+				));
+				break;
+
+			case BX_PAYMENT_TYPE_RECURRING:
+			    $oCustomer = $this->_retrieveCustomer(BX_PAYMENT_TYPE_RECURRING, $sCustomerId);
+				$oSubscription = $this->_retrieveSubscription($sCustomerId, $sOrderId);
+				if($oCustomer === false || $oSubscription === false)
+					return array('code' => 4, 'message' => $this->_sLangsPrefix . 'err_cannot_perform');
+
+				$aCustomer = $oCustomer->jsonSerialize();
+				$aSubscription = $oSubscription->jsonSerialize();
+				if(empty($aCustomer) || !is_array($aCustomer) || empty($aSubscription) || !is_array($aSubscription))
+					return array('code' => 4, 'message' => $this->_sLangsPrefix . 'err_cannot_perform');
+
+				$aResult = array_merge($aResult, array(
+					'message' => $this->_sLangsPrefix . 'strp_msg_subscribed',
+                    'customer_id' => $sCustomerId,
+				    'subscription_id' => $sOrderId,
+					'client_email' => $aCustomer['email'],
+				    'trial' => $aSubscription['status'] == 'trialing'
+				));
+				break;
+		}
+
+        //--- Update pending transaction ---//
+        $this->_oModule->_oDb->updateOrderPending($iPendingId, array(
+            'order' => $sOrderId,
+            'error_code' => $aResult['code'],
+            'error_msg' => _t($aResult['message'])
+        ));
+
+        return $aResult;
+    }
+
+    public function notify()
+    {
+		$iResult = $this->_processEvent();
+		http_response_code($iResult);
+    }
+
+    public function getButtonSingle($iClientId, $iVendorId, $aParams = array())
+    {
+        $aItems = array();
+        $aCartInfo = $this->_oModule->getObjectCart()->getInfo(BX_PAYMENT_TYPE_SINGLE, $iClientId, (int)$iVendorId, $aItems);
+        if(empty($aCartInfo) || !is_array($aCartInfo))
+            return '';
+
+    	return $this->_getButton(BX_PAYMENT_TYPE_SINGLE, $iClientId, $iVendorId, array_merge($aParams, array(
+			'sVendorName' => _t($this->_sLangsPrefix . 'txt_payment_to', $aCartInfo['vendor_name']),
+			'sVendorCurrency' => $aCartInfo['vendor_currency_code'],
+			'sVendorIcon' => $aCartInfo['vendor_avatar'],
+    	)));
+    }
+
+    public function getButtonRecurring($iClientId, $iVendorId, $aParams = array())
+    {
+    	$aVendor = $this->_oModule->getVendorInfo((int)$iVendorId);
+
+		return $this->_getButton(BX_PAYMENT_TYPE_RECURRING, $iClientId, $iVendorId, array_merge($aParams, array(
+			'sVendorName' => _t($this->_sLangsPrefix . 'txt_payment_to', $aVendor['name']),
+			'sVendorCurrency' => $aVendor['currency_code'],
+			'sVendorIcon' => $aVendor['avatar'],
+		)));
+    }
+
+    public function getMenuItemsActionsRecurring($iClientId, $iVendorId, $aParams = array())
+    {
+        if(empty($aParams['order']))
+            return array();
+
+        $sJsObject = $this->_oModule->_oConfig->getJsObject(BX_PAYMENT_ORDERS_TYPE_SUBSCRIPTION);
+
+        $sPrefix = 'bx-payment-strp-';
+        return array(
+            array('id' => $sPrefix . 'details', 'name' => $sPrefix . 'details', 'class' => '', 'link' => 'javascript:void(0)', 'onclick' => "javascript:" . $sJsObject . ".getDetails(this, '" . $aParams['id'] . "')", 'target' => '_self', 'title' => _t('_bx_payment_strp_menu_item_title_details')),
+            array('id' => $sPrefix . 'details_change', 'name' => $sPrefix . 'details_change', 'class' => '', 'link' => 'javascript:void(0)', 'onclick' => "javascript:" . $sJsObject . ".changeDetails(this, '" . $aParams['id'] . "')", 'target' => '_self', 'title' => _t('_bx_payment_strp_menu_item_title_details_change')),
+            array('id' => $sPrefix . 'billing', 'name' => $sPrefix . 'billing', 'class' => '', 'link' => 'javascript:void(0)', 'onclick' => "javascript:" . $sJsObject . ".getBilling(this, '" . $aParams['id'] . "')", 'target' => '_self', 'title' => _t('_bx_payment_strp_menu_item_title_billing')),
+            array('id' => $sPrefix . 'billing_change', 'name' => $sPrefix . 'billing_change', 'class' => '', 'link' => 'javascript:void(0)', 'onclick' => "javascript:" . $sJsObject . ".changeBilling(this, '" . $aParams['id'] . "')", 'target' => '_self', 'title' => _t('_bx_payment_strp_menu_item_title_billing_change')),
+        );
+    }
+
+    public function getDetailsRecurring($iPendingId, $sCustomerId, $sSubscriptionId)
+    {
+        $oSubscription = $this->_retrieveSubscription($sCustomerId, $sSubscriptionId);
+        if($oSubscription === false)
+            return '';
+
+        $aSubscription = $oSubscription->jsonSerialize();
+        if(empty($aSubscription) || !is_array($aSubscription))
+            return '';
+
+        $sNone = _t('_bx_payment_txt_none');
+        return $this->_oModule->_oTemplate->parseHtmlByName('strp_details_recurring.html', array(
+            'plan' => $aSubscription['plan']['name'],
+            'cost' => _t('_bx_payment_strp_txt_cost_mask', (int)$aSubscription['plan']['amount'] / 100, $aSubscription['plan']['currency'], $aSubscription['plan']['interval']),
+            'status' => $aSubscription['status'],
+        	'created' => bx_time_js($aSubscription['created']),
+        	'started' => !empty($aSubscription['start']) ? bx_time_js($aSubscription['start']) : $sNone,
+        	'trial_start' => !empty($aSubscription['trial_start']) ? bx_time_js($aSubscription['trial_start']) : $sNone,
+        	'trial_end' => !empty($aSubscription['trial_end']) ? bx_time_js($aSubscription['trial_end']) : $sNone,
+            'cperiod_start' => !empty($aSubscription['current_period_start']) ? bx_time_js($aSubscription['current_period_start']) : $sNone,
+        	'cperiod_end' => !empty($aSubscription['current_period_end']) ? bx_time_js($aSubscription['current_period_end']) : $sNone,
+        ));
+    }
+
+    public function changeDetailsRecurring($iPendingId, $sCustomerId, $sSubscriptionId)
+    {
+        $oForm = BxDolForm::getObjectInstance($this->_sFormDetails, $this->_sFormDisplayDetailsEdit, $this->_oModule->_oTemplate);
+        $oForm->aFormAttrs['id'] = $this->_oModule->_oConfig->getHtmlIds('subscription', 'form_subscription_change_details');
+        $oForm->aFormAttrs['action'] = BX_DOL_URL_ROOT . $this->_oModule->_oConfig->getBaseUri() . 'subscription_change_details/' . $iPendingId;
+
+        $oForm->aInputs['item_id']['values'] = $this->_getDataChangeDetailsRecurring($iPendingId);
+
+        $oForm->initChecker();
+        if($oForm->isSubmittedAndValid()) {
+            $aResultError = array('code' => 1, 'message' => _t('_bx_payment_strp_err_details_changed'));
+
+            $aPending = $this->_oModule->_oDb->getOrderPending(array('type' => 'id', 'id' => $iPendingId));
+            list($iVendorId, $iModuleId, $iItemId, $iItemCount) = $this->_oModule->_oConfig->descriptorS2A($aPending['items']);
+
+            $aItem = $this->_oModule->callGetCartItem($iModuleId, array($oForm->getCleanValue('item_id')));
+    		if(empty($aItem) || !is_array($aItem))
+    			return $aResultError;
+
+            $oSubscription = $this->_retrieveSubscription($sCustomerId, $sSubscriptionId);
+            if($oSubscription === false)
+                return $aResultError;
+
+            $oSubscription->plan = $aItem['name'];
+            $oSubscription->prorate = $this->_bProrate;
+            $oSubscription = $oSubscription->save();
+            if(strcmp($oSubscription->plan->id, $aItem['name']) !== 0)
+                return $aResultError;
+
+            $this->_oModule->_oDb->updateOrderPending($iPendingId, array(
+                'items' => $this->_oModule->_oConfig->descriptorA2S(array($iVendorId, $iModuleId, $aItem['id'], $iItemCount)),
+            ));
+
+            return array('code' => 0, 'message' => _t('_bx_payment_strp_msg_details_changed'));
+        }
+
+        return $this->_oModule->_oTemplate->parseHtmlByName('strp_details_change_recuring.html', array(
+        	'object' => $this->_oModule->_oConfig->getJsObject('subscription'),
+            'form' => $oForm->getCode(),
+            'form_id' => $oForm->aFormAttrs['id'],
+        ));
+    }
+
+    public function getBillingRecurring($iPendingId, $sCustomerId, $sSubscriptionId)
+    {
+        $aCard = $this->_retrieveCard($sCustomerId)->jsonSerialize();
+
+        return $this->_oModule->_oTemplate->parseHtmlByName('strp_billing_recurring.html', array(
+            'brand' => $aCard['brand'],
+        	'origin' => $aCard['country'],
+            'type' => $aCard['funding'],
+            'number' => _t('_bx_payment_strp_txt_card_number_mask', $aCard['last4']),
+            'expires' => _t('_bx_payment_strp_txt_card_expires_mask', $aCard['exp_month'], $aCard['exp_year']),
+            'cvc' => _t(strcmp($aCard['cvc_check'], 'pass') === 0 ? '_bx_payment_strp_txt_card_cvc_passed' : '_bx_payment_txt_none'),
+        ));
+    }
+
+    public function changeBillingRecurring($iPendingId, $sCustomerId, $sSubscriptionId)
+    {
+        $oForm = BxDolForm::getObjectInstance($this->_sFormCard, $this->_sFormDisplayCardAdd, $this->_oModule->_oTemplate);
+        $oForm->aFormAttrs['id'] = $this->_oModule->_oConfig->getHtmlIds('subscription', 'form_subscription_change_billing');
+        $oForm->aFormAttrs['action'] = BX_DOL_URL_ROOT . $this->_oModule->_oConfig->getBaseUri() . 'subscription_change_billing/' . $iPendingId;
+
+        $oForm->initChecker();
+        if($oForm->isSubmittedAndValid()) {
+            $aResultError = array('code' => 1, 'message' => _t('_bx_payment_strp_err_billing_changed'));
+
+            $aMatch = array();
+            if(!preg_match('/^([0-9]{2})\D([0-9]{4})$/i', $oForm->getCleanValue('card_expire'), $aMatch))
+                return $aResultError;
+
+            list($iMonth, $iYear) = array_slice($aMatch, 1);
+
+        	$aToken = $this->_createToken(array(
+                'number' => $oForm->getCleanValue('card_number'),
+                'exp_month' => $iMonth,
+                'exp_year' => $iYear,
+                'cvc' => $oForm->getCleanValue('card_cvv')
+            ));
+            if(empty($aToken) || !is_array($aToken))
+                return $aResultError;
+
+            $aCard = $this->_createCard(BX_PAYMENT_TYPE_RECURRING, $sCustomerId, $aToken['id']);
+            if(empty($aCard) || !is_array($aCard))
+                return $aResultError;
+
+            $oCustomer = $this->_retrieveCustomer(BX_PAYMENT_TYPE_RECURRING, $sCustomerId);
+            if($oCustomer === false)
+                return $aResultError;
+
+            $oCustomer->default_source = $aCard['id'];
+            $oCustomer->save();
+
+            return array('code' => 0, 'message' => _t('_bx_payment_strp_msg_billing_changed'));
+        }
+
+        return $this->_oModule->_oTemplate->parseHtmlByName('strp_billing_change_recuring.html', array(
+        	'object' => $this->_oModule->_oConfig->getJsObject('subscription'),
+            'form' => $oForm->getCode(),
+            'form_id' => $oForm->aFormAttrs['id'],
+        ));
+    }
+
+    public function cancelRecurring($iPendingId, $sCustomerId, $sSubscriptionId)
+    {
+        $oSubscription = $this->_cancelSubscription($sCustomerId, $sSubscriptionId);
+        if($oSubscription === false)
+            return false;
+
+        return true;
+    }
+
+    public function getCheckoutParamsSingle($aParams, &$oGrid)
+    {
+    	if(bx_get('token') !== false)
+    		$aParams['token'] = bx_process_input(bx_get('token'));
+
+    	return $aParams;
+    }
+
+	protected function _getPublicKey()
+	{
+		return $this->_iMode == STRP_MODE_LIVE ? $this->getOption('live_pub_key') : $this->getOption('test_pub_key');
+	}
+
+	protected function _getSecretKey()
+	{
+		return $this->_iMode == STRP_MODE_LIVE ? $this->getOption('live_sec_key') : $this->getOption('test_sec_key');
+	}
+
+    protected function _createToken($aCard)
+    {
+		try {
+			$oToken = Stripe\Token::create(array('card' => $aCard));
+		}
+		catch (Stripe\Error\Base $oException) {
+			return $this->_processException('Create Token Error: ', $oException);
+		}
+
+		return $oToken->jsonSerialize();
+	}
+
+	protected function _createCustomer($sType, $sToken, $aClient)
+	{
+	    $oCustomer = null;
+	    $aCustomer = array(
+			'card' => $sToken,
+			'email' => !empty($aClient['email']) ? $aClient['email'] : ''
+		);
+
+	    bx_alert($this->_oModule->_oConfig->getName(), $this->_sName . '_create_customer', 0, $aClient['id'], array(
+	    	'type' => $sType,
+			'customer_object' => &$oCustomer, 
+			'customer_params' => &$aCustomer
+		));
+
+		try {
+			$this->_oCustomer = !empty($oCustomer) ? $oCustomer : \Stripe\Customer::create($aCustomer);
+		}
+		catch (Exception $oException) {
+			return $this->_processException('Create Customer Error: ', $oException);
+		}
+
+		return $this->_oCustomer->jsonSerialize();
+	}
+
+	protected function _retrieveCustomer($sType, $sId)
+	{
+	    $oCustomer = null;
+	    bx_alert($this->_oModule->_oConfig->getName(), $this->_sName . '_retrieve_customer', 0, false, array(
+	    	'type' => $sType,
+	    	'customer_id' => &$sId,
+			'customer_object' => &$oCustomer
+		));
+
+		try {
+		    if(empty($oCustomer))
+			    $oCustomer = \Stripe\Customer::retrieve($sId);
+		}
+		catch (Exception $oException) {
+			return $this->_processException('Retrieve Customer Error: ', $oException);
+		}
+
+		return $oCustomer;
+	}
+
+	protected function _createCharge($sToken, $iPendingId, &$aClient, &$aCartInfo) {
+		if(empty($this->_oCustomer))
+			$this->_createCustomer(BX_PAYMENT_TYPE_SINGLE, $sToken, $aClient);
+
+		if(empty($this->_oCustomer))
+			return false;
+
+		$fAmount = 100 * (float)$aCartInfo['items_price'];
+
+		$oCharge = null;
+		$aCharge = array(
+			'customer' => $this->_oCustomer->id,
+			'amount' => $fAmount,
+			'currency' => $aCartInfo['vendor_currency_code'],
+			'description' => $aCartInfo['items_title'],
+			'metadata' => array(
+				'vendor' => $aCartInfo['vendor_id'],
+				'client' => $aClient['id'],
+				'product' => $iPendingId,
+				'verification' => $this->_getVerificationCodeCharge($aCartInfo['vendor_id'], $aClient['id'], $fAmount, $aCartInfo['vendor_currency_code'])
+			)
+		);
+
+		bx_alert($this->_oModule->_oConfig->getName(), $this->_sName . '_create_charge', $iPendingId, false, array(
+			'charge_object' => &$oCharge, 
+			'charge_params' => &$aCharge
+		));
+
+		try {
+		    if(empty($oCharge))
+			    $oCharge = \Stripe\Charge::create($aCharge);
+		}
+		catch (Exception $oException) {
+			return $this->_processException('Create Charge Error: ', $oException);
+		}
+
+		$aResult = $oCharge->jsonSerialize();
+		if(empty($aResult) || !is_array($aResult) || empty($aResult['paid']))
+			return false;
+
+		$aMetadata = $aResult['metadata'];
+		if(empty($aMetadata['verification']) || $aMetadata['verification'] != $this->_getVerificationCodeCharge($aCartInfo['vendor_id'], $aClient['id'], $aResult['amount'], $aResult['currency']))
+			return false;
+
+		return array(
+			'pending' => $iPendingId,
+			'amount' =>(float)$aResult['amount'] / 100,
+			'customer' => $this->_oCustomer->id,
+			'order' => $aResult['id']
+		);
+	}
+
+	protected function _retrieveCharge($sId) {
+	    $oCharge = null;
+	    bx_alert($this->_oModule->_oConfig->getName(), $this->_sName . '_retrieve_charge', 0, false, array(
+	    	'charge_id' => &$sId,
+			'charge_object' => &$oCharge
+		));
+
+		try {
+		    if(empty($oCharge))
+			    $oCharge = \Stripe\Charge::retrieve($sId);
+		}
+		catch (Exception $oException) {
+			return $this->_processException('Retrieve Charge Error: ', $oException);
+		}
+
+		return $oCharge;
+	}
+
+	protected function _createSubscription($sToken, $iPendingId, &$aClient, &$aCartInfo)
+	{
+		if(empty($this->_oCustomer))
+			$this->_createCustomer(BX_PAYMENT_TYPE_RECURRING, $sToken, $aClient);
+
+		if(empty($this->_oCustomer))
+			return false;
+
+		$aItem = array_shift($aCartInfo['items']);
+		if(empty($aItem) || !is_array($aItem))
+			return false;
+
+		$iTrial = $this->_oModule->_oConfig->getTrial(BX_PAYMENT_TYPE_RECURRING, $aItem);
+		$bTrial = !empty($iTrial);
+
+		$oSubscription = null;
+		$aSubscription = array(
+			'plan' => $aItem['name'],
+			'metadata' => array(
+				'vendor' => $aCartInfo['vendor_id'],
+				'client' => $aClient['id'],
+				'product' => $iPendingId,
+				'verification' => $this->_getVerificationCodeSubscription($aCartInfo['vendor_id'], $aClient['id'], $aItem['name'], $aCartInfo['vendor_currency_code'])
+			)
+		);
+
+		bx_alert($this->_oModule->_oConfig->getName(), $this->_sName . '_create_subscription', $iPendingId, false, array(
+		    'customer' => &$this->_oCustomer,
+			'subscription_object' => &$oSubscription, 
+			'subscription_params' => &$aSubscription
+		));
+
+		try {
+             if(empty($oSubscription))
+    			$oSubscription = $this->_oCustomer->subscriptions->create($aSubscription);
+		}
+		catch (Exception $oException) {
+			return $this->_processException('Create Subscription Error: ', $oException);
+		}
+
+		$aResult = $oSubscription->jsonSerialize();
+		if(empty($aResult) || !is_array($aResult) || (!$bTrial && $aResult['status'] != 'active') || ($bTrial && !in_array($aResult['status'], array('active', 'trialing'))))
+			return false;
+
+		$aMetadata = $aResult['metadata'];
+		if(empty($aMetadata['verification']) || $aMetadata['verification'] != $this->_getVerificationCodeSubscription($aCartInfo['vendor_id'], $aClient['id'], $aResult['plan']['id'], $aResult['plan']['currency']))
+			return false;
+
+		return array(
+			'pending' => $iPendingId,
+			'amount' =>(float)$aCartInfo['items_price'],
+			'customer' => $this->_oCustomer->id, 
+			'order' => $aResult['id'],
+			'trial' => $bTrial
+		);
+	}
+
+	protected function _retrieveSubscription($sCustomerId, $sSubscriptionId)
+	{
+		try {
+			$oCustomer = $this->_retrieveCustomer(BX_PAYMENT_TYPE_RECURRING, $sCustomerId);
+			$oSubscription = $oCustomer->subscriptions->retrieve($sSubscriptionId);
+		}
+		catch (Exception $oException) {
+			return $this->_processException('Retrieve Subscription Error: ', $oException);
+		}
+
+		return $oSubscription;
+	}
+//TODO: Continue from here!
+	protected function _cancelSubscription($sCustomerId, $sSubscriptionId)
+	{
+	    try {
+	        $oSubscription = $this->_retrieveSubscription($sCustomerId, $sSubscriptionId);
+	        $oSubscription = $oSubscription->cancel();
+	    }
+	    catch (Exception $oException) {
+			return $this->_processException('Cancel Subscription Error: ', $oException);
+		}
+
+		bx_alert($this->_oModule->_oConfig->getName(), $this->_sName . '_cancel_subscription', 0, false, array(
+		    'subscription_id' => $sSubscriptionId,
+			'subscription_object' => &$oSubscription
+		));
+
+		return $oSubscription;
+	}
+
+    protected function _listPlans()
+	{
+		try {
+			$oPlans = \Stripe\Plan::all();
+		}
+		catch (Exception $oException) {
+			return $this->_processException('List Plans Error: ', $oException);
+		}
+
+		return $oPlans;
+	}
+
+    protected function _createCard($sType, $sCustomerId, $sToken)
+	{
+		try {
+			$oCard = $this->_retrieveCustomer($sType, $sCustomerId)->sources->create(array(
+            	'source' => $sToken
+            ));
+		}
+		catch (Stripe\Error\Base $oException) {
+			return $this->_processException('Create Card Error: ', $oException);
+		}
+
+		return $oCard->jsonSerialize();
+	}
+
+    protected function _retrieveCard($sCustomerId, $sCardId = '') {
+		try {
+			$oCustomer = \Stripe\Customer::retrieve($sCustomerId);
+			$oCard = $oCustomer->sources->retrieve(!empty($sCardId) ? $sCardId : $oCustomer->default_source);
+		}
+		catch (Exception $oException) {
+			return $this->_processException('Retrieve Card Error: ', $oException);
+		}
+
+		return $oCard;
+	}
+
+	protected function _retrieveCoupon($sId) {
+		try {
+			$oCoupon = \Stripe\Coupon::retrieve($sId);
+		}
+		catch (Exception $oException) {
+			return $this->_processException('Retrieve Coupon Error: ', $oException);
+		}
+
+		return $oCoupon;
+	}
+
+	protected function _retrieveEvent($sId) {
+		try {
+			$oEvent = \Stripe\Event::retrieve($sId);
+		}
+		catch (Exception $oException) {
+			return $this->_processException('Retrieve Event Error: ', $oException);
+		}
+
+		return $oEvent;
+	}
+
+	protected function _processEvent()
+	{
+    	$sInput = @file_get_contents("php://input");
+		$aEvent = json_decode($sInput, true);
+		if(empty($aEvent) || !is_array($aEvent)) 
+			return 404;
+
+		$sType = $aEvent['type'];
+		if(!in_array($sType, array('invoice.payment_succeeded', 'charge.refunded', 'customer.subscription.deleted')))
+			return 200;
+
+		$this->log('Webhooks: ' . (!empty($sType) ? $sType : ''));
+		$this->log($aEvent);
+
+		$sMethod = '_processEvent' . bx_gen_method_name($sType, array('.', '_', '-'));
+    	if(!method_exists($this, $sMethod))
+    		return 200;
+
+    	return $this->$sMethod($aEvent) ? 200 : 403;
+    }
+
+	protected function _processEventInvoicePaymentSucceeded(&$aEvent)
+	{
+		$mixedResult = $this->_getData($aEvent);
+		if($mixedResult === false)
+			return false;
+
+		list($aPending, $oCharge) = $mixedResult;
+		if(empty($aPending) || !is_array($aPending) || empty($oCharge))
+			return false;
+
+		$fChargeAmount = (float)$oCharge->amount / 100;
+		$sChargeCurrency = strtoupper($oCharge->currency);
+		if($this->_bCheckAmount && ((float)$aPending['amount'] != $fChargeAmount || strcasecmp($this->_oModule->_oConfig->getDefaultCurrencyCode(), $sChargeCurrency) !== 0))
+			return false;
+
+        if($aPending['type'] == BX_PAYMENT_TYPE_RECURRING)
+            $this->_oModule->updateSubscription($aPending, array(
+                'paid' => 1
+            ));
+
+		return $this->_oModule->registerPayment($aPending);
+	}
+
+	protected function _processEventChargeRefunded(&$aEvent)
+	{
+		$mixedResult = $this->_getData($aEvent);
+		if($mixedResult === false)
+			return false;
+
+		list($aPending) = $mixedResult;
+		if(empty($aPending) || !is_array($aPending))
+			return false;
+
+		return $this->_oModule->refundPayment($aPending);
+	}
+
+	protected function _processEventCustomerSubscriptionDeleted(&$aEvent)
+	{
+		$mixedResult = $this->_getData($aEvent);
+		if($mixedResult === false)
+			return false;
+
+		list($aPending) = $mixedResult;
+		if(empty($aPending) || !is_array($aPending))
+			return true;
+
+		return $this->_oModule->cancelSubscription($aPending);
+	}
+
+	protected function _processException($sMessage, &$oException)
+	{
+		$aError = $oException->getJsonBody();
+
+		$sMessage = $aError['error']['message'];
+		if(empty($sMessage))
+			$sMessage = $oException->getMessage();
+
+		$this->log($sMessage . $aError['error']['message']);
+		$this->log($aError);
+
+		return false;
+	}
+
+	protected function _getData(&$aEvent, $bRetrieve = true)
+	{
+		if($bRetrieve)
+			$oEvent = $this->_retrieveEvent($aEvent['id']);
+		else 
+			$oEvent = \Stripe\Util\Util::convertToStripeObject($aEvent, array());
+
+		if(empty($oEvent))
+			return false;
+
+		$aPending = $this->_oModule->_oDb->getOrderPending(array('type' => 'order', 'order' => $oEvent->data->object->subscription));
+		$oCharge = $this->_retrieveCharge($oEvent->data->object->charge);
+
+		return array($aPending, $oCharge);
+	}
+
+    protected function _getDataChangeDetailsRecurring($iPendingId)
+    {
+        $aResult = array();
+
+        $aPending = $this->_oModule->_oDb->getOrderPending(array('type' => 'id', 'id' => $iPendingId));
+        list($iVendorId, $iModuleId, $iItemId) = $this->_oModule->_oConfig->descriptorS2A($aPending['items']);
+        if(empty($iModuleId) || empty($iVendorId) || (int)$iVendorId != (int)$aPending['seller_id'])
+            return $aResult;
+
+        $aItems = $this->_oModule->callGetCartItems((int)$iModuleId, array($iVendorId));
+        if(empty($aItems) || !is_array($aItems))
+            return $aResult;
+
+        $oPlans = $this->_listPlans();
+        if($oPlans === false)
+            return $aResult;
+
+        $aPlans = $oPlans->jsonSerialize();
+        if(empty($aPlans) || !is_array($aPlans) || empty($aPlans['data']) || !is_array($aPlans['data']))
+            return $aResult;
+
+        $aPlans = $aPlans['data'];
+
+        $aPlanNames = array();
+        foreach($aPlans as $aPlan)
+            $aPlanNames[] = $aPlan['id'];
+        if(empty($aPlanNames) || !is_array($aPlanNames))
+            return $aResult;
+
+        foreach($aItems as $aItem) {
+            $fPrice = $this->_oModule->_oConfig->getPrice(BX_PAYMENT_TYPE_RECURRING, $aItem);
+            if($fPrice == 0 || (int)$aItem['id'] == (int)$iItemId || !in_array($aItem['name'], $aPlanNames))
+                continue;
+
+            $aResult[] = array('key' => $aItem['id'], 'value' => $aItem['title']);
+        }
+
+        return $aResult;
+    }
+
+	protected function _getVerificationCodeCharge($iVendorId, $iCustomerId, $fAmount, $sCurrency) {
+		return md5(implode('#-#', array(
+			(int)$iVendorId,
+			(int)$iCustomerId,
+			(float)$fAmount,
+			strtoupper($sCurrency)
+		)));
+	}
+
+	protected function _getVerificationCodeSubscription($iVendorId, $iCustomerId, $sSubscription, $sCurrency) {
+		return md5(implode('#-#', array(
+			(int)$iVendorId,
+			(int)$iCustomerId,
+			strtoupper($sSubscription),
+			strtoupper($sCurrency)
+		)));
+	}
+
+    protected function _getButton($sType, $iClientId, $iVendorId, $aParams = array())
+    {
+    	$sClientEmail = '';
+    	if(!empty($iClientId)) {
+    		$oClient = BxDolProfile::getInstance($iClientId);
+    		if($oClient)
+    			$sClientEmail = $oClient->getAccountObject()->getEmail();
+    	}
+
+    	$sPublicKey = '';
+    	bx_alert($this->_oModule->_oConfig->getName(), $this->_sName . '_get_button', 0, $iClientId, array(
+			'type' => &$sType, 
+			'public_key' => &$sPublicKey
+		));
+
+    	return $this->_oModule->_oTemplate->parseHtmlByName('strp_button_' . $sType . '.html', array(
+    		'type' => $sType,
+    		'caption' => _t($this->_sLangsPrefix . 'strp_txt_checkout_with_' . $sType, $this->_sCaption),
+    		'js_object' => $this->_oModule->_oConfig->getJsObject($this->_sName),
+    		'js_code' => $this->_oModule->_oTemplate->getJsCode($this->_sName, array_merge(array(
+	    		'sProvider' => $this->_sName,
+	    		'sPublicKey' => !empty($sPublicKey) ? $sPublicKey : $this->_getPublicKey(),
+	    		'sVendorName' => '',
+	    		'sVendorCurrency' => '',
+	    		'sVendorIcon' => '',
+	    		'sClientEmail' => $sClientEmail,
+	    	), $aParams))
+    	));
+    }
+}
+
+/** @} */

+ 208 - 0
modules/boonex/payment/updates/9.0.5_9.0.6/source/classes/BxPaymentSubscriptions.php

@@ -0,0 +1,208 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Payment Payment
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+class BxPaymentSubscriptions extends BxBaseModPaymentSubscriptions
+{
+    function __construct()
+    {
+    	$this->MODULE = 'bx_payment';
+
+    	parent::__construct();
+    }
+
+    /*
+     * Service methods
+     */
+    
+    /**
+     * @page service Service Calls
+     * @section bx_payment Payment
+     * @subsection bx_payment-page_blocks Page Blocks
+     * @subsubsection bx_payment-get_block_list_my get_block_list_my
+     * 
+     * @code bx_srv('bx_payment', 'get_block_list_my', [...], 'Subscriptions'); @endcode
+     * 
+     * Get page block with a list of currently logged in member's subscriptions.
+     *
+     * @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 BxPaymentSubscriptions::serviceGetBlockListMy
+     */
+    /** 
+     * @ref bx_payment-get_block_list_my "get_block_list_my"
+     */
+    public function serviceGetBlockListMy()
+    {
+        return $this->_getBlock('list_my');
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_payment Payment
+     * @subsection bx_payment-page_blocks Page Blocks
+     * @subsubsection bx_payment-get_block_list_all get_block_list_all
+     * 
+     * @code bx_srv('bx_payment', 'get_block_list_all', [...], 'Subscriptions'); @endcode
+     * 
+     * Get page block with a list of all subscriptions. It's available for authorized members only.
+     *
+     * @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 BxPaymentSubscriptions::serviceGetBlockListAll
+     */
+    /** 
+     * @ref bx_payment-get_block_list_all "get_block_list_all"
+     */
+    public function serviceGetBlockListAll()
+    {
+        return $this->_getBlock('list_all');
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_payment Payment
+     * @subsection bx_payment-page_blocks Page Blocks
+     * @subsubsection bx_payment-get_block_history get_block_history
+     * 
+     * @code bx_srv('bx_payment', 'get_block_history', [...], 'Subscriptions'); @endcode
+     * 
+     * Get page block with a list of payments related to subscriptions of currently logged in member.
+     *
+     * @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 BxPaymentSubscriptions::serviceGetBlockHistory
+     */
+    /** 
+     * @ref bx_payment-get_block_history "get_block_history"
+     */
+    public function serviceGetBlockHistory()
+    {
+        return $this->_getBlock('history');
+    }
+
+	/**
+     * @page service Service Calls
+     * @section bx_payment Payment
+     * @subsection bx_payment-purchase_processing Purchase Processing
+     * @subsubsection bx_payment-subscribe subscribe
+     * 
+     * @code bx_srv('bx_payment', 'subscribe', [...], 'Subscriptions'); @endcode
+     * 
+     * Initialize subscription for specified item.
+     *
+     * @param $iSellerId integer value with seller ID.
+     * @param $sSellerProvider string value with a name of payment provider to be used for processing. Empty value means that payment provider selector should be shown.
+     * @param $iModuleId integer value with module ID.
+     * @param $iItemId integer value with item ID.
+     * @param $iItemCount integer value with a number of items for purchasing. It's equal to 1 in case of subscription.
+     * @param $sRedirect (optional) string value with redirect URL, if it's needed. 
+     * @return an array with special format which describes the result of operation.
+     * 
+     * @see BxPaymentSubscriptions::serviceSubscribe
+     */
+    /** 
+     * @ref bx_payment-subscribe "subscribe"
+     */
+	public function serviceSubscribe($iSellerId, $sSellerProvider, $iModuleId, $iItemId, $iItemCount, $sRedirect = '', $aCustom = array())
+    {
+    	$CNF = &$this->_oModule->_oConfig->CNF;
+
+    	$iClientId = $this->_oModule->getProfileId();
+
+    	$mixedResult = $this->_oModule->checkData($iClientId, $iSellerId, $iModuleId, $iItemId, $iItemCount);
+    	if($mixedResult !== true)
+    		return $mixedResult;
+
+        $aSellerProviders = $this->_oModule->_oDb->getVendorInfoProvidersRecurring($iSellerId);
+        if(empty($aSellerProviders))
+            return array('code' => 5, 'message' => _t($CNF['T']['ERR_NOT_ACCEPT_PAYMENTS']));
+
+        $aCartItem = array($iSellerId, $iModuleId, $iItemId, $iItemCount);
+        $sCartItem = $this->_oModule->_oConfig->descriptorA2S($aCartItem);
+
+		if(empty($sSellerProvider)) {
+			$sId = $this->_oModule->_oConfig->getHtmlIds('cart', 'providers_select') . BX_PAYMENT_TYPE_RECURRING;
+			$sTitle = _t($CNF['T']['POPUP_PROVIDERS_SELECT']);
+			return array('popup' => array(
+				'html' => BxTemplStudioFunctions::getInstance()->popupBox($sId, $sTitle, $this->_oModule->_oTemplate->displayProvidersSelector($aCartItem, $aSellerProviders, $sRedirect, $aCustom)), 
+				'options' => array('closeOnOuterClick' => true)
+			));
+		}
+
+		$aCustoms = array();
+		$this->_oModule->_oConfig->putCustom($aCartItem, $aCustom, $aCustoms);
+
+        $mixedResult = $this->_oModule->serviceInitializeCheckout(BX_PAYMENT_TYPE_RECURRING, $iSellerId, $aSellerProviders[$sSellerProvider]['name'], array($sCartItem), $sRedirect, $aCustoms);
+        if(is_string($mixedResult))
+        	return array('code' => 6, 'message' => _t($mixedResult));
+
+		return $mixedResult;
+    }
+
+    public function cancel($iPendingId)
+    {
+    	$aSubscription = $this->_oModule->_oDb->getSubscription(array('type' => 'pending_id', 'pending_id' => $iPendingId));
+		if(empty($aSubscription) || !is_array($aSubscription))
+	    	return true;
+
+        $aOrder = $this->_oModule->_oDb->getOrderSubscription(array('type' => 'id', 'id' => $iPendingId));
+        if(empty($aOrder) || !is_array($aOrder))
+	    	return false;
+
+        $iSellerId = (int)$aOrder['seller_id'];
+        $oProvider = $this->_oModule->getObjectProvider($aOrder['provider'], $iSellerId);
+        if($oProvider === false || !$oProvider->isActive())
+        	return false;
+
+        if(!$oProvider->cancelRecurring($iPendingId, $aSubscription['customer_id'], $aSubscription['subscription_id']))
+            return false;
+
+        list($iSellerId, $iModuleId, $iItemId, $iItemCount) = $this->_oModule->_oConfig->descriptorS2A($aOrder['items']);
+		if(!$this->_oModule->callCancelSubscriptionItem((int)$iModuleId, array($aOrder['client_id'], $iSellerId, $iItemId, $iItemCount, $aOrder['order'])))
+			return false;
+
+		if(!$this->_oModule->_oDb->deleteSubscription($aSubscription['id'], 'cancel'))
+			return false;
+
+        return true;
+    }
+
+    protected function _getBlock($sType)
+    {
+        $CNF = &$this->_oModule->_oConfig->CNF;
+
+        $sMethod = 'displayBlockSbs' . bx_gen_method_name($sType);
+        if(!method_exists($this->_oModule->_oTemplate, $sMethod))
+            return array(
+        		'content' => MsgBox(_t('_Empty'))
+            );
+
+    	$iUserId = $this->_oModule->getProfileId();
+        if(empty($iUserId))
+            return array(
+        		'content' => MsgBox(_t($CNF['T']['ERR_REQUIRED_LOGIN']))
+            );
+
+        $this->_oModule->setSiteSubmenu('menu_dashboard', 'system', 'dashboard-subscriptions');
+
+        $sBlockSubmenu = $this->_oModule->_oConfig->getObject('menu_sbs_submenu');
+        $oBlockSubmenu = BxDolMenu::getObjectInstance($sBlockSubmenu);
+        if($oBlockSubmenu) 
+            $oBlockSubmenu->setSelected($this->MODULE, 'sbs-' . str_replace('_', '-', $sType));     
+
+        return array(
+        	'content' => $this->_oModule->_oTemplate->$sMethod($iUserId),
+        	'menu' => $this->_oModule->_oConfig->getObject('menu_sbs_submenu')
+        );
+    }
+}
+
+/** @} */

+ 434 - 0
modules/boonex/payment/updates/9.0.5_9.0.6/source/classes/BxPaymentTemplate.php

@@ -0,0 +1,434 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Payment Payment
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+class BxPaymentTemplate extends BxBaseModPaymentTemplate
+{
+	protected $_sLangsPrefix;
+
+    function __construct(&$oConfig, &$oDb)
+    {
+    	$this->MODULE = 'bx_payment';
+
+        parent::__construct($oConfig, $oDb);
+
+        $this->_sLangsPrefix = $this->_oConfig->getPrefix('langs');
+    }
+
+    public function addJsCssOrders()
+    {
+    	$this->addJs(array(
+    		'jquery-ui/jquery.ui.widget.min.js',
+    		'jquery-ui/jquery.ui.menu.min.js', 
+    		'jquery-ui/jquery.ui.autocomplete.min.js', 
+    		'jquery.form.min.js', 
+    		'jquery.anim.js', 
+    		'jquery.webForms.js',
+    		'orders.js'
+    	));
+    	$this->addCss(array('orders.css'));
+    }
+    public function addJsCssSubscriptions()
+    {
+        $this->addJs(array('jquery.form.min.js', 'jquery.anim.js', 'jquery.webForms.js', 'main.js', 'subscriptions.js'));
+        $this->addCss(array('orders.css', 'subscriptions.css'));
+    }
+
+    public function addJsCssCart($sType = '', $iVendorId = 0)
+    {
+    	$this->addJsTranslation(array('_bx_payment_err_nothing_selected'));
+    	$this->addJs(array('jquery.anim.js', 'main.js', 'cart.js'));
+    	$this->addCss(array('orders.css', 'cart.css'));
+
+    	$oModule = $this->getModule();
+    	if(!empty($iVendorId)) {
+    		$sMethod = 'getVendorInfoProviders' . bx_gen_method_name($sType);
+    		$aProviders = $this->_oDb->$sMethod($iVendorId);
+    		foreach($aProviders as $sProvider => $aProvider)
+				$oModule->getObjectProvider($sProvider, $iVendorId)->addJsCss();
+    	}
+    }
+
+	public function displayCartJs($sType = '', $iVendorId = 0)
+    {
+        $this->addJsCssCart($sType, $iVendorId);
+        return $this->displayJsCode('cart');
+    }
+
+    public function displayAddToCartJs($iVendorId, $iModuleId, $iItemId, $iItemCount, $bNeedRedirect = false, $aCustom = array())
+    {
+        $sJsCode = $this->displayCartJs(BX_PAYMENT_TYPE_SINGLE, $iVendorId);
+        $sJsMethod = $this->parseHtmlByName('add_to_cart_js.html', array(
+            'js_object' => $this->_oConfig->getJsObject('cart'),
+            'vendor_id' => $iVendorId,
+            'module_id' => $iModuleId,
+            'item_id' => $iItemId,
+            'item_count' => $iItemCount,
+            'need_redirect' => (int)$bNeedRedirect,
+            'custom' => !empty($aCustom) && is_array($aCustom) ? base64_encode(serialize($aCustom)) : ''
+        ));
+
+        return array($sJsCode, $sJsMethod);
+    }
+
+    public function displayAddToCartLink($iVendorId, $iModuleId, $iItemId, $iItemCount, $bNeedRedirect = false, $aCustom = array())
+    {
+        $this->addJsCssCart(BX_PAYMENT_TYPE_SINGLE, $iVendorId);
+        return $this->parseHtmlByName('add_to_cart.html', array(
+        	'js_object' => $this->_oConfig->getJsObject('cart'),
+        	'js_content' => $this->displayJsCode('cart'),
+        	'txt_add_to_cart' => _t($this->_sLangsPrefix . 'txt_add_to_cart'),
+            'vendor_id' => $iVendorId,
+            'module_id' => $iModuleId,
+            'item_id' => $iItemId,
+            'item_count' => $iItemCount,
+            'need_redirect' => (int)$bNeedRedirect,
+        	'custom' => !empty($aCustom) && is_array($aCustom) ? base64_encode(serialize($aCustom)) : ''
+        ));
+    }
+
+	public function displaySubscribeJs($iVendorId, $sVendorProvider, $iModuleId, $iItemId, $iItemCount = 1, $sRedirect = '', $aCustom = array())
+    {
+        $sJsCode = $this->displayCartJs(BX_PAYMENT_TYPE_RECURRING, $iVendorId);
+        $sJsMethod = $this->parseHtmlByName('subscribe_js.html', array(
+            'js_object' => $this->_oConfig->getJsObject('cart'),
+            'vendor_id' => $iVendorId,
+        	'vendor_provider' => $sVendorProvider,
+            'module_id' => $iModuleId,
+            'item_id' => $iItemId,
+            'item_count' => $iItemCount,
+            'redirect' => !empty($sRedirect) ? $sRedirect : '',
+            'custom' => !empty($aCustom) && is_array($aCustom) ? base64_encode(serialize($aCustom)) : ''
+        ));
+
+        return array($sJsCode, $sJsMethod);
+    }
+
+    public function displaySubscribeLink($iVendorId, $sVendorProvider, $iModuleId, $iItemId, $iItemCount = 1, $sRedirect = '', $aCustom = array())
+    {
+        $this->addJsCssCart(BX_PAYMENT_TYPE_RECURRING, $iVendorId);
+        return $this->parseHtmlByName('subscribe.html', array(
+        	'js_object' => $this->_oConfig->getJsObject('cart'),
+        	'js_content' => $this->displayJsCode('cart'),
+        	'txt_add_to_cart' => _t($this->_sLangsPrefix . 'txt_subscribe'),
+            'vendor_id' => $iVendorId,
+        	'vendor_provider' => $sVendorProvider,
+            'module_id' => $iModuleId,
+            'item_id' => $iItemId,
+            'item_count' => $iItemCount,
+            'redirect' => !empty($sRedirect) ? $sRedirect : '',
+            'custom' => !empty($aCustom) && is_array($aCustom) ? base64_encode(serialize($aCustom)) : ''
+        ));
+    }
+
+    public function displaySubscriptionGetDetails($iId)
+    {
+    	return $this->_displaySubscriptionData('get_details', $iId);
+    }
+
+    public function displaySubscriptionChangeDetails($iId)
+    {
+    	return $this->_displaySubscriptionData('change_details', $iId);
+    }
+
+    public function displaySubscriptionGetBilling($iId)
+    {
+    	return $this->_displaySubscriptionData('get_billing', $iId);
+    }
+
+    public function displaySubscriptionChangeBilling($iId)
+    {
+    	return $this->_displaySubscriptionData('change_billing', $iId);
+    }
+
+	public function displayBlockCarts($iClientId)
+    {
+    	$oGrid = BxDolGrid::getObjectInstance($this->_oConfig->getObject('grid_carts'));
+        if(!$oGrid)
+            return MsgBox(_t($this->_sLangsPrefix . 'msg_no_results'));
+
+		$oGrid->addQueryParam('client_id', $iClientId);
+
+		$this->addJsCssCart(BX_PAYMENT_TYPE_SINGLE);
+        return $this->displayJsCode('cart') . $oGrid->getCode();
+    }
+
+	public function displayBlockCart($iClientId, $iSellerId = 0)
+    {
+    	$oGrid = BxDolGrid::getObjectInstance($this->_oConfig->getObject('grid_cart'));
+        if(!$oGrid || empty($iSellerId))
+            return MsgBox(_t($this->_sLangsPrefix . 'msg_no_results'));
+
+		$oGrid->addQueryParam('client_id', $iClientId);
+		$oGrid->addQueryParam('seller_id', $iSellerId);
+
+		$this->addJsCssCart(BX_PAYMENT_TYPE_SINGLE, $iSellerId);
+        return $this->displayJsCode('cart') . $oGrid->getCode();
+    }
+
+    public function displayBlockHistory($iClientId, $iSellerId)
+    {
+        return $this->_displayBlockHistory('grid_history', $iClientId, $iSellerId);
+    }
+
+    public function displayBlockSbsListMy($iClientId)
+    {
+        $oGrid = BxDolGrid::getObjectInstance($this->_oConfig->getObject('grid_sbs_list_my'), $this->getModule()->_oTemplate);
+        if(!$oGrid || empty($iClientId))
+            return MsgBox(_t($this->_sLangsPrefix . 'msg_no_results'));
+
+		$oGrid->addQueryParam('client_id', $iClientId);
+
+		$this->addJsCssSubscriptions();
+        return $this->displayJsCode(BX_PAYMENT_ORDERS_TYPE_SUBSCRIPTION) . $oGrid->getCode();
+    }
+
+    public function displayBlockSbsListAll()
+    {
+        $oGrid = BxDolGrid::getObjectInstance($this->_oConfig->getObject('grid_sbs_list_all'), $this->getModule()->_oTemplate);
+        if(!$oGrid)
+            return MsgBox(_t($this->_sLangsPrefix . 'msg_no_results'));
+
+		$this->addJsCssSubscriptions();
+        return $this->displayJsCode(BX_PAYMENT_ORDERS_TYPE_SUBSCRIPTION) . $oGrid->getCode();
+    }
+
+    public function displayBlockSbsHistory($iClientId)
+    {
+        return $this->_displayBlockHistory('grid_sbs_history', $iClientId);
+    }
+
+    public function displayBlockSbsDetails($iClientId)
+    {
+        return 'Details would be here';
+    }
+
+	public function displayBlockOrders($sType, $iSellerId)
+    {
+    	$oGrid = BxDolGrid::getObjectInstance($this->_oConfig->getObject('grid_' . $sType));
+        if(!$oGrid || empty($iSellerId))
+            return MsgBox(_t($this->_sLangsPrefix . 'msg_no_results'));
+
+		$oGrid->addQueryParam('seller_id', $iSellerId);
+
+		$this->addJsCssOrders();
+        return $this->displayJsCode($sType) . $oGrid->getCode();
+    }
+
+	public function displayOrder($sType, $iId)
+    {
+        $sMethodName = 'getOrder' . bx_gen_method_name($sType);
+        $aOrder = $this->_oDb->$sMethodName(array('type' => 'id', 'id' => $iId));
+
+        $oModule = $this->getModule();
+        $aSeller = $oModule->getVendorInfo((int)$aOrder['seller_id']);
+        $aClient = $oModule->getProfileInfo((int)$aOrder['client_id']);
+
+        $aResult = array(
+        	'txt_client' => _t($this->_sLangsPrefix . 'txt_client'),
+        	'txt_seller' => _t($this->_sLangsPrefix . 'txt_seller'),
+        	'txt_order' => _t($this->_sLangsPrefix . 'txt_order'),
+        	'txt_processed_with' => _t($this->_sLangsPrefix . 'txt_processed_with'),
+        	'txt_message' => _t($this->_sLangsPrefix . 'txt_message'),
+        	'txt_date' => _t($this->_sLangsPrefix . 'txt_date'),
+        	'txt_products' => _t($this->_sLangsPrefix . 'txt_products'),
+            'client_name' => $aClient['name'],
+            'client_url' => $aClient['link'],
+            'bx_if:show_link' => array(
+                'condition' => !empty($aSeller['link']),
+                'content' => array(
+                    'seller_name' => $aSeller['name'],
+                    'seller_url' => $aSeller['link'],
+                )
+            ),
+            'bx_if:show_text' => array(
+                'condition' => empty($aSeller['link']),
+                'content' => array(
+                    'seller_name' => $aSeller['name']
+                )
+            ),
+            'order' => $aOrder['order'],
+            'provider' => _t('_bx_payment_txt_name_' . $aOrder['provider']),
+            'error' => $aOrder['error_msg'],
+            'date' => bx_time_js($aOrder['date']),
+            'bx_repeat:items' => array()
+        );
+
+        if(in_array($sType, array(BX_PAYMENT_ORDERS_TYPE_PENDING, BX_PAYMENT_ORDERS_TYPE_SUBSCRIPTION)))
+            $aItems = $this->_oConfig->descriptorsM2A($aOrder['items']);
+        else
+            $aItems = $this->_oConfig->descriptorsM2A($this->_oConfig->descriptorA2S(array($aOrder['seller_id'], $aOrder['module_id'], $aOrder['item_id'], $aOrder['item_count'])));
+
+        foreach($aItems as $aItem) {
+            $aInfo = $oModule->callGetCartItem((int)$aItem['module_id'], array($aItem['item_id']));
+            if(!empty($aInfo) && is_array($aInfo))
+	            $aResult['bx_repeat:items'][] = array(
+	                'bx_if:link' => array(
+	                    'condition' => !empty($aInfo['url']),
+	                    'content' => array(
+	                        'title' => $aInfo['title'],
+	                        'url' => $aInfo['url']
+	                    )
+	                ),
+	                'bx_if:text' => array(
+	                    'condition' => empty($aInfo['url']),
+	                    'content' => array(
+	                        'title' => $aInfo['title'],
+	                    )
+	                ),
+	                'quantity' => $aItem['item_count'],
+	                'price' => $this->_oConfig->getPrice($aOrder['type'], $aInfo),
+	                'currency_code' => $aSeller['currency_code']
+	            );
+        }
+
+        return $this->parseHtmlByName('order_' . $sType . '.html', $aResult);
+    }
+
+    public function displayItems($sType, $aItems = array())
+    {
+        $aTmplVarsItems = array();
+
+        if(!empty($aItems) && is_array($aItems))
+            foreach($aItems as $aItem) {
+                $aTmplVarsItems[$aItem['title']] = array(
+                    'id' => $aItem['id'],
+                    'price' => $this->_oConfig->getPrice($sType, $aItem),
+                    'bx_if:link' => array(
+                        'condition' => !empty($aItem['url']),
+                        'content' => array(
+                            'url' => $aItem['url'],
+                            'title' => $aItem['title']
+                        )
+                    ),
+                    'bx_if:text' => array(
+                        'condition' => empty($aItem['url']),
+                        'content' => array(
+                            'title' => $aItem['title']
+                        )
+                    ),
+                );
+            }
+
+        if(!empty($aTmplVarsItems) && is_array($aTmplVarsItems)) {
+            ksort($aTmplVarsItems);
+            $aTmplVarsItems = array_values($aTmplVarsItems);
+        }
+        else 
+        	$aTmplVarsItems = MsgBox(_t($this->_sLangsPrefix . 'msg_no_results'));
+
+        return $this->parseHtmlByName('items.html', array(
+        	'html_id' => $this->_oConfig->getHtmlIds('processed', 'order_processed_items'),
+        	'bx_repeat:items' => $aTmplVarsItems
+        ));
+    }
+
+    public function displayProvidersSelector($aCartItem, $aProviders, $sRedirect = '', $aCustom = array())
+    {
+    	$oModule = $this->getModule();
+    	$iClientId = $oModule->getProfileId();
+
+		$oCart = $oModule->getObjectCart();
+		$oSubscriptions = $oModule->getObjectSubscriptions();
+		list($iSellerId, $iModuleId, $iItemId, $iItemCount) = $aCartItem;
+
+		$aTmplVarsProviders = array();
+		foreach($aProviders as $sProvider => $aProvider) {
+			$oProvider = $oModule->getObjectProvider($sProvider, $iSellerId);
+			if($oProvider !== false && method_exists($oProvider, 'getButtonRecurring')) {
+			    $aParams = array(
+					'sObjNameCart' => $oModule->_oConfig->getJsObject('cart'),
+					'iSellerId' => $iSellerId,
+					'iModuleId' => $iModuleId,
+					'iItemId' => $iItemId,
+					'iItemCount' => $iItemCount,
+				    'sRedirect' => $sRedirect,
+			        'sCustom' => base64_encode(serialize($aCustom))
+				);
+
+			    $aCartInfo = $oCart->getInfo(BX_PAYMENT_TYPE_RECURRING, $iClientId, $iSellerId, $this->_oConfig->descriptorA2S($aCartItem));
+			    if(!empty($aCartInfo['items_price']) && !empty($aCartInfo['items']) && is_array($aCartInfo['items'])) {
+			        $aTitles = array();
+			        foreach ($aCartInfo['items'] as $aItem)
+			            $aTitles[] = $aItem['title'];
+
+			        $aParams = array_merge($aParams, array(
+			            'iAmount' => (int)round(100 * (float)$aCartInfo['items_price']),
+			        	'sItemTitle' => implode(', ', $aTitles)
+			        ));
+			    }
+
+				$sButton = $oProvider->getButtonRecurring($iClientId, $iSellerId, $aParams);
+			}
+			else {
+				list($sJsCode, $sJsOnclick) = $oSubscriptions->serviceGetSubscribeJs($iSellerId, $aProvider['name'], $iModuleId, $iItemId, $iItemCount, $sRedirect, $aCustom);
+
+				$sButton = $this->parsePageByName('providers_select_button.html', array(
+					'onclick' => $sJsOnclick,
+					'title' => _t('_bx_payment_txt_checkout_with', _t($aProvider['caption']))
+				));
+			}
+
+			$aTmplVarsProviders[] = array(
+				'button' => $sButton
+			);
+		}
+
+		return $this->parseHtmlByName('providers_select.html', array(
+			'bx_repeat:providers' => $aTmplVarsProviders
+		));
+    }
+
+    protected function _displayBlockHistory($sObject, $iClientId, $iSellerId = 0)
+    {
+    	$oGrid = BxDolGrid::getObjectInstance($this->_oConfig->getObject($sObject), $this->getModule()->_oTemplate);
+        if(!$oGrid || empty($iClientId))
+            return MsgBox(_t($this->_sLangsPrefix . 'msg_no_results'));
+
+		$oGrid->addQueryParam('client_id', $iClientId);
+		if(!empty($iSellerId))
+			$oGrid->addQueryParam('seller_id', $iSellerId);
+
+		$this->addJsCssOrders();
+        return $this->displayJsCode(BX_PAYMENT_ORDERS_TYPE_HISTORY) . $oGrid->getCode();
+    }
+
+    protected function _displaySubscriptionData($sType, $iId)
+    {
+        $aPending = $this->_oDb->getOrderPending(array('type' => 'id', 'id' => $iId));
+        if(empty($aPending) && !is_array($aPending))
+            return array();
+
+        $aSubscription = $this->_oDb->getSubscription(array('type' => 'pending_id', 'pending_id' => $iId));
+        if(empty($aSubscription) && !is_array($aSubscription))
+            return array();
+
+        $sMethod = bx_gen_method_name($sType) . 'Recurring';
+        $oProvider = $this->getModule()->getObjectProvider($aPending['provider'], $aPending['seller_id']);
+        if($oProvider === false || !$oProvider->isActive() || !method_exists($oProvider, $sMethod))
+        	return array();
+
+        $mixedContent = $oProvider->$sMethod($iId, $aSubscription['customer_id'], $aSubscription['subscription_id']);
+        if(empty($mixedContent))
+            return array();
+        else if(is_array($mixedContent))
+            return $mixedContent;
+
+        $sKey = 'order_' . BX_PAYMENT_ORDERS_TYPE_SUBSCRIPTION . '_' . $sType;
+    	$sId = $this->_oConfig->getHtmlIds(BX_PAYMENT_ORDERS_TYPE_SUBSCRIPTION, $sKey);
+    	$sTitle = _t($this->_sLangsPrefix . 'popup_title_ods_' . $sKey);
+    	return array('popup' => array(
+    		'html' => BxTemplFunctions::getInstance()->popupBox($sId, $sTitle, $mixedContent), 
+    		'options' => array('closeOnOuterClick' => 1)
+    	));
+    }
+}
+
+/** @} */

+ 70 - 0
modules/boonex/payment/updates/9.0.5_9.0.6/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' => '9.0.6',
+    'vendor' => 'Boonex',
+    'help_url' => 'http://feed.una.io/?section={module_name}',
+
+    'compatible_with' => array(
+        '9.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(),
+);
+
+/** @} */

+ 496 - 0
modules/boonex/payment/updates/9.0.5_9.0.6/source/install/langs/en.xml

@@ -0,0 +1,496 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources name="en" flag="gb" title="English">
+	<string name="_bx_payment"><![CDATA[Payments]]></string>
+
+	<!-- OPTIONS -->
+	<string name="_bx_payment_option_default_currency_code"><![CDATA[Currency]]></string>
+	<string name="_bx_payment_option_err_default_currency_code"><![CDATA[Currency code cannot be empty.]]></string>
+	<string name="_bx_payment_option_site_admin"><![CDATA[Site administrator]]></string>
+
+	<!-- PAGES and BLOCKS -->
+	<string name="_bx_payment_page_title_sys_carts"><![CDATA[Shopping Carts]]></string>
+	<string name="_bx_payment_page_title_carts"><![CDATA[Shopping Carts]]></string>
+	<string name="_bx_payment_page_title_sys_cart"><![CDATA[Shopping Cart]]></string>
+	<string name="_bx_payment_page_title_cart"><![CDATA[Shopping Cart]]></string>
+    <string name="_bx_payment_page_title_sys_cart_thank_you"><![CDATA[Thank you!]]></string>
+    <string name="_bx_payment_page_title_cart_thank_you"><![CDATA[Thank you!]]></string>
+	<string name="_bx_payment_page_block_title_carts"><![CDATA[Shopping Carts]]></string>
+	<string name="_bx_payment_page_block_title_cart"><![CDATA[{0}'s Shopping Cart]]></string>
+    <string name="_bx_payment_page_block_title_cart_thank_you"><![CDATA[Thank you!]]></string>
+    <string name="_bx_payment_page_block_content_cart_thank_you"><![CDATA[Thank you! Payment was successfully performed. The data will be processed shortly. Please wait.]]></string>
+
+    <string name="_bx_payment_page_title_sys_sbs_list_my"><![CDATA[My Subscriptions]]></string>
+    <string name="_bx_payment_page_title_sbs_list_my"><![CDATA[My Subscriptions]]></string>
+    <string name="_bx_payment_page_block_title_sbs_list_my"><![CDATA[My Subscriptions]]></string>
+
+    <string name="_bx_payment_page_title_sys_sbs_list_all"><![CDATA[All Subscriptions]]></string>
+    <string name="_bx_payment_page_title_sbs_list_all"><![CDATA[All Subscriptions]]></string>
+    <string name="_bx_payment_page_block_title_sbs_list_all"><![CDATA[All Subscriptions]]></string>
+
+    <string name="_bx_payment_page_title_sys_sbs_history"><![CDATA[My Payments]]></string>
+    <string name="_bx_payment_page_title_sbs_history"><![CDATA[My Payments]]></string>
+    <string name="_bx_payment_page_block_title_sbs_history"><![CDATA[My Payments]]></string>
+
+	<string name="_bx_payment_page_title_sys_history"><![CDATA[Shopping History]]></string>
+	<string name="_bx_payment_page_title_history"><![CDATA[Shopping History]]></string>
+	<string name="_bx_payment_page_block_title_history"><![CDATA[Shopping History]]></string>
+
+	<string name="_bx_payment_page_title_sys_orders"><![CDATA[Orders]]></string>
+	<string name="_bx_payment_page_title_orders"><![CDATA[Orders]]></string>
+	<string name="_bx_payment_page_block_title_orders"><![CDATA[Orders]]></string>
+
+	<string name="_bx_payment_page_title_sys_details"><![CDATA[Payments Details]]></string>
+	<string name="_bx_payment_page_title_details"><![CDATA[Payments Details]]></string>
+	<string name="_bx_payment_page_block_title_details"><![CDATA[Payments Details]]></string>
+
+	<string name="_bx_payment_page_block_title_orders_processed"><![CDATA[Processed Orders]]></string>
+	<string name="_bx_payment_page_block_title_orders_pending"><![CDATA[Pending Orders]]></string>
+
+	<string name="_bx_payment_page_title_response"><![CDATA[Payment Response]]></string>
+	<string name="_bx_payment_page_title_error"><![CDATA[Payment Error]]></string>
+
+	<string name="_bx_payment_page_title_sys_join"><![CDATA[Join]]></string>
+	<string name="_bx_payment_page_title_join"><![CDATA[Join]]></string>
+	<string name="_bx_payment_page_block_title_join"><![CDATA[Join]]></string>
+
+	<!-- MENUS -->
+	<string name="_bx_payment_menu_title_orders_submenu"><![CDATA[Orders Submenu]]></string>
+    <string name="_bx_payment_menu_set_title_orders_submenu"><![CDATA[Orders Submenu]]></string>
+    <string name="_bx_payment_menu_item_title_system_orders_processed"><![CDATA[Processed Orders]]></string>
+    <string name="_bx_payment_menu_item_title_orders_processed"><![CDATA[Processed]]></string>
+    <string name="_bx_payment_menu_item_title_system_orders_pending"><![CDATA[Pending Orders]]></string>
+    <string name="_bx_payment_menu_item_title_orders_pending"><![CDATA[Pending]]></string>
+    <string name="_bx_payment_menu_item_title_system_details"><![CDATA[Payments Details]]></string>
+    <string name="_bx_payment_menu_item_title_details"><![CDATA[Payments]]></string>
+
+	<string name="_bx_payment_menu_title_cart_submenu"><![CDATA[Cart Submenu]]></string>
+    <string name="_bx_payment_menu_set_title_cart_submenu"><![CDATA[Cart Submenu]]></string>
+    <string name="_bx_payment_menu_item_title_system_cart"><![CDATA[Cart]]></string>
+    <string name="_bx_payment_menu_item_title_cart"><![CDATA[Cart]]></string>
+    <string name="_bx_payment_menu_item_title_system_cart_history"><![CDATA[Cart History]]></string>
+    <string name="_bx_payment_menu_item_title_cart_history"><![CDATA[Cart History]]></string>
+
+    <string name="_bx_payment_menu_title_sbs_submenu"><![CDATA[Subscriptions Submenu]]></string>
+    <string name="_bx_payment_menu_set_title_sbs_submenu"><![CDATA[Subscriptions Submenu]]></string>
+    <string name="_bx_payment_menu_item_title_system_sbs_list_my"><![CDATA[My Subscriptions List]]></string>
+    <string name="_bx_payment_menu_item_title_sbs_list_my"><![CDATA[My Subscriptions]]></string>
+    <string name="_bx_payment_menu_item_title_system_sbs_list_all"><![CDATA[All Subscriptions List]]></string>
+    <string name="_bx_payment_menu_item_title_sbs_list_all"><![CDATA[All Subscriptions]]></string>
+    <string name="_bx_payment_menu_item_title_system_sbs_history"><![CDATA[My Payments History]]></string>
+    <string name="_bx_payment_menu_item_title_sbs_history"><![CDATA[My Payments]]></string>
+
+    <string name="_bx_payment_menu_title_sbs_actions"><![CDATA[Subscription Actions]]></string>
+    <string name="_bx_payment_menu_set_title_sbs_actions"><![CDATA[Subscription Actions]]></string>
+    <string name="_bx_payment_menu_item_title_system_sbs_cancel"><![CDATA[Request Cancellation]]></string>
+    <string name="_bx_payment_menu_item_title_sbs_cancel"><![CDATA[Request Cancellation]]></string>
+
+	<!-- GRIDS -->
+	<string name="_bx_payment_grid_column_title_ods_client_id"><![CDATA[Client]]></string>
+	<string name="_bx_payment_grid_column_title_ods_seller_id"><![CDATA[Seller]]></string>
+	<string name="_bx_payment_grid_column_title_ods_transaction"><![CDATA[Transaction]]></string>
+	<string name="_bx_payment_grid_column_title_ods_license"><![CDATA[License]]></string>
+	<string name="_bx_payment_grid_column_title_ods_amount"><![CDATA[Amount]]></string>
+	<string name="_bx_payment_grid_column_title_ods_date"><![CDATA[Date]]></string>
+	<string name="_bx_payment_grid_column_title_sbs_seller_id"><![CDATA[Seller]]></string>
+	<string name="_bx_payment_grid_column_title_sbs_client_id"><![CDATA[Client]]></string>
+	<string name="_bx_payment_grid_column_title_sbs_customer_id"><![CDATA[Customer ID]]></string>
+	<string name="_bx_payment_grid_column_title_sbs_subscription_id"><![CDATA[Subscription]]></string>
+    <string name="_bx_payment_grid_column_title_sbs_transaction"><![CDATA[Transaction]]></string>
+    <string name="_bx_payment_grid_column_title_sbs_license"><![CDATA[License]]></string>
+    <string name="_bx_payment_grid_column_title_sbs_amount"><![CDATA[Amount]]></string>
+    <string name="_bx_payment_grid_column_title_sbs_provider"><![CDATA[Provider]]></string>
+    <string name="_bx_payment_grid_column_title_sbs_paid"><![CDATA[Paid]]></string>
+    <string name="_bx_payment_grid_column_title_sbs_date"><![CDATA[Date]]></string>
+	<string name="_bx_payment_grid_column_title_crts_vendor_id"><![CDATA[Vendor]]></string>
+	<string name="_bx_payment_grid_column_title_crts_items_count"><![CDATA[Count]]></string>
+	<string name="_bx_payment_grid_column_title_crts_items_price"><![CDATA[Price]]></string>
+	<string name="_bx_payment_grid_column_title_crt_title"><![CDATA[Product]]></string>
+	<string name="_bx_payment_grid_column_title_crt_description"><![CDATA[Description]]></string>
+	<string name="_bx_payment_grid_column_title_crt_quantity"><![CDATA[Quantity]]></string>
+	<string name="_bx_payment_grid_column_title_crt_price"><![CDATA[Price]]></string>
+
+	<string name="_bx_payment_grid_action_title_ods_add"><![CDATA[Manual Order]]></string>
+	<string name="_bx_payment_grid_action_title_ods_cancel"><![CDATA[Cancel]]></string>
+	<string name="_bx_payment_grid_action_title_ods_process"><![CDATA[Process]]></string>
+	<string name="_bx_payment_grid_action_title_ods_view_order"><![CDATA[View]]></string>
+	<string name="_bx_payment_grid_action_title_sbs_actions"><![CDATA[Actions]]></string>
+	<string name="_bx_payment_grid_action_title_sbs_view_order"><![CDATA[View]]></string>
+	<string name="_bx_payment_grid_action_title_sbs_cancel"><![CDATA[Cancel]]></string>
+	<string name="_bx_payment_grid_action_title_crts_delete"><![CDATA[Delete]]></string>
+	<string name="_bx_payment_grid_action_title_crts_continue"><![CDATA[Continue to checkout]]></string>
+	<string name="_bx_payment_grid_action_title_crt_checkout"><![CDATA[Checkout with {0}]]></string>
+	<string name="_bx_payment_grid_action_title_crt_delete"><![CDATA[Delete]]></string>
+
+    <string name="_bx_payment_popup_title_ods_order_subscription_view"><![CDATA[Subscription]]></string>
+    <string name="_bx_payment_popup_title_ods_order_subscription_get_details"><![CDATA[Subscription Details]]></string>
+    <string name="_bx_payment_popup_title_ods_order_subscription_change_details"><![CDATA[Change Subscription Details]]></string>
+    <string name="_bx_payment_popup_title_ods_order_subscription_get_billing"><![CDATA[Billing Information]]></string>
+    <string name="_bx_payment_popup_title_ods_order_subscription_change_billing"><![CDATA[Change Billing Information]]></string>
+	<string name="_bx_payment_popup_title_ods_order_history_view"><![CDATA[Order]]></string>
+	<string name="_bx_payment_popup_title_ods_order_pending_view"><![CDATA[Pending Order]]></string>
+	<string name="_bx_payment_popup_title_ods_order_pending_process"><![CDATA[Process Pending Order]]></string>
+	<string name="_bx_payment_popup_title_ods_order_processed_view"><![CDATA[Processed Order]]></string>
+	<string name="_bx_payment_popup_title_ods_order_processed_add"><![CDATA[Manual Order]]></string>
+	<string name="_bx_payment_popup_title_crd_providers_select"><![CDATA[Select Payment Method]]></string>
+
+	<!-- FORMS -->
+	<string name="_bx_payment_form_cart_input_do_delete"><![CDATA[Delete]]></string>
+	<string name="_bx_payment_form_cart_input_do_checkout"><![CDATA[Checkout]]></string>
+	<string name="_bx_payment_form_details_input_do_submit"><![CDATA[Save]]></string>
+
+	<string name="_bx_payment_form_pendings_form"><![CDATA[Pendings Form]]></string>
+	<string name="_bx_payment_form_processed_form"><![CDATA[Processed Form]]></string>
+	<string name="_bx_payment_form_pendings_display_process"><![CDATA[Process Pending Display]]></string>
+	<string name="_bx_payment_form_processed_display_add"><![CDATA[Add Processed Display]]></string>
+	<string name="_bx_payment_form_pendings_input_id_sys"><![CDATA[ID]]></string>
+	<string name="_bx_payment_form_pendings_input_seller_id_sys"><![CDATA[Seller ID]]></string>
+	<string name="_bx_payment_form_pendings_input_order_sys"><![CDATA[Order]]></string>
+	<string name="_bx_payment_form_pendings_input_order"><![CDATA[Order]]></string>
+	<string name="_bx_payment_form_pendings_input_order_err"><![CDATA[You need to fill in order number here.]]></string>
+	<string name="_bx_payment_form_pendings_input_process_sys"><![CDATA[Process]]></string>
+	<string name="_bx_payment_form_pendings_input_process"><![CDATA[Process]]></string>
+	<string name="_bx_payment_form_pendings_input_cancel_sys"><![CDATA[Cancel]]></string>
+	<string name="_bx_payment_form_pendings_input_cancel"><![CDATA[Cancel]]></string>
+	<string name="_bx_payment_form_processed_input_seller_id_sys"><![CDATA[Seller ID]]></string>
+	<string name="_bx_payment_form_processed_input_client_id_sys"><![CDATA[Client ID]]></string>
+	<string name="_bx_payment_form_processed_input_client_sys"><![CDATA[Client]]></string>
+	<string name="_bx_payment_form_processed_input_client"><![CDATA[Client]]></string>
+	<string name="_bx_payment_form_processed_input_client_err"><![CDATA[You need to enter a name of an existed member here.]]></string>
+	<string name="_bx_payment_form_processed_input_order_sys"><![CDATA[Order]]></string>
+	<string name="_bx_payment_form_processed_input_order"><![CDATA[Order]]></string>
+	<string name="_bx_payment_form_processed_input_order_err"><![CDATA[You need to fill in order number here.]]></string>
+	<string name="_bx_payment_form_processed_input_module_id_sys"><![CDATA[Module]]></string>
+	<string name="_bx_payment_form_processed_input_module_id"><![CDATA[Module]]></string>
+	<string name="_bx_payment_form_processed_input_module_id_err"><![CDATA[You need to select a module here.]]></string>
+	<string name="_bx_payment_form_processed_input_items_sys"><![CDATA[Items]]></string>
+	<string name="_bx_payment_form_processed_input_items"><![CDATA[Items]]></string>
+	<string name="_bx_payment_form_processed_input_items_err"><![CDATA[You need to select at least one item from the list here.]]></string>
+	<string name="_bx_payment_form_processed_input_add"><![CDATA[Add]]></string>
+	<string name="_bx_payment_form_processed_input_add_sys"><![CDATA[Add]]></string>
+	<string name="_bx_payment_form_processed_input_cancel"><![CDATA[Cancel]]></string>
+	<string name="_bx_payment_form_processed_input_cancel_sys"><![CDATA[Cancel]]></string>
+
+    <!-- Predefined Values -->
+    <string name="_bx_payment_pre_lists_currencies"><![CDATA[Currencies]]></string>
+
+	<!-- ACL -->
+	<string name="_bx_payment_acl_action_purchase"><![CDATA[Purchase]]></string>
+	<string name="_bx_payment_acl_action_sell"><![CDATA[Sell]]></string>
+
+	<!-- EMAIL TEMPLATES -->
+	<string name="_bx_payment_et_txt_name_paid_need_join"><![CDATA[Paid and need to join.]]></string>
+	<string name="_bx_payment_et_txt_subject_paid_need_join"><![CDATA[Payment was processed.]]></string>
+	<string name="_bx_payment_et_txt_body_paid_need_join"><![CDATA[{email_header}
+<p>Hello, {RealName}.</p>
+<p>Your payment was processed. If you did not fill in the join form yet, then you may do it using the following link.</p>
+<p><a href="{JoinLink}">Join Now</a></p>
+{email_footer}]]></string>
+
+    <string name="_bx_payment_et_txt_name_cancelation_request"><![CDATA[Subscription cancellation request.]]></string>
+    <string name="_bx_payment_et_txt_subject_cancelation_request"><![CDATA[Subscription cancellation request.]]></string>
+    <string name="_bx_payment_et_txt_body_cancelation_request"><![CDATA[{email_header}
+<p>Hello,</p>
+<p>A user with {profile_name} profile name requested cancellation for a subscription.</p>
+<p>Subscription info:<br />ID: {sibscription_id}<br />Customer: {sibscription_customer}<br />Date: {sibscription_date}</p>
+{email_footer}]]></string>
+
+	<!-- MESSAGES, WARNINGS and ERRORS -->
+	<string name="_bx_payment_msg_no_results"><![CDATA[Empty]]></string>
+	<string name="_bx_payment_msg_redirecting"><![CDATA[Redirecting... Please wait.]]></string>
+	<string name="_bx_payment_msg_item_added"><![CDATA[The item was successfully added to your shopping cart.]]></string>
+	<string name="_bx_payment_msg_item_deleted"><![CDATA[The item was successfully deleted from your shopping cart.]]></string>
+	<string name="_bx_payment_msg_successfully_processed_free"><![CDATA[Free item was successfully processed]]></string>
+	<string name="_bx_payment_msg_cancelation_request_sent"><![CDATA[Cancellation request was sent. Please wait.]]></string>
+	<string name="_bx_payment_err_access_db"><![CDATA[Database access error.]]></string>
+	<string name="_bx_payment_err_cannot_validate"><![CDATA[Can't connect to remote host for validation.]]></string>
+	<string name="_bx_payment_err_empty_items"><![CDATA[There are no items selected.]]></string>
+	<string name="_bx_payment_err_empty_order"><![CDATA[The order is empty.]]></string>
+	<string name="_bx_payment_err_inactive_vendor"><![CDATA[The vendor status is not active.]]></string>
+	<string name="_bx_payment_err_incorrect_provider"><![CDATA[Incorrect or unavailable payment provider.]]></string>
+	<string name="_bx_payment_err_not_accept_payments"><![CDATA[The vendor does not accept payments.]]></string>
+	<string name="_bx_payment_err_nothing_selected"><![CDATA[You need to select at least one item.]]></string>
+	<string name="_bx_payment_err_self_purchase"><![CDATA[You cannot purchase your own item. It's just a bad luck thing, you know.]]></string>
+	<string name="_bx_payment_err_required_login"><![CDATA[You need to login.]]></string>
+	<string name="_bx_payment_err_unknown_vendor"><![CDATA[Unknown vendor.]]></string>
+	<string name="_bx_payment_err_wrong_data"><![CDATA[Incorrect input data.]]></string>
+	<string name="_bx_payment_err_not_found_pending"><![CDATA[Pending order was not found.]]></string>
+	<string name="_bx_payment_err_cannot_perform"><![CDATA[Cannot perform the action. Please report.]]></string>
+	<string name="_bx_payment_err_wrong_quantity"><![CDATA[Incorrect quantity specified.]]></string>
+	<string name="_bx_payment_err_already_processed"><![CDATA[This payment has already processed.]]></string>
+
+	<!-- Other -->
+	<string name="_bx_payment_txt_add_to_cart"><![CDATA[Add to Cart]]></string>
+	<string name="_bx_payment_txt_subscribe"><![CDATA[Subscribe]]></string>
+	<string name="_bx_payment_txt_payment_to"><![CDATA[Payment to {0}]]></string>
+	<string name="_bx_payment_txt_payment_to_for"><![CDATA[Payment to {0} for:]]></string>
+	<string name="_bx_payment_txt_checkout_to"><![CDATA[Continue checkouting to {0}]]></string>
+	<string name="_bx_payment_txt_checkout_with"><![CDATA[Checkout with {0}]]></string>
+	<string name="_bx_payment_txt_client"><![CDATA[Client]]></string>
+	<string name="_bx_payment_txt_seller"><![CDATA[Seller]]></string>
+	<string name="_bx_payment_txt_order"><![CDATA[Order ID]]></string>
+	<string name="_bx_payment_txt_processed_with"><![CDATA[Processed with]]></string>
+	<string name="_bx_payment_txt_message"><![CDATA[Result]]></string>
+	<string name="_bx_payment_txt_date"><![CDATA[Date]]></string>
+	<string name="_bx_payment_txt_products"><![CDATA[Products]]></string>
+	<string name="_bx_payment_txt_buyer_name_mask"><![CDATA[{0} {1}]]></string>
+	<string name="_bx_payment_txt_none"><![CDATA[none]]></string>
+	<string name="_bx_payment_txt_name_manual"><![CDATA[Manually]]></string>
+	<string name="_bx_payment_txt_yes"><![CDATA[Yes]]></string>
+	<string name="_bx_payment_txt_no"><![CDATA[No]]></string>
+
+	<!-- PayPal payment provider -->
+	<string name="_bx_payment_pp_cpt"><![CDATA[PayPal]]></string>
+	<string name="_bx_payment_pp_dsc"><![CDATA[PayPal payment provider]]></string>
+	<string name="_bx_payment_pp_active_cpt"><![CDATA[Active]]></string>
+	<string name="_bx_payment_pp_active_dsc"><![CDATA[Activate(Deactivate) provider]]></string>
+	<string name="_bx_payment_pp_mode_cpt"><![CDATA[Mode]]></string>
+	<string name="_bx_payment_pp_mode_dsc"><![CDATA[Mode to process payments]]></string>
+	<string name="_bx_payment_pp_mode_live"><![CDATA[live]]></string>
+	<string name="_bx_payment_pp_mode_test"><![CDATA[test]]></string>
+	<string name="_bx_payment_pp_business_cpt"><![CDATA[Business]]></string>
+	<string name="_bx_payment_pp_business_dsc"><![CDATA[Business email address]]></string>
+	<string name="_bx_payment_pp_prc_type_cpt"><![CDATA[Process type]]></string>
+	<string name="_bx_payment_pp_prc_type_dsc"><![CDATA[The type in which data is to be processed]]></string>
+	<string name="_bx_payment_pp_prc_type_direct"><![CDATA[direct]]></string>
+	<string name="_bx_payment_pp_prc_type_pdt"><![CDATA[PDT]]></string>
+	<string name="_bx_payment_pp_prc_type_ipn"><![CDATA[IPN]]></string>
+	<string name="_bx_payment_pp_token_cpt"><![CDATA[Identity token]]></string>
+	<string name="_bx_payment_pp_token_dsc"><![CDATA[Identity token]]></string>
+	<string name="_bx_payment_pp_sandbox_cpt"><![CDATA[Sandbox]]></string>
+	<string name="_bx_payment_pp_sandbox_dsc"><![CDATA[Sandbox email address]]></string>
+	<string name="_bx_payment_pp_return_data_url_cpt"><![CDATA[Data return URL]]></string>
+	<string name="_bx_payment_pp_err_no_data_given"><![CDATA[No data given.]]></string>
+	<string name="_bx_payment_pp_err_not_completed"><![CDATA[Payment is not completed.]]></string>
+	<string name="_bx_payment_pp_err_wrong_vendor"><![CDATA[Wrong vendor.]]></string>
+	<string name="_bx_payment_pp_err_wrong_business"><![CDATA[Wrong receiver email.]]></string>
+	<string name="_bx_payment_pp_err_wrong_transaction"><![CDATA[Transaction verification failed.]]></string>
+	<string name="_bx_payment_pp_err_wrong_verification_status"><![CDATA[No verification status received.]]></string>
+	<string name="_bx_payment_pp_err_wrong_amount"><![CDATA[Wrong amount.]]></string>
+	<string name="_bx_payment_pp_err_wrong_custom_data"><![CDATA[Incorrect custom data.]]></string>
+	<string name="_bx_payment_pp_msg_verified"><![CDATA[Payment was successfully processed.]]></string>
+	<string name="_bx_payment_txt_name_paypal"><![CDATA[PayPal]]></string>
+	<string name="_bx_payment_txt_cart_paypal"><![CDATA[PayPal]]></string>
+
+	<!-- 2Checkout payment provider -->
+	<string name="_bx_payment_2co_cpt"><![CDATA[2Checkout]]></string>
+	<string name="_bx_payment_2co_dsc"><![CDATA[2Checkout payment provider]]></string>
+	<string name="_bx_payment_2co_active_cpt"><![CDATA[Active]]></string>
+	<string name="_bx_payment_2co_active_dsc"><![CDATA[Activate(Deactivate) provider]]></string>
+	<string name="_bx_payment_2co_mode_cpt"><![CDATA[Mode]]></string>
+	<string name="_bx_payment_2co_mode_dsc"><![CDATA[Mode to process payments]]></string>
+	<string name="_bx_payment_2co_mode_live"><![CDATA[live]]></string>
+	<string name="_bx_payment_2co_mode_test"><![CDATA[test]]></string>
+	<string name="_bx_payment_2co_account_id_cpt"><![CDATA[Account number]]></string>
+	<string name="_bx_payment_2co_account_id_dsc"><![CDATA[Your 2Checkout vendor account number]]></string>
+	<string name="_bx_payment_2co_payment_method_cpt"><![CDATA[Payment Method]]></string>
+	<string name="_bx_payment_2co_payment_method_dsc"><![CDATA[This will set the default selection on the payment method step during the checkout process]]></string>
+	<string name="_bx_payment_2co_payment_method_cc"><![CDATA[Credit Card(CC)]]></string>
+	<string name="_bx_payment_2co_payment_method_ppi"><![CDATA[PayPal(PPI)]]></string>
+	<string name="_bx_payment_2co_secret_word_cpt"><![CDATA[Secret Word]]></string>
+	<string name="_bx_payment_2co_secret_word_dsc"><![CDATA[Secret word is used to calculate a check hash]]></string>
+	<string name="_bx_payment_2co_return_data_url_cpt"><![CDATA[Data return URL]]></string>
+	<string name="_bx_payment_2co_err_no_vendor_given"><![CDATA[Unknown vendor]]></string>
+	<string name="_bx_payment_2co_err_no_data_given"><![CDATA[No data given.]]></string>
+	<string name="_bx_payment_2co_err_wrong_key"><![CDATA[Check key is incorrect.]]></string>
+	<string name="_bx_payment_2co_err_wrong_payment"><![CDATA[Wrong payment.]]></string>
+	<string name="_bx_payment_2co_err_already_processed"><![CDATA[This payment has already processed]]></string>
+	<string name="_bx_payment_2co_msg_verified"><![CDATA[Successfully verified.]]></string>
+	<string name="_bx_payment_txt_name_2checkout"><![CDATA[2Checkout]]></string>
+	<string name="_bx_payment_txt_cart_2checkout"><![CDATA[2Checkout]]></string>
+
+	<!-- BitPay payment provider -->
+	<string name="_bx_payment_bp_cpt"><![CDATA[BitPay]]></string>
+	<string name="_bx_payment_bp_dsc"><![CDATA[BitPay payment provider]]></string>
+	<string name="_bx_payment_bp_active_cpt"><![CDATA[Active]]></string>
+	<string name="_bx_payment_bp_active_dsc"><![CDATA[Activate(Deactivate) provider]]></string>
+	<string name="_bx_payment_bp_active_err"><![CDATA[You should have SSL certificate (HTTPS connection) to activate and use BitPay on your site.]]></string>
+	<string name="_bx_payment_bp_api_key_cpt"><![CDATA[API Key]]></string>
+	<string name="_bx_payment_bp_api_key_dsc"><![CDATA[Your merchant BitPay API Access key]]></string>
+	<string name="_bx_payment_bp_transaction_speed_cpt"><![CDATA[Transaction speed]]></string>
+	<string name="_bx_payment_bp_transaction_speed_dsc"><![CDATA[Determines when an invoice is confirmed]]></string>
+	<string name="_bx_payment_bp_transaction_speed_high"><![CDATA[High]]></string>
+	<string name="_bx_payment_bp_transaction_speed_medium"><![CDATA[Medium]]></string>
+	<string name="_bx_payment_bp_transaction_speed_low"><![CDATA[Low]]></string>
+	<string name="_bx_payment_bp_full_notifications_cpt"><![CDATA[Enable full notifications]]></string>
+	<string name="_bx_payment_bp_full_notifications_dsc"><![CDATA[When enabled notifications will be sent on every status change, otherwise when an invoice is confirmed only.]]></string>
+	<string name="_bx_payment_bp_notification_email_cpt"><![CDATA[Notification Email]]></string>
+	<string name="_bx_payment_bp_notification_email_dsc"><![CDATA[Email where invoice update notifications will be sent. Leave empty to disable.]]></string>
+	<string name="_bx_payment_bp_err_posdata_exceed_limit"><![CDATA[The value of posData exceeds limit. Contact with administrator.]]></string>
+	<string name="_bx_payment_bp_err_no_data_given"><![CDATA[No data given.]]></string>
+	<string name="_bx_payment_bp_err_no_vendor_given"><![CDATA[Unknown vendor.]]></string>
+	<string name="_bx_payment_bp_err_incorrect_data"><![CDATA[Incorrect order data.]]></string>
+	<string name="_bx_payment_bp_err_wrong_amount"><![CDATA[Wrong payment amount.]]></string>
+	<string name="_bx_payment_bp_err_already_processed"><![CDATA[This payment has already processed.]]></string>
+	<string name="_bx_payment_bp_err_no_confirmation_given"><![CDATA[Payment is waiting for full confirmation from the Bitcoin network.]]></string>
+	<string name="_bx_payment_bp_msg_checkout_finished"><![CDATA[A payment has been confirmed. Once the transaction is fully confirmed on the Bitcoin network, the payment will be processed automatically here. Then the purchased product(s) will be displayed in shopping cart history.<br /><b>Note.</b> If it doesn't happen for some reason, you need to contact with product\'s vendor and provide him with your payment's details. He'll be able to process payment manually if the payment was received.]]></string>
+	<string name="_bx_payment_txt_name_bitpay"><![CDATA[BitPay]]></string>
+	<string name="_bx_payment_txt_cart_bitpay"><![CDATA[BitPay]]></string>
+
+	<!-- Chargebee payment provider -->
+	<string name="_bx_payment_cbee_cpt"><![CDATA[Chargebee]]></string>
+	<string name="_bx_payment_cbee_dsc"><![CDATA[Chargebee payment provider]]></string>
+	<string name="_bx_payment_cbee_active_cpt"><![CDATA[Active]]></string>
+	<string name="_bx_payment_cbee_active_dsc"><![CDATA[Activate(Deactivate) provider. Note. It's recommended to use SSL for better payment processing.]]></string>
+	<string name="_bx_payment_cbee_mode_cpt"><![CDATA[Mode]]></string>
+	<string name="_bx_payment_cbee_mode_dsc"><![CDATA[Mode to process payments]]></string>
+	<string name="_bx_payment_cbee_mode_live"><![CDATA[live]]></string>
+	<string name="_bx_payment_cbee_mode_test"><![CDATA[test]]></string>
+	<string name="_bx_payment_cbee_live_site_cpt"><![CDATA[Site (live)]]></string>
+	<string name="_bx_payment_cbee_live_site_dsc"><![CDATA[Your site name registered in Chargebee for 'live' mode]]></string>
+	<string name="_bx_payment_cbee_live_api_key_cpt"><![CDATA[API Key (live)]]></string>
+	<string name="_bx_payment_cbee_live_api_key_dsc"><![CDATA[Your Chargebee API Access key for 'live' mode]]></string>
+	<string name="_bx_payment_cbee_test_site_cpt"><![CDATA[Site (test)]]></string>
+	<string name="_bx_payment_cbee_test_site_dsc"><![CDATA[Your site name registered in Chargebee for 'test' mode]]></string>
+	<string name="_bx_payment_cbee_test_api_key_cpt"><![CDATA[API Key (test)]]></string>
+	<string name="_bx_payment_cbee_test_api_key_dsc"><![CDATA[Your Chargebee API Access key for 'test' mode]]></string>
+	<string name="_bx_payment_cbee_ssl_cpt"><![CDATA[Enable SSL]]></string>
+	<string name="_bx_payment_cbee_ssl_dsc"><![CDATA[Enable SSL connection to communicate with Chargebee. Note. URLs below will be updated after saving.]]></string>
+	<string name="_bx_payment_cbee_return_data_url_cpt"><![CDATA[Data return URL]]></string>
+	<string name="_bx_payment_cbee_notify_url_cpt"><![CDATA[Webhooks URL]]></string>
+	<string name="_bx_payment_cbee_msg_subscribed"><![CDATA[Thank you! Subscription created. Please, check your email for further instructions.]]></string>
+	<string name="_bx_payment_txt_name_chargebee"><![CDATA[Chargebee]]></string>
+	<string name="_bx_payment_txt_cart_chargebee"><![CDATA[Chargebee]]></string>
+
+	<!-- Recurly payment provider -->
+	<string name="_bx_payment_rcrl_cpt"><![CDATA[Recurly]]></string>
+	<string name="_bx_payment_rcrl_dsc"><![CDATA[Recurly payment provider]]></string>
+	<string name="_bx_payment_rcrl_active_cpt"><![CDATA[Active]]></string>
+	<string name="_bx_payment_rcrl_active_dsc"><![CDATA[Activate(Deactivate) provider.]]></string>
+	<string name="_bx_payment_rcrl_active_err"><![CDATA[You should have SSL certificate (HTTPS connection) to activate and use Recurly on your site.]]></string>
+	<string name="_bx_payment_rcrl_mode_cpt"><![CDATA[Mode]]></string>
+	<string name="_bx_payment_rcrl_mode_dsc"><![CDATA[Mode to process payments]]></string>
+	<string name="_bx_payment_rcrl_mode_live"><![CDATA[live]]></string>
+	<string name="_bx_payment_rcrl_mode_test"><![CDATA[test]]></string>
+	<string name="_bx_payment_rcrl_site_cpt"><![CDATA[Site]]></string>
+	<string name="_bx_payment_rcrl_site_dsc"><![CDATA[Your site name registered in Recurly]]></string>
+	<string name="_bx_payment_rcrl_api_key_private_cpt"><![CDATA[Private API Key]]></string>
+	<string name="_bx_payment_rcrl_api_key_private_dsc"><![CDATA[Your Recurly Private API Access key]]></string>
+	<string name="_bx_payment_rcrl_api_key_public_cpt"><![CDATA[Public API Key]]></string>
+	<string name="_bx_payment_rcrl_api_key_public_dsc"><![CDATA[Your Recurly Public API Access key]]></string>
+	<string name="_bx_payment_rcrl_return_data_url_cpt"><![CDATA[Data return URL]]></string>
+	<string name="_bx_payment_rcrl_notify_url_cpt"><![CDATA[Webhooks URL]]></string>
+	<string name="_bx_payment_rcrl_msg_subscribed"><![CDATA[Thank you! Subscription created. Please, check your email for further instructions.]]></string>
+	<string name="_bx_payment_txt_name_recurly"><![CDATA[Recurly]]></string>
+	<string name="_bx_payment_txt_cart_recurly"><![CDATA[Recurly]]></string>
+
+	<string name="_bx_payment_form_rcrl_card"><![CDATA[Recurly: Card Form]]></string>
+	<string name="_bx_payment_form_rcrl_card_display_add"><![CDATA[Recurly: Add Card Display]]></string>
+	<string name="_bx_payment_form_rcrl_card_input_pending_id_sys"><![CDATA[Pending ID]]></string>
+	<string name="_bx_payment_form_rcrl_card_input_item_sys"><![CDATA[Item]]></string>
+	<string name="_bx_payment_form_rcrl_card_input_token_sys"><![CDATA[Token]]></string>
+	<string name="_bx_payment_form_rcrl_card_input_first_name_sys"><![CDATA[First Name]]></string>
+	<string name="_bx_payment_form_rcrl_card_input_first_name"><![CDATA[First Name]]></string>
+	<string name="_bx_payment_form_rcrl_card_input_first_name_err"><![CDATA[You need to fill in your first name here.]]></string>
+	<string name="_bx_payment_form_rcrl_card_input_last_name_sys"><![CDATA[Last Name]]></string>
+	<string name="_bx_payment_form_rcrl_card_input_last_name"><![CDATA[Last Name]]></string>
+	<string name="_bx_payment_form_rcrl_card_input_last_name_err"><![CDATA[You need to fill in your last name here.]]></string>
+	<string name="_bx_payment_form_rcrl_card_input_email_sys"><![CDATA[Email]]></string>
+	<string name="_bx_payment_form_rcrl_card_input_email"><![CDATA[Email]]></string>
+	<string name="_bx_payment_form_rcrl_card_input_email_err"><![CDATA[You need to fill in your email here.]]></string>
+	<string name="_bx_payment_form_rcrl_card_input_card_number_sys"><![CDATA[Card Number]]></string>
+	<string name="_bx_payment_form_rcrl_card_input_card_number"><![CDATA[Card Number]]></string>
+	<string name="_bx_payment_form_rcrl_card_input_card_number_inf"><![CDATA[16 digits without spaces describing your card number]]></string>
+	<string name="_bx_payment_form_rcrl_card_input_card_expire_sys"><![CDATA[Expiry Date]]></string>
+	<string name="_bx_payment_form_rcrl_card_input_card_expire"><![CDATA[Expiry Date]]></string>
+	<string name="_bx_payment_form_rcrl_card_input_card_expire_month"><![CDATA[Month]]></string>
+	<string name="_bx_payment_form_rcrl_card_input_card_expire_year"><![CDATA[Year]]></string>
+	<string name="_bx_payment_form_rcrl_card_input_card_expire_inf"><![CDATA[Use 'mm yyyy' format]]></string>
+	<string name="_bx_payment_form_rcrl_card_input_card_cvv_sys"><![CDATA[CVV]]></string>
+	<string name="_bx_payment_form_rcrl_card_input_card_cvv"><![CDATA[CVV]]></string>
+	<string name="_bx_payment_form_rcrl_card_input_card_cvv_inf"><![CDATA[Three digits from the back side of your card.]]></string>
+	<string name="_bx_payment_form_rcrl_card_input_submit_sys"><![CDATA[Submit]]></string>
+	<string name="_bx_payment_form_rcrl_card_input_submit"><![CDATA[Submit]]></string>
+	<string name="_bx_payment_form_rcrl_card_input_cancel_sys"><![CDATA[Cancel]]></string>
+	<string name="_bx_payment_form_rcrl_card_input_cancel"><![CDATA[Cancel]]></string>
+	
+	<string name="_bx_payment_popup_title_rcrl_card_add"><![CDATA[Card details]]></string>
+
+	<!-- Stripe payment provider -->
+	<string name="_bx_payment_strp_cpt"><![CDATA[Stripe]]></string>
+	<string name="_bx_payment_strp_dsc"><![CDATA[Stripe payment provider]]></string>
+	<string name="_bx_payment_strp_active_cpt"><![CDATA[Active]]></string>
+	<string name="_bx_payment_strp_active_dsc"><![CDATA[Activate(Deactivate) provider. Note. It's recommended to use SSL for better payment processing.]]></string>
+	<string name="_bx_payment_strp_mode_cpt"><![CDATA[Mode]]></string>
+	<string name="_bx_payment_strp_mode_dsc"><![CDATA[Mode to process payments]]></string>
+	<string name="_bx_payment_strp_mode_live"><![CDATA[live]]></string>
+	<string name="_bx_payment_strp_mode_test"><![CDATA[test]]></string>
+	<string name="_bx_payment_strp_live_pub_key_cpt"><![CDATA[Public Key (live)]]></string>
+	<string name="_bx_payment_strp_live_pub_key_dsc"><![CDATA[Your Public Key generated in Stripe for 'live' mode]]></string>
+	<string name="_bx_payment_strp_live_sec_key_cpt"><![CDATA[Secret Key (live)]]></string>
+	<string name="_bx_payment_strp_live_sec_key_dsc"><![CDATA[Your Stripe Secret Key for 'live' mode]]></string>
+	<string name="_bx_payment_strp_test_pub_key_cpt"><![CDATA[Public Key (test)]]></string>
+	<string name="_bx_payment_strp_test_pub_key_dsc"><![CDATA[Your Public Key generated in Stripe for 'test' mode]]></string>
+	<string name="_bx_payment_strp_test_sec_key_cpt"><![CDATA[Secret Key (test)]]></string>
+	<string name="_bx_payment_strp_test_sec_key_dsc"><![CDATA[Your Stripe Secret Key for 'test' mode]]></string>
+	<string name="_bx_payment_strp_check_amount_cpt"><![CDATA[Enable amount checking]]></string>
+	<string name="_bx_payment_strp_check_amount_dsc"><![CDATA[Enable amount checking for Stripe Webhooks (recomended). However checking should be disabled when discounts and coupons are used.]]></string>
+	<string name="_bx_payment_strp_ssl_cpt"><![CDATA[Enable SSL]]></string>
+	<string name="_bx_payment_strp_ssl_dsc"><![CDATA[Enable SSL connection to communicate with Stripe. Note. URLs below will be updated after saving.]]></string>
+	<string name="_bx_payment_strp_notify_url_cpt"><![CDATA[Webhooks URL]]></string>
+	<string name="_bx_payment_strp_cancellation_email_cpt"><![CDATA[Cancellation Email]]></string>
+	<string name="_bx_payment_strp_msg_charged"><![CDATA[Payment was successfully processed.]]></string>
+	<string name="_bx_payment_strp_msg_subscribed"><![CDATA[Thank you! Subscription created. Please, check your email for further instructions.]]></string>
+	<string name="_bx_payment_strp_msg_details_changed"><![CDATA[Subscription details were changed.]]></string>
+    <string name="_bx_payment_strp_err_details_changed"><![CDATA[Cannot change subscription details. Recheck provided data and try again.]]></string>
+	<string name="_bx_payment_strp_msg_billing_changed"><![CDATA[Billing information was changed.]]></string>
+	<string name="_bx_payment_strp_err_billing_changed"><![CDATA[Cannot change billing information. Recheck provided data and try again.]]></string>
+	<string name="_bx_payment_strp_txt_checkout_with_single"><![CDATA[Checkout with {0}]]></string>
+	<string name="_bx_payment_strp_txt_checkout_with_recurring"><![CDATA[Checkout with {0}]]></string>
+	<string name="_bx_payment_strp_menu_item_title_details"><![CDATA[Details]]></string>
+	<string name="_bx_payment_strp_menu_item_title_details_change"><![CDATA[Change Details]]></string>
+	<string name="_bx_payment_strp_menu_item_title_billing"><![CDATA[Billing Info]]></string>
+	<string name="_bx_payment_strp_menu_item_title_billing_change"><![CDATA[Change Billing Info]]></string>	
+	<string name="_bx_payment_strp_txt_plan"><![CDATA[Plan]]></string>
+	<string name="_bx_payment_strp_txt_cost"><![CDATA[Cost]]></string>
+	<string name="_bx_payment_strp_txt_cost_mask"><![CDATA[{0} {1} / {2}]]></string>
+	<string name="_bx_payment_strp_txt_status"><![CDATA[Status]]></string>
+	<string name="_bx_payment_strp_txt_created"><![CDATA[Created]]></string>
+	<string name="_bx_payment_strp_txt_started"><![CDATA[Started]]></string>
+	<string name="_bx_payment_strp_txt_trial_start"><![CDATA[Trial start]]></string>
+	<string name="_bx_payment_strp_txt_trial_end"><![CDATA[Trial end]]></string>
+	<string name="_bx_payment_strp_txt_cperiod_start"><![CDATA[Current period start]]></string>
+	<string name="_bx_payment_strp_txt_cperiod_end"><![CDATA[Current period end]]></string>
+	<string name="_bx_payment_strp_txt_card_brand"><![CDATA[Brand]]></string>
+	<string name="_bx_payment_strp_txt_card_origin"><![CDATA[Origin]]></string>
+	<string name="_bx_payment_strp_txt_card_type"><![CDATA[Type]]></string>
+	<string name="_bx_payment_strp_txt_card_number"><![CDATA[Number]]></string>
+	<string name="_bx_payment_strp_txt_card_number_mask"><![CDATA[....{0}]]></string>
+	<string name="_bx_payment_strp_txt_card_expires"><![CDATA[Expires]]></string>
+	<string name="_bx_payment_strp_txt_card_expires_mask"><![CDATA[{0} / {1}]]></string>
+	<string name="_bx_payment_strp_txt_card_cvc"><![CDATA[CVC check]]></string>
+	<string name="_bx_payment_strp_txt_card_cvc_passed"><![CDATA[passed]]></string>
+
+    <string name="_bx_payment_form_strp_details"><![CDATA[Stripe: Details Form]]></string>
+    <string name="_bx_payment_form_strp_details_display_edit"><![CDATA[Stripe: Edit Details Display]]></string>
+    <string name="_bx_payment_form_strp_details_input_item_id_sys"><![CDATA[Plan]]></string>
+    <string name="_bx_payment_form_strp_details_input_item_id"><![CDATA[Plan]]></string>
+    <string name="_bx_payment_form_strp_details_input_item_id_err"><![CDATA[You need to select some plan here]]></string>
+    <string name="_bx_payment_form_strp_details_input_submit_sys"><![CDATA[Submit]]></string>
+    <string name="_bx_payment_form_strp_details_input_submit"><![CDATA[Submit]]></string>
+    <string name="_bx_payment_form_strp_details_input_cancel_sys"><![CDATA[Cancel]]></string>
+    <string name="_bx_payment_form_strp_details_input_cancel"><![CDATA[Cancel]]></string>
+
+    <string name="_bx_payment_form_strp_card"><![CDATA[Stripe: Card Form]]></string>
+    <string name="_bx_payment_form_strp_card_display_add"><![CDATA[Stripe: Add Card Display]]></string>
+    <string name="_bx_payment_form_strp_card_input_card_number_sys"><![CDATA[Card Number]]></string>
+    <string name="_bx_payment_form_strp_card_input_card_number"><![CDATA[Card Number]]></string>
+    <string name="_bx_payment_form_strp_card_input_card_number_inf"><![CDATA[16 digits without spaces describing your card number]]></string>
+    <string name="_bx_payment_form_strp_card_input_card_number_err"><![CDATA[You need to enter card number here]]></string>
+    <string name="_bx_payment_form_strp_card_input_card_expire_sys"><![CDATA[Expiry Date]]></string>
+    <string name="_bx_payment_form_strp_card_input_card_expire"><![CDATA[Expiry Date]]></string>
+    <string name="_bx_payment_form_strp_card_input_card_expire_month"><![CDATA[Month]]></string>
+    <string name="_bx_payment_form_strp_card_input_card_expire_year"><![CDATA[Year]]></string>
+    <string name="_bx_payment_form_strp_card_input_card_expire_inf"><![CDATA[Use 'mm yyyy' format]]></string>
+    <string name="_bx_payment_form_strp_card_input_card_expire_err"><![CDATA[You need to enter expiry date in specified format here]]></string>
+    <string name="_bx_payment_form_strp_card_input_card_cvv_sys"><![CDATA[CVV]]></string>
+    <string name="_bx_payment_form_strp_card_input_card_cvv"><![CDATA[CVV]]></string>
+    <string name="_bx_payment_form_strp_card_input_card_cvv_inf"><![CDATA[Three digits from the back side of your card.]]></string>
+    <string name="_bx_payment_form_strp_card_input_card_cvv_err"><![CDATA[You need to enter card CVV here]]></string>
+    <string name="_bx_payment_form_strp_card_input_submit_sys"><![CDATA[Submit]]></string>
+    <string name="_bx_payment_form_strp_card_input_submit"><![CDATA[Submit]]></string>
+    <string name="_bx_payment_form_strp_card_input_cancel_sys"><![CDATA[Cancel]]></string>
+    <string name="_bx_payment_form_strp_card_input_cancel"><![CDATA[Cancel]]></string>
+
+	<string name="_bx_payment_txt_name_stripe"><![CDATA[Stripe]]></string>
+	<string name="_bx_payment_txt_cart_stripe"><![CDATA[Stripe]]></string>
+</resources>

+ 39 - 0
modules/boonex/payment/updates/9.0.5_9.0.6/source/install/sql/disable.sql

@@ -0,0 +1,39 @@
+SET @sName = 'bx_payment';
+
+
+-- OPTIONS
+SET @iTypeId = (SELECT `ID` FROM `sys_options_types` WHERE `name` = @sName LIMIT 1);
+SET @iCategId = (SELECT `ID` FROM `sys_options_categories` WHERE `type_id` = @iTypeId LIMIT 1);
+DELETE FROM `sys_options` WHERE `category_id` = @iCategId;
+DELETE FROM `sys_options_categories` WHERE `type_id` = @iTypeId;
+DELETE FROM `sys_options_types` WHERE `id` = @iTypeId;
+
+
+-- PAGES & BLOCKS
+DELETE FROM `sys_objects_page` WHERE `module` = @sName;
+DELETE FROM `sys_pages_blocks` WHERE `module` = @sName;
+
+
+-- MENU
+DELETE FROM `sys_objects_menu` WHERE `module` = @sName;
+DELETE FROM `sys_menu_sets` WHERE `module` = @sName;
+DELETE FROM `sys_menu_items` WHERE `module` = @sName OR `set_name` IN('bx_payment_menu_cart_submenu', 'bx_payment_menu_sbs_submenu', 'bx_payment_menu_sbs_actions', 'bx_payment_menu_orders_submenu');
+
+
+-- ALERTS
+SET @iHandlerId = (SELECT `id` FROM `sys_alerts_handlers` WHERE `name` = @sName LIMIT 1);
+DELETE FROM `sys_alerts` WHERE `handler_id` = @iHandlerId;
+DELETE FROM `sys_alerts_handlers` WHERE `id` = @iHandlerId LIMIT 1;
+
+
+-- ACL
+DELETE `sys_acl_actions`, `sys_acl_matrix` FROM `sys_acl_actions`, `sys_acl_matrix` WHERE `sys_acl_matrix`.`IDAction` = `sys_acl_actions`.`ID` AND `sys_acl_actions`.`Module` = @sName;
+DELETE FROM `sys_acl_actions` WHERE `Module` = @sName;
+
+
+-- EMAIL TEMPLATES
+DELETE FROM `sys_email_templates` WHERE `Module` = @sName;
+
+
+-- PAYMENTS
+DELETE FROM `sys_objects_payments` WHERE `object` = @sName;

+ 441 - 0
modules/boonex/payment/updates/9.0.5_9.0.6/source/install/sql/install.sql

@@ -0,0 +1,441 @@
+SET @sName = 'bx_payment';
+
+
+-- TABLES
+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_single` tinyint(4) NOT NULL default '0',
+  `for_recurring` tinyint(4) NOT NULL default '0',
+  `class_name` varchar(128) NOT NULL default '',
+  `class_file` varchar(255) NOT NULL  default '',
+  PRIMARY KEY(`id`)
+) ENGINE=MyISAM  DEFAULT CHARSET=utf8;
+
+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`)
+) ENGINE=MyISAM  DEFAULT CHARSET=utf8;
+
+CREATE TABLE IF NOT EXISTS `bx_payment_user_values` (
+  `user_id` int(11) NOT NULL default '0',
+  `option_id` int(11) NOT NULL default '0',  
+  `value` varchar(255) NOT NULL default '',
+  UNIQUE KEY `value`(`user_id`, `option_id`)
+) ENGINE=MyISAM  DEFAULT CHARSET=utf8;
+
+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`)
+) ENGINE=MyISAM  DEFAULT CHARSET=utf8;
+
+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',
+  `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',
+  `license` varchar(16) NOT NULL default '',
+  `date` int(11) NOT NULL default '0',
+  `new` tinyint(1) NOT NULL default '1',
+  PRIMARY KEY(`id`)
+) ENGINE=MyISAM  DEFAULT CHARSET=utf8;
+
+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 '',
+  `paid` tinyint(4) NOT NULL default '0',
+  `date` int(11) NOT NULL default '0',
+  PRIMARY KEY(`id`),
+  UNIQUE KEY `pending_id` (`pending_id`)
+) ENGINE=MyISAM  DEFAULT CHARSET=utf8;
+
+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 '',
+  `paid` tinyint(4) NOT NULL default '0',
+  `date` int(11) NOT NULL default '0',
+  `reason` varchar(16) NOT NULL default '',
+  `deleted` int(11) NOT NULL default '0',
+  PRIMARY KEY(`id`),
+  UNIQUE KEY `pending_id` (`pending_id`)
+) ENGINE=MyISAM  DEFAULT CHARSET=utf8;
+
+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',
+  `order` varchar(32) NOT NULL default '',
+  `error_code` varchar(16) NOT NULL default '',
+  `error_msg` varchar(255) NOT NULL default '',
+  `date` int(11) NOT NULL default '0',
+  `processed` tinyint(4) NOT NULL default '0',
+  PRIMARY KEY(`id`)
+) ENGINE=MyISAM  DEFAULT CHARSET=utf8;
+
+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`)
+) ENGINE=MyISAM  DEFAULT CHARSET=utf8;
+
+
+-- PayPal payment provider
+INSERT INTO `bx_payment_providers`(`name`, `caption`, `description`, `option_prefix`, `for_visitor`, `for_single`, `for_recurring`, `class_name`) VALUES
+('paypal', '_bx_payment_pp_cpt', '_bx_payment_pp_dsc', 'pp_', 1, 1, 0, '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', '', '', '', '', 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', '', '', '', '', 6),
+(@iProviderId, 'pp_return_data_url', 'value', '_bx_payment_pp_return_data_url_cpt', '', '', '', '', '', 7);
+
+
+-- 2Checkout payment provider
+INSERT INTO `bx_payment_providers`(`name`, `caption`, `description`, `option_prefix`, `for_visitor`, `for_single`, `for_recurring`, `class_name`) VALUES
+('2checkout', '_bx_payment_2co_cpt', '_bx_payment_2co_dsc', '2co_', 1, 1, 0, 'BxPaymentProvider2Checkout');
+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, '2co_active', 'checkbox', '_bx_payment_2co_active_cpt', '_bx_payment_2co_active_dsc', '', '', '', '', 1),
+(@iProviderId, '2co_mode', 'select', '_bx_payment_2co_mode_cpt', '_bx_payment_2co_mode_dsc', '1|_bx_payment_2co_mode_live,2|_bx_payment_2co_mode_test', '', '', '', 2),
+(@iProviderId, '2co_account_id', 'text', '_bx_payment_2co_account_id_cpt', '_bx_payment_2co_account_id_dsc', '', '', '', '', 3),
+(@iProviderId, '2co_payment_method', 'select', '_bx_payment_2co_payment_method_cpt', '_bx_payment_2co_payment_method_dsc', 'CC|_bx_payment_2co_payment_method_cc,PPI|_bx_payment_2co_payment_method_ppi', '', '', '', 4),
+(@iProviderId, '2co_secret_word', 'text', '_bx_payment_2co_secret_word_cpt', '_bx_payment_2co_secret_word_dsc', '', '', '', '', 5),
+(@iProviderId, '2co_return_data_url', 'value', '_bx_payment_2co_return_data_url_cpt', '', '', '', '', '', 6);
+
+
+-- BitPay payment provider
+INSERT INTO `bx_payment_providers`(`name`, `caption`, `description`, `option_prefix`, `for_visitor`, `for_single`, `for_recurring`, `class_name`) VALUES
+('bitpay', '_bx_payment_bp_cpt', '_bx_payment_bp_dsc', 'bp_', 0, 1, 0, 'BxPaymentProviderBitPay');
+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, 'bp_active', 'checkbox', '_bx_payment_bp_active_cpt', '_bx_payment_bp_active_dsc', '', 'https', '', '_bx_payment_bp_active_err', 1),
+(@iProviderId, 'bp_api_key', 'text', '_bx_payment_bp_api_key_cpt', '_bx_payment_bp_api_key_dsc', '', '', '', '', 2),
+(@iProviderId, 'bp_transaction_speed', 'select', '_bx_payment_bp_transaction_speed_cpt', '_bx_payment_bp_transaction_speed_dsc', 'high|_bx_payment_bp_transaction_speed_high,medium|_bx_payment_bp_transaction_speed_medium,low|_bx_payment_bp_transaction_speed_low', '', '', '', 3),
+(@iProviderId, 'bp_full_notifications', 'checkbox', '_bx_payment_bp_full_notifications_cpt', '_bx_payment_bp_full_notifications_dsc', '', '', '', '', 4),
+(@iProviderId, 'bp_notification_email', 'text', '_bx_payment_bp_notification_email_cpt', '_bx_payment_bp_notification_email_dsc', '', '', '', '', 5);
+
+
+-- Chargebee payment provider
+INSERT INTO `bx_payment_providers`(`name`, `caption`, `description`, `option_prefix`, `for_visitor`, `for_single`, `for_recurring`, `class_name`) VALUES
+('chargebee', '_bx_payment_cbee_cpt', '_bx_payment_cbee_dsc', 'cbee_', 1, 0, 1, '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_mode', 'select', '_bx_payment_cbee_mode_cpt', '_bx_payment_cbee_mode_dsc', '1|_bx_payment_cbee_mode_live,2|_bx_payment_cbee_mode_test', '', '', '', 2),
+(@iProviderId, 'cbee_live_site', 'text', '_bx_payment_cbee_live_site_cpt', '_bx_payment_cbee_live_site_dsc', '', '', '', '', 3),
+(@iProviderId, 'cbee_live_api_key', 'text', '_bx_payment_cbee_live_api_key_cpt', '_bx_payment_cbee_live_api_key_dsc', '', '', '', '', 4),
+(@iProviderId, 'cbee_test_site', 'text', '_bx_payment_cbee_test_site_cpt', '_bx_payment_cbee_test_site_dsc', '', '', '', '', 5),
+(@iProviderId, 'cbee_test_api_key', 'text', '_bx_payment_cbee_test_api_key_cpt', '_bx_payment_cbee_test_api_key_dsc', '', '', '', '', 6),
+(@iProviderId, 'cbee_ssl', 'checkbox', '_bx_payment_cbee_ssl_cpt', '_bx_payment_cbee_ssl_dsc', '', '', '', '', 7),
+(@iProviderId, 'cbee_return_data_url', 'value', '_bx_payment_cbee_return_data_url_cpt', '', '', '', '', '', 8),
+(@iProviderId, 'cbee_notify_url', 'value', '_bx_payment_cbee_notify_url_cpt', '', '', '', '', '', 9);
+
+-- Recurly payment provider
+INSERT INTO `bx_payment_providers`(`name`, `caption`, `description`, `option_prefix`, `for_visitor`, `for_single`, `for_recurring`, `class_name`) VALUES
+('recurly', '_bx_payment_rcrl_cpt', '_bx_payment_rcrl_dsc', 'rcrl_', 1, 0, 1, 'BxPaymentProviderRecurly');
+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, 'rcrl_active', 'checkbox', '_bx_payment_rcrl_active_cpt', '_bx_payment_rcrl_active_dsc', '', 'https', '', '_bx_payment_rcrl_active_err', 1),
+(@iProviderId, 'rcrl_mode', 'select', '_bx_payment_rcrl_mode_cpt', '_bx_payment_rcrl_mode_dsc', '1|_bx_payment_rcrl_mode_live,2|_bx_payment_rcrl_mode_test', '', '', '', 2),
+(@iProviderId, 'rcrl_site', 'text', '_bx_payment_rcrl_site_cpt', '_bx_payment_rcrl_site_dsc', '', '', '', '', 3),
+(@iProviderId, 'rcrl_api_key_private', 'text', '_bx_payment_rcrl_api_key_private_cpt', '_bx_payment_rcrl_api_key_private_dsc', '', '', '', '', 4),
+(@iProviderId, 'rcrl_api_key_public', 'text', '_bx_payment_rcrl_api_key_public_cpt', '_bx_payment_rcrl_api_key_public_dsc', '', '', '', '', 5),
+(@iProviderId, 'rcrl_return_data_url', 'value', '_bx_payment_rcrl_return_data_url_cpt', '', '', '', '', '', 6),
+(@iProviderId, 'rcrl_notify_url', 'value', '_bx_payment_rcrl_notify_url_cpt', '', '', '', '', '', 7);
+
+-- Stripe payment provider
+INSERT INTO `bx_payment_providers`(`name`, `caption`, `description`, `option_prefix`, `for_visitor`, `for_single`, `for_recurring`, `class_name`) VALUES
+('stripe', '_bx_payment_strp_cpt', '_bx_payment_strp_dsc', 'strp_', 1, 1, 1, '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_mode', 'select', '_bx_payment_strp_mode_cpt', '_bx_payment_strp_mode_dsc', '1|_bx_payment_strp_mode_live,2|_bx_payment_strp_mode_test', '', '', '', 2),
+(@iProviderId, 'strp_live_pub_key', 'text', '_bx_payment_strp_live_pub_key_cpt', '_bx_payment_strp_live_pub_key_dsc', '', '', '', '', 3),
+(@iProviderId, 'strp_live_sec_key', 'text', '_bx_payment_strp_live_sec_key_cpt', '_bx_payment_strp_live_sec_key_dsc', '', '', '', '', 4),
+(@iProviderId, 'strp_test_pub_key', 'text', '_bx_payment_strp_test_pub_key_cpt', '_bx_payment_strp_test_pub_key_dsc', '', '', '', '', 5),
+(@iProviderId, 'strp_test_sec_key', 'text', '_bx_payment_strp_test_sec_key_cpt', '_bx_payment_strp_test_sec_key_dsc', '', '', '', '', 6),
+(@iProviderId, 'strp_check_amount', 'checkbox', '_bx_payment_strp_check_amount_cpt', '_bx_payment_strp_check_amount_dsc', '', '', '', '', 7),
+(@iProviderId, 'strp_ssl', 'checkbox', '_bx_payment_strp_ssl_cpt', '_bx_payment_strp_ssl_dsc', '', '', '', '', 8),
+(@iProviderId, 'strp_cancellation_email', 'text', '_bx_payment_strp_cancellation_email_cpt', '', '', '', '', '', 9),
+(@iProviderId, 'strp_notify_url', 'value', '_bx_payment_strp_notify_url_cpt', '', '', '', '', '', 10);
+
+
+-- 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`, `override_class_name`, `override_class_file`) VALUES
+('bx_payment_grid_carts', 'Array', '', '', 'vendor_id', '', '', '', 20, NULL, 'start', '', '', '', 'like', '', '', 2147483647, 'BxPaymentGridCarts', 'modules/boonex/payment/classes/BxPaymentGridCarts.php'),
+('bx_payment_grid_cart', 'Array', '', '', 'descriptor', '', '', '', 20, NULL, 'start', '', 'title,description', '', 'like', '', '', 2147483647, '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`, `ts`.`date` AS `date` 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', '', '', 100, NULL, 'start', '', 'ts`.`customer_id,ts`.`subscription_id,ts`.`date', '', 'auto', '', '', 2147483647, '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`, `ttp`.`seller_id` AS `seller_id`, `ts`.`customer_id` AS `customer_id`, `ts`.`subscription_id` AS `subscription_id`, `ttp`.`provider` AS `provider`, `ts`.`paid` AS `paid`, `ts`.`date` AS `date` 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', '', '', 100, NULL, 'start', '', 'ts`.`customer_id,ts`.`subscription_id,ts`.`date', '', 'auto', '', '', 192, '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`.`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, 'BxPaymentGridSbsHistory', 'modules/boonex/payment/classes/BxPaymentGridSbsHistory.php'),
+
+('bx_payment_grid_orders_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`.`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, '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`.`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`.`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 ', 'bx_payment_transactions', 'id', 'date', '', '', 100, NULL, 'start', '', 'ttp`.`order,tt`.`license,tt`.`amount,tt`.`date', '', 'auto', '', '', 2147483647, '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`.`order` AS `transaction`, `tt`.`error_msg` AS `error_msg`, `tt`.`provider` AS `provider`, `tt`.`date` AS `date` FROM `bx_payment_transactions_pending` AS `tt` 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', '', 'auto', '', '', 2147483647, 'BxPaymentGridPending', 'modules/boonex/payment/classes/BxPaymentGridPending.php');
+
+INSERT INTO `sys_grid_fields` (`object`, `name`, `title`, `width`, `translatable`, `chars_limit`, `params`, `order`) VALUES
+('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, '', '', 1),
+('bx_payment_grid_sbs_list_my', 'seller_id', '_bx_payment_grid_column_title_sbs_seller_id', '20%', 0, '24', '', 2),
+('bx_payment_grid_sbs_list_my', 'customer_id', '_bx_payment_grid_column_title_sbs_customer_id', '20%', 0, '24', '', 3),
+('bx_payment_grid_sbs_list_my', 'subscription_id', '_bx_payment_grid_column_title_sbs_subscription_id', '20%', 0, '24', '', 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', '_bx_payment_grid_column_title_sbs_date', '14%', 0, '10', '', 6),
+('bx_payment_grid_sbs_list_my', 'actions', '', '14%', 0, '', '', 7),
+
+('bx_payment_grid_sbs_list_all', 'seller_id', '_bx_payment_grid_column_title_sbs_seller_id', '15%', 0, '24', '', 1),
+('bx_payment_grid_sbs_list_all', 'client_id', '_bx_payment_grid_column_title_sbs_client_id', '15%', 0, '24', '', 2),
+('bx_payment_grid_sbs_list_all', 'customer_id', '_bx_payment_grid_column_title_sbs_customer_id', '15%', 0, '18', '', 3),
+('bx_payment_grid_sbs_list_all', 'subscription_id', '_bx_payment_grid_column_title_sbs_subscription_id', '15%', 0, '18', '', 4),
+('bx_payment_grid_sbs_list_all', 'provider', '_bx_payment_grid_column_title_sbs_provider', '10%', 0, '16', '', 5),
+('bx_payment_grid_sbs_list_all', 'paid', '_bx_payment_grid_column_title_sbs_paid', '4%', 0, '4', '', 6),
+('bx_payment_grid_sbs_list_all', 'date', '_bx_payment_grid_column_title_sbs_date', '10%', 0, '10', '', 7),
+('bx_payment_grid_sbs_list_all', 'actions', '', '16%', 0, '', '', 8),
+
+('bx_payment_grid_sbs_history', 'seller_id', '_bx_payment_grid_column_title_sbs_seller_id', '24%', 0, '20', '', 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, '20', '', 1),
+('bx_payment_grid_orders_history', 'transaction', '_bx_payment_grid_column_title_ods_transaction', '22%', 0, '18', '', 2),
+('bx_payment_grid_orders_history', 'license', '_bx_payment_grid_column_title_ods_license', '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, '', '', 1),
+('bx_payment_grid_orders_processed', 'client_id', '_bx_payment_grid_column_title_ods_client_id', '22%', 0, '18', '', 2),
+('bx_payment_grid_orders_processed', 'transaction', '_bx_payment_grid_column_title_ods_transaction', '20%', 0, '18', '', 3),
+('bx_payment_grid_orders_processed', 'license', '_bx_payment_grid_column_title_ods_license', '20%', 0, '18', '', 4),
+('bx_payment_grid_orders_processed', 'amount', '_bx_payment_grid_column_title_ods_amount', '10%', 1, '10', '', 5),
+('bx_payment_grid_orders_processed', 'date', '_bx_payment_grid_column_title_ods_date', '10%', 0, '10', '', 6),
+('bx_payment_grid_orders_processed', 'actions', '', '16%', 0, '', '', 7),
+
+('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, '25', '', 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);
+
+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', 'money', 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', 'times', 1, 1, 2),
+
+('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', 'refresh', 1, 0, 2),
+('bx_payment_grid_orders_pending', 'single', 'cancel', '_bx_payment_grid_action_title_ods_cancel', 'times', 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_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'),
+-- 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_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),
+-- 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, 'id', '0', '', 0, 'hidden', '_bx_payment_form_processed_input_id_sys', '', '', 0, 0, 0, '', '', '', '', '', '', 'Int', '', 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),
+
+-- 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', 'id', 2147483647, 0, 1),
+('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),
+
+-- 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', '&#128;'),
+('bx_payment_currencies', 'GBP', 4, 'GBP', '&#163;'),
+('bx_payment_currencies', 'USD', 5, 'USD', '&#36;'),
+('bx_payment_currencies', 'YEN', 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`, `url`, `click`, `icon`, `caption`, `cnt_notices`, `cnt_actions`) VALUES
+(@iPageId, @sName, '{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));

+ 99 - 0
modules/boonex/payment/updates/9.0.5_9.0.6/source/js/cart.js

@@ -0,0 +1,99 @@
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Payment Payment
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+function BxPaymentCart(oOptions) {
+	this.init(oOptions);
+}
+
+BxPaymentCart.prototype = new BxPaymentMain();
+
+BxPaymentCart.prototype.init = function(oOptions) {
+	if($.isEmptyObject(oOptions))
+		return;
+
+	this._sActionsUrl = oOptions.sActionUrl;
+    this._sObjName = oOptions.sObjName == undefined ? 'oPmtCart' : oOptions.sObjName;
+    this._sAnimationEffect = oOptions.sAnimationEffect == undefined ? 'fade' : oOptions.sAnimationEffect;
+    this._iAnimationSpeed = oOptions.iAnimationSpeed == undefined ? 'slow' : oOptions.iAnimationSpeed;
+};
+
+BxPaymentCart.prototype.addToCart = function(iSellerId, iModuleId, iItemId, iItemCount, iRedirect, sCustom) {
+	var $this = this;
+    var oDate = new Date();
+
+    var sRedirect = '';
+    if(typeof iRedirect == 'number' && parseInt(iRedirect) > 0)
+    	sRedirect = sUrlRoot + 'cart.php?seller_id=' + iSellerId;
+	else if(typeof iRedirect == 'string' && iRedirect.length > 0)
+		sRedirect = iRedirect;
+
+    $.post(
+        this._sActionsUrl + 'add_to_cart/' + iSellerId + '/' + iModuleId + '/' + iItemId + '/' + iItemCount + '/',
+        {
+        	custom: sCustom ? sCustom : '',
+            _t:oDate.getTime()
+        },
+        function(oData) {
+        	if(sRedirect)
+        		oData.redirect = sRedirect;
+
+        	processJsonData(oData);
+        },
+        'json'
+    );
+};
+
+BxPaymentCart.prototype.onCartContinue = function(oData) {
+	if (!oData || oData.link == undefined)
+		return;
+
+	location.href = oData.link;
+};
+
+BxPaymentCart.prototype.onCartCheckout = function(oData) {
+	if (!oData || oData.link == undefined)
+		return;
+
+	location.href = oData.link;
+};
+
+BxPaymentCart.prototype.subscribe = function(iSellerId, sSellerProvider, iModuleId, iItemId, iItemCount, sRedirect, sCustom) {
+    var $this = this;
+    var oDate = new Date();
+
+    var oParams = {
+    	seller_id: iSellerId,
+    	seller_provider: sSellerProvider,
+    	module_id: iModuleId,
+    	item_id: iItemId,
+    	item_count: 1,
+    	redirect: sRedirect ? sRedirect : '',
+    	custom: sCustom ? sCustom : '',
+    	_t: oDate.getTime()
+    };
+
+    if(iItemCount != undefined && iItemCount.length > 0)
+    	oParams.item_count = parseInt(iItemCount);
+
+    $.post(
+        this._sActionsUrl + 'subscribe_json/',
+        oParams,
+        function(oData){
+        	processJsonData(oData);
+        },
+        'json'
+    );
+};
+
+BxPaymentCart.prototype.onSubscribeSubmit = function(oData) {
+	document.location = oData.redirect;
+};
+
+/** @} */

+ 25 - 0
modules/boonex/payment/updates/9.0.5_9.0.6/source/js/main.js

@@ -0,0 +1,25 @@
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Payment Payment
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+function BxPaymentMain() {}
+
+BxPaymentMain.prototype.loadingInButton = function(e, bShow) {
+	if($(e).length)
+		bx_loading_btn($(e), bShow);
+	else
+		bx_loading($('body'), bShow);	
+};
+
+BxPaymentMain.prototype.loadingInPopup = function(e, bShow) {
+	var oParent = $(e).length ? $(e).parents('.bx-popup-content:first') : $('body'); 
+	bx_loading(oParent, bShow);
+};
+
+/** @} */

+ 57 - 0
modules/boonex/payment/updates/9.0.5_9.0.6/source/js/orders.js

@@ -0,0 +1,57 @@
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Payment Payment
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+function BxPaymentOrders(oOptions) {
+	this.init(oOptions);
+}
+
+BxPaymentOrders.prototype.init = function(oOptions) {
+	if($.isEmptyObject(oOptions))
+		return;
+
+	this._sActionsUrl = oOptions.sActionUrl;
+    this._sObjName = oOptions.sObjName == undefined ? 'oPaymentOrders' : oOptions.sObjName;
+    this._sAnimationEffect = oOptions.sAnimationEffect == undefined ? 'fade' : oOptions.sAnimationEffect;
+    this._iAnimationSpeed = oOptions.iAnimationSpeed == undefined ? 'slow' : oOptions.iAnimationSpeed;
+    this._iTimeout = (oOptions.iTimeout == undefined ? 5 : oOptions.iTimeout) * 1000;
+    this._aHtmlIds = oOptions.aHtmlIds == undefined ? {} : oOptions.aHtmlIds;
+};
+
+/*--- Manual Order function ---*/
+BxPaymentOrders.prototype.showPopup = function(oUi) {
+	$('#' + this._aHtmlIds['order_processed_client_id']).val(oUi.item.value);	
+};
+
+BxPaymentOrders.prototype.selectModule = function(oSelect) {
+    var oDate = new Date();
+
+    var oPopup = $('#' + this._aHtmlIds['order_processed_add']);
+    oPopup.bx_loading(true);
+
+    $.get(
+        this._sActionsUrl + 'get_items/single/' + parseInt($(oSelect).val()) + '/',
+        {
+            _t:oDate.getTime()
+        },
+        function(oData) {
+        	oPopup.bx_loading(false);
+
+        	processJsonData(oData);
+        },
+        'json'
+    );
+};
+
+BxPaymentOrders.prototype.onSelectModule = function(oData) {
+	if(oData.data != undefined)
+		$('#' + this._aHtmlIds['order_processed_items']).replaceWith(oData.data);
+};
+
+/** @} */

+ 111 - 0
modules/boonex/payment/updates/9.0.5_9.0.6/source/js/stripe.js

@@ -0,0 +1,111 @@
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Payment Payment
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+function BxPaymentProviderStripe(oOptions) {
+	this.init(oOptions);
+}
+
+BxPaymentProviderStripe.prototype = new BxPaymentMain();
+
+BxPaymentProviderStripe.prototype.init = function(oOptions) {
+	this._sProvider = oOptions.sProvider;
+	this._sActionsUrl = oOptions.sActionUrl;
+    this._sObjName = oOptions.sObjName == undefined ? 'oPaymentProviderStripe' : oOptions.sObjName;
+    this._sAnimationEffect = oOptions.sAnimationEffect == undefined ? 'fade' : oOptions.sAnimationEffect;
+    this._iAnimationSpeed = oOptions.iAnimationSpeed == undefined ? 'slow' : oOptions.iAnimationSpeed;
+
+    this._rHandler = StripeCheckout.configure({
+	  key: oOptions.sPublicKey,
+	  name: oOptions.sVendorName,
+	  amount: oOptions.iAmount == undefined ? '' : oOptions.iAmount,
+	  currency: oOptions.sVendorCurrency,
+	  image: oOptions.sVendorIcon,
+	  locale: 'auto',
+	  email: oOptions.sClientEmail,
+	  description: oOptions.sItemTitle == undefined ? '' : oOptions.sItemTitle
+	});
+
+    //--- For Single payment
+    this._sObjNameGrid = oOptions.sObjNameGrid;
+
+    //--- For Recurring payment
+    this._sObjNameCart = oOptions.sObjNameCart;
+    this._iSellerId  = oOptions.iSellerId;
+    this._iModuleId  = oOptions.iModuleId;
+    this._iItemId  = oOptions.iItemId;
+    this._iItemCount  = oOptions.iItemCount;
+    this._sRedirect  = oOptions.sRedirect;
+    this._sCustom  = oOptions.sCustom;
+};
+
+BxPaymentProviderStripe.prototype.checkout = function(oLink) {
+  	oLink = jQuery(oLink);
+	if(oLink.hasClass('bx-btn-disabled'))
+		return;
+
+	oLink.toggleClass('bx-btn-disabled');
+
+	var $this = this;
+	this._rHandler.open({
+		token: function(token) {
+			glGrids[$this._sObjNameGrid]._oQueryAppend['provider'] = $this._sProvider;
+			glGrids[$this._sObjNameGrid]._oQueryAppend['token'] = token.id;
+			glGrids[$this._sObjNameGrid].actionWithSelected('', 'checkout', {}, '', false, false);
+		},
+		closed: function() {
+			oLink.toggleClass('bx-btn-disabled');
+		}
+	});
+};
+
+BxPaymentProviderStripe.prototype.subscribe = function(oLink) {
+	var $this = this;
+    var oDate = new Date();
+
+  	oLink = jQuery(oLink);
+	if(oLink.hasClass('bx-btn-disabled'))
+		return;
+
+	oLink.addClass('bx-btn-disabled');
+
+	this._rHandler.open({
+		token: function(token) {
+			$this.loadingInButton(oLink, true);
+
+		    var oParams = {
+		    	seller_id: $this._iSellerId,
+		    	seller_provider: $this._sProvider,
+		    	module_id: $this._iModuleId,
+		    	item_id: $this._iItemId,
+		    	item_count: $this._iItemCount,
+		    	redirect: $this._sRedirect,
+		    	custom: $this._sCustom,
+		    	token: token.id,
+		    	_t: oDate.getTime()
+		    };
+
+		    $.post(
+		        $this._sActionsUrl + 'subscribe_json/',
+		        oParams,
+		        function(oData){
+		        	$this.loadingInButton(oLink, true);
+
+		        	processJsonData(oData);
+		        },
+		        'json'
+		    );
+		},
+		closed: function() {
+			oLink.removeClass('bx-btn-disabled');
+		}
+	});
+};
+
+/** @} */

+ 68 - 0
modules/boonex/payment/updates/9.0.5_9.0.6/source/js/subscriptions.js

@@ -0,0 +1,68 @@
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Payment Payment
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+function BxPaymentSubscriptions(oOptions) {
+	this.init(oOptions);
+}
+
+BxPaymentSubscriptions.prototype = new BxPaymentMain();
+
+BxPaymentSubscriptions.prototype.init = function(oOptions) {
+	if($.isEmptyObject(oOptions))
+		return;
+
+	this._sActionsUrl = oOptions.sActionUrl;
+    this._sObjName = oOptions.sObjName == undefined ? 'oPmtSubscriptions' : oOptions.sObjName;
+    this._sAnimationEffect = oOptions.sAnimationEffect == undefined ? 'fade' : oOptions.sAnimationEffect;
+    this._iAnimationSpeed = oOptions.iAnimationSpeed == undefined ? 'slow' : oOptions.iAnimationSpeed;
+};
+
+BxPaymentSubscriptions.prototype.getDetails = function(oLink, iId) {
+	this._performRequest(oLink, iId, 'subscription_get_details');
+};
+
+BxPaymentSubscriptions.prototype.changeDetails = function(oLink, iId) {
+	this._performRequest(oLink, iId, 'subscription_change_details');
+};
+
+BxPaymentSubscriptions.prototype.getBilling = function(oLink, iId) {
+	this._performRequest(oLink, iId, 'subscription_get_billing');
+};
+
+BxPaymentSubscriptions.prototype.changeBilling = function(oLink, iId) {
+	this._performRequest(oLink, iId, 'subscription_change_billing');
+};
+
+BxPaymentSubscriptions.prototype.requestCancelation = function(oLink, iId) {
+	this._performRequest(oLink, iId, 'subscription_cancelation');
+};
+
+BxPaymentSubscriptions.prototype._performRequest = function(oLink, iId, sUri) {
+	var $this = this;
+    var oDate = new Date();
+
+    this.loadingInButton(oLink, true);
+
+    $.post(
+        this._sActionsUrl + sUri + '/' + iId + '/',
+        {
+            _t:oDate.getTime()
+        },
+        function(oData){
+        	$this.loadingInButton(oLink, false);
+        	$(".bx-popup-applied:visible").dolPopupHide();
+
+        	processJsonData(oData);
+        },
+        'json'
+    );
+};
+
+/** @} */

+ 4 - 0
modules/boonex/payment/updates/9.0.5_9.0.6/source/template/add_to_cart.html

@@ -0,0 +1,4 @@
+<button class="bx-btn bx-btn-img bx-payment-add-to-cart bx-def-margin-sec-left-auto" onclick="javascript:__js_object__.addToCart(__vendor_id__, __module_id__, __item_id__, __item_count__, __need_redirect__, '__custom__')">
+    <i class="sys-icon shopping-cart"></i>__txt_add_to_cart__
+</button>
+__js_content__

+ 1 - 0
modules/boonex/payment/updates/9.0.5_9.0.6/source/template/add_to_cart_js.html

@@ -0,0 +1 @@
+__js_object__.addToCart(__vendor_id__, __module_id__, __item_id__, __item_count__, __need_redirect__, '__custom__')

+ 19 - 0
modules/boonex/payment/updates/9.0.5_9.0.6/source/template/order_processed_add.html

@@ -0,0 +1,19 @@
+<div class="bx-payment-processed-add">
+    <div class="bx-payment-processed-add-cnt">
+        __form__
+        <script type="text/javascript">
+            $(document).ready(function () {
+                $("#__form_id__").ajaxForm({ 
+                    dataType: "json",
+                    beforeSubmit: function (formData, jqForm, options) {
+                        bx_loading($("#__form_id__"), true);
+                    },
+                    success: function (data) {
+                        $(".bx-popup-applied:visible").dolPopupHide();
+                        glGrids.__object__.processJson(data, '__action__');
+                    }
+                });
+            });
+        </script>
+    </div>
+</div>

Некоторые файлы не были показаны из-за большого количества измененных файлов