Parcourir la source

Modules updates.

AntonLV il y a 4 ans
Parent
commit
b15c1705d6
100 fichiers modifiés avec 21990 ajouts et 1 suppressions
  1. 1 1
      modules/boonex/invites/install/sql/enable.sql
  2. 51 0
      modules/boonex/invites/updates/12.0.0_13.0.0/install/config.php
  3. 13 0
      modules/boonex/invites/updates/12.0.0_13.0.0/install/installer.php
  4. 4 0
      modules/boonex/invites/updates/12.0.0_13.0.0/install/langs/en.xml
  5. 21 0
      modules/boonex/invites/updates/12.0.0_13.0.0/install/sql/enable.sql
  6. 131 0
      modules/boonex/invites/updates/12.0.0_13.0.0/source/classes/BxInvConfig.php
  7. 283 0
      modules/boonex/invites/updates/12.0.0_13.0.0/source/classes/BxInvGridInvites.php
  8. 319 0
      modules/boonex/invites/updates/12.0.0_13.0.0/source/classes/BxInvGridRequests.php
  9. 566 0
      modules/boonex/invites/updates/12.0.0_13.0.0/source/classes/BxInvModule.php
  10. 283 0
      modules/boonex/invites/updates/12.0.0_13.0.0/source/classes/BxInvTemplate.php
  11. 80 0
      modules/boonex/invites/updates/12.0.0_13.0.0/source/install/config.php
  12. 182 0
      modules/boonex/invites/updates/12.0.0_13.0.0/source/install/langs/en.xml
  13. 172 0
      modules/boonex/invites/updates/12.0.0_13.0.0/source/install/sql/enable.sql
  14. 19 0
      modules/boonex/invites/updates/12.0.0_13.0.0/source/template/popup_invite.html
  15. 51 0
      modules/boonex/market/updates/13.0.0_13.0.1/install/config.php
  16. 50 0
      modules/boonex/market/updates/13.0.0_13.0.1/install/installer.php
  17. 4 0
      modules/boonex/market/updates/13.0.0_13.0.1/install/langs/en.xml
  18. 18 0
      modules/boonex/market/updates/13.0.0_13.0.1/install/sql/enable.sql
  19. 11 0
      modules/boonex/market/updates/13.0.0_13.0.1/install/sql/install.sql
  20. 272 0
      modules/boonex/market/updates/13.0.0_13.0.1/source/classes/BxMarketConfig.php
  21. 708 0
      modules/boonex/market/updates/13.0.0_13.0.1/source/classes/BxMarketDb.php
  22. 150 0
      modules/boonex/market/updates/13.0.0_13.0.1/source/classes/BxMarketSearchResult.php
  23. 433 0
      modules/boonex/market/updates/13.0.0_13.0.1/source/classes/BxMarketTemplate.php
  24. 140 0
      modules/boonex/market/updates/13.0.0_13.0.1/source/install/config.php
  25. 474 0
      modules/boonex/market/updates/13.0.0_13.0.1/source/install/langs/en.xml
  26. 668 0
      modules/boonex/market/updates/13.0.0_13.0.1/source/install/sql/enable.sql
  27. 629 0
      modules/boonex/market/updates/13.0.0_13.0.1/source/install/sql/install.sql
  28. 21 0
      modules/boonex/market/updates/13.0.0_13.0.1/source/js/manage_tools.js
  29. 40 0
      modules/boonex/market/updates/13.0.0_13.0.1/source/template/attachments.html
  30. 40 0
      modules/boonex/market/updates/13.0.0_13.0.1/source/template/css/forms.css
  31. 1 0
      modules/boonex/market/updates/13.0.0_13.0.1/source/template/embed.html
  32. 51 0
      modules/boonex/massmailer/updates/12.0.1_13.0.0/install/config.php
  33. 13 0
      modules/boonex/massmailer/updates/12.0.1_13.0.0/install/installer.php
  34. 258 0
      modules/boonex/massmailer/updates/12.0.1_13.0.0/source/classes/BxMassMailerDb.php
  35. 212 0
      modules/boonex/massmailer/updates/12.0.1_13.0.0/source/classes/BxMassMailerGridCampaigns.php
  36. 675 0
      modules/boonex/massmailer/updates/12.0.1_13.0.0/source/classes/BxMassMailerModule.php
  37. 183 0
      modules/boonex/massmailer/updates/12.0.1_13.0.0/source/classes/BxMassMailerTemplate.php
  38. 77 0
      modules/boonex/massmailer/updates/12.0.1_13.0.0/source/install/config.php
  39. 10 0
      modules/boonex/massmailer/updates/12.0.1_13.0.0/source/template/subscribers_info.html
  40. 51 0
      modules/boonex/notifications/updates/13.0.0_13.0.1/install/config.php
  41. 13 0
      modules/boonex/notifications/updates/13.0.0_13.0.1/install/installer.php
  42. 13 0
      modules/boonex/notifications/updates/13.0.0_13.0.1/install/langs/en.xml
  43. 254 0
      modules/boonex/notifications/updates/13.0.0_13.0.1/source/classes/BxNtfsConfig.php
  44. 256 0
      modules/boonex/notifications/updates/13.0.0_13.0.1/source/classes/BxNtfsGridSettingsAdministration.php
  45. 94 0
      modules/boonex/notifications/updates/13.0.0_13.0.1/source/classes/BxNtfsMenuPreview.php
  46. 262 0
      modules/boonex/notifications/updates/13.0.0_13.0.1/source/classes/BxNtfsResponse.php
  47. 51 0
      modules/boonex/notifications/updates/13.0.0_13.0.1/source/classes/BxNtfsStudioPage.php
  48. 416 0
      modules/boonex/notifications/updates/13.0.0_13.0.1/source/classes/BxNtfsTemplate.php
  49. 82 0
      modules/boonex/notifications/updates/13.0.0_13.0.1/source/install/config.php
  50. 137 0
      modules/boonex/notifications/updates/13.0.0_13.0.1/source/install/langs/en.xml
  51. 51 0
      modules/boonex/oauth2/updates/13.0.0_13.0.1/install/config.php
  52. 23 0
      modules/boonex/oauth2/updates/13.0.0_13.0.1/install/installer.php
  53. 1 0
      modules/boonex/oauth2/updates/13.0.0_13.0.1/install/sql/install.sql
  54. 68 0
      modules/boonex/oauth2/updates/13.0.0_13.0.1/source/install/config.php
  55. 78 0
      modules/boonex/oauth2/updates/13.0.0_13.0.1/source/install/sql/install.sql
  56. 51 0
      modules/boonex/organizations/updates/13.0.0_13.0.1/install/config.php
  57. 44 0
      modules/boonex/organizations/updates/13.0.0_13.0.1/install/installer.php
  58. 8 0
      modules/boonex/organizations/updates/13.0.0_13.0.1/install/langs/en.xml
  59. 40 0
      modules/boonex/organizations/updates/13.0.0_13.0.1/install/sql/enable.sql
  60. 2 0
      modules/boonex/organizations/updates/13.0.0_13.0.1/install/sql/install.sql
  61. 311 0
      modules/boonex/organizations/updates/13.0.0_13.0.1/source/classes/BxOrgsConfig.php
  62. 26 0
      modules/boonex/organizations/updates/13.0.0_13.0.1/source/classes/BxOrgsFormEntry.php
  63. 150 0
      modules/boonex/organizations/updates/13.0.0_13.0.1/source/classes/BxOrgsModule.php
  64. 29 0
      modules/boonex/organizations/updates/13.0.0_13.0.1/source/classes/BxOrgsPrivacyNotifications.php
  65. 249 0
      modules/boonex/organizations/updates/13.0.0_13.0.1/source/classes/BxOrgsSearchResult.php
  66. 152 0
      modules/boonex/organizations/updates/13.0.0_13.0.1/source/install/config.php
  67. 569 0
      modules/boonex/organizations/updates/13.0.0_13.0.1/source/install/langs/en.xml
  68. 746 0
      modules/boonex/organizations/updates/13.0.0_13.0.1/source/install/sql/enable.sql
  69. 554 0
      modules/boonex/organizations/updates/13.0.0_13.0.1/source/install/sql/install.sql
  70. 51 0
      modules/boonex/payment/updates/13.0.0_13.0.1/install/config.php
  71. 23 0
      modules/boonex/payment/updates/13.0.0_13.0.1/install/installer.php
  72. 4 0
      modules/boonex/payment/updates/13.0.0_13.0.1/install/langs/en.xml
  73. 5 0
      modules/boonex/payment/updates/13.0.0_13.0.1/install/sql/install.sql
  74. 1707 0
      modules/boonex/payment/updates/13.0.0_13.0.1/source/classes/BxPaymentModule.php
  75. 239 0
      modules/boonex/payment/updates/13.0.0_13.0.1/source/classes/BxPaymentOrders.php
  76. 539 0
      modules/boonex/payment/updates/13.0.0_13.0.1/source/classes/BxPaymentProviderChargebee.php
  77. 410 0
      modules/boonex/payment/updates/13.0.0_13.0.1/source/classes/BxPaymentProviderChargebeeV3.php
  78. 783 0
      modules/boonex/payment/updates/13.0.0_13.0.1/source/classes/BxPaymentProviderPayPalApi.php
  79. 472 0
      modules/boonex/payment/updates/13.0.0_13.0.1/source/classes/BxPaymentProviderStripe.php
  80. 620 0
      modules/boonex/payment/updates/13.0.0_13.0.1/source/classes/BxPaymentProviderStripeBasic.php
  81. 610 0
      modules/boonex/payment/updates/13.0.0_13.0.1/source/classes/BxPaymentProviderStripeV3.php
  82. 527 0
      modules/boonex/payment/updates/13.0.0_13.0.1/source/classes/BxPaymentTemplate.php
  83. 70 0
      modules/boonex/payment/updates/13.0.0_13.0.1/source/install/config.php
  84. 768 0
      modules/boonex/payment/updates/13.0.0_13.0.1/source/install/langs/en.xml
  85. 692 0
      modules/boonex/payment/updates/13.0.0_13.0.1/source/install/sql/install.sql
  86. 182 0
      modules/boonex/payment/updates/13.0.0_13.0.1/source/js/chargebee_v3.js
  87. 2 0
      modules/boonex/payment/updates/13.0.0_13.0.1/source/template/cbee_v3_button_single.html
  88. 18 0
      modules/boonex/payment/updates/13.0.0_13.0.1/source/template/items.html
  89. 51 0
      modules/boonex/persons/updates/13.0.0_13.0.1/install/config.php
  90. 47 0
      modules/boonex/persons/updates/13.0.0_13.0.1/install/installer.php
  91. 16 0
      modules/boonex/persons/updates/13.0.0_13.0.1/install/langs/en.xml
  92. 36 0
      modules/boonex/persons/updates/13.0.0_13.0.1/install/sql/enable.sql
  93. 4 0
      modules/boonex/persons/updates/13.0.0_13.0.1/install/sql/install.sql
  94. 235 0
      modules/boonex/persons/updates/13.0.0_13.0.1/source/classes/BxPersonsConfig.php
  95. 80 0
      modules/boonex/persons/updates/13.0.0_13.0.1/source/classes/BxPersonsModule.php
  96. 211 0
      modules/boonex/persons/updates/13.0.0_13.0.1/source/classes/BxPersonsSearchResult.php
  97. 152 0
      modules/boonex/persons/updates/13.0.0_13.0.1/source/install/config.php
  98. 359 0
      modules/boonex/persons/updates/13.0.0_13.0.1/source/install/langs/en.xml
  99. 566 0
      modules/boonex/persons/updates/13.0.0_13.0.1/source/install/sql/enable.sql
  100. 416 0
      modules/boonex/persons/updates/13.0.0_13.0.1/source/install/sql/install.sql

+ 1 - 1
modules/boonex/invites/install/sql/enable.sql

@@ -97,7 +97,7 @@ INSERT INTO `sys_acl_matrix` (`IDLevel`, `IDAction`) VALUES
 (@iModerator, @iIdActionDeleteInvite),
 (@iAdministrator, @iIdActionDeleteInvite);
 
-INSERT INTO `sys_acl_matrix` (`IDLevel`, `IDAction`, `AllowedCOunt`) VALUES
+INSERT INTO `sys_acl_matrix` (`IDLevel`, `IDAction`, `AllowedCount`) VALUES
 -- invite
 (@iAccount, @iIdActionInvite, 5),
 (@iStandard, @iIdActionInvite, 5),

+ 51 - 0
modules/boonex/invites/updates/12.0.0_13.0.0/install/config.php

@@ -0,0 +1,51 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ */
+
+$aConfig = array(
+    /**
+     * Main Section.
+     */
+    'title' => 'Invitations',
+    'version_from' => '12.0.0',
+    'version_to' => '13.0.0',
+    'vendor' => 'BoonEx',
+
+    'compatible_with' => array(
+        '13.0.0-A3'
+    ),
+
+    /**
+     * 'home_dir' and 'home_uri' - should be unique. Don't use spaces in 'home_uri' and the other special chars.
+     */
+    'home_dir' => 'boonex/invites/updates/update_12.0.0_13.0.0/',
+    'home_uri' => 'invites_update_1200_1300',
+
+    'module_dir' => 'boonex/invites/',
+    'module_uri' => 'invites',
+
+    'db_prefix' => 'bx_inv_',
+    'class_prefix' => 'BxInv',
+
+    /**
+     * Installation/Uninstallation Section.
+     */
+    'install' => array(
+        'execute_sql' => 1,
+        'update_files' => 1,
+        'update_languages' => 1,
+        'clear_db_cache' => 1,
+    ),
+
+    /**
+     * Category for language keys.
+     */
+    'language_category' => 'Invitations',
+
+    /**
+     * Files Section
+     */
+    'delete_files' => array(),
+);

+ 13 - 0
modules/boonex/invites/updates/12.0.0_13.0.0/install/installer.php

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

+ 4 - 0
modules/boonex/invites/updates/12.0.0_13.0.0/install/langs/en.xml

@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources name="en" flag="gb" title="English">
+    <string_del name="_bx_invites_option_count_per_user"><![CDATA[How many invitations one user can send]]></string_del>
+</resources>

+ 21 - 0
modules/boonex/invites/updates/12.0.0_13.0.0/install/sql/enable.sql

@@ -0,0 +1,21 @@
+SET @sName = 'bx_invites';
+
+
+-- SETTINGS
+DELETE FROM `sys_options` WHERE `name`='bx_invites_count_per_user';
+
+
+-- ACL
+SET @iIdActionInvite = (SELECT `ID` FROM `sys_acl_actions` WHERE `Module`=@sName AND `Name`='invite' LIMIT 1);
+
+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;
+
+UPDATE `sys_acl_matrix` SET `AllowedCount`='5' WHERE `IDLevel` IN (@iAccount, @iStandard, @iUnconfirmed, @iPending, @iSuspended, @iModerator, @iAdministrator, @iPremium) AND `IDAction`=@iIdActionInvite;

+ 131 - 0
modules/boonex/invites/updates/12.0.0_13.0.0/source/classes/BxInvConfig.php

@@ -0,0 +1,131 @@
+<?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
+ *
+ * @{
+ */
+
+class BxInvConfig extends BxBaseModGeneralConfig
+{
+    protected $_oDb;
+
+    protected $_iCountPerUser;
+    protected $_sKeyCode;
+    protected $_iKeyLifetime;
+    protected $_bRequestInvite;
+    protected $_sRequestsEmail;
+    protected $_bRegistrationByInvitation;
+
+    /**
+     * Constructor
+     */
+    public function __construct($aModule)
+    {
+        parent::__construct($aModule);
+
+        $this->CNF = array (
+            'URL_INVITE' => 'page.php?i=invites-invite',
+            'URL_REQUEST' => 'page.php?i=invites-request',
+            'URL_REQUESTS' => 'page.php?i=invites-requests',
+            'URL_INVITES' => 'page.php?i=invites-invites',
+            
+            'TABLE_REQUESTS' => $aModule['db_prefix'] . 'requests',
+            'TABLE_INVITES' => $aModule['db_prefix'] . 'invites',
+            'TABLE_ENTRIES' => $aModule['db_prefix'] . 'invites',
+            
+            'FIELD_ADDED' => 'date'
+        );
+
+        $this->_aObjects = array(
+            'alert' => $this->_sName,
+            'grid_requests' => $this->_sName . '_requests',
+            'grid_invites' => $this->_sName . '_invites',
+            'form_invite' => $this->_sName . '_invite',
+            'form_request' => $this->_sName . '_request',
+            'form_display_invite_send' => $this->_sName . '_invite_send',
+            'form_display_request_send' => $this->_sName . '_request_send',
+        );
+
+        $this->_aPrefixes = array(
+            'style' => 'bx-inv',
+            'option' => 'bx_invites_',
+        );
+
+        $this->_iCountPerUser = 0;
+        $this->_sKeyCode = 'icode';
+        $this->_iKeyLifetime = 86400;
+        $this->_bRequestInvite = true;
+        $this->_sRequestsEmail = '';
+        $this->_bRegistrationByInvitation = true;
+
+        $this->_aJsClasses = array(
+            'main' => 'BxInvMain',
+        );
+        $this->_aJsObjects = array(
+            'main' => 'oInvMain',
+        );
+
+        $sHtmlPrefix = str_replace('_', '-', $this->_sName);
+        $this->_aHtmlIds = array(
+            'link_popup' => $sHtmlPrefix . '-link-popup',
+            'link_input' => $sHtmlPrefix . '-link-input',
+        );
+    }
+
+    public function init(&$oDb)
+    {
+        $this->_oDb = &$oDb;
+
+        $sOptionPrefix = $this->getPrefix('option');
+
+        $this->_iCountPerUser = (int)getParam($sOptionPrefix . 'count_per_user');
+        $this->_iKeyLifetime = 86400 * (int)getParam($sOptionPrefix . 'key_lifetime');
+        $this->_bRequestInvite = getParam($sOptionPrefix . 'enable_request_invite') == 'on';
+        $this->_sRequestsEmail = getParam($sOptionPrefix . 'requests_email');
+        $this->_bRegistrationByInvitation = getParam($sOptionPrefix . 'enable_reg_by_inv') == 'on';
+    }
+
+    public function getCountPerUser()
+    {
+        return getActionNumberLeftModule(bx_get_logged_profile_id(), 'invite', $this->_sName);
+    }
+
+    public function getKeyCode()
+    {
+        return $this->_sKeyCode;
+    }
+
+    public function getKeyLifetime()
+    {
+        return $this->_iKeyLifetime;
+    }
+
+    public function isRequestInvite()
+    {
+        return $this->_bRequestInvite;
+    }
+
+    public function getRequestsEmail()
+    {
+        return $this->_sRequestsEmail;
+    }
+
+    public function isRegistrationByInvitation()
+    {
+        return $this->_bRegistrationByInvitation;
+    }
+
+    public function getHtmlIds($sKey = '')
+    {
+        if(empty($sKey))
+            return $this->_aHtmlIds;
+
+        return isset($this->_aHtmlIds[$sKey]) ? $this->_aHtmlIds[$sKey] : '';
+    }
+}
+
+/** @} */

+ 283 - 0
modules/boonex/invites/updates/12.0.0_13.0.0/source/classes/BxInvGridInvites.php

@@ -0,0 +1,283 @@
+<?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
+ * 
+ * @{
+ */
+define('BX_INV_FILTER_STATUS_ACCEPTED', 1);
+define('BX_INV_FILTER_STATUS_NOT_ACCEPTED', 2);
+
+class BxInvGridInvites extends BxTemplGrid
+{
+    protected $_sModule;
+    protected $_oModule;
+
+    protected $_sFilter1Name;
+    protected $_sFilter1Value;
+    protected $_aFilter1Values;
+    protected $_sParamsDivider;
+    
+    public function __construct ($aOptions, $oTemplate = false)
+    {
+        parent::__construct ($aOptions, $oTemplate);
+
+        $this->_sModule = 'bx_invites';
+        $this->_oModule = BxDolModule::getInstance($this->_sModule);
+       
+        $this->_sFilter1Name = 'filter1';
+        $this->_aFilter1Values = array(
+            '' => _t('_bx_invites_invites_status_for_filter_all'),
+            BX_INV_FILTER_STATUS_ACCEPTED => _t('_bx_invites_invites_status_for_filter_accepted'),
+            BX_INV_FILTER_STATUS_NOT_ACCEPTED => _t('_bx_invites_invites_status_for_filter_not_accepted'),
+        );
+        
+        $sFilter1 = bx_get($this->_sFilter1Name);
+        if(!empty($sFilter1)) {
+            $this->_sFilter1Value = bx_process_input($sFilter1);
+            $this->_aQueryAppend['filter1'] = $this->_sFilter1Value;
+        }
+        $this->_sParamsDivider = '#-#';
+    }
+    
+    protected function _getDataSql($sFilter, $sOrderField, $sOrderDir, $iStart, $iPerPage)
+    {
+        $CNF = $this->_oModule->_oConfig->CNF;
+        $sTableInvites = $CNF['TABLE_INVITES'];
+        
+        if(strpos($sFilter, $this->_sParamsDivider) !== false)
+            list($this->_sFilter1Value, $sFilter) = explode($this->_sParamsDivider, $sFilter);
+        
+        $sFilterSql = "";
+        if(isset($this->_sFilter1Value) && $this->_sFilter1Value != ''){
+            if ($this->_sFilter1Value == BX_INV_FILTER_STATUS_ACCEPTED){
+                $sFilterSql = " AND " . $sTableInvites . ".`joined_account_id` IS NOT NULL";
+            }
+            else{
+                $sFilterSql = " AND " . $sTableInvites . ".`joined_account_id` IS NULL";
+            }
+        }
+        $this->_aOptions['source'] .= $this->_oModule->_oDb->prepareAsString($sFilterSql);
+        return parent::_getDataSql($sFilter, $sOrderField, $sOrderDir, $iStart, $iPerPage);
+    }
+    
+    public function performActionAdd()
+    {
+        $sAction = 'add';
+        $oForm = $this->_oModule->getFormObjectInvite();
+        if (!$oForm)
+            return '';
+
+        $oForm->aInputs['text']['value'] = _t('_bx_invites_msg_invitation');
+        $oForm->aFormAttrs['action'] = BX_DOL_URL_ROOT . 'grid.php?' . bx_encode_url_params($_GET, array('ids', '_r'));
+        $oForm->initChecker();
+        
+        if($oForm->isSubmittedAndValid()) {
+            $sResult = $this->_oModule->processFormObjectInvite($oForm);
+            $aRes = array('msg' => $sResult);
+            echoJson($aRes);
+        }
+        else {
+            $sContent = BxTemplFunctions::getInstance()->popupBox('_bx_invites_form_invite', _t('_bx_invites_form_invite'), $this->_oModule->_oTemplate->parseHtmlByName('popup_invite.html', array(
+                'form_id' => $oForm->id,
+                'form' => $oForm->getCode(true),
+                'object' => $this->_sObject,
+                'action' => $sAction
+            )));
+            echoJson(array('popup' => array('html' => $sContent, 'options' => array('closeOnOuterClick' => true))));
+        }
+    }
+    
+    public function performActionDelete($aParams = array())
+    {
+        $iProfileId = $this->_oModule->getProfileId();
+
+        $mixedAllowed = $this->_oModule->isAllowedDeleteInvite($iProfileId);
+        if($mixedAllowed !== true) {
+            echoJson(array('msg' => $mixedAllowed));
+            exit;
+        }
+
+        $iAffected = 0;
+        $aIds = bx_get('ids');
+        if(!$aIds || !is_array($aIds)) {
+            echoJson(array());
+            exit;
+        }
+
+        $aIdsAffected = array ();
+        foreach($aIds as $iId) {
+            if(!$this->_oModule->_oDb->deleteInvites(array('id' => $iId)))
+                continue;
+
+            $this->_oModule->isAllowedDeleteInvite($iProfileId, true);
+
+            $aIdsAffected[] = $iId;
+            $iAffected++;
+        }
+
+        echoJson($iAffected ? array('grid' => $this->getCode(false), 'blink' => $aIdsAffected) : array('msg' => _t('_bx_invites_err_delete_invite')));
+    }
+    
+    protected function _getFilterControls ()
+    {
+        parent::_getFilterControls();
+        return  $this->_getFilterSelectOne($this->_sFilter1Name, $this->_sFilter1Value, $this->_aFilter1Values) . $this->_getSearchInput();
+    }
+    
+    protected function _getSearchInput()
+    {
+        $sJsObject = $this->_oModule->_oConfig->getJsObject('main');
+        $aInputSearch = array(
+            'type' => 'text',
+            'name' => 'search',
+            'attrs' => array(
+                'id' => 'bx-grid-search-' . $this->_sObject,
+                'onKeyup' => 'javascript:$(this).off(\'keyup focusout\'); ' . $sJsObject . '.onChangeFilter(this)',
+                'onBlur' => 'javascript:' . $sJsObject . '.onChangeFilter(this)',
+            )
+        );
+
+        $oForm = new BxTemplFormView(array());
+        return $oForm->genRow($aInputSearch);
+    }
+    
+    protected function _getFilterSelectOne($sFilterName, $sFilterValue, $aFilterValues)
+    {
+        if(empty($sFilterName) || empty($aFilterValues))
+            return '';
+
+        $CNF = &$this->_oModule->_oConfig->CNF;
+        $sJsObject = $this->_oModule->_oConfig->getJsObject('main');
+
+        foreach($aFilterValues as $sKey => $sValue)
+            $aFilterValues[$sKey] = _t($sValue);
+
+        $aInputModules = array(
+            'type' => 'select',
+            'name' => $sFilterName,
+            'attrs' => array(
+                'id' => 'bx-grid-' . $sFilterName . '-' . $this->_sObject,
+                'onChange' => 'javascript:' . $sJsObject . '.onChangeFilter(this)'
+            ),
+            'value' => $sFilterValue,
+            'values' => $aFilterValues
+        );
+
+        $oForm = new BxTemplFormView(array());
+        return $oForm->genRow($aInputModules);
+    }
+    
+    protected function _getCellDate($mixedValue, $sKey, $aField, $aRow)
+    {
+        return parent::_getCellDefault(bx_time_js($mixedValue), $sKey, $aField, $aRow);
+    }
+    
+    protected function _getCellDateSeen($mixedValue, $sKey, $aField, $aRow)
+    {
+        if ($mixedValue == 'undefined')
+            return parent::_getCellDefault('', $sKey, $aField, $aRow);
+        return parent::_getCellDefault(bx_time_js($mixedValue), $sKey, $aField, $aRow);
+    }
+    
+    protected function _getCellDateJoined($mixedValue, $sKey, $aField, $aRow)
+    {
+        if ($mixedValue == 'undefined')
+            return parent::_getCellDefault('', $sKey, $aField, $aRow);
+        return parent::_getCellDefault(bx_time_js($mixedValue), $sKey, $aField, $aRow);
+    }
+    
+    protected function _getCellWhoSend($mixedValue, $sKey, $aField, $aRow)
+    {
+        $oProfile = BxDolProfile::getInstanceMagic($aRow['profile_id']);
+        if ($oProfile)
+            return $this->_getProfileCell($oProfile, $sKey, $aField, $aRow);
+       
+        return parent::_getCellDefault('', $sKey, $aField, $aRow);
+    }
+    
+    protected function _getCellJoinedAccount($mixedValue, $sKey, $aField, $aRow)
+    {
+        if ($aRow['joined_account_id'] == '')
+            return parent::_getCellDefault('', $sKey, $aField, $aRow);
+        
+        $oProfile = BxDolProfile::getInstanceAccountProfile($aRow['joined_account_id']);
+        if ($oProfile)
+            return $this->_getProfileCell($oProfile, $sKey, $aField, $aRow);
+        
+        return parent::_getCellDefault('', $sKey, $aField, $aRow);
+    }
+    
+    protected function _getCellRequest($mixedValue, $sKey, $aField, $aRow)
+    {
+        if ($aRow['request_id'] == '')
+            return parent::_getCellDefault('', $sKey, $aField, $aRow);
+        
+        $aRequest = $this->_oModule->_oDb->getRequests(array('type' => 'by_id', 'value' => $aRow['request_id']));
+        if ($aRequest || true){
+            $CNF = &$this->_oModule->_oConfig->CNF;
+            $sLink = BX_DOL_URL_ROOT . BxDolPermalinks::getInstance()->permalink($CNF['URL_REQUESTS']);
+            $sLink = bx_append_url_params($sLink, array('filter' => $aRequest['email']));
+            $sAddon = $this->_oTemplate->parseHtmlByName('account_link.html', array(
+                    'href' => $sLink,
+                    'title' => _t('_bx_invites_grid_txt_view_request'),
+                    'content' => _t('_bx_invites_grid_txt_view_request'),
+                    'class' => ''
+            ));
+            return parent::_getCellDefault($sAddon, $sKey, $aField, $aRow);
+        }
+        return parent::_getCellDefault('', $sKey, $aField, $aRow);
+    }
+    
+    protected function _getProfileCell($oProfile, $sKey, $aField, $aRow)
+    {
+    	$sProfile = $oProfile->getDisplayName();
+
+        $oAcl = BxDolAcl::getInstance();
+
+    	$sAccountEmail = '';
+    	$sManageAccountUrl = '';
+    	if($oProfile && $oProfile instanceof BxDolProfile && $oAcl->isMemberLevelInSet(128)) {
+            $sAccountEmail = $oProfile->getAccountObject()->getEmail();
+            $sManageAccountUrl = $this->_getManageAccountUrl($sAccountEmail);
+    	}
+
+        $sAddon = '';
+        if(!empty($sManageAccountUrl))
+            $sAddon = $this->_oTemplate->parseHtmlByName('account_link.html', array(
+                'href' => $sManageAccountUrl,
+                'title' => _t('_bx_invites_grid_txt_account_manager'),
+                'content' => $sAccountEmail,
+                'class' => 'bx-def-font-grayed'
+            ));
+
+        $mixedValue = $oProfile->getUnit(0, array('template' => array('vars' => array('addon' => $sAddon))));
+
+        return parent::_getCellDefault($mixedValue, $sKey, $aField, $aRow);
+    }
+    
+    protected function _getManageAccountUrl($sFilter = '')
+    {
+    	$sModuleAccounts = 'bx_accounts';
+    	if(!BxDolModuleQuery::getInstance()->isEnabledByName($sModuleAccounts))
+    		return '';
+
+		$oModuleAccounts = BxDolModule::getInstance($sModuleAccounts);
+		if(!$oModuleAccounts || empty($oModuleAccounts->_oConfig->CNF['URL_MANAGE_ADMINISTRATION']))
+			return 'cccc';
+
+		$sLink = $oModuleAccounts->_oConfig->CNF['URL_MANAGE_ADMINISTRATION'];
+
+		$sLink = BX_DOL_URL_ROOT . BxDolPermalinks::getInstance()->permalink($sLink);
+		
+		if(!empty($sFilter))
+			$sLink = bx_append_url_params($sLink, array('filter' => $sFilter));
+
+		return $sLink;
+    }
+}
+
+/** @} */

+ 319 - 0
modules/boonex/invites/updates/12.0.0_13.0.0/source/classes/BxInvGridRequests.php

@@ -0,0 +1,319 @@
+<?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
+ * 
+ * @{
+ */
+
+define('BX_INV_FILTER_STATUS_NEW', 0);
+define('BX_INV_FILTER_STATUS_INVITED', 1);
+define('BX_INV_FILTER_STATUS_SEEN', 2);
+define('BX_INV_FILTER_STATUS_JOINED', 3);
+
+class BxInvGridRequests extends BxTemplGrid
+{
+    protected $_sModule;
+    protected $_oModule;
+
+    protected $_sFilter1Name;
+    protected $_sFilter1Value;
+    protected $_aFilter1Values;
+    protected $_sParamsDivider;
+    
+    public function __construct ($aOptions, $oTemplate = false)
+    {
+        parent::__construct ($aOptions, $oTemplate);
+
+        $this->_aQueryReset = array('order_field', 'order_dir', $this->_aOptions['paginate_get_start'], $this->_aOptions['paginate_get_per_page']);
+        
+        $this->_sModule = 'bx_invites';
+        $this->_oModule = BxDolModule::getInstance($this->_sModule);
+        
+        $this->_sFilter1Name = 'filter1';
+        $this->_aFilter1Values = array(
+            '' => _t('_bx_invites_request_status_for_filter_all'),
+            BX_INV_FILTER_STATUS_NEW => _t('_bx_invites_request_status_for_filter_new'),
+            BX_INV_FILTER_STATUS_INVITED => _t('_bx_invites_request_status_for_filter_invited'),
+            BX_INV_FILTER_STATUS_SEEN => _t('_bx_invites_request_status_for_filter_seen'),
+            BX_INV_FILTER_STATUS_JOINED => _t('_bx_invites_request_status_for_filter_joined')
+        );
+        
+        $sFilter1 = bx_get($this->_sFilter1Name);
+        if(!empty($sFilter1)) {
+            $this->_sFilter1Value = bx_process_input($sFilter1);
+            $this->_aQueryAppend['filter1'] = $this->_sFilter1Value;
+        }
+        $this->_sParamsDivider = '#-#';
+    }
+    
+    protected function _getDataSql($sFilter, $sOrderField, $sOrderDir, $iStart, $iPerPage)
+    {
+        $CNF = $this->_oModule->_oConfig->CNF;
+        $sTableRequests = $CNF['TABLE_REQUESTS'];
+        
+        if(strpos($sFilter, $this->_sParamsDivider) !== false)
+            list($this->_sFilter1Value, $sFilter) = explode($this->_sParamsDivider, $sFilter);
+       
+        $sFilterSql = "";
+        if(isset($this->_sFilter1Value) && $this->_sFilter1Value != ''){
+            if ($this->_sFilter1Value == BX_INV_FILTER_STATUS_INVITED){
+                $sFilterSql = " AND " . $sTableRequests . ".`status` IN (" . BX_INV_FILTER_STATUS_INVITED . ', ' . BX_INV_FILTER_STATUS_SEEN . ', ' . BX_INV_FILTER_STATUS_JOINED . ')';
+            }
+            else{
+                $sFilterSql = " AND " . $sTableRequests . ".`status` = " . $this->_sFilter1Value;
+            }
+        }
+        $this->_aOptions['source'] .= $this->_oModule->_oDb->prepareAsString($sFilterSql);
+        return parent::_getDataSql($sFilter, $sOrderField, $sOrderDir, $iStart, $iPerPage);
+    }
+    
+    protected function _getDataSqlOrderClause ($sOrderByFilter, $sOrderField, $sOrderDir, $bFieldsOnly = false)
+    {
+        return " ORDER BY `status` ASC, `date` DESC";
+    }
+    
+    public function performActionAdd()
+    {
+        $sAction = 'add';
+        $oForm = $this->_oModule->getFormObjectInvite();
+        if (!$oForm)
+            return '';
+
+        $oForm->aInputs['text']['value'] = _t('_bx_invites_msg_invitation');
+        $oForm->aFormAttrs['action'] = BX_DOL_URL_ROOT . 'grid.php?' . bx_encode_url_params($_GET, array('ids', '_r'));
+        $oForm->initChecker();
+
+        if($oForm->isSubmittedAndValid()) {
+            $sResult = $this->_oModule->processFormObjectInvite($oForm);
+            $aRes = array('msg' => $sResult);
+            echoJson($aRes);
+        }
+        else {
+            $sContent = BxTemplFunctions::getInstance()->popupBox('_bx_invites_form_invite', _t('_bx_invites_form_invite'), $this->_oModule->_oTemplate->parseHtmlByName('popup_invite.html', array(
+                'form_id' => $oForm->id,
+                'form' => $oForm->getCode(true),
+                'object' => $this->_sObject,
+                'action' => $sAction
+            )));
+            echoJson(array('popup' => array('html' => $sContent, 'options' => array('closeOnOuterClick' => true))));
+        }
+    }
+    
+    public function performActionInfo()
+    {
+        $aIds = bx_get('ids');
+        if(!$aIds || !is_array($aIds)) {
+            echoJson(array());
+            exit;
+        }
+
+        $aRequest = $this->_oModule->_oDb->getRequests(array('type' => 'by_id', 'value' => (int)array_shift($aIds)));
+        if(empty($aRequest) || !is_array($aRequest)){
+            echoJson(array());
+            exit;
+        }
+
+        $sContent = BxTemplFunctions::getInstance()->transBox('bx-invites-info-popup', $this->_oModule->_oTemplate->getBlockRequestText($aRequest));
+
+        echoJson(array('popup' => array('html' => $sContent)));
+    }
+    
+    public function performActionInviteInfo()
+    {
+        $aIds = bx_get('ids');
+        if(!$aIds || !is_array($aIds)) {
+            echoJson(array());
+            exit;
+        }
+
+        $aRequest = $this->_oModule->_oDb->getInvites(array('type' => 'all', 'value' => (int)array_shift($aIds)));
+        if(empty($aRequest) || !is_array($aRequest)){
+            echoJson(array());
+            exit;
+        }
+
+        $sContent = BxTemplFunctions::getInstance()->transBox('bx-invites-info-popup', $this->_oModule->_oTemplate->getBlockInviteInfo($aRequest));
+
+        echoJson(array('popup' => array('html' => $sContent)));
+    }
+    
+    public function performActionInvite($aParams = array())
+    {
+        $iProfileId = $this->_oModule->getProfileId();
+
+        $mixedAllowed = $this->_oModule->isAllowedInvite($iProfileId);
+        if($mixedAllowed !== true) {
+            echoJson(array('msg' => $mixedAllowed));
+            exit;
+        }
+
+        $iAffected = 0;
+        $aIds = bx_get('ids');
+        if(!$aIds || !is_array($aIds)) {
+            echoJson(array());
+            exit;
+        }
+
+        $sText = _t('_bx_invites_msg_invitation');
+
+        $aIdsAffected = array ();
+        foreach($aIds as $iId) {
+            $aRequest = $this->_oModule->_oDb->getRequests(array('type' => 'by_id', 'value' => $iId));
+            if(empty($aRequest) || !is_array($aRequest))
+                continue;
+            
+            $iInviteId = -1;
+            $mixedResult = $this->_oModule->invite(BX_INV_TYPE_FROM_SYSTEM, $aRequest['email'], $sText);
+            if(empty($mixedResult) || !is_array($mixedResult))
+                continue;
+
+            $iInviteId = (int)array_shift($mixedResult);
+            $this->_oModule->onInvite($iProfileId);
+            $this->_oModule->_oDb->attachInviteToRequest($iId, $iInviteId);
+            $aIdsAffected[] = $iId;
+            $iAffected++;
+        }
+
+        echoJson($iAffected ? array('grid' => $this->getCode(false), 'blink' => $aIdsAffected, 'msg' => _t('_bx_invites_msg_invitation_sent', $iAffected)) : array('msg' => _t('_bx_invites_err_invite')));
+    }
+    
+    public function performActionDelete($aParams = array())
+    {
+        $iProfileId = $this->_oModule->getProfileId();
+
+        $mixedAllowed = $this->_oModule->isAllowedDeleteRequest($iProfileId);
+        if($mixedAllowed !== true) {
+            echoJson(array('msg' => $mixedAllowed));
+            exit;
+        }
+
+        $iAffected = 0;
+        $aIds = bx_get('ids');
+        if(!$aIds || !is_array($aIds)) {
+            echoJson(array());
+            exit;
+        }
+
+        $oForm = BxDolForm::getObjectInstance($this->_oModule->_oConfig->getObject('form_request'), $this->_oModule->_oConfig->getObject('form_display_request_send'));
+
+        $aIdsAffected = array ();
+        foreach($aIds as $iId) {
+            if(!$oForm->delete($iId))
+                continue;
+
+            $this->_oModule->isAllowedDeleteRequest($iProfileId, true);
+
+            $aIdsAffected[] = $iId;
+            $iAffected++;
+        }
+
+        echoJson($iAffected ? array('grid' => $this->getCode(false), 'blink' => $aIdsAffected) : array('msg' => _t('_bx_invites_err_delete_request')));
+    }
+    
+    protected function _getFilterControls ()
+    {
+        parent::_getFilterControls();
+        return  $this->_getFilterSelectOne($this->_sFilter1Name, $this->_sFilter1Value, $this->_aFilter1Values) . $this->_getSearchInput();
+    }
+    
+    protected function _getSearchInput()
+    {
+        $sJsObject = $this->_oModule->_oConfig->getJsObject('main');
+        $aInputSearch = array(
+            'type' => 'text',
+            'name' => 'search',
+            'attrs' => array(
+                'id' => 'bx-grid-search-' . $this->_sObject,
+                'onKeyup' => 'javascript:$(this).off(\'keyup focusout\'); ' . $sJsObject . '.onChangeFilter(this)',
+                'onBlur' => 'javascript:' . $sJsObject . '.onChangeFilter(this)',
+            )
+        );
+
+        $oForm = new BxTemplFormView(array());
+        return $oForm->genRow($aInputSearch);
+    }
+    
+    protected function _getFilterSelectOne($sFilterName, $sFilterValue, $aFilterValues)
+    {
+        if(empty($sFilterName) || empty($aFilterValues))
+            return '';
+
+        $CNF = &$this->_oModule->_oConfig->CNF;
+        $sJsObject = $this->_oModule->_oConfig->getJsObject('main');
+
+        foreach($aFilterValues as $sKey => $sValue)
+            $aFilterValues[$sKey] = _t($sValue);
+
+        $aInputModules = array(
+            'type' => 'select',
+            'name' => $sFilterName,
+            'attrs' => array(
+                'id' => 'bx-grid-' . $sFilterName . '-' . $this->_sObject,
+                'onChange' => 'javascript:' . $sJsObject . '.onChangeFilter(this)'
+            ),
+            'value' => $sFilterValue,
+            'values' => $aFilterValues
+        );
+
+        $oForm = new BxTemplFormView(array());
+        return $oForm->genRow($aInputModules);
+    }
+
+    protected function _getCellNip($mixedValue, $sKey, $aField, $aRow)
+    {
+        return parent::_getCellDefault(long2ip($mixedValue), $sKey, $aField, $aRow);
+    }
+
+    protected function _getCellDate($mixedValue, $sKey, $aField, $aRow)
+    {
+        return parent::_getCellDefault(bx_time_js($mixedValue), $sKey, $aField, $aRow);
+    }
+    
+    protected function _getCellStatus($mixedValue, $sKey, $aField, $aRow)
+    {
+        $sStatus = _t('_bx_invites_request_status_new');
+        switch ($mixedValue) {
+            case 1:
+            case 2:
+                $sLinkHtml = $this->_oTemplate->parseLink('javascript:void(0)', $this->_oModule->_oDb->getInvites(array('type' => 'count_by_request', 'value' => $aRow['id'])), array(
+                    'title' => _t('_bx_invites_grid_action_title_adm_invite_info'),
+                    'bx_grid_action_single' => 'invite_info',
+                    'bx_grid_action_data' => $aRow['id']
+                ));
+                $sStatus = ($mixedValue == 1 ? _t('_bx_invites_request_status_invited') : _t('_bx_invites_request_status_seen')) . ' (' . $sLinkHtml . ')';
+                break;
+            case 3:
+                $sStatus = _t('_bx_invites_request_status_joined') . ' (' . bx_time_js($this->_oModule->_oDb->getInvites(array('type' => 'date_joined_by_request', 'value' => $aRow['id']))) . ')';
+                break;
+        }
+        return parent::_getCellDefault($sStatus, $sKey, $aField, $aRow);
+    }
+    
+    protected function _getCellJoinedAccount($mixedValue, $sKey, $aField, $aRow)
+    {
+        $sAccountInfo = "";
+        if(isset($aRow["status"]) && $aRow["status"] == 3){
+            $sAccountInfo = $this->_oModule->_oTemplate->getProfilesByAccount($this->_oModule->_oDb->getInvites(array('type' => 'account_by_request', 'value' => $aRow['id'])));
+        }
+        return parent::_getCellDefault($sAccountInfo, $sKey, $aField, $aRow);
+    }
+    
+    protected function _getActionInvite($sType, $sKey, $a, $isSmall = false, $isDisabled = false, $aRow = array())
+    {
+        if(isset($aRow["status"]) && $aRow["status"] == 3)
+            return '';
+        return parent::_getActionDefault ($sType, $sKey, $a, $isSmall, $isDisabled, $aRow);
+    }
+    
+    protected function _getActionInviteInfo ($sType, $sKey, $a, $isSmall = false, $isDisabled = false, $aRow = array())
+    {
+        return '';
+    }
+    
+}
+
+/** @} */

+ 566 - 0
modules/boonex/invites/updates/12.0.0_13.0.0/source/classes/BxInvModule.php

@@ -0,0 +1,566 @@
+<?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)) {
+            if($this->_oConfig->getCountPerUser() <= 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()
+        ));
+        $this->onInvite($iProfileId);
+
+        echoJson(array('popup' => $this->_oTemplate->getLinkPopup(
+            $this->getJoinLink($sKey)
+        )));
+    }
+    
+    public function actionSetSeenMark($Code)
+    {
+        header('Content-Type: image/png');
+        if (isset($Code) && trim($Code) != "")
+            $this->_oDb->updateDateSeenForInvite($Code);
+    }
+
+    /**
+     * SERVICE METHODS
+     */
+    
+    public function serviceGetSafeServices()
+    {
+        return array (
+            'GetBlockInvite' => '',
+            'GetBlockFormInvite' => '',
+            'GetBlockFormRequest' => '',
+        );
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_invites Invitations
+     * @subsection bx_invites-other Other
+     * @subsubsection bx_invites-get_include get_include
+     * 
+     * @code bx_srv('bx_invites', 'get_include', [...]); @endcode
+     * 
+     * Get all necessary CSS and JS files to include in a page.
+     *
+     * @return string with all necessary CSS and JS files.
+     * 
+     * @see BxInvModule::serviceGetInclude
+     */
+    /** 
+     * @ref bx_invites-get_include "get_include"
+     */
+    public function serviceGetInclude()
+    {
+        return $this->_oTemplate->getInclude();
+    }
+
+    /**
+     * @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 '';
+
+        if(!isAdmin($iAccountId) && $this->_oConfig->getCountPerUser() <= 0)
+            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()
+    {
+        $oForm = $this->getFormObjectInvite();
+        $oForm->aInputs['text']['value'] = _t('_bx_invites_msg_invitation');
+
+        $sResult = '';
+        $oForm->initChecker();
+        if($oForm->isSubmittedAndValid()) {
+            
+            $sResult = $this->processFormObjectInvite($oForm);
+            $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()
+    {
+        $mixedResult = $this->_oTemplate->getBlockFormRequest();
+        if(is_array($mixedResult)) {
+            echoJson($mixedResult);
+            exit;
+        }
+
+        return array(
+            'content' => $mixedResult
+        );
+    }
+
+    /**
+     * @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()
+    {
+        return $this->getBlockManage('requests');
+    }
+    
+    /**
+     * @page service Service Calls
+     * @section bx_invites Invitations
+     * @subsection bx_invites-page_blocks Page Blocks
+     * @subsubsection bx_invites-get_block_manage_invites get_block_manage_requests
+     * 
+     * @code bx_srv('bx_invites', 'get_block_manage_invites', [...]); @endcode
+     * 
+     * Get page block with manage invitations 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::serviceGetBlockManageInvites
+     */
+    /** 
+     * @ref bx_invites-get_block_manage_invites "get_block_manage_invites"
+     */
+    public function serviceGetBlockManageInvites()
+    {
+        return $this->getBlockManage('invites');
+    }
+
+    /**
+     * @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 array('counter3_value' => $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 = '';
+
+        $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'));
+        
+        if ($this->_oConfig->isRegistrationByInvitation())
+            $sReturn .= $this->_oTemplate->getBlockRequest();
+
+        return $sReturn;
+    }
+    
+    /**
+     * Data for Notifications module
+     */
+    public function serviceGetNotificationsData()
+    {
+    	$sModule = $this->_aModule['name'];
+
+    	$sEventPrivacy = $sModule . '_allow_view_event_to';
+		if(BxDolPrivacy::getObjectInstance($sEventPrivacy) === false)
+			$sEventPrivacy = '';
+
+        return array(
+            'handlers' => array(
+                array('group' => $sModule . '_object', 'type' => 'insert', 'alert_unit' => $sModule, 'alert_action' => 'request_notify', 'module_name' => $sModule, 'module_method' => 'get_notifications_request', 'module_class' => 'Module', 'module_event_privacy' => $sEventPrivacy),
+            ),
+            'settings' => array(
+                array('group' => 'request', 'unit' => $sModule, 'action' => 'request_notify', 'types' => array('personal')),
+            ),
+            'alerts' => array(
+                array('unit' => $sModule, 'action' => 'request_notify'),
+            )
+        );
+    }
+    
+    /**
+     * Entry post for Notifications module
+     */
+    public function serviceGetNotificationsRequest($aEvent)
+    {  
+        if (getParam('bx_invites_requests_notifications') != 'on')
+             return array();
+        
+        $aRequest = $this->_oDb->getRequests(array('type' => 'by_id', 'value' => $aEvent['object_id']));
+        if (!$aRequest)
+            return array();
+           
+        $CNF = &$this->_oConfig->CNF;
+        $sEntryUrl = BX_DOL_URL_ROOT . BxDolPermalinks::getInstance()->permalink($CNF['URL_REQUESTS']);
+            
+		return array(
+			'entry_sample' => $aRequest['name'] . '(' . $aRequest['email'] . ')',
+			'entry_url' => $sEntryUrl,
+			'entry_caption' => $aRequest['text'],
+			'entry_author' => '',
+			'entry_privacy' => '', //may be empty or not specified. In this case Public privacy will be used.
+			'lang_key' => '_bx_invites_alert_action_request', //may be empty or not specified. In this case the default one from Notification module will be used.
+		);
+    }
+    
+    
+    public function attachAccountIdToInvite($iAccountId, $sKey)
+    {
+        $this->_oDb->attachAccountIdToInvite($iAccountId, $sKey);
+    }
+    
+    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);
+
+        $aAccountIds = array();
+        $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), 'seen_image_url' => $this->getSeenImageUrl($sKey)), BX_EMAIL_SYSTEM)) {
+                    $iInviteId = (int)$this->_oDb->insertInvite($iAccountId, $iProfileId, $sKey, $sEmail, $iDate);
+                    array_push($aAccountIds, $iInviteId);
+                    
+                    $this->onInvite($iProfileId);
+                    
+                    if($mixedLimit !== false)
+                        $mixedLimit -= 1;
+                }
+            }
+        }
+        return $aAccountIds;
+    }
+    
+    public function processFormObjectInvite($oForm)
+    {
+        $iProfileId = $this->getProfileId();
+        $iAccountId = $this->getAccountId($iProfileId);
+
+        $mixedAllowed = $this->isAllowedInvite($iProfileId);
+        if($mixedAllowed !== true)
+            return $mixedAllowed;
+
+        $mixedInvites = false;
+        if(!isAdmin($iAccountId)) {
+            if( $this->_oConfig->getCountPerUser() <= 0)
+                return _t('_bx_invites_err_limit_reached');
+        }
+        
+        $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);
+        $this->onInvite($iProfileId);
+        if($mixedResult !== false)
+            $sResult = _t('_bx_invites_msg_invitation_sent', count($mixedResult));
+        else
+            $sResult = _t('_bx_invites_err_not_available');
+        
+        return  $sResult;
+    }
+
+    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 isAllowedDeleteInvite($iProfileId, $bPerform = false)
+    {
+        $aCheckResult = checkActionModule($iProfileId, 'delete invite', $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();
+    }
+
+    public function onRequest($iRequestId)
+    {
+        //--- Event -> Request for Alerts Engine ---//
+        bx_alert($this->_oConfig->getObject('alert'), 'request', $iRequestId);
+        $aProfiles = BxDolAclQuery::getInstance()->getProfilesByMembership(array(MEMBERSHIP_ID_MODERATOR, MEMBERSHIP_ID_ADMINISTRATOR));
+        foreach($aProfiles as $aProfile) {
+            bx_alert($this->_oConfig->getObject('alert'), 'request_notify', $iRequestId, 0, array('parent_author_id' => $aProfile['id']));
+        }
+        //--- Event -> Request for Alerts Engine ---//
+    }
+
+    public 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 getBlockManage($sType)
+    {
+        $this->_oTemplate->addJs('jquery.form.min.js');
+        $this->_oTemplate->addJs('main.js');
+        $oGrid = BxDolGrid::getObjectInstance($this->_oConfig->getObject('grid_' . $sType));
+        if(!$oGrid)
+            return '';
+
+        $this->_oTemplate->addCss(array('main.css'));
+        $this->_oTemplate->addJsTranslation(array('_sys_grid_search'));
+       
+        return array(
+           'menu' => $this->_oTemplate->getMenuForManageBlocks($sType),
+           'content' => $this->_oTemplate->getJsCode('main', array('grid' => $sType)) . $oGrid->getCode()
+       );
+    }
+
+    protected function onInvite($iProfileId)
+    {
+        $this->isAllowedInvite($iProfileId, true);
+
+        //--- Event -> Invite for Alerts Engine ---//
+        bx_alert($this->_oConfig->getObject('alert'), 'invite', 0, $iProfileId);
+        //--- Event -> Invite for Alerts Engine ---//
+    }
+    
+    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));
+    }
+    
+    protected function getSeenImageUrl($sKey)
+    {
+        return  BX_DOL_URL_ROOT . $this->_oConfig->getBaseUri() . 'SetSeenMark/' . $sKey . "/";
+    }
+
+}
+
+/** @} */

+ 283 - 0
modules/boonex/invites/updates/12.0.0_13.0.0/source/classes/BxInvTemplate.php

@@ -0,0 +1,283 @@
+<?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
+ *
+ * @{
+ */
+
+class BxInvTemplate extends BxBaseModGeneralTemplate
+{
+    function __construct(&$oConfig, &$oDb)
+    {
+        parent::__construct($oConfig, $oDb);
+    }
+
+    public function getCssJs()
+    {
+        $this->addCss(array(
+            'main.css',
+        ));
+
+        $this->addJs(array(
+            'clipboard.min.js',
+            'jquery.form.min.js',
+            'jquery.anim.js',
+            'main.js'
+        ));
+    }
+
+    public function getInclude()
+    {
+        $this->getCssJs();
+        return $this->getJsCode('main');
+    }
+
+    public function getBlockRequestText($aRequest)
+    {
+        return $this->parseHtmlByName('request_text.html', array(
+            'style_prefix' => $this->_oConfig->getPrefix('style'),
+            'text' => bx_process_output(nl2br($aRequest['text']), BX_DATA_TEXT_MULTILINE),
+        ));
+    }
+    
+    public function getBlockInviteInfo($aRequest)
+    {
+        $aVars = array(
+            'date_sent_title' => _t('_bx_invites_title_date_invite_sent'),
+            'date_seen_title' => _t('_bx_invites_title_date_invite_seen'),
+            'bx_repeat:items' => array()
+        );
+        foreach ($aRequest as $r) {
+            $aVars['bx_repeat:items'][] = array (
+                 'date_sent' => bx_time_js($r['date'], BX_FORMAT_DATE_TIME, true),
+                 'date_seen' => ($r['date_seen'] != '' ? bx_time_js($r['date_seen'], BX_FORMAT_DATE_TIME, true) : ' - ')
+            );
+        }
+        return $this->parseHtmlByName('invite_info.html', $aVars);
+    }
+    
+    public function getBlockInvite($iAccountId, $iProfileId)
+    {
+        $sInvitesRemain = '';
+        if(!isAdmin($iAccountId)) {
+            $mInvitesRemain = $this->_oConfig->getCountPerUser();
+            if ($mInvitesRemain === true)
+                 $sInvitesRemain = _t('_bx_invites_txt_unlimited');
+        }
+           
+
+        $sUrl = BX_DOL_URL_ROOT . BxDolPermalinks::getInstance()->permalink($this->_oConfig->CNF['URL_INVITE']);
+
+        $this->getCssJs();
+        return $this->parseHtmlByName('block_invite.html', array(
+            'style_prefix' => $this->_oConfig->getPrefix('style'),
+            'js_object' => $this->_oConfig->getJsObject('main'),
+            'text' => _t('_bx_invites_txt_invite_block_text', $sInvitesRemain),
+            'url' => $sUrl,
+            'js_code' => $this->getJsCode('main')
+        ));
+    }
+
+    public function getBlockRequest()
+    {
+        $sUrl = BX_DOL_URL_ROOT . BxDolPermalinks::getInstance()->permalink($this->_oConfig->CNF['URL_REQUEST']);
+
+        $this->getCssJs();
+        return $this->parseHtmlByName('block_request.html', array(
+            'style_prefix' => $this->_oConfig->getPrefix('style'),
+            'text' => _t('_bx_invites_txt_request_block_text'),
+            'bx_if:show_button_request' => array(
+                'condition' => $this->_oConfig->isRequestInvite(),
+                'content' => array(
+                    'url' => $sUrl
+                )
+            )
+        ));
+    }
+    public function getBlockFormRequest()
+    {
+        if(!$this->_oConfig->isRequestInvite())
+            return MsgBox(_t('_bx_invites_err_not_available'));
+
+        $mixedAllowed = $this->getModule()->isAllowedRequest(0);
+        if($mixedAllowed !== true)
+            return MsgBox($mixedAllowed);
+
+        $CNF = &$this->_oConfig->CNF;
+
+        $sJsObject = $this->_oConfig->getJsObject('main');
+        $oPermalink = BxDolPermalinks::getInstance();
+
+        $oForm = BxDolForm::getObjectInstance($this->_oConfig->getObject('form_request'), $this->_oConfig->getObject('form_display_request_send'));
+        $oForm->aFormAttrs['action'] = BX_DOL_URL_ROOT . $oPermalink->permalink($CNF['URL_REQUEST']);
+
+        $sFormId = $oForm->getId();
+        $sEval = $sJsObject . '.onRequestFormSubmit(oData)';
+
+        $oForm->initChecker();
+        if(!$oForm->isSubmittedAndValid()) {
+            $sForm = $oForm->getCode();
+            if(!$oForm->isSubmitted()) {
+                $this->getCssJs();
+                return $this->parseHtmlByName('block_request_form.html', array(
+                    'style_prefix' => $this->_oConfig->getPrefix('style'),
+                    'js_object' => $sJsObject,
+                    'js_code' => $this->getJsCode('main'),
+                    'form' => $sForm,
+                    'form_id' => $sFormId,
+                ));
+            }
+
+            if(!$oForm->isValid())
+                return array('content' => $sForm, 'content_id' => $sFormId, 'eval' => $sEval);
+        }
+        
+        $sEmail = $oForm->getCleanValue('email');
+        $oAccountQuery = BxDolAccountQuery::getInstance();
+        $iAccount = $oAccountQuery->getIdByEmail($sEmail);
+        if ($iAccount > 0)
+            return array('content' => MsgBox(_t('_bx_invites_err_already_registed', BX_DOL_URL_ROOT . BxDolPermalinks::getInstance()->permalink('page.php?i=forgot-password'))), 'content_id' => $sFormId, 'eval' => $sEval);
+        $iCountByEmail = $this->_oDb->getRequests(array('type' => 'count_by_email', 'value' => $sEmail));
+        if ($iCountByEmail > 0)
+            return array('content' => MsgBox(_t('_bx_invites_err_already_send')), 'content_id' => $sFormId, 'eval' => $sEval);
+       
+        $sIp = getVisitorIP();
+        $iId = (int)$oForm->insert(array('nip' => ip2long($sIp),'date' => time()));
+        if(!$iId)
+            return array('content' => MsgBox(_t('_bx_invites_err_cannot_perform')), 'content_id' => $sFormId, 'eval' => $sEval);
+        $this->getModule()->onRequest($iId);
+        $sRequestsEmail = $this->_oConfig->getRequestsEmail();
+        if(!empty($sRequestsEmail)) {
+            $sManageUrl = BX_DOL_URL_ROOT . $oPermalink->permalink($CNF['URL_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
+            ));
+            
+            $aRequestsEmails = explode(',', $sRequestsEmail);
+            foreach ($aRequestsEmails as $s) {
+                sendMail(trim($s), $aMessage['Subject'], $aMessage['Body'], 0, array(), BX_EMAIL_SYSTEM);
+            }
+        }
+
+        return array('content' => MsgBox(_t('_bx_invites_msg_request_sent')), 'content_id' => $sFormId, 'eval' => $sEval);
+    }
+
+    public function getLinkPopup($sLink)
+    {
+        $sId = $this->_oConfig->getHtmlIds('link_popup');
+        $sTitle = _t('_bx_invites_txt_link_popup_title');
+        $sContent = $this->parseHtmlByName('popup_link.html', array(
+            'style_prefix' => $this->_oConfig->getPrefix('style'),
+            'html_id_link' => $this->_oConfig->getHtmlIds('link_input'),
+            'link' => $sLink
+        ));
+
+        return BxTemplFunctions::getInstance()->popupBox($sId, $sTitle, $sContent, true);
+    }
+    
+    public function getJsCode($sType, $aParams = array(), $mixedWrap = true)
+    {
+        $sGrid = 'requests';
+        if(!empty($aParams['grid'])) {
+            $sGrid = $aParams['grid'];
+            unset($aParams['grid']);
+        }
+
+        $aParams = array_merge(array(
+            'aHtmlIds' => $this->_oConfig->getHtmlIds(),
+            'sObjNameGrid' => $this->_oConfig->getObject('grid_' . $sGrid),
+        ), $aParams);
+
+        return parent::getJsCode($sType, $aParams);
+    }
+
+    public function getMenuForManageBlocks($sType)
+    {
+        $CNF = &$this->_oConfig->CNF;
+        
+        $sMenu = '';
+		$oPermalink = BxDolPermalinks::getInstance();
+
+		$aMenuItems = array();
+		$aMenuItems[] = array('id' => 'invites-requests', 'name' => 'invites-requests', 'class' => '', 'link' => $oPermalink->permalink($CNF['URL_REQUESTS']), 'target' => '_self', 'title' => _t('_bx_invites_menu_item_title_manage_requests'), 'active' => 1);
+		$aMenuItems[] = array('id' => 'invites-invites', 'name' => 'invites-invites', 'class' => '', 'link' => $oPermalink->permalink($CNF['URL_INVITES']), 'target' => '_self', 'title' => _t('_bx_invites_menu_item_title_manage_invites'), 'active' => 1);
+
+		if(count($aMenuItems) > 1) {
+	        $oMenu = new BxTemplMenu(array(
+	            'template' => 'menu_vertical.html', 
+	            'menu_items' => $aMenuItems
+	        ), $this);
+	        $oMenu->setSelected($this->getModule()->_aModule['name'], 'invites-' . $sType);
+	        $sMenu = $oMenu->getCode();
+		}
+        return $sMenu;
+    }
+    
+    public function getProfilesByAccount($iAccountId, $iMaxVisible = 2)
+    {
+        $aProfiles = BxDolAccount::getInstance($iAccountId)->getProfiles();
+        $iProfiles = count($aProfiles);
+
+        $aTmplVars = array (
+            'class_cnt' => '',
+            'bx_repeat:profiles' => array(),
+            'bx_if:profiles_more' => array(
+                'condition' => $iProfiles > $iMaxVisible,
+                'content' => array(
+                    'html_id' => $this->_oConfig->getHtmlIds('profile_more_popup') . $iAccountId,
+                    'more' => _t('_bx_accnt_txt_more', $iProfiles - $iMaxVisible),
+                    'more_attr' => bx_html_attribute(_t('_bx_accnt_txt_see_more')),
+                    'popup' => '',
+                ),
+            ),
+        );
+
+        $aTmplVarsPopup = array (
+            'class_cnt' => ' bx-def-padding',
+            'bx_repeat:profiles' => array(),
+            'bx_if:profiles_more' => array(
+                'condition' => false,
+                'content' => array(),
+            ),
+        );
+
+        $i = 0;
+        foreach ($aProfiles as $iProfileId => $aProfile) {
+            $oProfile = BxDolProfile::getInstance($iProfileId);
+            if(!$oProfile)
+                continue;
+
+            $sName = $oProfile->getDisplayName();
+            $aTmplVarsProfile = array (
+                'html_id' => $this->_oConfig->getHtmlIds('profile') . $aProfile['id'],
+                'id' => $oProfile->id(),
+                'url' => $oProfile->getUrl(),
+                'name' => $sName,
+                'name_attr' => bx_html_attribute($sName)
+            );
+
+            if($i < $iMaxVisible)
+                $aTmplVars['bx_repeat:profiles'][] = $aTmplVarsProfile;
+            if($i >= $iMaxVisible)
+                $aTmplVarsPopup['bx_repeat:profiles'][] = $aTmplVarsProfile;
+
+            ++$i;
+        }
+
+        if($aTmplVarsPopup['bx_repeat:profiles']) {
+            $aTmplVars['bx_if:profiles_more']['content']['popup'] = BxTemplFunctions::getInstance()->transBox('', $this->parseHtmlByName('profiles.html', $aTmplVarsPopup));
+        }
+
+        return $this->parseHtmlByName('profiles.html', $aTmplVars);
+    }
+}
+
+/** @} */

+ 80 - 0
modules/boonex/invites/updates/12.0.0_13.0.0/source/install/config.php

@@ -0,0 +1,80 @@
+<?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' => '13.0.0',
+    'vendor' => 'BoonEx',
+    'help_url' => 'http://feed.una.io/?section={module_name}',
+
+    'compatible_with' => array(
+        '13.0.0-A3'
+    ),
+
+    /**
+     * '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,
+        'update_relations' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'enable' => array(
+        'execute_sql' => 1,
+        'update_relations' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'disable' => array (
+        'execute_sql' => 1,
+        'update_relations' => 1,
+        'clear_db_cache' => 1,
+    ),
+
+    /**
+     * Dependencies Section
+     */
+    'dependencies' => array(),
+    
+    /**
+      * Relations Section
+      */
+    'relations' => array(
+    	'bx_notifications'
+    ),
+);
+
+/** @} */

+ 182 - 0
modules/boonex/invites/updates/12.0.0_13.0.0/source/install/langs/en.xml

@@ -0,0 +1,182 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources name="en" flag="gb" title="English">
+
+	<string name="_bx_invites"><![CDATA[Invitations]]></string>
+
+	<!-- Forms -->
+	<string name="_bx_invites_form_invite"><![CDATA[Invite]]></string>
+	<string name="_bx_invites_form_invite_display_send"><![CDATA[Send]]></string>
+	<string name="_bx_invites_form_invite_input_sys_emails"><![CDATA[Emails]]></string>
+	<string name="_bx_invites_form_invite_input_emails"><![CDATA[Emails]]></string>
+	<string name="_bx_invites_form_invite_input_emails_inf"><![CDATA[Use semicolon to separate emails.]]></string>
+	<string name="_bx_invites_form_invite_input_emails_err"><![CDATA[You need to use correct emails and enter at least one email.]]></string>
+	<string name="_bx_invites_form_invite_input_sys_text"><![CDATA[Text]]></string>
+	<string name="_bx_invites_form_invite_input_text"><![CDATA[Text]]></string>
+	<string name="_bx_invites_form_invite_input_text_err"><![CDATA[You need to type the text which will be added to invitation email.]]></string>
+	<string name="_bx_invites_form_invite_input_sys_do_submit"><![CDATA[Send]]></string>
+	<string name="_bx_invites_form_invite_input_do_submit"><![CDATA[Send]]></string>
+
+	<string name="_bx_invites_form_request"><![CDATA[Request Invitation]]></string>
+	<string name="_bx_invites_form_request_display_send"><![CDATA[Send]]></string>
+	<string name="_bx_invites_form_request_input_sys_name"><![CDATA[Your Name]]></string>
+	<string name="_bx_invites_form_request_input_name"><![CDATA[Your Name]]></string>
+	<string name="_bx_invites_form_request_input_name_err"><![CDATA[You need to type your name.]]></string>
+	<string name="_bx_invites_form_request_input_sys_email"><![CDATA[Your email]]></string>
+	<string name="_bx_invites_form_request_input_email"><![CDATA[Your email]]></string>
+	<string name="_bx_invites_form_request_input_email_err"><![CDATA[You need to type the correct email.]]></string>
+	<string name="_bx_invites_form_request_input_sys_text"><![CDATA[Text]]></string>
+	<string name="_bx_invites_form_request_input_text"><![CDATA[Why do you want to join?]]></string>
+	<string name="_bx_invites_form_request_input_text_err"><![CDATA[You need to briefly describe why you want to join our site.]]></string>
+	<string name="_bx_invites_form_request_input_sys_do_submit"><![CDATA[Send]]></string>
+	<string name="_bx_invites_form_request_input_do_submit"><![CDATA[Send]]></string>
+
+
+	<!-- Grids -->
+	<string name="_bx_invites_grid_column_title_name"><![CDATA[Name]]></string>
+	<string name="_bx_invites_grid_column_title_email"><![CDATA[Email]]></string>
+	<string name="_bx_invites_grid_column_title_nip"><![CDATA[IP]]></string>
+	<string name="_bx_invites_grid_column_title_date"><![CDATA[Date]]></string>
+
+  <string name="_bx_invites_grid_column_title_date_invite"><![CDATA[Date invite]]></string>
+  <string name="_bx_invites_grid_column_title_date_seen"><![CDATA[Date seen]]></string>
+  <string name="_bx_invites_grid_column_title_date_joined"><![CDATA[Date joined]]></string>
+  <string name="_bx_invites_grid_column_title_joined_account"><![CDATA[Joined]]></string>
+  <string name="_bx_invites_grid_column_title_status"><![CDATA[Status]]></string>
+
+	<string name="_bx_invites_grid_action_title_adm_info"><![CDATA[Info]]></string>
+  <string name="_bx_invites_grid_action_title_adm_invite_info"><![CDATA[Invitation info]]></string>
+  <string name="_bx_invites_grid_action_title_adm_invite"><![CDATA[Invite]]></string>
+	<string name="_bx_invites_grid_action_title_adm_delete"><![CDATA[Delete]]></string>
+  <string name="_bx_invites_grid_action_title_adm_add"><![CDATA[Send invitations]]></string>
+
+  <string name="_bx_invites_grid_invites_column_title_email"><![CDATA[Email]]></string>
+  <string name="_bx_invites_grid_invites_column_title_date"><![CDATA[Date]]></string>
+  <string name="_bx_invites_grid_invites_column_title_who_sent"><![CDATA[Who sent]]></string>
+  <string name="_bx_invites_grid_invites_column_title_date_seen"><![CDATA[Date seen]]></string>
+  <string name="_bx_invites_grid_invites_column_title_joined_account"><![CDATA[Joined account]]></string>
+  <string name="_bx_invites_grid_invites_column_title_date_joined"><![CDATA[Date joined]]></string>
+  <string name="_bx_invites_grid_invites_column_title_request"><![CDATA[Request]]></string>
+  <string name="_bx_invites_grid_txt_account_manager"><![CDATA[Redirect to manage account.]]></string>
+  <string name="_bx_invites_grid_txt_view_request"><![CDATA[View request]]></string>
+
+  <!-- Pages and Blocks -->
+	<string name="_bx_invites_page_title_sys_invite"><![CDATA[Invite]]></string>
+	<string name="_bx_invites_page_title_invite"><![CDATA[Invite]]></string>
+<string name="_bx_invites_page_block_title_system_invite_form"><![CDATA[Invite Form]]></string>
+	<string name="_bx_invites_page_block_title_invite_form"><![CDATA[Invite]]></string>
+
+	<string name="_bx_invites_page_title_sys_request"><![CDATA[Request Invitation]]></string>
+	<string name="_bx_invites_page_title_request"><![CDATA[Request Invitation]]></string>
+	<string name="_bx_invites_page_block_title_request_form"><![CDATA[Request Invitation]]></string>
+
+	<string name="_bx_invites_page_title_sys_requests"><![CDATA[Manage Invites]]></string>
+	<string name="_bx_invites_page_title_invites"><![CDATA[Manage Invites]]></string>
+	<string name="_bx_invites_page_block_title_invites"><![CDATA[Manage Invites]]></string>
+
+	<string name="_bx_invites_page_block_title_invite"><![CDATA[Invite]]></string>
+
+  <string name="_bx_invites_page_title_sys_invites"><![CDATA[Manage Requests]]></string>
+  <string name="_bx_invites_page_title_requests"><![CDATA[Manage Requests]]></string>
+  <string name="_bx_invites_page_block_title_requests"><![CDATA[Manage Requests]]></string>
+
+	<!-- Menus -->
+	<string name="_bx_invites_menu_item_title_system_admt_requests"><![CDATA[Invitation requests]]></string>
+	<string name="_bx_invites_menu_item_title_admt_requests"><![CDATA[Invitations]]></string>
+	<string name="_bx_invites_menu_item_title_requests"><![CDATA[Requests]]></string>
+  <string name="_bx_invites_menu_dashboard_manage_tools_addon_counter1_caption"><![CDATA[awaiting]]></string>
+  <string name="_bx_invites_menu_item_title_manage_requests"><![CDATA[Manage requests]]></string>
+  <string name="_bx_invites_menu_item_title_manage_invites"><![CDATA[Manage invites]]></string>
+
+  <!-- Options -->
+  <string name="_bx_invites_option_automatically_befriend"><![CDATA[Enable automatically befriend inviter and invited]]></string>
+	<string name="_bx_invites_option_key_lifetime"><![CDATA[Invitation key lifetime (in days)]]></string>
+	<string name="_bx_invites_option_enable_request_invite"><![CDATA[Enable invitation requests by email]]></string>
+  <string name="_bx_invites_option_requests_notifications"><![CDATA[Enable invitation requests in notifications]]></string>
+  <string name="_bx_invites_option_requests_email"><![CDATA[Emails to send invitation requests to (comma separated)]]></string>
+	<string name="_bx_invites_option_enable_reg_by_inv"><![CDATA[Enable registration by invitation only]]></string>
+
+
+	<!-- ACL -->
+	<string name="_bx_invites_acl_action_invite"><![CDATA[Invite]]></string>
+	<string name="_bx_invites_acl_action_request"><![CDATA[Request Invitation]]></string>
+	<string name="_bx_invites_acl_action_delete_request"><![CDATA[Delete invitation requests]]></string>
+  <string name="_bx_invites_acl_action_delete_invite"><![CDATA[Delete invite]]></string>
+
+	<!-- Email Templates -->
+	<string name="_bx_invites_et_invite_form_message"><![CDATA[Invite form message.]]></string>
+	<string name="_bx_invites_et_invite_form_message_subject"><![CDATA[Invitation from {site_name}.]]></string>
+	<string name="_bx_invites_et_invite_form_message_body"><![CDATA[{email_header}
+<p><b>Dear Friend</b>,</p>
+<p>{profile_name} invites you to join to <a href="{site_url}">{site_name}</a> community site.<br />Message from {profile_name}:</p>
+<hr />
+<p>{text}</p>
+<hr />
+<p>Click the following link to join: <a href="{join_url}">{join_url}</a></p>
+{email_footer}]]></string>
+
+	<string name="_bx_invites_et_invite_by_request_message"><![CDATA[Invite by request message.]]></string>
+	<string name="_bx_invites_et_invite_by_request_message_subject"><![CDATA[Invitation from {site_name}.]]></string>
+	<string name="_bx_invites_et_invite_by_request_message_body">
+  <![CDATA[{email_header}
+<p><b>Dear Friend</b>,</p>
+<p>You are welcome to join <a href="{site_url}">{site_name}</a> community site.</p>
+<p>Click the following link to join: <a href="{join_url}">{join_url}</a></p>
+<img src="{seen_image_url}" width="1" height="1">
+{email_footer}]]></string>
+
+	<string name="_bx_invites_et_request_form_message"><![CDATA[Request Invitation form message.]]></string>
+	<string name="_bx_invites_et_request_form_message_subject"><![CDATA[Request invitation.]]></string>
+	<string name="_bx_invites_et_request_form_message_body"><![CDATA[{email_header}
+<p><b>Dear Administrator</b>,</p>
+<p>{sender_name} (<a href="mailto:{sender_email}">{sender_email}</a>; IP {sender_ip}) requested an invitation to join <b>{site_name}</b> site.</p>
+<p><a href="{manage_url}">Click here</a> to manage requests.</p>
+{email_footer}]]></string>
+
+
+	<!-- Common Texts -->
+	<string name="_bx_invites_txt_link_popup_title"><![CDATA[Invitation Link]]></string>
+	<string name="_bx_invites_txt_invite_block_text"><![CDATA[You can invite your friends to join. You have <b>{0}</b> invites to share.]]></string>
+	<string name="_bx_invites_txt_request_block_text"><![CDATA[Registration is by invitation only.]]></string>
+	<string name="_bx_invites_txt_unlimited"><![CDATA[unlimited]]></string>
+	
+	<string name="_bx_invites_btn_invite_email"><![CDATA[Invite By Email]]></string>
+	<string name="_bx_invites_btn_invite_link"><![CDATA[Get Invitation Link]]></string>
+	<string name="_bx_invites_btn_copy"><![CDATA[Copy]]></string>
+	<string name="_bx_invites_btn_request"><![CDATA[Request Invitation]]></string>
+	<string name="_bx_invites_msg_invitation"><![CDATA[Hello! This site might be interesting for you.]]></string>
+	<string name="_bx_invites_msg_invitation_sent"><![CDATA[Invitation message was sent to {0} email addresses from the list.]]></string>
+	<string name="_bx_invites_msg_request_sent"><![CDATA[Invitation request was sent.]]></string>
+	<string name="_bx_invites_err_cannot_perform"><![CDATA[An error appeared. Please report.]]></string>
+	<string name="_bx_invites_err_limit_reached"><![CDATA[The number of invitations sent by you reached the limit.]]></string>
+	<string name="_bx_invites_err_not_available"><![CDATA[The feature is not available now. Please, try again later.]]></string>
+	<string name="_bx_invites_err_invite"><![CDATA[Cannot send an invitation on request.]]></string>
+	<string name="_bx_invites_err_delete_invite"><![CDATA[Cannot delete the invite.]]></string>
+  <string name="_bx_invites_err_delete_request"><![CDATA[Cannot delete the request.]]></string>
+	<string name="_bx_invites_err_used"><![CDATA[The invitation link isn't available or already used.]]></string>
+  <string name="_bx_invites_err_already_send"><![CDATA[The request already sent for this email.]]></string>
+  <string name="_bx_invites_err_already_registed"><![CDATA[User with this email already registered. Please use  <a href="{0}">forgot password</a> to restore access to your account.]]></string>
+  <string name="_bx_invites_request_status_new"><![CDATA[New]]></string>
+  <string name="_bx_invites_request_status_invited"><![CDATA[Invited]]></string>
+  <string name="_bx_invites_request_status_seen"><![CDATA[Seen]]></string>
+  <string name="_bx_invites_request_status_joined"><![CDATA[Joined]]></string>
+  <string name="_bx_invites_request_status_for_filter_all"><![CDATA[All requests]]></string>
+  <string name="_bx_invites_request_status_for_filter_new"><![CDATA[New requests]]></string>
+  <string name="_bx_invites_request_status_for_filter_invited"><![CDATA[Requests with invites]]></string>
+  <string name="_bx_invites_request_status_for_filter_seen"><![CDATA[Invite seen]]></string>
+  <string name="_bx_invites_request_status_for_filter_joined"><![CDATA[Joined]]></string>
+
+  <string name="_bx_invites_invites_status_for_filter_all"><![CDATA[All invites]]></string>
+  <string name="_bx_invites_invites_status_for_filter_accepted"><![CDATA[Accepted invites]]></string>
+  <string name="_bx_invites_invites_status_for_filter_not_accepted"><![CDATA[Not accepted invites]]></string>
+
+  <string name="_bx_invites_title_date_invite_sent"><![CDATA[Date sent]]></string>
+  <string name="_bx_invites_title_date_invite_seen"><![CDATA[Date seen]]></string>
+
+  <string name="_bx_invites_reports_for_analytics_invited_total"><![CDATA[Invited - Total numbers]]></string>
+  <string name="_bx_invites_reports_for_analytics_invited_speed_grows"><![CDATA[Invited - Grows speed]]></string>
+  <string name="_bx_invites_reports_for_analytics_invitation_total"><![CDATA[Invitation - Total numbers]]></string>
+  <string name="_bx_invites_reports_for_analytics_invitation_speed_grows"><![CDATA[Invitation - Grows speed]]></string>
+
+  <string name="_bx_invites_alert_action_request"><![CDATA[<b class="bx-ntfs-content-profile">{entry_sample}</b> request invitation - <b class="bx-ntfs-content-entry">{entry_caption}</b>]]></string>
+  <string name="_bx_invites_alert_action_request_notify_personal"><![CDATA[New requests]]></string>
+</resources>

+ 172 - 0
modules/boonex/invites/updates/12.0.0_13.0.0/source/install/sql/enable.sql

@@ -0,0 +1,172 @@
+SET @sName = 'bx_invites';
+
+
+-- 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_invites_invite', '_bx_invites_page_title_sys_invite', '_bx_invites_page_title_invite', @sName, 5, 2147483647, 1, 'invites-invite', 'page.php?i=invites-invite', '', '', '', 0, 1, 0, '', '');
+
+INSERT INTO `sys_pages_blocks` (`object`, `cell_id`, `module`, `title_system`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `order`) VALUES
+('bx_invites_invite', 1, @sName, '_bx_invites_page_block_title_system_invite_form', '_bx_invites_page_block_title_invite_form', 11, 2147483647, 'service', 'a:2:{s:6:"module";s:10:"bx_invites";s:6:"method";s:21:"get_block_form_invite";}', 0, 1, 1);
+
+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_invites_request', '_bx_invites_page_title_sys_request', '_bx_invites_page_title_request', @sName, 5, 2147483647, 1, 'invites-request', 'page.php?i=invites-request', '', '', '', 0, 1, 0, '', '');
+
+INSERT INTO `sys_pages_blocks` (`object`, `cell_id`, `module`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `order`) VALUES
+('bx_invites_request', 1, @sName, '_bx_invites_page_block_title_request_form', 11, 2147483647, 'service', 'a:2:{s:6:"module";s:10:"bx_invites";s:6:"method";s:22:"get_block_form_request";}', 0, 1, 1);
+
+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_invites_requests', '_bx_invites_page_title_sys_requests', '_bx_invites_page_title_requests', @sName, 5, 192, 1, 'invites-requests', 'page.php?i=invites-requests', '', '', '', 0, 1, 0, '', '');
+
+INSERT INTO `sys_pages_blocks` (`object`, `cell_id`, `module`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `order`) VALUES
+('bx_invites_requests', 1, @sName, '_bx_invites_page_block_title_requests', 11, 2147483647, 'service', 'a:2:{s:6:"module";s:10:"bx_invites";s:6:"method";s:25:"get_block_manage_requests";}', 0, 1, 1);
+
+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_invites_invites', '_bx_invites_page_title_sys_invites', '_bx_invites_page_title_invites', @sName, 5, 2147483647, 1, 'invites-invites', 'page.php?i=invites-invites', '', '', '', 0, 1, 0, '', '');
+
+INSERT INTO `sys_pages_blocks` (`object`, `cell_id`, `module`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `order`) VALUES
+('bx_invites_invites', 1, @sName, '_bx_invites_page_block_title_invites', 11, 2147483647, 'service', 'a:2:{s:6:"module";s:10:"bx_invites";s:6:"method";s:24:"get_block_manage_invites";}', 0, 1, 1);
+
+-- PAGES: add page block on dashboard
+SET @iPBCellDashboard = 3;
+SET @iPBOrderDashboard = 2; --(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_invites_page_block_title_invite', 11, 2147483647, 'service', 'a:2:{s:6:"module";s:10:"bx_invites";s:6:"method";s:16:"get_block_invite";}', 0, 1, @iPBOrderDashboard);
+
+
+-- 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', @sName, 'invites-requests', '_bx_invites_menu_item_title_system_admt_requests', '_bx_invites_menu_item_title_admt_requests', 'page.php?i=invites-requests', '', '_self', 'envelope-open-text', 'a:2:{s:6:"module";s:10:"bx_invites";s:6:"method";s:23:"get_menu_addon_requests";}', '', 192, 1, 0, @iManageMenuOrder + 1);
+
+
+-- 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', @sName, '_bx_invites', 'bx_invites@modules/boonex/invites/|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, @sName, '_bx_invites', 1);
+SET @iCategId = LAST_INSERT_ID();
+
+INSERT INTO `sys_options` (`name`, `value`, `category_id`, `caption`, `type`, `check`, `check_error`, `extra`, `order`) VALUES
+('bx_invites_key_lifetime', '7', @iCategId, '_bx_invites_option_key_lifetime', 'digit', '', '', '', 2),
+('bx_invites_enable_request_invite', 'on', @iCategId, '_bx_invites_option_enable_request_invite', 'checkbox', '', '', '', 3),
+('bx_invites_requests_email', '', @iCategId, '_bx_invites_option_requests_email', 'digit', '', '', '', 4),
+('bx_invites_enable_reg_by_inv', 'on', @iCategId, '_bx_invites_option_enable_reg_by_inv', 'checkbox', '', '', '', 5),
+('bx_invites_requests_notifications', 'on', @iCategId, '_bx_invites_option_requests_notifications', 'checkbox', '', '', '', 6),
+('bx_invites_automatically_befriend', 'on', @iCategId, '_bx_invites_option_automatically_befriend', 'checkbox', '', '', '', 7);
+
+-- ACL
+INSERT INTO `sys_acl_actions` (`Module`, `Name`, `AdditionalParamName`, `Title`, `Desc`, `Countable`, `DisabledForLevels`) VALUES
+(@sName, 'request', NULL, '_bx_invites_acl_action_request', '', 0, 2147483646);
+SET @iIdActionRequest = LAST_INSERT_ID();
+
+INSERT INTO `sys_acl_actions` (`Module`, `Name`, `AdditionalParamName`, `Title`, `Desc`, `Countable`, `DisabledForLevels`) VALUES
+(@sName, 'delete request', NULL, '_bx_invites_acl_action_delete_request', '', 0, 1);
+SET @iIdActionDeleteRequest = LAST_INSERT_ID();
+
+INSERT INTO `sys_acl_actions` (`Module`, `Name`, `AdditionalParamName`, `Title`, `Desc`, `Countable`, `DisabledForLevels`) VALUES
+(@sName, 'delete invite', NULL, '_bx_invites_acl_action_delete_invite', '', 0, 1);
+SET @iIdActionDeleteInvite = LAST_INSERT_ID();
+
+INSERT INTO `sys_acl_actions` (`Module`, `Name`, `AdditionalParamName`, `Title`, `Desc`, `Countable`, `DisabledForLevels`) VALUES
+(@sName, 'invite', NULL, '_bx_invites_acl_action_invite', '', 1, 1);
+SET @iIdActionInvite = 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
+
+-- request invite
+(@iUnauthenticated, @iIdActionRequest),
+
+-- delete request
+(@iModerator, @iIdActionDeleteRequest),
+(@iAdministrator, @iIdActionDeleteRequest),
+
+-- delete invite
+(@iModerator, @iIdActionDeleteInvite),
+(@iAdministrator, @iIdActionDeleteInvite);
+
+INSERT INTO `sys_acl_matrix` (`IDLevel`, `IDAction`, `AllowedCount`) VALUES
+-- invite
+(@iAccount, @iIdActionInvite, 5),
+(@iStandard, @iIdActionInvite, 5),
+(@iUnconfirmed, @iIdActionInvite, 5),
+(@iPending, @iIdActionInvite, 5),
+(@iSuspended, @iIdActionInvite, 5),
+(@iModerator, @iIdActionInvite, 5),
+(@iAdministrator, @iIdActionInvite, 5),
+(@iPremium, @iIdActionInvite, 5);
+
+-- 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_invites_requests', 'Sql', 'SELECT `bx_inv_requests`.* FROM `bx_inv_requests` WHERE 1', 'bx_inv_requests', 'id', 'status, date', '', '', 20, NULL, 'start', '', 'bx_inv_requests`.`name, bx_inv_requests`.`email', '', 'like', '', '', 192, 'BxInvGridRequests', 'modules/boonex/invites/classes/BxInvGridRequests.php'),
+('bx_invites_invites', 'Sql', 'SELECT `bx_inv_invites`.* FROM `bx_inv_invites` WHERE 1', 'bx_inv_invites', 'id', 'date', '', '', 20, NULL, 'start', '', 'email', '', 'like', '', '', 192, 'BxInvGridInvites', 'modules/boonex/invites/classes/BxInvGridInvites.php');
+
+INSERT INTO `sys_grid_fields` (`object`, `name`, `title`, `width`, `translatable`, `chars_limit`, `params`, `order`) VALUES
+('bx_invites_requests', 'checkbox', '_sys_select', '2%', 0, '', '', 1),
+('bx_invites_requests', 'name', '_bx_invites_grid_column_title_name', '14%', 0, '', '', 2),
+('bx_invites_requests', 'email', '_bx_invites_grid_column_title_email', '14%', 1, '25', '', 3),
+('bx_invites_requests', 'nip', '_bx_invites_grid_column_title_nip', '10%', 0, '15', '', 4),
+('bx_invites_requests', 'date', '_bx_invites_grid_column_title_date', '10%', 0, '20', '', 5),
+('bx_invites_requests', 'joined_account', '_bx_invites_grid_column_title_joined_account', '20%', 0, '20', '', 6),
+('bx_invites_requests', 'status', '_bx_invites_grid_column_title_status', '10%', 0, '15', '', 7),
+('bx_invites_requests', 'actions', '', '20%', 0, '', '', 8),
+
+('bx_invites_invites', 'checkbox', '_sys_select', '2%', 0, '', '', 1),
+('bx_invites_invites', 'email', '_bx_invites_grid_invites_column_title_email', '15%', 1, '25', '', 2),
+('bx_invites_invites', 'who_send', '_bx_invites_grid_invites_column_title_who_sent', '15%', 0, '', '', 3),
+('bx_invites_invites', 'date', '_bx_invites_grid_invites_column_title_date', '10%', 0, '20', '', 4),
+('bx_invites_invites', 'date_seen', '_bx_invites_grid_invites_column_title_date_seen', '10%', 0, '20', '', 5),
+('bx_invites_invites', 'joined_account', '_bx_invites_grid_invites_column_title_joined_account', '15%', 0, '20', '', 6),
+('bx_invites_invites', 'date_joined', '_bx_invites_grid_invites_column_title_date_joined', '10%', 0, '20', '', 7),
+('bx_invites_invites', 'request', '_bx_invites_grid_invites_column_title_request', '13%', 0, '20', '', 8),
+('bx_invites_invites', 'actions', '', '20%', 0, '', '', 8);
+
+
+INSERT INTO `sys_grid_actions` (`object`, `type`, `name`, `title`, `icon`, `icon_only`, `confirm`, `order`) VALUES
+('bx_invites_requests', 'bulk', 'invite', '_bx_invites_grid_action_title_adm_invite', '', 0, 0, 1),
+('bx_invites_requests', 'bulk', 'delete', '_bx_invites_grid_action_title_adm_delete', '', 0, 1, 2),
+('bx_invites_requests', 'single', 'info', '_bx_invites_grid_action_title_adm_info', 'info-circle', 1, 0, 1),
+('bx_invites_requests', 'single', 'invite', '_bx_invites_grid_action_title_adm_invite', 'envelope', 1, 0, 2),
+('bx_invites_requests', 'single', 'delete', '_bx_invites_grid_action_title_adm_delete', 'remove', 1, 1, 3),
+('bx_invites_requests', 'single', 'invite_info', '_bx_invites_grid_action_title_adm_invite_info', 'info-circle', 1, 0, 4),
+('bx_invites_requests', 'independent', 'add', '_bx_invites_grid_action_title_adm_add', '', 0, 0, 5),
+
+('bx_invites_invites', 'bulk', 'delete', '_bx_invites_grid_action_title_adm_delete', '', 0, 1, 1),
+('bx_invites_invites', 'single', 'delete', '_bx_invites_grid_action_title_adm_delete', 'remove', 1, 1, 2),
+('bx_invites_invites', 'independent', 'add', '_bx_invites_grid_action_title_adm_add', '', 0, 0, 3);
+
+
+
+-- EMAIL TEMPLATES
+INSERT INTO `sys_email_templates` (`Module`, `NameSystem`, `Name`, `Subject`, `Body`) VALUES 
+(@sName, '_bx_invites_et_invite_form_message', 'bx_invites_invite_form_message', '_bx_invites_et_invite_form_message_subject', '_bx_invites_et_invite_form_message_body'),
+(@sName, '_bx_invites_et_invite_by_request_message', 'bx_invites_invite_by_request_message', '_bx_invites_et_invite_by_request_message_subject', '_bx_invites_et_invite_by_request_message_body'),
+(@sName, '_bx_invites_et_request_form_message', 'bx_invites_request_form_message', '_bx_invites_et_request_form_message_subject', '_bx_invites_et_request_form_message_body');
+
+
+-- ALERTS
+INSERT INTO `sys_alerts_handlers`(`name`, `class`, `file`, `service_call`) VALUES 
+(@sName, 'BxInvResponse', 'modules/boonex/invites/classes/BxInvResponse.php', '');
+SET @iHandler := LAST_INSERT_ID();
+
+INSERT INTO `sys_alerts` (`unit`, `action`, `handler_id`) VALUES
+('account', 'add_form', @iHandler),
+('account', 'added', @iHandler),
+('account', 'delete', @iHandler),
+('profile', 'delete', @iHandler),
+('profile', 'add', @iHandler),
+('bx_analytics', 'get_modules', @iHandler),
+('bx_analytics', 'get_reports', @iHandler),
+('bx_analytics', 'get_chart_data_line', @iHandler);

+ 19 - 0
modules/boonex/invites/updates/12.0.0_13.0.0/source/template/popup_invite.html

@@ -0,0 +1,19 @@
+<div class="bx-pgt-new-key">
+    <div class="bx-pgt-new-key-cnt">
+        __form__
+        <script language="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>

+ 51 - 0
modules/boonex/market/updates/13.0.0_13.0.1/install/config.php

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

+ 50 - 0
modules/boonex/market/updates/13.0.0_13.0.1/install/installer.php

@@ -0,0 +1,50 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ */
+
+class BxMarketUpdater extends BxDolStudioUpdater
+{
+    function __construct($aConfig)
+    {
+        parent::__construct($aConfig);
+    }
+
+    public function actionExecuteSql($sOperation)
+    {
+        if($sOperation == 'install') {
+            if(!$this->oDb->isFieldExists('bx_market_products', 'cf'))
+                $this->oDb->query("ALTER TABLE `bx_market_products` ADD `cf` int(11) NOT NULL default '1' AFTER `featured`");
+
+            if(!$this->oDb->isFieldExists('bx_market_cmts', 'cmt_cf'))
+                $this->oDb->query("ALTER TABLE `bx_market_cmts` ADD `cmt_cf` int(11) NOT NULL default '1' AFTER `cmt_pinned`");
+
+            if(!$this->oDb->isFieldExists('bx_market_votes', 'id'))
+                $this->oDb->query("ALTER TABLE `bx_market_votes` ADD `id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT FIRST");
+
+            if(!$this->oDb->isFieldExists('bx_market_reactions', 'id'))
+                $this->oDb->query("ALTER TABLE `bx_market_reactions` ADD `id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT FIRST");
+
+            if(!$this->oDb->isFieldExists('bx_market_views_track', 'id'))
+                $this->oDb->query("ALTER TABLE `bx_market_views_track` ADD `id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT FIRST");
+
+            if(!$this->oDb->isFieldExists('bx_market_meta_keywords', 'id'))
+                $this->oDb->query("ALTER TABLE `bx_market_meta_keywords` ADD `id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT FIRST");
+
+            if(!$this->oDb->isFieldExists('bx_market_meta_mentions', 'id'))
+                $this->oDb->query("ALTER TABLE `bx_market_meta_mentions` ADD `id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT FIRST");
+
+            if(!$this->oDb->isFieldExists('bx_market_reports', 'id'))
+                $this->oDb->query("ALTER TABLE `bx_market_reports` ADD `id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT FIRST");
+
+            if(!$this->oDb->isFieldExists('bx_market_favorites_track', 'id'))
+                $this->oDb->query("ALTER TABLE `bx_market_favorites_track` ADD `id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT FIRST");
+
+            if(!$this->oDb->isFieldExists('bx_market_scores', 'id'))
+                $this->oDb->query("ALTER TABLE `bx_market_scores` ADD `id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT FIRST");
+        }
+
+        return parent::actionExecuteSql($sOperation);
+    }
+}

+ 4 - 0
modules/boonex/market/updates/13.0.0_13.0.1/install/langs/en.xml

@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources name="en" flag="gb" title="English">
+    <string_add name="_bx_market_grid_filter_item_title_adm_select_one_filter2"><![CDATA[Any Audience]]></string_add>
+</resources>

+ 18 - 0
modules/boonex/market/updates/13.0.0_13.0.1/install/sql/enable.sql

@@ -0,0 +1,18 @@
+-- MENUS
+DELETE FROM `sys_menu_items` WHERE `set_name`='bx_market_view_actions' AND `name` IN ('social-sharing', 'social-sharing-facebook', 'social-sharing-twitter', 'social-sharing-pinterest');
+INSERT INTO `sys_menu_items`(`set_name`, `module`, `name`, `title_system`, `title`, `link`, `onclick`, `target`, `icon`, `addon`, `submenu_object`, `submenu_popup`, `visible_for_levels`, `visibility_custom`, `active`, `copyable`, `order`) VALUES 
+('bx_market_view_actions', 'bx_market', 'social-sharing', '_sys_menu_item_title_system_social_sharing', '_sys_menu_item_title_social_sharing', 'javascript:void(0)', 'oBxDolPage.share(this, \'{url_encoded}\')', '', 'share', '', '', 0, 2147483647, '', 1, 0, 300);
+
+UPDATE `sys_menu_items` SET `name`='profile-stats-my-market', `link`='page.php?i=products-author&profile_id={member_id}' WHERE `set_name`='sys_profile_stats' AND `name`='profile-stats-manage-products';
+
+
+-- CONNECTIONS
+UPDATE `sys_objects_connection` SET `profile_initiator`='0', `profile_content`='0' WHERE `object`='bx_market_subentries';
+
+
+-- METATAGS
+UPDATE `sys_objects_metatags` SET `module`='bx_market' WHERE `object`='bx_market';
+
+
+-- CATEGORY
+UPDATE `sys_objects_category` SET `module`='bx_market' WHERE `object`='bx_market_cats';

+ 11 - 0
modules/boonex/market/updates/13.0.0_13.0.1/install/sql/install.sql

@@ -0,0 +1,11 @@
+-- FORMS
+DELETE FROM `sys_form_inputs` WHERE `object`='bx_market' AND `name`='cf';
+INSERT INTO `sys_form_inputs`(`object`, `module`, `name`, `value`, `values`, `checked`, `type`, `caption_system`, `caption`, `info`, `required`, `collapsed`, `html`, `attrs`, `attrs_tr`, `attrs_wrapper`, `checker_func`, `checker_params`, `checker_error`, `db_pass`, `db_params`, `editable`, `deletable`) VALUES 
+('bx_market', 'bx_market', 'cf', '1', '#!sys_content_filter', 0, 'select', '_sys_form_entry_input_sys_cf', '_sys_form_entry_input_cf', '', 0, 0, 0, '', '', '', '', '', '', 'Int', '', 1, 0);
+
+UPDATE `sys_form_inputs` SET `type`='price' WHERE `object`='bx_market' AND `name` IN ('price_single', 'price_recurring');
+
+DELETE FROM `sys_form_display_inputs` WHERE `display_name` IN ('bx_market_entry_add', 'bx_market_entry_edit') AND `input_name`='cf';
+INSERT INTO `sys_form_display_inputs`(`display_name`, `input_name`, `visible_for_levels`, `active`, `order`) VALUES 
+('bx_market_entry_add', 'cf', 2147483647, 1, 21),
+('bx_market_entry_edit', 'cf', 2147483647, 1, 21);

+ 272 - 0
modules/boonex/market/updates/13.0.0_13.0.1/source/classes/BxMarketConfig.php

@@ -0,0 +1,272 @@
+<?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 (
+            'hide-product' => 'checkAllowedHide',
+            'unhide-product' => 'checkAllowedUnhide',
+            'approve' => 'checkAllowedApprove',
+            'edit-product' => 'checkAllowedEdit',
+            'delete-product' => 'checkAllowedDelete',
+            'product-more' => 'checkAllowedViewMoreMenu'
+        );
+
+        $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_CF' => 'cf',
+            'FIELD_SUBENTRIES' => 'subentries',
+            'FIELD_PHOTO' => 'pictures',
+            'FIELD_THUMB' => 'thumb',
+            'FIELD_COVER' => 'cover',
+            'FIELD_FILE' => 'files',
+            'FIELD_PACKAGE' => 'package',
+            'FIELD_NOTES_PURCHASED' => 'notes_purchased',
+            'FIELD_VIEWS' => 'views',
+            'FIELD_COMMENTS' => 'comments',
+            'FIELD_FEATURED' => 'featured',
+            'FIELD_STATUS' => 'status',
+            'FIELD_STATUS_ADMIN' => 'status_admin',
+            'FIELD_LOCATION' => 'location',
+            'FIELD_LOCATION_PREFIX' => 'location',
+            'FIELD_LABELS' => 'labels',
+            '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_ENTRIES_BY_CONTEXT' => 'products-context',
+            'URI_ADD_ENTRY' => 'create-product',
+            'URI_EDIT_ENTRY' => 'edit-product',
+            'URI_DOWNLOAD_ENTRY' => 'download-product',
+            'URI_MANAGE_COMMON' => 'products-manage',
+            'URI_FAVORITES_LIST' => 'products-favorites',
+
+            '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_TOP' => 'page.php?i=products-top',
+            'URL_UPDATED' => 'page.php?i=products-updated',
+            'URL_MANAGE_COMMON' => 'page.php?i=products-manage',
+            'URL_MANAGE_ADMINISTRATION' => 'page.php?i=products-administration',
+            'URL_LICENSES_COMMON' => 'page.php?i=products-licenses',
+            'URL_LICENSES_ADMINISTRATION' => 'page.php?i=products-licenses-administration',
+            'URL_VIEW_ENTRY' => 'page.php?i=view-product&id=',
+
+            // some params
+            'PARAM_AUTO_APPROVE' => 'bx_market_enable_auto_approve',
+            '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',
+            'PARAM_PER_PAGE_FOR_FAVORITES_LISTS' => 'bx_market_per_page_for_favorites_lists',
+
+            // 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_REACTIONS' => 'bx_market_reactions',
+            'OBJECT_SCORES' => 'bx_market',
+            'OBJECT_FAVORITES' => 'bx_market',
+            'OBJECT_FEATURED' => 'bx_market',
+            'OBJECT_METATAGS' => 'bx_market',
+            'OBJECT_COMMENTS' => 'bx_market',
+            'OBJECT_NOTES' => 'bx_market_notes',
+            'OBJECT_CATEGORY' => 'bx_market_cats',
+            'OBJECT_PRIVACY_VIEW' => 'bx_market_allow_view_to',
+            'OBJECT_PRIVACY_LIST_VIEW' => 'bx_market_allow_view_favorite_list',
+            '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_MORE' => 'bx_market_view_more', 
+            'OBJECT_MENU_ACTIONS_VIEW_ENTRY_ALL' => 'bx_market_view_actions', // all actions menu on view entry page
+            '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_ACTIONS_SNIPPET_MORE' => 'bx_market_snippet_more', // actions menu (short) from view entry page but created for snippet actions menu
+            '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_MENU_LICENSES' => 'bx_market_licenses_submenu',
+            'OBJECT_GRID_ADMINISTRATION' => 'bx_market_administration',
+            'OBJECT_GRID_COMMON' => 'bx_market_common',
+            'OBJECT_GRID_LICENSES_ADMINISTRATION' => 'bx_market_licenses_administration',
+            'OBJECT_GRID_LICENSES' => 'bx_market_licenses',
+            'OBJECT_UPLOADERS' => array('bx_market_simple', 'bx_market_html5'),
+            'OBJECT_CONNECTION_SUBENTRIES' => 'bx_market_subentries',
+            
+            'BADGES_AVALIABLE' => true,
+
+            // 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_more' => $aMenuItems2Methods,
+                'bx_market_snippet_more' => $aMenuItems2Methods,
+            ),
+
+            // informer messages
+            'INFORMERS' => array (
+                'approving' => array (
+                    'name' => 'bx-market-approving',
+                    'map' => array (
+                        'pending' => array('msg' => '_bx_market_txt_msg_status_pending', 'type' => BX_INFORMER_ALERT),
+                        'hidden' => array('msg' => '_bx_market_txt_msg_status_hidden', 'type' => BX_INFORMER_ERROR),
+                    ),
+                ),
+            ),
+
+            // global settings
+            'OPTION_ENABLE_RECURRING' => 'bx_market_enable_recurring',
+            'OPTION_RECURRING_RESERVE' => 'bx_market_recurring_reserve',
+
+            // email templates
+            'ETEMPLATE_PURCHASED' => 'bx_market_purchased',
+
+            // 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',
+                'txt_sample_reaction_single' => '_bx_market_txt_sample_reaction_single',
+                'txt_sample_score_up_single' => '_bx_market_txt_sample_score_up_single',
+                'txt_sample_score_down_single' => '_bx_market_txt_sample_score_down_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_pending' => '_bx_market_grid_filter_item_title_adm_pending',
+            	'filter_item_select_one_filter1' => '_bx_market_grid_filter_item_title_adm_select_one_filter1',
+                'filter_item_select_one_filter2' => '_bx_market_grid_filter_item_title_adm_select_one_filter2',
+            	'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_in' => '_bx_market_txt_all_entries_in',
+                'txt_all_entries_by_author' => '_bx_market_page_title_browse_by_author',
+                'txt_all_entries_by_context' => '_bx_market_page_title_browse_by_context',
+                '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(
+        	'form' => 'BxMarketForm',
+        	'entry' => 'BxMarketEntry',
+        	'manage_tools' => 'BxMarketManageTools',
+        	'licenses' => 'BxMarketLicenses'
+        );
+
+        $this->_aJsObjects = array(
+        	'form' => 'oBxMarketForm',
+        	'entry' => 'oBxMarketEntry',
+        	'manage_tools' => 'oBxMarketManageTools',
+        	'licenses' => 'oBxMarketLicenses'
+        );
+
+        $this->_aGridObjects = array(
+        	'common' => $this->CNF['OBJECT_GRID_COMMON'],
+        	'administration' => $this->CNF['OBJECT_GRID_ADMINISTRATION'],
+                'licenses_administration' => $this->CNF['OBJECT_GRID_LICENSES_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;
+    }
+
+    public function getEntryName($sName)
+    {
+        return uriGenerate($sName, $this->CNF['TABLE_ENTRIES'], $this->CNF['FIELD_NAME']);
+    }
+}
+
+/** @} */

+ 708 - 0
modules/boonex/market/updates/13.0.0_13.0.1/source/classes/BxMarketDb.php

@@ -0,0 +1,708 @@
+<?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 getProductsNames ($iVendor = 0, $iLimit = 1000)
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        $sWhere = '';
+        $aBindings = array('limit' => $iLimit);
+        if ($iVendor) {
+            $aBindings['author'] = $iVendor;
+            $sWhere .= "AND `{$CNF['FIELD_AUTHOR']} = :author`";
+        }
+
+        return $this->getColumn("SELECT `{$CNF['FIELD_NAME']}` FROM `{$CNF['TABLE_ENTRIES']}` WHERE (`{$CNF['FIELD_PRICE_SINGLE']}` != '0' OR `{$CNF['FIELD_PRICE_RECURRING']}` != '0') $sWhere LIMIT :limit", $aBindings);
+    }
+    
+    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('latest', 'popular', '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']) . ") ";
+
+        //--- Attach custom queries described with field - value pairs.
+        if(!empty($aParams['custom_and']) && is_array($aParams['custom_and']))
+            $sWhereClause .= " AND (" . $this->arrayToSQL($aParams['custom_and'], ' AND ') . ") ";
+
+        if(!empty($aParams['custom_or']) && is_array($aParams['custom_or']))
+            $sWhereClause .= " AND (" . $this->arrayToSQL($aParams['custom_or'], ' OR ') . ") ";
+
+    	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 updateContentInfoBy ($aSet, $aWhere)
+    {
+        $sQuery = "UPDATE `" . $this->_oConfig->CNF['TABLE_ENTRIES'] . "` SET " . $this->arrayToSQL($aSet) . " WHERE " . (!empty($aWhere) ? $this->arrayToSQL($aWhere, ' AND ') : "1");
+        return (int)$this->query($sQuery) > 0;
+    }
+
+	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 'product_id':
+                $aMethod['params'][1] = array(
+                    'product_id' => $aParams['product_id']
+                );
+
+                $sWhereClause = " AND `tl`.`product_id`=:product_id";
+
+                if(!empty($aParams['profile_id'])) {
+                    $aMethod['params'][1]['profile_id'] = $aParams['profile_id'];
+                    $sWhereClause .= " AND `tl`.`profile_id`=:profile_id";
+                }
+                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 `te`.`" . $CNF['FIELD_ID'] . "` FROM `" . $CNF['TABLE_ENTRIES'] . "` AS `te` LEFT JOIN `" . $CNF['TABLE_FILES2ENTRIES'] . "` AS `tfe` ON `te`.`id`=`tfe`.`content_id` WHERE `tfe`.`file_id`=: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;
+
+        $oPayments = BxDolPayments::getInstance();
+
+        $iProcessed = 0;
+        for($i = 0; $i < $iCount; $i++) {
+            $aQueryParams = array(
+                'profile_id' => $iProfileId,
+                'product_id' => $iProductId,
+                'count' => 1,
+                '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))';
+
+            if((int)$this->query("INSERT INTO `" . $CNF['TABLE_LICENSES'] . "` SET " . $this->arrayToSQL($aQueryParams) . ", `added`=UNIX_TIMESTAMP()" . $sExpireParam) == 0)
+                continue;
+
+            $sLicense = $oPayments->generateLicense();
+            $iProcessed += 1;
+        }
+
+        return $iCount == $iProcessed;
+    }
+
+    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 ?", $iProfileId, $iProductId, $sOrder, (int)$iCount);
+
+        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 processExpiredLicense($aLicense)
+    {
+        //--- Move to deleted licenses table with 'expire' as reason.  
+        $this->query("INSERT IGNORE INTO `" . $this->_oConfig->CNF['TABLE_LICENSES_DELETED'] . "` SET " . $this->arrayToSQL($aLicense));
+
+        return $this->query("DELETE FROM `" . $this->_oConfig->CNF['TABLE_LICENSES'] . "` WHERE `id`=:id LIMIT 1", array('id' => $aLicense['id'])) !== 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`.`order` 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";
+                }
+
+                if(isset($aParams['ordered']) && $aParams['ordered'] === true)
+                    $sOrderClause = "`tfe`.`version` ASC";
+
+            	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;
+    }
+}
+
+/** @} */

+ 150 - 0
modules/boonex/market/updates/13.0.0_13.0.1/source/classes/BxMarketSearchResult.php

@@ -0,0 +1,150 @@
+<?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',
+            		'Image' => 'thumb'
+                ),
+            ),
+            '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;
+                
+            case 'context':
+                if(!$this->_updateCurrentForContext($sMode, $aParams, $oProfileAuthor))
+                    $this->isError = true;
+                break;
+
+            case 'favorite':
+                if(!$this->_updateCurrentForFavorite($sMode, $aParams, $oProfileAuthor))
+                    $this->isError = true;
+                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 'top':
+                $this->sBrowseUrl = BxDolPermalinks::getInstance()->permalink($CNF['URL_TOP']);
+                $this->aCurrent['title'] = _t('_bx_market_page_title_browse_top');
+                $this->aCurrent['rss']['link'] = 'modules/?r=market/rss/' . $sMode;
+                $this->aCurrent['sorting'] = 'top';
+                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);
+        $this->addCustomConditions($CNF, $oProfileAuthor, $sMode, $aParams);
+    }
+
+    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();
+    }
+}
+
+/** @} */

+ 433 - 0
modules/boonex/market/updates/13.0.0_13.0.1/source/classes/BxMarketTemplate.php

@@ -0,0 +1,433 @@
+<?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 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 getTmplVarsText($aData)
+    {
+        $oModule = $this->getModule();
+        $CNF = &$oModule->_oConfig->CNF;
+
+        $aVars = parent::getTmplVarsText($aData);
+
+        $sIcon = '';
+        $mixedIcon = $oModule->getEntryImageData($aData, 'FIELD_THUMB', array('OBJECT_IMAGES_TRANSCODER_THUMB', 'OBJECT_IMAGES_TRANSCODER_GALLERY'));
+        if($mixedIcon !== false) {
+            if(!empty($mixedIcon['object']))
+                $o = BxDolStorage::getObjectInstance($mixedIcon['object']);
+            else if(!empty($mixedIcon['transcoder']))
+                $o = BxDolTranscoder::getObjectInstance($mixedIcon['transcoder']);
+
+            if($o)
+                $sIcon = $o->getFileUrlById($mixedIcon['id']);
+        }
+
+        $aVars['bx_if:show_icon'] = array(
+            'condition' => !empty($sIcon),
+            'content' => array(
+                'entry_icon' => $sIcon
+            )
+        );
+
+        $sScreenshots = $this->getScreenshots($aData);
+        $bScreenshots = !empty($sScreenshots);
+        if($bScreenshots) {
+            $this->addCss(BX_DIRECTORY_PATH_PLUGINS_PUBLIC . 'flickity/|flickity.css');
+            $this->addJs('flickity/flickity.pkgd.min.js');
+        }
+
+        $aVars['bx_if:show_screenshots'] = array(
+            'condition' => $bScreenshots,
+            'content' => array(
+                'screenshots' => $sScreenshots
+            )
+        );
+        
+        return $aVars;
+    }
+
+    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
+    	));    	
+    }
+
+    protected function getUnit ($aData, $aParams = array())
+    {
+        $bTmplVarsSectionAuthor = true;
+        $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 = !$oPayment->isCreditsOnly() && (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) {
+                $sDuration = 'txt_per_' . $aData[$CNF['FIELD_DURATION_RECURRING']] . '_short';
+                $sDuration = _t(!empty($CNF['T'][$sDuration]) ? $CNF['T'][$sDuration] : '_bx_market_txt_per_' . $aData[$CNF['FIELD_DURATION_RECURRING']] . '_short');
+
+                $sPricing = _t('_bx_market_txt_price_recurring_short', $this->_aCurrency['sign'], $aData[$CNF['FIELD_PRICE_RECURRING']], $sDuration);
+            }
+
+            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())
+    {
+        $mixedAttachments = parent::getAttachments($sStorage, $aData, $aParams);
+        if(empty($mixedAttachments) || !is_array($mixedAttachments))
+            return $mixedAttachments;
+
+        $aAttachments = [];
+        foreach($mixedAttachments as $aAttachment)
+            $aAttachments[(int)$aAttachment['id']] = $aAttachment;       
+
+        $aFiles = $this->_oDb->getFile(['type' => 'content_id_key_file_id', 'content_id' => $aData['id']]);
+
+        $aResults = [];
+        $sCaptionType = "";
+        foreach($aFiles as $iAttachmentId => $aFile) {
+            $aAttachments[$iAttachmentId]['class'] = (int)$aData['package'] == $iAttachmentId ? ' bx-market-attachment-main' : '';
+            $aAttachments[$iAttachmentId]['bx_if:main'] = [
+                'condition' => (int)$aData['package'] == $iAttachmentId,
+                'content' => []
+            ];
+
+            $bSeparatorNeeded = false;
+            if ($aFiles[$iAttachmentId]['type'] != $sCaptionType){
+                $bSeparatorNeeded = true;
+                $sCaptionType = $aFiles[$iAttachmentId]['type'];
+            }
+
+            if ((int)$aData['package'] == $iAttachmentId){
+                $bSeparatorNeeded = true;
+                $sCaptionType = 'latest';
+            }
+
+            $bAttachment = !empty($aFiles[$iAttachmentId]);
+            $aAttachments[$iAttachmentId]['bx_if:not_image']['content'] = array_merge($aAttachments[$iAttachmentId]['bx_if:not_image']['content'], [
+                'file_type' => $bAttachment ? _t('_bx_market_form_entry_input_files_type_' . $aFiles[$iAttachmentId]['type']) : '',
+                'file_name_attr' => bx_html_attribute($aAttachments[$iAttachmentId]['file_name']),
+                'bx_if:show_version' => [
+                    'condition' => $bAttachment && $aFiles[$iAttachmentId]['type'] == BX_MARKET_FILE_TYPE_VERSION,
+                    'content' => [
+                        'file_version' => $bAttachment ? $aFiles[$iAttachmentId]['version'] : ''
+                    ]
+                ],
+                'bx_if:show_update' => [
+                    'condition' => $bAttachment && $aFiles[$iAttachmentId]['type'] == BX_MARKET_FILE_TYPE_UPDATE,
+                    'content' => [
+                        'file_version_from_to' => $bAttachment ? _t('_bx_market_form_entry_input_files_version_from_x_to_y', $aFiles[$iAttachmentId]['version'], $aFiles[$iAttachmentId]['version_to']) : ''
+                    ]
+                ]
+            ]);
+            $aAttachments[$iAttachmentId]['bx_if:show_separator'] = [
+                'condition' => $bSeparatorNeeded, 
+                'content' => [
+                    'type' => _t('_bx_market_form_entry_input_files_version_caption_' . $sCaptionType)
+                ]
+            ];
+
+            $aFiles[$iAttachmentId] = $aAttachments[$iAttachmentId];
+            $aResults[$iAttachmentId] = $aAttachments[$iAttachmentId];
+        }
+
+        return array_intersect_key($aFiles, $aResults);
+    }
+
+    protected function getAttachmentsImagesTranscoders ($sStorage = '')
+    {
+        $CNF = &$this->getModule()->_oConfig->CNF;
+
+        $oTranscoder = BxDolTranscoderImage::getObjectInstance($CNF['OBJECT_IMAGES_TRANSCODER_PREVIEW']);
+        $oTranscoderPreview = isset($CNF['OBJECT_IMAGES_TRANSCODER_PICTURE']) && $CNF['OBJECT_IMAGES_TRANSCODER_PICTURE'] ? BxDolTranscoderImage::getObjectInstance($CNF['OBJECT_IMAGES_TRANSCODER_PICTURE']) : null;
+
+        return array($oTranscoder, $oTranscoderPreview);
+    }
+
+    protected function _getHeaderImage($aData)
+    {
+        return $this->getModule()->getEntryImageData($aData, 'FIELD_COVER');
+    }
+}
+
+/** @} */

+ 140 - 0
modules/boonex/market/updates/13.0.0_13.0.1/source/install/config.php

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

+ 474 - 0
modules/boonex/market/updates/13.0.0_13.0.1/source/install/langs/en.xml

@@ -0,0 +1,474 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources name="en" flag="gb" title="English">
+
+	<string name="_bx_market"><![CDATA[Market]]></string>
+	<string name="_bx_market_cmts"><![CDATA[Market's Reviews]]></string>
+        <string name="_bx_market_reactions"><![CDATA[Market's Reactions]]></string>
+
+        <string name="_bx_market_option_enable_auto_approve"><![CDATA[Auto approve a product after creation]]></string>
+	<string name="_bx_market_option_enable_recurring"><![CDATA[Allow to sell subscriptions]]></string>
+	<string name="_bx_market_option_recurring_reserve"><![CDATA[Reserve (in days) to accept and process recurring payment notification]]></string>
+	<string name="_bx_market_option_summary_chars"><![CDATA[Number of characters in auto-cropped product summary]]></string>
+	<string name="_bx_market_option_plain_summary_chars"><![CDATA[Number of characters in plain product description when product hasn't thumb]]></string>
+	<string name="_bx_market_option_per_page_browse"><![CDATA[Number of items per page]]></string>
+	<string name="_bx_market_option_per_page_profile"><![CDATA[Number of items on profile page]]></string>
+	<string name="_bx_market_option_rss_num"><![CDATA[Number of items in RSS feed]]></string>
+	<string name="_bx_market_option_searchable_fields"><![CDATA[Searchable fields for keyword search]]></string>
+        <string name="_bx_market_option_per_page_for_favorites_lists"><![CDATA[Number of favorite lists per page]]></string>
+
+	<string name="_bx_market_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[Leave empty to make the product free.]]></string>
+    <string name="_bx_market_form_entry_input_sys_duration_recurring"><![CDATA[Billing period]]></string>
+    <string name="_bx_market_form_entry_input_duration_recurring"><![CDATA[Billing period]]></string>
+    <string name="_bx_market_form_entry_input_sys_trial_recurring"><![CDATA[Recurring trial]]></string>
+    <string name="_bx_market_form_entry_input_trial_recurring"><![CDATA[Trial period]]></string>
+    <string name="_bx_market_form_entry_input_trial_recurring_inf"><![CDATA[The number of days new customers should receive a free trial. Leave empty to disable trial period.]]></string>
+    <string name="_bx_market_form_entry_input_sys_header_beg_single"><![CDATA[One-time payment: begin]]></string>
+    <string name="_bx_market_form_entry_input_header_beg_single"><![CDATA[One-time payment]]></string>
+    <string name="_bx_market_form_entry_input_sys_header_beg_recurring"><![CDATA[Recurring payment: begin]]></string>
+    <string name="_bx_market_form_entry_input_header_beg_recurring"><![CDATA[Recurring payment]]></string>
+    <string name="_bx_market_form_entry_input_sys_header_beg_privacy"><![CDATA[Privacy: begin]]></string>
+    <string name="_bx_market_form_entry_input_header_beg_privacy"><![CDATA[Privacy]]></string>
+    <string name="_bx_market_form_entry_input_sys_header_beg_notes"><![CDATA[Notes: begin]]></string>
+    <string name="_bx_market_form_entry_input_header_beg_notes"><![CDATA[Notes]]></string>
+    <string name="_bx_market_form_entry_input_sys_header_beg_other"><![CDATA[Other: begin]]></string>
+    <string name="_bx_market_form_entry_input_header_beg_other"><![CDATA[Other]]></string>
+    <string name="_bx_market_form_entry_input_sys_header_end_single"><![CDATA[One-time payment: end]]></string>
+    <string name="_bx_market_form_entry_input_sys_header_end_recurring"><![CDATA[Recurring payment: end]]></string>
+    <string name="_bx_market_form_entry_input_sys_header_end_privacy"><![CDATA[Privacy: end]]></string>
+    <string name="_bx_market_form_entry_input_sys_header_end_notes"><![CDATA[Notes: end]]></string>
+    <string name="_bx_market_form_entry_input_sys_header_end_other"><![CDATA[Other: end]]></string>
+	<string name="_bx_market_form_entry_input_sys_text"><![CDATA[Text]]></string>
+	<string name="_bx_market_form_entry_input_text"><![CDATA[Text]]></string>
+	<string name="_bx_market_form_entry_input_text_err"><![CDATA[Text field can't be empty]]></string>
+	<string name="_bx_market_form_entry_input_sys_notes"><![CDATA[Notes]]></string>
+	<string name="_bx_market_form_entry_input_notes"><![CDATA[Notes]]></string>
+        <string name="_bx_market_form_entry_input_notes_inf"><![CDATA[Will be shown on product's info page.]]></string>
+        <string name="_bx_market_form_entry_input_sys_notes_purchased"><![CDATA[After purchase notes]]></string>
+        <string name="_bx_market_form_entry_input_notes_purchased"><![CDATA[After purchase notes]]></string>
+        <string name="_bx_market_form_entry_input_notes_purchased_inf"><![CDATA[Will be attached to email message which is sent to buyer after purchase.]]></string>
+	<string name="_bx_market_form_entry_input_sys_delete_confirm"><![CDATA[Delete confirmation]]></string>
+	<string name="_bx_market_form_entry_input_delete_confirm"><![CDATA[I am sure I want to delete this product]]></string>
+	<string name="_bx_market_form_entry_input_delete_confirm_info"><![CDATA[This action can not be undone]]></string>
+	<string name="_bx_market_form_entry_input_delete_confirm_error"><![CDATA[Please check this checkbox if you really want to delete the product]]></string>
+	<string name="_bx_market_form_entry_input_sys_pictures"><![CDATA[Pictures]]></string>
+	<string name="_bx_market_form_entry_input_pictures"><![CDATA[Pictures]]></string>
+	<string name="_bx_market_form_entry_input_pictures_title"><![CDATA[Title]]></string>
+	<string name="_bx_market_form_entry_input_pictures_use_as_thumb"><![CDATA[Icon]]></string>
+	<string name="_bx_market_form_entry_input_pictures_use_as_cover"><![CDATA[Header Image]]></string>
+	<string name="_bx_market_form_entry_input_sys_files"><![CDATA[Files]]></string>
+	<string name="_bx_market_form_entry_input_files"><![CDATA[Files]]></string>
+	<string name="_bx_market_form_entry_input_files_use_as_main"><![CDATA[Use as Main]]></string>
+	<string name="_bx_market_form_entry_input_files_name"><![CDATA[Name:]]></string>
+	<string name="_bx_market_form_entry_input_files_version"><![CDATA[Version:]]></string>
+	<string name="_bx_market_form_entry_input_files_type"><![CDATA[Type:]]></string>
+	<string name="_bx_market_form_entry_input_files_type_version"><![CDATA[version]]></string>
+	<string name="_bx_market_form_entry_input_files_type_update"><![CDATA[update]]></string>
+	<string name="_bx_market_form_entry_input_files_version_from"><![CDATA[Version from:]]></string>
+	<string name="_bx_market_form_entry_input_files_version_to"><![CDATA[Version to:]]></string>
+	<string name="_bx_market_form_entry_input_files_version_from_x_to_y"><![CDATA[{0} to {1}]]></string>
+    <string name="_bx_market_form_entry_input_sys_allow_view_to"><![CDATA[Who can view]]></string>
+    <string name="_bx_market_form_entry_input_allow_view_to"><![CDATA[Who can view]]></string>
+    <string name="_bx_market_form_entry_input_allow_view_favorite_list"><![CDATA[Visibility]]></string>
+    <string name="_bx_market_form_entry_input_sys_allow_purchase_to"><![CDATA[Who can purchase]]></string>
+    <string name="_bx_market_form_entry_input_allow_purchase_to"><![CDATA[Who can purchase]]></string>
+    <string name="_bx_market_form_entry_input_sys_allow_comment_to"><![CDATA[Who can review]]></string>
+    <string name="_bx_market_form_entry_input_allow_comment_to"><![CDATA[Who can review]]></string>
+    <string name="_bx_market_form_entry_input_sys_allow_vote_to"><![CDATA[Who can vote]]></string>
+    <string name="_bx_market_form_entry_input_allow_vote_to"><![CDATA[Who can vote]]></string>
+    <string name="_bx_market_form_entry_input_sys_added"><![CDATA[Created]]></string>
+    <string name="_bx_market_form_entry_input_added"><![CDATA[Created]]></string>
+    <string name="_bx_market_form_entry_input_sys_changed"><![CDATA[Updated]]></string>
+    <string name="_bx_market_form_entry_input_changed"><![CDATA[Updated]]></string>
+    <string name="_bx_market_form_entry_input_sys_warning_single"><![CDATA[Warning for single payments]]></string>
+    <string name="_bx_market_form_entry_input_sys_warning_recurring"><![CDATA[Warning for recurring payments]]></string>
+    <string name="_bx_market_form_entry_input_sys_subentries"><![CDATA[Subproducts]]></string>
+    <string name="_bx_market_form_entry_input_subentries"><![CDATA[Subproducts]]></string>
+    <string name="_bx_market_form_entry_input_subentries_inf"><![CDATA[Leave empty if you don't want to create association.]]></string>
+    <string name="_bx_market_form_entry_input_subentries_placeholder"><![CDATA[Type product name here...]]></string>
+    <string name="_bx_market_form_entry_input_files_version_caption_latest"><![CDATA[Latest version]]></string>
+    <string name="_bx_market_form_entry_input_files_version_caption_version"><![CDATA[Older versions]]></string>
+    <string name="_bx_market_form_entry_input_files_version_caption_update"><![CDATA[Updates]]></string>
+
+  <string name="_bx_market_acl_action_create_entry"><![CDATA[Create Product]]></string>
+	<string name="_bx_market_acl_action_delete_entry"><![CDATA[Delete Product]]></string>
+	<string name="_bx_market_acl_action_download_entry"><![CDATA[Download Product]]></string>
+	<string name="_bx_market_acl_action_view_entry"><![CDATA[View Product]]></string>
+	<string name="_bx_market_acl_action_set_cover"><![CDATA[Set Product Cover]]></string>
+	<string name="_bx_market_acl_action_set_subentries"><![CDATA[Set Product Subproducts]]></string>
+	<string name="_bx_market_acl_action_set_thumb"><![CDATA[Set Product Thumbnail]]></string>
+	<string name="_bx_market_acl_action_edit_any_entry"><![CDATA[Edit Any Product]]></string>
+	<string name="_bx_market_acl_action_delete_any_entry"><![CDATA[Delete Any Product]]></string>
+
+	<string name="_bx_market_privacy_group_customers"><![CDATA[Customers]]></string>
+
+	<string name="_bx_market_page_title_sys_create_entry"><![CDATA[New Product]]></string>
+	<string name="_bx_market_page_title_create_entry"><![CDATA[New Product]]></string>
+	<string name="_bx_market_page_block_title_create_entry"><![CDATA[New Product]]></string>
+	<string name="_bx_market_page_title_sys_edit_entry"><![CDATA[Edit Product]]></string>
+	<string name="_bx_market_page_title_edit_entry"><![CDATA[Edit Product]]></string>
+	<string name="_bx_market_page_block_title_edit_entry"><![CDATA[Edit Product]]></string>
+    <string name="_bx_market_page_title_sys_delete_entry"><![CDATA[Delete Product]]></string>
+    <string name="_bx_market_page_title_delete_entry"><![CDATA[Delete Product]]></string>
+    <string name="_bx_market_page_block_title_delete_entry"><![CDATA[Delete Product]]></string>
+	<string name="_bx_market_page_title_sys_download_entry"><![CDATA[Download Product]]></string>
+    <string name="_bx_market_page_title_download_entry"><![CDATA[Download Product]]></string>
+    <string name="_bx_market_page_block_title_download_entry"><![CDATA[Download Product]]></string>
+	<string name="_bx_market_page_title_sys_view_entry"><![CDATA[View Product]]></string>
+	<string name="_bx_market_page_title_view_entry"><![CDATA[{title}]]></string>
+	<string name="_bx_market_page_block_title_entry_text"><![CDATA[Product Overview]]></string>
+	<string name="_bx_market_page_title_browse"><![CDATA[Products]]></string>
+	<string name="_bx_market_page_title_search_results"><![CDATA[Products matching "{0}"]]></string>
+	<string name="_bx_market_page_title_browse_by_author"><![CDATA[Products of {display_name}]]></string>
+  <string name="_bx_market_page_title_browse_by_context"><![CDATA[Products in {display_name}]]></string>
+	<string name="_bx_market_page_title_browse_featured"><![CDATA[Featured Products]]></string>
+    <string name="_bx_market_page_title_browse_latest"><![CDATA[Latest Products]]></string>
+    <string name="_bx_market_page_title_browse_popular"><![CDATA[Popular Products]]></string>
+    <string name="_bx_market_page_title_browse_top"><![CDATA[Top Products]]></string>
+    <string name="_bx_market_page_title_browse_updated"><![CDATA[Updated Products]]></string>
+    <string name="_bx_market_page_title_browse_category"><![CDATA[Products by category: {0}]]></string>
+    <string name="_bx_market_page_title_browse_keyword"><![CDATA[Products by hashtag: {0}]]></string>
+    <string name="_bx_market_page_title_sys_home"><![CDATA[Market Home]]></string>
+    <string name="_bx_market_page_title_home"><![CDATA[Market]]></string>
+    <string name="_bx_market_page_block_title_featured_entries"><![CDATA[Featured Products]]></string>
+    <string name="_bx_market_page_block_title_featured_entries_view_extended"><![CDATA[Featured Products (Extended View)]]></string>
+    <string name="_bx_market_page_block_title_featured_entries_view_full"><![CDATA[Featured Products (Full View)]]></string>
+    <string name="_bx_market_page_block_title_latest_entries"><![CDATA[Latest Products]]></string>
+    <string name="_bx_market_page_block_title_latest_entries_view_extended"><![CDATA[Latest Products (Extended View)]]></string>
+    <string name="_bx_market_page_block_title_latest_entries_view_full"><![CDATA[Latest Products (Full View)]]></string>
+    <string name="_bx_market_page_block_title_entry_social_sharing"><![CDATA[Share]]></string>
+    <string name="_bx_market_page_block_title_entry_author"><![CDATA[Vendor]]></string>
+    <string name="_bx_market_page_block_title_entry_author_entries"><![CDATA[More Products From {0}]]></string>
+    <string name="_bx_market_page_block_title_entry_actions"><![CDATA[Actions]]></string>
+    <string name="_bx_market_page_block_title_entry_breadcrumb"><![CDATA[Breadcrumb]]></string>
+    <string name="_bx_market_page_block_title_entry_comments"><![CDATA[Reviews]]></string>
+	<string name="_bx_market_page_block_title_entry_reports"><![CDATA[Reports]]></string>
+    <string name="_bx_market_page_block_title_entry_comments_link"><![CDATA[Reviews to <a href="{entry_link}">{title}</a>]]></string>
+    <string name="_bx_market_page_block_title_entry_comments_n"><![CDATA[Reviews ({0})]]></string>
+    <string name="_bx_market_page_block_title_entry_info"><![CDATA[Info]]></string>
+    <string name="_bx_market_page_block_title_entry_info_link"><![CDATA[<a href="{entry_link}">{title}</a> Info]]></string>
+    <string name="_bx_market_page_block_title_entry_location"><![CDATA[Location]]></string>
+    <string name="_bx_market_page_block_title_entry_attachments"><![CDATA[Attachments]]></string>
+    <string name="_bx_market_page_block_title_entry_all_actions"><![CDATA[All Actions]]></string>
+    <string name="_bx_market_page_block_title_entry_rating"><![CDATA[Rating]]></string>
+    <string name="_bx_market_page_title_sys_entries_latest"><![CDATA[Latest Products]]></string>
+    <string name="_bx_market_page_title_entries_latest"><![CDATA[Latest Products]]></string>
+    <string name="_bx_market_page_title_sys_entries_featured"><![CDATA[Featured Products]]></string>
+    <string name="_bx_market_page_title_entries_featured"><![CDATA[Featured Products]]></string>
+    <string name="_bx_market_page_title_sys_entries_popular"><![CDATA[Popular Products]]></string>
+    <string name="_bx_market_page_title_entries_popular"><![CDATA[Popular Products]]></string>
+    <string name="_bx_market_page_title_sys_entries_top"><![CDATA[Top Products]]></string>
+    <string name="_bx_market_page_title_entries_top"><![CDATA[Top Products]]></string>
+    <string name="_bx_market_page_title_sys_entries_updated"><![CDATA[Updated Products]]></string>
+    <string name="_bx_market_page_title_entries_updated"><![CDATA[Updated Products]]></string>
+    <string name="_bx_market_page_block_title_popular_entries"><![CDATA[Popular Products]]></string>
+    <string name="_bx_market_page_block_title_popular_entries_view_extended"><![CDATA[Popular Products (Extended View)]]></string>
+    <string name="_bx_market_page_block_title_popular_entries_view_full"><![CDATA[Popular Products (Full View)]]></string>
+    <string name="_bx_market_page_block_title_top_entries"><![CDATA[Top Products]]></string>
+    <string name="_bx_market_page_block_title_updated_entries"><![CDATA[Updated Products]]></string>
+    <string name="_bx_market_page_block_title_updated_entries_view_extended"><![CDATA[Updated Products (Extended View)]]></string>
+    <string name="_bx_market_page_block_title_updated_entries_view_full"><![CDATA[Updated Products (Full View)]]></string>
+    <string name="_bx_market_page_block_title_favorites_entries"><![CDATA["{title}" List]]></string>
+    <string name="_bx_market_page_block_title_favorites_entries_info"><![CDATA[Info]]></string>
+	<string name="_bx_market_page_block_title_sys_entry_context"><![CDATA[Posted in]]></string>
+    <string name="_bx_market_page_block_title_entry_context"><![CDATA[Posted in]]></string>
+	
+    <string name="_bx_market_page_title_sys_view_entry_comments"><![CDATA[Product Reviews]]></string>
+    <string name="_bx_market_page_title_view_entry_comments"><![CDATA[Reviews to {title}]]></string>
+    <string name="_bx_market_page_title_sys_view_entry_info"><![CDATA[Product Info]]></string>
+    <string name="_bx_market_page_title_view_entry_info"><![CDATA[{title} Info]]></string>
+    <string name="_bx_market_page_title_sys_entries_of_author"><![CDATA[Products of author]]></string>
+    <string name="_bx_market_page_title_entries_of_author"><![CDATA[Products by {display_name}]]></string>
+    <string name="_bx_market_page_title_sys_entries_in_context"><![CDATA[Products in context]]></string>
+    <string name="_bx_market_page_title_entries_in_context"><![CDATA[Products in {display_name}]]></string>
+    <string name="_bx_market_page_block_title_favorites_of_author"><![CDATA[Favorites by <a href="{profile_link}">{display_name}</a>]]></string>
+    <string name="_bx_market_page_block_title_sys_favorites_of_author"><![CDATA[Favorites of author]]></string>
+    <string name="_bx_market_page_block_title_entries_of_author"><![CDATA[Products by <a href="{profile_link}">{display_name}</a>]]></string>
+    <string name="_bx_market_page_block_title_sys_entries_of_author"><![CDATA[Products of author]]></string>
+    <string name="_bx_market_page_block_title_entries_in_context"><![CDATA[Products in <a href="{profile_link}">{display_name}</a>]]></string>
+    <string name="_bx_market_page_block_title_sys_entries_in_context"><![CDATA[Products in context]]></string>
+    <string name="_bx_market_page_block_title_entries_actions"><![CDATA[Products actions]]></string>
+    <string name="_bx_market_page_block_title_browse_cmts"><![CDATA[Products' Reviews]]></string>
+	<string name="_bx_market_page_title_sys_manage"><![CDATA[Manage Own Products]]></string>
+	<string name="_bx_market_page_title_sys_manage_administration"><![CDATA[Manage All Products]]></string>
+	<string name="_bx_market_page_title_manage"><![CDATA[Manage Products]]></string>
+	<string name="_bx_market_page_block_title_system_manage"><![CDATA[Manage Own Products]]></string>
+	<string name="_bx_market_page_block_title_system_manage_administration"><![CDATA[Manage All Products]]></string>
+	<string name="_bx_market_page_block_title_manage"><![CDATA[Manage Products]]></string>    
+	<string name="_bx_market_page_block_title_popular_keywords"><![CDATA[Popular Hashtags]]></string>
+	<string name="_bx_market_page_block_title_cats"><![CDATA[Products Categories]]></string>
+	<string name="_bx_market_page_title_sys_entries_categories"><![CDATA[Categories]]></string>
+    <string name="_bx_market_page_title_entries_categories"><![CDATA[Categories]]></string>
+    <string name="_bx_market_page_block_title_categories_entries"><![CDATA[Products]]></string>
+    
+    <string name="_bx_market_page_title_sys_licenses_administration"><![CDATA[Licenses]]></string>
+    <string name="_bx_market_page_title_licenses_administration"><![CDATA[Licenses]]></string>
+    <string name="_bx_market_page_block_title_licenses_administration"><![CDATA[Licenses]]></string>
+    <string name="_bx_market_page_title_sys_licenses"><![CDATA[Licenses]]></string>
+    <string name="_bx_market_page_title_licenses"><![CDATA[Licenses]]></string>
+    <string name="_bx_market_page_block_title_licenses"><![CDATA[Licenses]]></string>
+    <string name="_bx_market_page_block_title_licenses_note"><![CDATA[Note]]></string>
+    <string name="_bx_market_page_block_content_licenses_note"><![CDATA[The licenses are for reference only. There is no need to "register" them, as you can simply download and install licensed UNA apps directly from your site Studio Apps store.]]></string>
+    <string name="_bx_market_page_block_title_sys_view_profile"><![CDATA[User Products]]></string>
+    <string name="_bx_market_page_block_title_view_profile"><![CDATA[{display_name} Products]]></string>
+    <string name="_bx_market_page_title_sys_entries_search"><![CDATA[Search]]></string>
+    <string name="_bx_market_page_title_entries_search"><![CDATA[Search]]></string>
+    <string name="_bx_market_page_title_sys_entries_favorites"><![CDATA[Favorites Products]]></string>
+    <string name="_bx_market_page_title_entries_favorites"><![CDATA[Favorites Products]]></string>
+    <string name="_bx_market_page_block_title_search_form"><![CDATA[Search Form]]></string>
+    <string name="_bx_market_page_block_title_search_results"><![CDATA[Search Results]]></string>
+    <string name="_bx_market_page_block_title_search_form_cmts"><![CDATA[Comments Search Form]]></string>
+    <string name="_bx_market_page_block_title_search_results_cmts"><![CDATA[Comments Search Results]]></string>
+    <string name="_bx_market_page_block_title_sys_recent_entries_view_showcase"><![CDATA[Latest Products (Showcase View)]]></string>
+    <string name="_bx_market_page_block_title_recent_entries_view_showcase"><![CDATA[Latest Products]]></string>
+    <string name="_bx_market_page_block_title_sys_popular_entries_view_showcase"><![CDATA[Popular Products (Showcase View)]]></string>
+    <string name="_bx_market_page_block_title_popular_entries_view_showcase"><![CDATA[Popular Products]]></string>
+    <string name="_bx_market_page_block_title_sys_featured_entries_view_showcase"><![CDATA[Featured Products (Showcase View)]]></string>
+    <string name="_bx_market_page_block_title_featured_entries_view_showcase"><![CDATA[Featured Products]]></string>
+
+    <string name="_bx_market_menu_set_title_view_entry"><![CDATA[Product Actions]]></string>
+    <string name="_bx_market_menu_title_view_entry"><![CDATA[Product Actions]]></string>
+    <string name="_bx_market_menu_set_title_view_entry_more"><![CDATA[Product More Actions]]></string>
+    <string name="_bx_market_menu_title_view_entry_more"><![CDATA[Product More Actions]]></string>
+    <string name="_bx_market_menu_title_submenu"><![CDATA[Market Submenu]]></string>
+    <string name="_bx_market_menu_set_title_submenu"><![CDATA[Market Submenu]]></string>
+    <string name="_bx_market_menu_item_title_system_create_entry"><![CDATA[Product]]></string>
+    <string name="_bx_market_menu_item_title_create_entry"><![CDATA[Product]]></string>
+    <string name="_bx_market_menu_item_title_system_edit_entry"><![CDATA[Edit Product]]></string>
+    <string name="_bx_market_menu_item_title_edit_entry"><![CDATA[Edit]]></string>
+    <string name="_bx_market_menu_item_title_system_delete_entry"><![CDATA[Delete Product]]></string>
+    <string name="_bx_market_menu_item_title_delete_entry"><![CDATA[Delete]]></string>
+    <string name="_bx_market_menu_item_title_system_add_to_cart"><![CDATA[Add to Cart]]></string>
+    <string name="_bx_market_menu_item_title_add_to_cart"><![CDATA[Buy for {0}{1}]]></string>
+    <string name="_bx_market_menu_item_title_system_subscribe"><![CDATA[Subscribe]]></string>
+    <string name="_bx_market_menu_item_title_subscribe"><![CDATA[Subscribe for {0}{1}/{2}]]></string>
+    <string name="_bx_market_menu_item_title_system_download"><![CDATA[Download Product]]></string>
+    <string name="_bx_market_menu_item_title_download"><![CDATA[Download]]></string>
+    <string name="_bx_market_menu_item_title_system_product_more"><![CDATA[More Actions]]></string>
+    <string name="_bx_market_menu_item_title_product_more"><![CDATA[]]></string>
+    <string name="_bx_market_menu_item_title_system_unhide_entry"><![CDATA[Unhide Product]]></string>
+    <string name="_bx_market_menu_item_title_unhide_entry"><![CDATA[Publish]]></string>
+    <string name="_bx_market_menu_item_title_system_hide_entry"><![CDATA[Hide Product]]></string>
+    <string name="_bx_market_menu_item_title_hide_entry"><![CDATA[Hide]]></string>
+    <string name="_bx_market_menu_item_title_system_entries_home"><![CDATA[Market]]></string>
+    <string name="_bx_market_menu_item_title_entries_home"><![CDATA[Market]]></string>
+    <string name="_bx_market_menu_item_title_system_entries_categories"><![CDATA[Categories]]></string>
+    <string name="_bx_market_menu_item_title_entries_categories"><![CDATA[Categories]]></string>
+    <string name="_bx_market_menu_item_title_system_entries_public"><![CDATA[Storefront]]></string>
+    <string name="_bx_market_menu_item_title_entries_public"><![CDATA[Storefront]]></string>
+    <string name="_bx_market_menu_item_title_system_entries_search"><![CDATA[Search]]></string>
+    <string name="_bx_market_menu_item_title_entries_search"><![CDATA[Search]]></string>
+    <string name="_bx_market_menu_item_title_system_entries_manage"><![CDATA[Manage Products]]></string>
+    <string name="_bx_market_menu_item_title_entries_manage"><![CDATA[Manage]]></string>
+    <string name="_bx_market_menu_item_title_system_entries_latest"><![CDATA[Latest Products]]></string>
+    <string name="_bx_market_menu_item_title_entries_latest"><![CDATA[Latest]]></string>
+    <string name="_bx_market_menu_item_title_system_entries_featured"><![CDATA[Featured Products]]></string>
+    <string name="_bx_market_menu_item_title_entries_featured"><![CDATA[Featured]]></string>
+    <string name="_bx_market_menu_item_title_system_entries_popular"><![CDATA[Popular Products]]></string>
+    <string name="_bx_market_menu_item_title_entries_popular"><![CDATA[Popular]]></string>
+    <string name="_bx_market_menu_item_title_system_entries_top"><![CDATA[Top Products]]></string>
+    <string name="_bx_market_menu_item_title_entries_top"><![CDATA[Top]]></string>
+    <string name="_bx_market_menu_item_title_system_entries_updated"><![CDATA[Updated Products]]></string>
+    <string name="_bx_market_menu_item_title_entries_updated"><![CDATA[Updated]]></string>
+    <string name="_bx_market_menu_title_view_entry_submenu"><![CDATA[View Product Submenu]]></string>
+    <string name="_bx_market_menu_set_title_view_entry_submenu"><![CDATA[View Product Submenu]]></string>
+    <string name="_bx_market_menu_item_title_system_view_entry_submenu_entry"><![CDATA[Overview]]></string>
+    <string name="_bx_market_menu_item_title_view_entry_submenu_entry"><![CDATA[Overview]]></string>
+    <string name="_bx_market_menu_item_title_system_view_entry_submenu_comments"><![CDATA[Reviews]]></string>
+    <string name="_bx_market_menu_item_title_view_entry_submenu_comments"><![CDATA[Reviews]]></string>
+    <string name="_bx_market_menu_item_title_system_view_entry_submenu_info"><![CDATA[Info]]></string>
+    <string name="_bx_market_menu_item_title_view_entry_submenu_info"><![CDATA[Info]]></string>
+    <string name="_bx_market_menu_item_title_system_view_entries_author"><![CDATA[Products]]></string>
+    <string name="_bx_market_menu_item_title_view_entries_author"><![CDATA[Products]]></string>
+    <string name="_bx_market_menu_item_title_system_view_entries_in_context"><![CDATA[Products]]></string>
+    <string name="_bx_market_menu_item_title_view_entries_in_context"><![CDATA[Products]]></string>
+    <string name="_bx_market_menu_title_entries_my"><![CDATA[My Products Action Menu]]></string>
+    <string name="_bx_market_menu_set_title_entries_my"><![CDATA[My Products Menu]]></string>
+    <string name="_bx_market_menu_item_title_system_manage_my_products"><![CDATA[My products]]></string>
+    <string name="_bx_market_menu_item_title_manage_my_products"><![CDATA[Products]]></string>
+    <string name="_bx_market_menu_set_title_manage_tools"><![CDATA[Manage Tools Submenu]]></string>
+    <string name="_bx_market_menu_title_manage_tools"><![CDATA[Manage Tools Submenu]]></string>
+    <string name="_bx_market_menu_item_title_system_manage_account"><![CDATA[Manage account]]></string>
+    <string name="_bx_market_menu_item_title_manage_account"><![CDATA[Manage account]]></string>
+    <string name="_bx_market_menu_item_title_system_admt_products"><![CDATA[Products]]></string>
+    <string name="_bx_market_menu_item_title_admt_products"><![CDATA[Products]]></string>
+    <string name="_bx_market_menu_item_title_manage_my"><![CDATA[My Products]]></string>
+    <string name="_bx_market_menu_item_title_manage_all"><![CDATA[All Products]]></string>
+    <string name="_bx_market_menu_item_title_system_licenses"><![CDATA[Licenses]]></string>
+    <string name="_bx_market_menu_item_title_licenses"><![CDATA[Licenses]]></string>
+    <string name="_bx_market_menu_title_snippet"><![CDATA[Snippet Actions]]></string>
+    <string name="_bx_market_menu_set_title_snippet"><![CDATA[Snippet Actions]]></string>
+    <string name="_bx_market_menu_item_title_system_snippet_more"><![CDATA[More Actions]]></string>
+    <string name="_bx_market_menu_item_title_snippet_more"><![CDATA[More Actions]]></string>
+    <string name="_bx_market_menu_title_snippet_more"><![CDATA[Snippet More Actions]]></string>
+    <string name="_bx_market_menu_set_title_snippet_more"><![CDATA[Snippet More Actions]]></string>
+    <string name="_bx_market_menu_item_title_downloads_more"><![CDATA[Show More]]></string>
+    <string name="_bx_market_menu_title_licenses_submenu"><![CDATA[Licenses Submenu]]></string>
+    <string name="_bx_market_menu_set_title_licenses_submenu"><![CDATA[Licenses Submenu]]></string>
+    <string name="_bx_market_menu_item_title_system_products_licenses_administration"><![CDATA[All Licenses]]></string>
+    <string name="_bx_market_menu_item_title_products_licenses_administration"><![CDATA[All Licenses]]></string>
+    <string name="_bx_market_menu_item_title_system_products_licenses"><![CDATA[My Licenses]]></string>
+    <string name="_bx_market_menu_item_title_products_licenses"><![CDATA[My Licenses]]></string>
+    
+
+    <string name="_bx_market_grid_filter_item_title_adm_select_one_filter1"><![CDATA[All Statuses]]></string>
+    <string name="_bx_market_grid_filter_item_title_adm_select_one_filter2"><![CDATA[Any Audience]]></string>
+    <string name="_bx_market_grid_filter_item_title_adm_active"><![CDATA[Active]]></string>
+    <string name="_bx_market_grid_filter_item_title_adm_hidden"><![CDATA[Hidden]]></string>
+    <string name="_bx_market_grid_filter_item_title_adm_pending"><![CDATA[Pending]]></string>
+    <string name="_bx_market_grid_column_title_adm_active"><![CDATA[Active]]></string>
+    <string name="_bx_market_grid_column_title_adm_title"><![CDATA[Title]]></string>
+    <string name="_bx_market_grid_column_title_adm_added"><![CDATA[Added]]></string>
+    <string name="_bx_market_grid_column_title_adm_author"><![CDATA[Author]]></string>
+    <string name="_bx_market_grid_action_title_adm_edit"><![CDATA[Edit]]></string>
+    <string name="_bx_market_grid_action_title_adm_delete"><![CDATA[Delete]]></string>
+    <string name="_bx_market_grid_action_title_adm_more_actions"><![CDATA[More Actions]]></string>
+    <string name="_bx_market_grid_action_title_adm_audit_content"><![CDATA[Audit actions]]></string>
+    <string name="_bx_market_grid_action_title_adm_clear_reports"><![CDATA[Clear reports]]></string>
+    <string name="_bx_market_grid_column_title_adm_status_admin"><![CDATA[Moderation]]></string>
+    <string name="_bx_market_grid_action_err_delete"><![CDATA[Cannot delete the selected product(s).]]></string>
+    <string name="_bx_market_grid_txt_account_manager"><![CDATA[Redirect to manage account.]]></string>
+
+
+    <string name="_bx_market_grid_column_title_lcs_profile_id"><![CDATA[Owner]]></string>
+    <string name="_bx_market_grid_column_title_lcs_transaction"><![CDATA[Order]]></string>
+    <string name="_bx_market_grid_column_title_lcs_product"><![CDATA[Product]]></string>
+    <string name="_bx_market_grid_column_title_lcs_license"><![CDATA[License]]></string>
+    <string name="_bx_market_grid_column_title_lcs_type"><![CDATA[Type]]></string>
+    <string name="_bx_market_grid_column_title_lcs_domain"><![CDATA[Domain]]></string>
+    <string name="_bx_market_grid_column_title_lcs_added"><![CDATA[Begin]]></string>
+    <string name="_bx_market_grid_column_title_lcs_expired"><![CDATA[Expire]]></string>
+    <string name="_bx_market_grid_action_title_lcs_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_durations"><![CDATA[Product durations]]></string>
+    <string name="_bx_market_cat_duration_day"><![CDATA[daily]]></string>
+    <string name="_bx_market_cat_duration_week"><![CDATA[weekly]]></string>
+    <string name="_bx_market_cat_duration_month"><![CDATA[monthly]]></string>
+    <string name="_bx_market_cat_duration_year"><![CDATA[yearly]]></string>
+
+    <string name="_bx_market_vote_counter"><![CDATA[{0} ratings]]></string>
+
+    <string name="_bx_market_txt_msg_status_hidden"><![CDATA[This product was hidden.]]></string>
+    <string name="_bx_market_txt_msg_status_pending"><![CDATA[This product is pending approval.]]></string>
+    <string name="_bx_market_err_access_denied"><![CDATA[Access denied.]]></string>
+    <string name="_bx_market_err_no_payments"><![CDATA[There is no installed payment processing module.]]></string>
+    <string name="_bx_market_err_not_accept_payments"><![CDATA[You need to activate at least one payment provider. You may do it via My Account menu -> Settings page -> <a href="{0}">Payments</a> tab.]]></string>
+    <string name="_bx_market_err_not_accept_payments_single"><![CDATA[You need to activate at least one payment provider, which is working with Shopping Cart. You may do it via My Account menu -> Settings page -> <a href="{0}">Payments</a> tab.]]></string>
+    <string name="_bx_market_err_not_accept_payments_recurring"><![CDATA[You need to activate at least one payment provider, which is working with Subscriptions. You may do it via My Account menu -> Settings page -> <a href="{0}">Payments</a> tab.]]></string>
+
+    <string name="_bx_market_txt_all_entries_by"><![CDATA[{0} products]]></string>
+    <string name="_bx_market_txt_all_entries_in"><![CDATA[<a href="{0}">All Products in {1} ({2})</a>]]></string>
+    <string name="_bx_market_txt_category"><![CDATA[Category:]]></string>
+    <string name="_bx_market_txt_most_current_version"><![CDATA[The most current version]]></string>
+    <string name="_bx_market_txt_sample_single"><![CDATA[product]]></string>
+    <string name="_bx_market_txt_sample_single_with_article"><![CDATA[a product]]></string>
+    <string name="_bx_market_txt_sample_comment_single"><![CDATA[comment to product]]></string>
+    <string name="_bx_market_txt_sample_vote_single"><![CDATA[vote to product]]></string>
+    <string name="_bx_market_txt_sample_reaction_single"><![CDATA['{0}' reaction to product]]></string>
+    <string name="_bx_market_txt_sample_score_up_single"><![CDATA[score up vote to product]]></string>
+    <string name="_bx_market_txt_sample_score_down_single"><![CDATA[score down vote to product]]></string>
+    <string name="_bx_market_txt_author_added_product"><![CDATA[{0} {1}]]></string>
+    <string name="_bx_market_txt_joined"><![CDATA[Joined:]]></string>
+    <string name="_bx_market_txt_last_active"><![CDATA[Last Active:]]></string>
+    <string name="_bx_market_txt_price_single"><![CDATA[Buy for {0}{1}]]></string>
+    <string name="_bx_market_txt_price_single_short"><![CDATA[{0}{1}]]></string>
+    <string name="_bx_market_txt_price_recurring"><![CDATA[Subscribe for {0}{1}/{2}]]></string>
+    <string name="_bx_market_txt_price_recurring_short"><![CDATA[{0}{1}/{2}]]></string>
+    <string name="_bx_market_txt_price_free"><![CDATA[Free]]></string>
+    <string name="_bx_market_txt_per_hour"><![CDATA[hour]]></string>
+    <string name="_bx_market_txt_per_hour_short"><![CDATA[hour]]></string>
+    <string name="_bx_market_txt_per_day"><![CDATA[day]]></string>
+    <string name="_bx_market_txt_per_day_short"><![CDATA[day]]></string>
+    <string name="_bx_market_txt_per_week"><![CDATA[week]]></string>
+    <string name="_bx_market_txt_per_week_short"><![CDATA[week]]></string>
+    <string name="_bx_market_txt_per_month"><![CDATA[month]]></string>
+    <string name="_bx_market_txt_per_month_short"><![CDATA[month]]></string>
+    <string name="_bx_market_txt_per_year"><![CDATA[year]]></string>
+    <string name="_bx_market_txt_per_year_short"><![CDATA[year]]></string>
+    <string name="_bx_market_txt_get_for_free"><![CDATA[Download for Free]]></string>
+    <string name="_bx_market_txt_purchased_note"><![CDATA[Contact <a href="{0}">{1}</a> if you have any questions or need support.]]></string>
+
+    <!-- EMAIL TEMPLATES -->
+    <string name="_bx_market_et_txt_name_purchased"><![CDATA[Product purchased.]]></string>
+    <string name="_bx_market_et_txt_subject_purchased"><![CDATA[You've purchased {product_name} product.]]></string>
+    <string name="_bx_market_et_txt_body_purchased"><![CDATA[{email_header}
+<p>Hello, {client_name}.</p>
+<p>You've purchased <a href="{product_url}">{product_name}</a> product from <a href="{vendor_url}">{vendor_name}</a>.<br />Your license is <b>{license}</b>.</p>
+<p>{notes}</p>
+{email_footer}]]></string>
+</resources>

+ 668 - 0
modules/boonex/market/updates/13.0.0_13.0.1/source/install/sql/enable.sql

@@ -0,0 +1,668 @@
+
+-- 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_auto_approve', 'on', @iCategId, '_bx_market_option_enable_auto_approve', 'checkbox', '', '', '', 0),
+('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', '6', @iCategId, '_bx_market_option_per_page_profile', 'digit', '', '', '', 21),
+('bx_market_per_page_browse_showcase', '32', @iCategId, '_sys_option_per_page_browse_showcase', 'digit', '', '', '', 23),
+('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', 12, 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, 1),
+('bx_market_view_entry', 2, 'bx_market', '', '_bx_market_page_block_title_entry_text', 13, 2147483647, 'service', 'a:2:{s:6:"module";s:9:"bx_market";s:6:"method";s:17:"entity_text_block";}', 0, 0, 1, 1),
+('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, 1, 2),
+('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, 0),
+('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', 3, '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, 6),
+('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, 0, 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, 4),
+('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, 3),
+('bx_market_view_entry', 3, 'bx_market', '_bx_market_page_block_title_sys_entry_context', '_bx_market_page_block_title_entry_context', 11, 2147483647, 'service', 'a:2:{s:6:\"module\";s:9:\"bx_market\";s:6:\"method\";s:14:\"entity_context\";}', 0, 0, 1, 1),
+('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, 0),
+('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, 5),
+('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, 0),
+('bx_market_view_entry', 2, 'bx_market', '', '_bx_market_page_block_title_entry_reports', 11, 2147483647, 'service', 'a:2:{s:6:\"module\";s:9:\"bx_market\";s:6:\"method\";s:14:\"entity_reports\";}', 0, 0, 1, 6);
+
+
+
+
+-- 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: top 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_top', '_bx_market_page_title_sys_entries_top', '_bx_market_page_title_entries_top', 'bx_market', 5, 2147483647, 1, 'products-top', 'page.php?i=products-top', '', '', '', 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_top', 1, 'bx_market', '_bx_market_page_block_title_top_entries', 11, 2147483647, 'service', 'a:3:{s:6:"module";s:9:"bx_market";s:6:"method";s:10:"browse_top";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),
+('bx_market_author', 1, 'bx_market', '_bx_market_page_block_title_sys_entries_in_context', '_bx_market_page_block_title_entries_in_context', 11, 2147483647, 'service', 'a:3:{s:6:"module";s:9:"bx_market";s:6:"method";s:14:"browse_context";s:6:"params";a:2:{s:10:"profile_id";s:12:"{profile_id}";i:0;a:1:{s:13:"empty_message";b:0;}}}', 0, 0, 1, 4);
+
+-- PAGE: licenses administration
+INSERT INTO `sys_objects_page`(`object`, `title_system`, `title`, `module`, `layout_id`, `visible_for_levels`, `visible_for_levels_editable`, `uri`, `url`, `meta_description`, `meta_keywords`, `meta_robots`, `cache_lifetime`, `cache_editable`, `deletable`, `override_class_name`, `override_class_file`) VALUES 
+('bx_market_licenses_administration', '_bx_market_page_title_sys_licenses_administration', '_bx_market_page_title_licenses_administration', 'bx_market', 5, 192, 1, 'products-licenses-administration', '', '', '', '', 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_administration', 1, 'bx_market', '', '_bx_market_page_block_title_licenses_administration', 11, 192, 'service', 'a:2:{s:6:"module";s:9:"bx_market";s:6:"method";s:29:"block_licenses_administration";}', 0, 0, 1, 0);
+
+-- 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: entries in context
+
+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_context', 'products-context', '_bx_market_page_title_sys_entries_in_context', '_bx_market_page_title_entries_in_context', '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_context', 1, 'bx_market', '_bx_market_page_block_title_sys_entries_in_context', '_bx_market_page_block_title_entries_in_context', 11, 2147483647, 'service', 'a:2:{s:6:\"module\";s:9:\"bx_market\";s:6:\"method\";s:14:\"browse_context\";}', 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_system`, `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_sys_view_profile', '_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_system`, `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),
+('', 0, 'bx_market', '_bx_market_page_block_title_sys_recent_entries_view_showcase', '_bx_market_page_block_title_recent_entries_view_showcase', 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:8:\"showcase\";s:13:\"empty_message\";b:0;s:13:\"ajax_paginate\";b:0;}}', 0, 1, IFNULL(@iBlockOrder, 0) + 9),
+('', 0, 'bx_market', '_bx_market_page_block_title_sys_popular_entries_view_showcase', '_bx_market_page_block_title_popular_entries_view_showcase', 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:8:\"showcase\";s:13:\"empty_message\";b:0;s:13:\"ajax_paginate\";b:0;}}', 0, 1, IFNULL(@iBlockOrder, 0) + 10),
+('', 0, 'bx_market', '_bx_market_page_block_title_sys_featured_entries_view_showcase', '_bx_market_page_block_title_featured_entries_view_showcase', 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:8:\"showcase\";s:13:\"empty_message\";b:0;s:13:\"ajax_paginate\";b:0;}}', 0, 1, IFNULL(@iBlockOrder, 0) + 11);
+
+
+-- MENU: add to site menu
+SET @iSiteMenuOrder = (SELECT `order` FROM `sys_menu_items` WHERE `set_name` = 'sys_site' AND `active` = 1 AND `order` < 9999 ORDER BY `order` DESC LIMIT 1);
+INSERT INTO `sys_menu_items` (`set_name`, `module`, `name`, `title_system`, `title`, `link`, `onclick`, `target`, `icon`, `submenu_object`, `visible_for_levels`, `active`, `copyable`, `order`) VALUES 
+('sys_site', 'bx_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');
+
+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`, `submenu_popup`, `visible_for_levels`, `active`, `copyable`, `order`) VALUES
+('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', '', 0, 2147483647, 1, 0, 10),
+('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', '', 0, 2147483647, 1, 0, 20),
+('bx_market_view', 'bx_market', 'subscribe', '_bx_market_menu_item_title_system_subscribe', '{subscribe_title}', 'javascript:void(0);', 'javascript:{subscribe_onclick}', '', 'credit-card', '', 0, 2147483647, 1, 0, 30),
+('bx_market_view', 'bx_market', 'unhide-product', '_bx_market_menu_item_title_system_unhide_entry', '_bx_market_menu_item_title_unhide_entry', 'javascript:void(0);', 'javascript:{js_object}.perform(this, ''unhide-product'', {content_id});', '', 'play-circle', '', 0, 2147483647, 1, 0, 40),
+('bx_market_view', 'bx_market', 'approve', '_sys_menu_item_title_system_va_approve', '_sys_menu_item_title_va_approve', 'javascript:void(0)', 'javascript:bx_approve(this, ''{module_uri}'', {content_id});', '', 'check', '', 0, 2147483647, 1, 0, 50),
+('bx_market_view', 'bx_market', 'product-more', '_bx_market_menu_item_title_system_product_more', '_bx_market_menu_item_title_product_more', 'javascript:void(0)', 'bx_menu_popup(''bx_market_view_more'', this, {}, {id:{content_id}});', '', 'cog', 'bx_market_view_more', 1, 2147483647, 1, 0, 9999);
+
+-- MENU: actions more 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_more', '_bx_market_menu_title_view_entry_more', 'bx_market_view_more', 'bx_market', 6, 0, 1, 'BxMarketMenuView', 'modules/boonex/market/classes/BxMarketMenuView.php');
+
+INSERT INTO `sys_menu_sets`(`set_name`, `module`, `title`, `deletable`) VALUES 
+('bx_market_view_more', 'bx_market', '_bx_market_menu_set_title_view_entry_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_market_view_more', 'bx_market', 'hide-product', '_bx_market_menu_item_title_system_hide_entry', '_bx_market_menu_item_title_hide_entry', 'javascript:void(0);', 'javascript:{js_object}.perform(this, ''hide-product'', {content_id});', '', 'stop-circle', '', 2147483647, 1, 0, 10),
+('bx_market_view_more', '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-alt', '', 2147483647, 1, 0, 20),
+('bx_market_view_more', '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, 30);
+
+-- MENU: all 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_actions', '_sys_menu_title_view_actions', 'bx_market_view_actions', 'bx_market', 15, 0, 1, 'BxMarketMenuViewActions', 'modules/boonex/market/classes/BxMarketMenuViewActions.php');
+
+INSERT INTO `sys_menu_sets`(`set_name`, `module`, `title`, `deletable`) VALUES 
+('bx_market_view_actions', 'bx_market', '_sys_menu_set_title_view_actions', 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`, `visibility_custom`, `active`, `copyable`, `order`) VALUES 
+('bx_market_view_actions', 'bx_market', 'download', '_bx_market_menu_item_title_system_download', '', '', '', '', '', '', '', 0, 2147483647, '', 1, 0, 10),
+('bx_market_view_actions', 'bx_market', 'add-to-cart', '_bx_market_menu_item_title_system_add_to_cart', '', '', '', '', '', '', '', 0, 2147483647, '', 1, 0, 20),
+('bx_market_view_actions', 'bx_market', 'subscribe', '_bx_market_menu_item_title_system_subscribe', '', '', '', '', '', '', '', 0, 2147483647, '', 1, 0, 30),
+('bx_market_view_actions', 'bx_market', 'unhide-product', '_bx_market_menu_item_title_system_unhide_entry', '', '', '', '', '', '', '', 0, 2147483647, '', 1, 0, 40),
+('bx_market_view_actions', 'bx_market', 'hide-product', '_bx_market_menu_item_title_system_hide_entry', '', '', '', '', '', '', '', 0, 2147483647, '', 1, 0, 50),
+('bx_market_view_actions', 'bx_market', 'edit-product', '_bx_market_menu_item_title_system_edit_entry', '', '', '', '', '', '', '', 0, 2147483647, '', 1, 0, 60),
+('bx_market_view_actions', 'bx_market', 'delete-product', '_bx_market_menu_item_title_system_delete_entry', '', '', '', '', '', '', '', 0, 2147483647, '', 1, 0, 70),
+('bx_market_view_actions', 'bx_market', 'approve', '_sys_menu_item_title_system_va_approve', '', '', '', '', '', '', '', 0, 2147483647, '', 1, 0, 80),
+('bx_market_view_actions', 'bx_market', 'set-badges', '_sys_menu_item_title_system_set_badges', '_sys_menu_item_title_set_badges', 'javascript:void(0)', 'bx_menu_popup(''sys_set_badges'', window, {}, {module: ''bx_market'', content_id: {content_id}});', '', 'check-circle', '', '', 0, 2147483647, 'a:2:{s:6:"module";s:9:"bx_market";s:6:"method";s:19:"is_badges_avaliable";}', 1, 0, 90),
+('bx_market_view_actions', 'bx_market', 'comment', '_sys_menu_item_title_system_va_comment', '', '', '', '', '', '', '', 0, 2147483647, '', 0, 0, 200),
+('bx_market_view_actions', 'bx_market', 'view', '_sys_menu_item_title_system_va_view', '', '', '', '', '', '', '', 0, 2147483647, '', 1, 0, 210),
+('bx_market_view_actions', 'bx_market', 'vote', '_sys_menu_item_title_system_va_vote', '', '', '', '', '', '', '', 0, 2147483647, '', 0, 0, 220),
+('bx_market_view_actions', 'bx_market', 'reaction', '_sys_menu_item_title_system_va_reaction', '', '', '', '', '', '', '', 0, 2147483647, '', 1, 0, 225),
+('bx_market_view_actions', 'bx_market', 'score', '_sys_menu_item_title_system_va_score', '', '', '', '', '', '', '', 0, 2147483647, '', 1, 0, 230),
+('bx_market_view_actions', 'bx_market', 'favorite', '_sys_menu_item_title_system_va_favorite', '', '', '', '', '', '', '', 0, 2147483647, '', 1, 0, 240),
+('bx_market_view_actions', 'bx_market', 'feature', '_sys_menu_item_title_system_va_feature', '', '', '', '', '', '', '', 0, 2147483647, '', 1, 0, 250),
+('bx_market_view_actions', 'bx_market', 'repost', '_sys_menu_item_title_system_va_repost', '', '', '', '', '', '', '', 0, 2147483647, '', 1, 0, 260),
+('bx_market_view_actions', 'bx_market', 'report', '_sys_menu_item_title_system_va_report', '', '', '', '', '', '', '', 0, 2147483647, '', 1, 0, 270),
+('bx_market_view_actions', 'bx_market', 'notes', '_sys_menu_item_title_system_va_notes', '_sys_menu_item_title_va_notes', 'javascript:void(0)', 'javascript:bx_get_notes(this,  ''{module_uri}'', {content_id});', '', 'exclamation-triangle', '', '', 0, 2147483647, '', 1, 0, 280),
+('bx_market_view_actions', 'bx_market', 'audit', '_sys_menu_item_title_system_va_audit', '_sys_menu_item_title_va_audit', 'page.php?i=dashboard-audit&module=bx_market&content_id={content_id}', '', '', 'history', '', '', 0, 192, '', 1, 0, 290),
+('bx_market_view_actions', 'bx_market', 'social-sharing', '_sys_menu_item_title_system_social_sharing', '_sys_menu_item_title_social_sharing', 'javascript:void(0)', 'oBxDolPage.share(this, \'{url_encoded}\')', '', 'share', '', '', 0, 2147483647, '', 1, 0, 300),
+('bx_market_view_actions', 'bx_market', 'more-auto', '_sys_menu_item_title_system_va_more_auto', '_sys_menu_item_title_va_more_auto', 'javascript:void(0)', '', '', 'ellipsis-v', '', '', 0, 2147483647, '', 1, 0, 9999);
+
+-- 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_snippet_more'', this, {''id'':''bx_market_snippet_{content_id}''}, {id:{content_id}});', '', 'ellipsis-v', '', 'bx_market_snippet_more', 1, 2147483647, 1, 0, 0, 1);
+
+-- MENU: actions more menu for snippet actions menu
+INSERT INTO `sys_objects_menu`(`object`, `title`, `set_name`, `module`, `template_id`, `deletable`, `active`, `override_class_name`, `override_class_file`) VALUES
+('bx_market_snippet_more', '_bx_market_menu_title_snippet_more', 'bx_market_snippet_more', '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_snippet_more', 'bx_market', '_bx_market_menu_set_title_snippet_more', 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`, `order`) VALUES
+('bx_market_snippet_more', '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', '', 0, 2147483647, 1, 0, 10),
+('bx_market_snippet_more', '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', '', 0, 2147483647, 1, 0, 20),
+('bx_market_snippet_more', 'bx_market', 'subscribe', '_bx_market_menu_item_title_system_subscribe', '{subscribe_title}', 'javascript:void(0);', 'javascript:{subscribe_onclick}', '', 'credit-card', '', 0, 2147483647, 1, 0, 30);
+
+-- 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', 18, 0, 1, 'BxMarketMenuSubmenu', 'modules/boonex/market/classes/BxMarketMenuSubmenu.php');
+
+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-top', '_bx_market_menu_item_title_system_entries_top', '_bx_market_menu_item_title_entries_top', 'page.php?i=products-top', '', '', '', '', 2147483647, 1, 1, 5),
+('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, 6),
+('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, 7),
+('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, 8),
+('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, 9),
+('bx_market_submenu', 'bx_market', 'more-auto', '_sys_menu_item_title_system_more_auto', '_sys_menu_item_title_more_auto', 'javascript:void(0)', '', '', '', '', 2147483647, 1, 0, 9999);
+
+-- 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: licenses submenu
+INSERT INTO `sys_objects_menu`(`object`, `title`, `set_name`, `module`, `template_id`, `deletable`, `active`, `override_class_name`, `override_class_file`) VALUES 
+('bx_market_licenses_submenu', '_bx_market_menu_title_licenses_submenu', 'bx_market_licenses_submenu', 'bx_market', 6, 0, 1, '', '');
+
+INSERT INTO `sys_menu_sets`(`set_name`, `module`, `title`, `deletable`) VALUES 
+('bx_market_licenses_submenu', 'bx_market', '_bx_market_menu_set_title_licenses_submenu', 0);
+
+INSERT INTO `sys_menu_items`(`set_name`, `module`, `name`, `title_system`, `title`, `link`, `onclick`, `target`, `icon`, `addon`, `submenu_object`, `visible_for_levels`, `active`, `copyable`, `editable`, `order`) VALUES 
+('bx_market_licenses_submenu', 'bx_market', 'products-licenses-administration', '_bx_market_menu_item_title_system_products_licenses_administration', '_bx_market_menu_item_title_products_licenses_administration', 'page.php?i=products-licenses-administration', '', '_self', '', '', '', 192, 1, 0, 1, 1),
+('bx_market_licenses_submenu', 'bx_market', 'products-licenses', '_bx_market_menu_item_title_system_products_licenses', '_bx_market_menu_item_title_products_licenses', 'page.php?i=products-licenses', '', '_self', '', '', '', 2147483646, 1, 0, 1, 2);
+
+-- 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-my-market', '_bx_market_menu_item_title_system_manage_my_products', '_bx_market_menu_item_title_manage_my_products', 'page.php?i=products-author&profile_id={member_id}', '', '_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', 'far trash-alt', '', 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', 'shopping-cart', '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),
+('trigger_group_view_submenu', 'bx_market', 'products-context', '_bx_market_menu_item_title_system_view_entries_in_context', '_bx_market_menu_item_title_view_entries_in_context', 'page.php?i=products-context&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`, `spaces`, `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', 'all', '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'),
+('bx_market_allow_view_favorite_list', 'bx_market', 'view_favorite_list', '_bx_market_form_entry_input_allow_view_favorite_list', '3', 'all', 'bx_market_favorites_lists', 'id', 'author_id', '', '');
+
+
+-- 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();
+
+INSERT INTO `sys_acl_actions` (`Module`, `Name`, `AdditionalParamName`, `Title`, `Desc`, `Countable`, `DisabledForLevels`) VALUES
+('bx_market', 'delete any entry', NULL, '_bx_market_acl_action_delete_any_entry', '', 1, 3);
+SET @iIdActionEntryDeleteAny = 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),
+
+-- delete any entry
+(@iAdministrator, @iIdActionEntryDeleteAny);
+
+-- 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`, `profile_initiator`, `profile_content`, `type`, `override_class_name`, `override_class_file`) VALUES
+('bx_market_subentries', 'bx_market_subproducts', 0, 0, 'one-way', '', '');
+
+
+-- METATAGS
+INSERT INTO `sys_objects_metatags` (`object`, `module`, `table_keywords`, `table_locations`, `table_mentions`, `override_class_name`, `override_class_file`) VALUES
+('bx_market', 'bx_market', 'bx_market_meta_keywords', 'bx_market_meta_locations', 'bx_market_meta_mentions', '', '');
+
+-- CATEGORY
+INSERT INTO `sys_objects_category` (`object`, `module`, `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', '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', 'reports', '', 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_administration', 'Sql', 'SELECT `tl`.`id` AS `id`, `tl`.`profile_id` AS `profile_id`, `tl`.`product_id` AS `product_id`, `tp`.`title` AS `product`, `tl`.`order` AS `transaction`, `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`.`order,tl`.`license,tl`.`type,tl`.`domain', '', 'like', '', '', 192, 'BxMarketGridLicensesAdministration', 'modules/boonex/market/classes/BxMarketGridLicensesAdministration.php'),
+('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`.`order` AS `transaction`, `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`.`order,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', 'reports', '_sys_txt_reports_title', '5%', 0, '', '', 3),
+('bx_market_administration', 'title', '_bx_market_grid_column_title_adm_title', '25%', 0, '', '', 4),
+('bx_market_administration', 'added', '_bx_market_grid_column_title_adm_added', '20%', 1, '25', '', 5),
+('bx_market_administration', 'author', '_bx_market_grid_column_title_adm_author', '20%', 0, '25', '', 6),
+('bx_market_administration', 'actions', '', '20%', 0, '', '', 7),
+
+('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', '15%', 1, '25', '', 4),
+('bx_market_common', 'status_admin', '_bx_market_grid_column_title_adm_status_admin', '15%', 0, '16', '', 5),
+('bx_market_common', 'actions', '', '20%', 0, '', '', 6),
+
+('bx_market_licenses_administration', 'profile_id', '_bx_market_grid_column_title_lcs_profile_id', '10%', 0, '28', '', 1),
+('bx_market_licenses_administration', 'product', '_bx_market_grid_column_title_lcs_product', '20%', 0, '28', '', 2),
+('bx_market_licenses_administration', 'transaction', '_bx_market_grid_column_title_lcs_transaction', '10%', 0, '32', '', 3),
+('bx_market_licenses_administration', 'license', '_bx_market_grid_column_title_lcs_license', '10%', 0, '8', '', 4),
+('bx_market_licenses_administration', 'type', '_bx_market_grid_column_title_lcs_type', '5%', 1, '12', '', 5),
+('bx_market_licenses_administration', 'domain', '_bx_market_grid_column_title_lcs_domain', '15%', 0, '18', '', 6),
+('bx_market_licenses_administration', 'added', '_bx_market_grid_column_title_lcs_added', '10%', 1, '25', '', 7),
+('bx_market_licenses_administration', 'expired', '_bx_market_grid_column_title_lcs_expired', '10%', 1, '25', '', 8),
+('bx_market_licenses_administration', 'actions', '', '10%', 0, '', '', 9),
+
+('bx_market_licenses', 'product', '_bx_market_grid_column_title_lcs_product', '20%', 0, '28', '', 1),
+('bx_market_licenses', 'transaction', '_bx_market_grid_column_title_lcs_transaction', '10%', 0, '32', '', 2),
+('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', 'bulk', 'clear_reports', '_bx_market_grid_action_title_adm_clear_reports', '', 0, 1, 2),
+('bx_market_administration', 'single', 'edit', '_bx_market_grid_action_title_adm_edit', 'pencil-alt', 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_administration', 'single', 'audit_content', '_bx_market_grid_action_title_adm_audit_content', 'search', 1, 0, 4),
+('bx_market_administration', 'single', 'clear_reports', '_bx_market_grid_action_title_adm_clear_reports', 'eraser', 1, 0, 5),
+
+('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-alt', 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_administration', 'single', 'reset', '_bx_market_grid_action_title_lcs_reset', 'eraser', 1, 1, 1),
+('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', '');
+
+
+-- EMAIL TEMPLATES
+INSERT INTO `sys_email_templates` (`Module`, `NameSystem`, `Name`, `Subject`, `Body`) VALUES 
+('bx_market', '_bx_market_et_txt_name_purchased', 'bx_market_purchased', '_bx_market_et_txt_subject_purchased', '_bx_market_et_txt_body_purchased');

+ 629 - 0
modules/boonex/market/updates/13.0.0_13.0.1/source/install/sql/install.sql

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

+ 21 - 0
modules/boonex/market/updates/13.0.0_13.0.1/source/js/manage_tools.js

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

+ 40 - 0
modules/boonex/market/updates/13.0.0_13.0.1/source/template/attachments.html

@@ -0,0 +1,40 @@
+<div class="bx-base-text-attachments bx-market-attachments bx-clearfix">
+    <bx_repeat:attachments>
+        <bx_if:show_separator>
+            <div class="bx-market-attachment-separator bx-base-text-attachment bx-market-attachment bx-def-margin-sec-left"><div class="bx-def-font-h3 bx-def-padding-top"> __type__</div></div>
+        </bx_if:show_separator>
+        <div class="bx-base-text-attachment bx-market-attachment bx-def-box bx-def-color-bg-box bx-def-round-corners bx-def-margin-sec __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-market-a-text bx-def-margin">
+                    <i class="sys-icon file-archive sys-colored far"></i>
+                    <div class="bx-market-attachment-text">
+                        <bx_if:show_version>
+                            <div class="bx-def-font-h3"> __file_version__</div>
+                        </bx_if:show_version>
+                        <bx_if:show_update>
+                            <div class="bx-def-font-h3">__file_version_from_to__</div>
+                        </bx_if:show_update>
+                        <div class="bx-market-attachment-info bx-def-font-small bx-def-font-grayed">__file_type__ &bull; <span title="__file_name_attr__">__file_name__</span></div>
+                    </div>
+                    <div class="bx-def-margin-sec-top">
+                        <a target="_blank" href="__url_original__" title="__attr_file_name__" class="bx-btn bx-btn-primary bx-btn-small"><bx_text_attribute:_bx_market_menu_item_title_download /></a>
+                    </div>
+                </div>
+            </bx_if:not_image>
+        </div>
+    </bx_repeat:attachments>
+</div>

+ 40 - 0
modules/boonex/market/updates/13.0.0_13.0.1/source/template/css/forms.css

@@ -0,0 +1,40 @@
+/*--- Subentries field ---*/
+#bx-form-element-subentries .bx-form-value .bx-form-input-autotoken b {
+    padding-left: 0.5rem;
+}
+
+/*--- Uploader Ghost ---*/
+#bx-form-element-files .bx-form-input-files-result {
+    position: relative;
+    max-height: 22.25rem;
+    overflow: hidden;
+}
+
+.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);
+}

+ 1 - 0
modules/boonex/market/updates/13.0.0_13.0.1/source/template/embed.html

@@ -0,0 +1 @@
+<iframe width="300" height="370" src="__url__" frameborder="0" allowfullscreen></iframe>

+ 51 - 0
modules/boonex/massmailer/updates/12.0.1_13.0.0/install/config.php

@@ -0,0 +1,51 @@
+<?php
+/**
+ * Copyright (c) BoonEx Pty Limited - http://www.boonex.com/
+ * CC-BY License - http://creativecommons.org/licenses/by/3.0/
+ */
+
+$aConfig = array(
+    /**
+     * Main Section.
+     */
+    'title' => 'Mass mailer',
+    'version_from' => '12.0.1',
+    'version_to' => '13.0.0',
+    'vendor' => 'BoonEx',
+
+    'compatible_with' => array(
+        '13.0.0-A3'
+    ),
+
+    /**
+     * 'home_dir' and 'home_uri' - should be unique. Don't use spaces in 'home_uri' and the other special chars.
+     */
+    'home_dir' => 'boonex/massmailer/updates/update_12.0.1_13.0.0/',
+    'home_uri' => 'massmailer_update_1201_1300',
+
+    'module_dir' => 'boonex/massmailer/',
+    'module_uri' => 'massmailer',
+
+    'db_prefix' => 'bx_massmailer_',
+    'class_prefix' => 'BxMassMailer',
+
+    /**
+     * Installation/Uninstallation Section.
+     */
+    'install' => array(
+        'execute_sql' => 0,
+        'update_files' => 1,
+        'update_languages' => 0,
+        'clear_db_cache' => 0,
+    ),
+
+    /**
+     * Category for language keys.
+     */
+    'language_category' => 'MassMailer',
+
+    /**
+     * Files Section
+     */
+    'delete_files' => array(),
+);

+ 13 - 0
modules/boonex/massmailer/updates/12.0.1_13.0.0/install/installer.php

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

+ 258 - 0
modules/boonex/massmailer/updates/12.0.1_13.0.0/source/classes/BxMassMailerDb.php

@@ -0,0 +1,258 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    MassMailer Mass Mailer
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+class BxMassMailerDb extends BxBaseModGeneralDb
+{
+    function __construct(&$oConfig)
+    {
+        parent::__construct($oConfig);
+    }
+    
+    public function copyCampaign($iCampaignId)
+    {
+        $CNF = &$this->_oConfig->CNF;
+        $aBindings = array(
+            'campaign_id' => $iCampaignId,
+            'date_created' => time(),
+            'copy_title' => _t('_bx_massmailer_txt_copy_title')
+        );
+        $this->query("INSERT INTO `" . $CNF['TABLE_CAMPAIGNS'] . "` (`" . $CNF['FIELD_AUTHOR'] . "`, `" . $CNF['FIELD_TITLE'] . "`, `" . $CNF['FIELD_BODY'] . "`, `" . $CNF['FIELD_SEGMENTS'] . "`, `" . $CNF['FIELD_ADDED'] . "`, `" . $CNF['FIELD_SUBJECT'] . "`, `" . $CNF['FIELD_FROM_NAME'] . "`, `" . $CNF['FIELD_REPLY_TO'] . "`, `" . $CNF['FIELD_PER_ACCOUNT'] . "`) SELECT `" . $CNF['FIELD_AUTHOR'] . "`, CONCAT(`" . $CNF['FIELD_TITLE'] . "`, :copy_title), `" . $CNF['FIELD_BODY'] . "`, `" . $CNF['FIELD_SEGMENTS'] . "`, :date_created, `" . $CNF['FIELD_SUBJECT'] . "`, `" . $CNF['FIELD_FROM_NAME'] . "`, `" . $CNF['FIELD_REPLY_TO'] . "`, `" . $CNF['FIELD_PER_ACCOUNT'] . "` FROM `" . $CNF['TABLE_CAMPAIGNS'] . "` WHERE `" . $CNF['FIELD_ID'] . "` = :campaign_id", $aBindings);
+        return $this->lastId();
+    }
+        
+    public function sendCampaign($iCampaignId)
+    {
+        $CNF = &$this->_oConfig->CNF;
+        $aBindings = array(
+            'campaign_id' => $iCampaignId,
+            'date_sent' => time()
+        );
+        $this->query("UPDATE `" . $CNF['TABLE_CAMPAIGNS'] . "` SET `" . $CNF['FIELD_DATE_SENT'] . "` = :date_sent WHERE `" . $CNF['FIELD_ID'] . "` = :campaign_id", $aBindings);
+    }
+    
+    public function addEmailToSentListForCampaign($iCampaignId, $sEmailList)
+    {
+        $CNF = &$this->_oConfig->CNF;
+        $aBindings = array(
+            'campaign_id' => $iCampaignId,
+            'email_list' => $sEmailList
+        );
+        $this->query("UPDATE `" . $CNF['TABLE_CAMPAIGNS'] . "` SET `" . $CNF['FIELD_EMAIL_LIST'] . "` = CONCAT(IFNULL(`" . $CNF['FIELD_EMAIL_LIST'] . "`, ''), ',', :email_list) WHERE `" . $CNF['FIELD_ID'] . "` = :campaign_id", $aBindings);
+    }
+    
+    public function getCampaignInfoById ($iCampaignId)
+    {
+        $CNF = &$this->_oConfig->CNF;
+        $sQuery = $this->prepare ("SELECT * FROM `" . $CNF['TABLE_CAMPAIGNS'] . "` WHERE `" . $CNF['FIELD_ID'] . "` = ?", $iCampaignId);
+        return $this->getRow($sQuery);
+    }
+    
+    public function getSegmentInfoById ($iSegmentId)
+    {
+        $CNF = &$this->_oConfig->CNF;
+        $sQuery = $this->prepare ("SELECT * FROM `" . $CNF['TABLE_SEGMENTS'] . "` WHERE `" . $CNF['FIELD_ID'] . "` = ?", $iSegmentId);
+        return $this->getRow($sQuery);
+    }
+    
+    public function getSegments()
+    {
+        $CNF = &$this->_oConfig->CNF;
+        $sQuery = $this->prepare ("SELECT `" . $CNF['FIELD_ID'] . "`, `" . $CNF['FIELD_TITLE'] . "` FROM `" . $CNF['TABLE_SEGMENTS'] . "`");
+        return $this->getPairs($sQuery, $CNF['FIELD_ID'], $CNF['FIELD_TITLE']);
+    }
+    
+    public function getAccountsByTerms($sTerms = "")
+    {
+        $sSql = "SELECT `ta`.`email`, `tp`.`id` AS `profile_id`, `ta`.`id` as `account_id` FROM `sys_accounts` AS `ta` " . $sTerms . "  WHERE `ta`.`receive_news` <> 0 AND `ta`.`email_confirmed` = 1";
+        return $this->getAll($sSql);
+    }
+    
+    public function getAccountsByTermsStat($iDateFrom, $iDateTo, $sTerms = "")
+    {
+        $aBindings = array(
+           'datefrom' => $iDateFrom,
+           'dateto' => $iDateTo
+       );
+        $sSql = "SELECT DATE(FROM_UNIXTIME(`ta`.`added`)) AS `period`, YEAR(FROM_UNIXTIME(`ta`.`added`)) AS `year`, COUNT(*) AS `count` FROM `sys_accounts` AS `ta` " . $sTerms . " WHERE `ta`.`receive_news` <> 0  AND `ta`.`email_confirmed` = 1 AND `ta`.`added` >= :datefrom AND `ta`.`added` <= :dateto GROUP BY `period`, `year` ORDER BY `year`, `period` ASC";
+        return $this->getAll($sSql, $aBindings);
+    }
+    
+    public function getAccountsByTermsStatUnsubscribe($iDateFrom, $iDateTo, $sTerms = "")
+    {
+        $CNF = &$this->_oConfig->CNF;
+        $aBindings = array(
+           'datefrom' => $iDateFrom,
+           'dateto' => $iDateTo
+       );
+        $sSql = "SELECT DATE(FROM_UNIXTIME(`tu`.`unsubscribed`)) AS `period`, YEAR(FROM_UNIXTIME(`tu`.`unsubscribed`)) AS `year`, COUNT(*) AS `count` FROM `sys_accounts` AS `ta` INNER JOIN `" . $CNF['TABLE_UNSUBSCRIBE'] . "` AS `tu` ON `tu`.`account_id`=`ta`.`id` " . $sTerms . " WHERE `tu`.`unsubscribed` >= :datefrom AND `tu`.`unsubscribed` <= :dateto GROUP BY `period`, `year` ORDER BY `year`, `period` ASC";
+        return $this->getAll($sSql, $aBindings);
+    }
+    
+    public function getAccountsByTermsStatInitValue($iDateFrom, $sTerms)
+    {
+        $aBindings = array(
+            'datefrom' => $iDateFrom
+        );
+        $sQuery = "SELECT COUNT(`ta`.`id`) AS `count` FROM `sys_accounts` AS `ta` " . $sTerms . " WHERE `ta`.`added` < :datefrom ";
+        return $this->getOne($sQuery, $aBindings);
+    }
+    
+    public function getAccountsByTermsStatInitValueUnsubscribe($iDateFrom, $sTerms)
+    {
+        $CNF = &$this->_oConfig->CNF;
+        $aBindings = array(
+            'datefrom' => $iDateFrom
+        );
+        $sQuery = "SELECT COUNT(`tu`.`id`) AS `count` FROM `sys_accounts` AS `ta` INNER JOIN `" . $CNF['TABLE_UNSUBSCRIBE'] . "` AS `tu` ON `tu`.`account_id`=`ta`.`id` " . $sTerms . " WHERE `tu`.`unsubscribed` < :datefrom ";
+        return $this->getOne($sQuery, $aBindings);
+    }
+    
+    public function addLetter($iCampaignId, $sEmail)
+    {
+        $iTime = time();
+        $sCode = md5($iCampaignId . $sEmail . $iTime);
+        $CNF = &$this->_oConfig->CNF;
+        $aBindings = array(
+            'campaign_id' => $iCampaignId,
+            'email' => $sEmail,
+            'date_sent' => $iTime,
+            'code' => $sCode,
+        );
+        $this->query("INSERT INTO `" . $CNF['TABLE_LETTERS'] . "` (`" . $CNF['FIELD_CAMPAIGN_ID'] . "`, `" . $CNF['FIELD_EMAIL'] . "`, `" . $CNF['FIELD_DATE_SENT'] . "`, `" . $CNF['FIELD_HASH'] . "`) VALUES (:campaign_id, :email, :date_sent, :code)", $aBindings);
+        return $sCode;
+    }
+    
+    public function updateDateSeenForLetter($sCode)
+    {
+        $CNF = &$this->_oConfig->CNF;
+        $aBindings = array(
+            'code' => $sCode,
+            'date_seen' => time()
+        );
+        $this->query("UPDATE `" . $CNF['TABLE_LETTERS'] . "` SET `" . $CNF['FIELD_DATE_SEEN'] . "` = :date_seen WHERE `" . $CNF['FIELD_HASH'] . "` = :code", $aBindings);
+    }
+    
+    public function deleteCampaignData($iCampaignId)
+    {
+        $CNF = &$this->_oConfig->CNF;
+        $aBindings = array(
+            'campaign_id' => $iCampaignId
+        );
+        $this->query("DELETE FROM `" . $CNF['TABLE_LETTERS'] . "` WHERE `" . $CNF['FIELD_CAMPAIGN_ID'] . "` = :campaign_id", $aBindings);
+        $this->query("DELETE FROM `" . $CNF['TABLE_LINKS'] . "` WHERE `" . $CNF['FIELD_CAMPAIGN_ID'] . "` = :campaign_id", $aBindings);
+        $this->query("DELETE FROM `" . $CNF['TABLE_UNSUBSCRIBE'] . "` WHERE `" . $CNF['FIELD_CAMPAIGN_ID'] . "` = :campaign_id", $aBindings);
+    }
+    
+    public function getLettersByCampaignId ($iCampaignId)
+    {
+        $CNF = &$this->_oConfig->CNF;
+        $sQuery = $this->prepare ("SELECT * FROM `" . $CNF['TABLE_LETTERS'] . "` WHERE `" . $CNF['FIELD_CAMPAIGN_ID'] . "` = ?", $iCampaignId);
+        return $this->getAll($sQuery);
+    }
+    
+    public function getClicksByCampaignId ($iCampaignId)
+    {
+        $CNF = &$this->_oConfig->CNF;
+        $sQuery = $this->prepare ("SELECT `" . $CNF['FIELD_LINK'] . "`, `" . $CNF['FIELD_TITLE'] . "`, COUNT( `" . $CNF['FIELD_ID'] . "`) AS `click_count`, MAX( `" . $CNF['FIELD_DATE_CLICK'] . "`) AS `last_click` FROM `" . $CNF['TABLE_LINKS'] . "` WHERE `" . $CNF['FIELD_CAMPAIGN_ID'] . "` = ? AND `" . $CNF['FIELD_DATE_CLICK'] . "` > 0 GROUP BY `" . $CNF['FIELD_LINK'] . "`, `" . $CNF['FIELD_TITLE'] . "` ORDER BY COUNT( `" . $CNF['FIELD_ID'] . "`)  DESC", $iCampaignId);
+        return $this->getAll($sQuery);
+    }
+    
+    public function getStatByCampaignId ($iCampaignId)
+    {
+        $CNF = &$this->_oConfig->CNF;
+         $aBindings = array(
+            'campaign_id' => $iCampaignId
+        );
+        $q = "
+        SELECT COUNT(*) AS `count`, 'total' AS `title` FROM `" . $CNF['TABLE_LETTERS'] . "` WHERE `" . $CNF['FIELD_CAMPAIGN_ID'] . "` = :campaign_id UNION
+        SELECT COUNT(*), 'seen' FROM `" . $CNF['TABLE_LETTERS'] . "` WHERE `" . $CNF['FIELD_CAMPAIGN_ID'] . "` = :campaign_id AND `" . $CNF['FIELD_DATE_SEEN'] . "` > 0 UNION
+        SELECT COUNT(*), 'clicked' FROM `" . $CNF['TABLE_LETTERS'] . "` WHERE `" . $CNF['FIELD_CAMPAIGN_ID'] . "` = :campaign_id AND `" . $CNF['FIELD_DATE_CLICK'] . "` > 0 UNION 
+        SELECT COUNT(*), 'unsubscribed' FROM `" . $CNF['TABLE_UNSUBSCRIBE'] . "` WHERE `" . $CNF['FIELD_CAMPAIGN_ID'] . "` = :campaign_id 
+        ";
+        return $this->getPairs($q, 'title', 'count', $aBindings);
+    }
+    
+    public function getLetterByCode ($sCode)
+    {
+        $CNF = &$this->_oConfig->CNF;
+        $sQuery = $this->prepare ("SELECT * FROM `" . $CNF['TABLE_LETTERS'] . "` WHERE `" . $CNF['FIELD_HASH'] . "` = ?", $sCode);
+        return $this->getRow($sQuery);
+    }
+    
+    public function addLink($sLetterHash, $sLink, $sTitle, $iCampaignId)
+    {
+        $CNF = &$this->_oConfig->CNF;
+        $sCode = md5($sLetterHash . $sLink . $sTitle);
+        $aBindings = array(
+            'letter_hash' => $sLetterHash,
+            'hash' => $sCode,
+            'link' => $sLink,
+            'title' => $sTitle,
+            'campaign_id' => $iCampaignId,
+        );
+        $this->query("INSERT INTO `" . $CNF['TABLE_LINKS'] . "` (`" . $CNF['FIELD_LETTER_HASH'] . "`, `" . $CNF['FIELD_HASH'] . "`, `" . $CNF['FIELD_LINK'] . "`, `" . $CNF['FIELD_TITLE'] . "`, `" . $CNF['FIELD_CAMPAIGN_ID'] . "`) VALUES (:letter_hash, :hash, :link, :title, :campaign_id)", $aBindings);
+        return $sCode;
+    }
+    
+    public function updateDateClickForLink($sCode)
+    {
+        $CNF = &$this->_oConfig->CNF;
+        $aBindings = array(
+            'code' => $sCode,
+            'date_click' => time()
+        );
+        $this->query("UPDATE `" . $CNF['TABLE_LINKS'] . "` SET `" . $CNF['FIELD_DATE_CLICK'] . "` = :date_click WHERE `" . $CNF['FIELD_HASH'] . "` = :code", $aBindings);
+        $aData = $this->getRow("SELECT * FROM `" . $CNF['TABLE_LINKS'] . "` WHERE `" . $CNF['FIELD_HASH'] . "` = :code", array('code' => $sCode));
+        $aBindings['code'] = $aData[$CNF['FIELD_LETTER_HASH']];
+        if ($aData[$CNF['FIELD_LETTER_HASH']] != '')
+            $this->query("UPDATE `" . $CNF['TABLE_LETTERS'] . "` SET `" . $CNF['FIELD_DATE_CLICK'] . "` = :date_click WHERE `" . $CNF['FIELD_HASH'] . "` = :code", $aBindings);
+        
+        return $aData[$CNF['FIELD_LINK']];
+    }
+    
+    
+    public function updateUnsubscribe($iAccountId, $iValue, $iCampaignId)
+    {
+        $CNF = &$this->_oConfig->CNF;
+        if ($iValue != 1){
+            $aBindings = array(
+                'account_id' => $iAccountId,
+                'campaign_id' => $iCampaignId,
+                'date_unsubscribed' => time()
+            );
+            $this->query("INSERT INTO `" . $CNF['TABLE_UNSUBSCRIBE'] . "` (`" . $CNF['FIELD_DATE_UNSUBSCRIBED'] . "`, `" . $CNF['FIELD_ACCOUNT_ID'] . "`, `" . $CNF['FIELD_CAMPAIGN_ID'] . "`) VALUES (:date_unsubscribed, :account_id, :campaign_id)", $aBindings);
+        }
+        else{
+            $aBindings = array(
+                'account_id' => $iAccountId
+            );
+            $this->query("DELETE FROM `" . $CNF['TABLE_UNSUBSCRIBE'] . "` WHERE `" . $CNF['FIELD_ACCOUNT_ID'] . "` = :account_id", $aBindings);
+        }
+    }
+    
+    public function deleteOldCampagns($iDayBefore)
+    {
+        $CNF = &$this->_oConfig->CNF;
+        $aBindings = array(
+            'time_from' => (time() - $iDayBefore * 86400)
+        );
+        $aTmp = $this->getColumn("SELECT `" . $CNF['FIELD_ID'] . "` FROM `" . $CNF['TABLE_CAMPAIGNS'] . "` WHERE `" . $CNF['FIELD_DATE_SENT'] . "` < :time_from AND `" . $CNF['FIELD_DATE_SENT'] . "` > 0", $aBindings);
+        if (count($aTmp) > 0){
+            $sIdList = $this->implode_escape($aTmp);
+            $this->query("DELETE FROM `" . $CNF['TABLE_LETTERS'] . "` WHERE `" . $CNF['FIELD_CAMPAIGN_ID'] . "` IN (" . $sIdList . ")", $aBindings);
+            $this->query("DELETE FROM `" . $CNF['TABLE_LINKS'] . "` WHERE `" . $CNF['FIELD_CAMPAIGN_ID'] . "` IN (" . $sIdList . ")", $aBindings);
+            $this->query("DELETE FROM `" . $CNF['TABLE_UNSUBSCRIBE'] . "` WHERE `" . $CNF['FIELD_CAMPAIGN_ID'] . "` IN (" . $sIdList . ")", $aBindings);
+            $this->query("DELETE FROM `" . $CNF['TABLE_CAMPAIGNS'] . "` WHERE `" . $CNF['FIELD_ID'] . "` IN (" . $sIdList . ")", $aBindings);
+        }
+    }
+}
+
+/** @} */

+ 212 - 0
modules/boonex/massmailer/updates/12.0.1_13.0.0/source/classes/BxMassMailerGridCampaigns.php

@@ -0,0 +1,212 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+* Copyright (c) UNA, Inc - https://una.io
+* MIT License - https://opensource.org/licenses/MIT
+*
+* @defgroup    MassMailer Mass Mailer
+* @ingroup     UnaModules
+* 
+* @{
+*/
+
+class BxMassMailerGridCampaigns extends BxTemplGrid
+{
+    public function __construct ($aOptions, $oTemplate = false)
+    {
+        $this->MODULE = 'bx_massmailer';
+        $this->_oModule = BxDolModule::getInstance($this->MODULE);
+        parent::__construct ($aOptions, $oTemplate);
+    }
+    
+    public function performActionDelete()
+    {
+        $aIds = bx_get('ids');
+        foreach ($aIds as $iId){
+            $this->_oModule->_oDb->deleteCampaignData($iId);
+        }
+        parent::performActionDelete();
+    }
+    
+    public function performActionSendTest()
+    {
+        $sAction = 'send_test';
+        $aIds = bx_get('ids');
+        $iId = $aIds[0];
+        $oForm = BxDolForm::getObjectInstance('bx_massmailer', 'bx_massmailer_campaign_send_test');
+        if (!$oForm)
+            return '';
+        $oForm->aFormAttrs['action'] = BX_DOL_URL_ROOT . 'grid.php?' . bx_encode_url_params($_GET, array('_r'));
+        $aContentInfo = array('email' => BxDolProfile::getInstance()->getAccountObject()->getEmail());
+        $oForm->initChecker($aContentInfo, array());
+        if($oForm->isSubmittedAndValid()) {
+            $mixedResult = $this->_oModule->sendTest($oForm->aInputs['email']['value'], $iId);
+            if($mixedResult !== false)
+                $aRes = array('grid' => $this->getCode(false), 'blink' => $mixedResult);
+            else
+                $aRes = array('msg' => _t('_bx_massmailer_txt_send_test_error'));
+            echoJson($aRes);
+        }
+        else {
+            
+            $sContent = BxTemplStudioFunctions::getInstance()->popupBox('bx_massmailer_campaign_send_test', _t('_bx_massmailer_campaign_form_send_test_title'), $this->_oModule->_oTemplate->parseHtmlByName('manage_item.html', array(
+                'form_id' => $oForm->id,
+                'form' => $oForm->getCode(true),
+                'object' => $this->_sObject,
+                'action' => $sAction
+            )));
+            echoJson(array('popup' => array('html' => $sContent, 'options' => array('closeOnOuterClick' => false))));
+        }
+    }
+    
+    public function performActionSendAll()
+    {
+        $sAction = 'send_all';
+        $aIds = bx_get('ids');
+        $iId = $aIds[0];
+        $oForm = BxDolForm::getObjectInstance('bx_massmailer', 'bx_massmailer_campaign_send_all');
+        if (!$oForm)
+            return '';
+        $oForm->aFormAttrs['action'] = BX_DOL_URL_ROOT . 'grid.php?' . bx_encode_url_params($_GET, array('_r'));
+        $oForm->initChecker(array(), array());
+        $oForm->aInputs['campaign_info']['value'] = _t($oForm->aInputs['campaign_info']['value'], $this->_oModule->getEmailCountInSegment($iId));
+        if($oForm->isSubmittedAndValid()) {
+            $mixedResult = $this->_oModule->sendAll($iId);
+            if($mixedResult !== false)
+                $aRes = array('grid' => $this->getCode(false), 'blink' => $mixedResult);
+            else
+                $aRes = array('msg' => $mixedResult);
+            echoJson($aRes);
+        }
+        else {
+            $sContent = BxTemplFunctions::getInstance()->popupBox('bx_massmailer_campaign_send_all', _t('_bx_massmailer_campaign_form_send_all_title'), $this->_oModule->_oTemplate->parseHtmlByName('manage_item.html', array(
+                'form_id' => $oForm->id,
+                'form' => $oForm->getCode(true),
+                'object' => $this->_sObject,
+                'action' => $sAction
+            )));
+            echoJson(array('popup' => array('html' => $sContent, 'options' => array('closeOnOuterClick' => false))));
+        }
+    }
+    
+    public function performActionCopy()
+    {
+        $aIds = bx_get('ids');
+        $iId = $aIds[0];
+        $mixedResult = $this->_oModule->_oDb->copyCampaign($iId);
+        if($mixedResult !== false)
+            $aRes = array('grid' => $this->getCode(false), 'blink' => $mixedResult);
+        else
+            $aRes = array('msg' => $mixedResult);
+        echoJson($aRes);
+    }
+    
+    protected function _getCellAdded($mixedValue, $sKey, $aField, $aRow)
+    {
+        return parent::_getCellDefault(bx_time_js($mixedValue), $sKey, $aField, $aRow);
+    }
+    
+    protected function _getCellSegments($mixedValue, $sKey, $aField, $aRow)
+    {
+        return parent::_getCellDefault($this->_oModule->getSegments($mixedValue), $sKey, $aField, $aRow);
+    }
+
+    protected function _getCellDateSent($mixedValue, $sKey, $aField, $aRow)
+    {
+        $sValue = bx_time_js($mixedValue);
+        if ($mixedValue == '0')
+            $sValue = _t('_bx_massmailer_txt_never_sent');
+        return parent::_getCellDefault($sValue, $sKey, $aField, $aRow);
+    }
+    
+    protected function _getCellIsOnePerAccount($mixedValue, $sKey, $aField, $aRow)
+    {
+        $sValue = _t('_bx_massmailer_grid_column_title_adm_is_one_per_account_no');
+        if ($mixedValue == '1')
+            $sValue = _t('_bx_massmailer_grid_column_title_adm_is_one_per_account_yes');
+        return parent::_getCellDefault($sValue, $sKey, $aField, $aRow);
+    }
+    
+    protected function _getActionCopy($sType, $sKey, $a, $isSmall = false, $isDisabled = false, $aRow = array())
+    {
+        if(isset($aRow["date_sent"]) && $aRow["date_sent"] == '0')
+            return '';
+        return parent::_getActionDefault ($sType, $sKey, $a, $isSmall, $isDisabled, $aRow);
+    }
+    
+    protected function _getActionSendTest($sType, $sKey, $a, $isSmall = false, $isDisabled = false, $aRow = array())
+    {
+        if(isset($aRow["date_sent"]) && $aRow["date_sent"] != '0')
+            return '';
+        return parent::_getActionDefault ($sType, $sKey, $a, $isSmall, $isDisabled, $aRow);
+    }
+    
+    protected function _getActionSendAll($sType, $sKey, $a, $isSmall = false, $isDisabled = false, $aRow = array())
+    {
+        if(isset($aRow["date_sent"]) && $aRow["date_sent"] != '0')
+            return '';
+        return parent::_getActionDefault ($sType, $sKey, $a, $isSmall, $isDisabled, $aRow);
+    }
+    
+    protected function _getActionAdd ($sType, $sKey, $a, $isSmall = false, $isDisabled = false, $aRow = array())
+    {
+        $CNF = &$this->_oModule->_oConfig->CNF;
+        $sUrl = BX_DOL_URL_ROOT . BxDolPermalinks::getInstance()->permalink('page.php?i=' . $CNF['URI_ADD_CAMPAIGN']);
+
+        unset($a['attr']['bx_grid_action_independent']);
+        $a['attr'] = array_merge($a['attr'], array(
+            "onclick" => "window.open('" . $sUrl . "','_self');"
+        ));
+
+        return parent::_getActionDefault ($sType, $sKey, $a, $isSmall, $isDisabled, $aRow);
+    }
+    
+    protected function _getActionEdit ($sType, $sKey, $a, $isSmall = false, $isDisabled = false, $aRow = array())
+    {
+        if(isset($aRow["date_sent"]) && $aRow["date_sent"] != '0')
+            return '';
+
+        $CNF = &$this->_oModule->_oConfig->CNF;
+
+        $sUrl = BX_DOL_URL_ROOT . BxDolPermalinks::getInstance()->permalink('page.php?i=' . $CNF['URI_EDIT_CAMPAIGN'] . '&id=' . $aRow[$CNF['FIELD_ID']]);
+
+        $a['attr'] = array_merge($a['attr'], array(
+            "onclick" => "window.open('" . $sUrl . "','_self');"
+        ));
+
+        return $this->_getActionDefault ($sType, $sKey, $a, $isSmall, $isDisabled, $aRow);
+    }
+    
+    protected function _getActionView ($sType, $sKey, $a, $isSmall = false, $isDisabled = false, $aRow = array())
+    {
+        if(isset($aRow["date_sent"]) && $aRow["date_sent"] == '0')
+            return '';
+        
+        $CNF = &$this->_oModule->_oConfig->CNF;
+        
+        $sUrl = BX_DOL_URL_ROOT . BxDolPermalinks::getInstance()->permalink('page.php?i=' . $CNF['URI_VIEW_CAMPAIGN'] . '&id=' . $aRow[$CNF['FIELD_ID']]);
+
+        unset($a['attr']['bx_grid_action_independent']);
+        $a['attr'] = array_merge($a['attr'], array(
+            "onclick" => "window.open('" . $sUrl . "','_self');"
+        ));
+
+        return parent::_getActionDefault ($sType, $sKey, $a, $isSmall, $isDisabled, $aRow);
+    }
+    
+    protected function _getCellAuthor($mixedValue, $sKey, $aField, $aRow)
+    {
+        $oProfile = BxDolProfile::getInstance($aRow['author']);
+        if (!$oProfile)
+            $oProfile = BxDolProfileUndefined::getInstance();
+        return parent::_getCellDefault($oProfile->getDisplayName(), $sKey, $aField, $aRow);
+    }
+    
+    protected function _isVisibleGrid ($a)
+    {
+        if (isAdmin() || !isset($a['visible_for_levels']))
+            return true;
+        return $this->_oModule->checkAllowed() === CHECK_ACTION_RESULT_ALLOWED ? true : false;
+    }
+}
+
+/** @} */

+ 675 - 0
modules/boonex/massmailer/updates/12.0.1_13.0.0/source/classes/BxMassMailerModule.php

@@ -0,0 +1,675 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+* Copyright (c) UNA, Inc - https://una.io
+* MIT License - https://opensource.org/licenses/MIT
+*
+* @defgroup    MassMailer Mass Mailer
+* @ingroup     UnaModules
+*
+* @{
+*/
+
+class BxMassMailerModule extends BxBaseModGeneralModule
+{
+    private $aSegments = array();
+          
+    function __construct(&$aModule)
+    {
+        parent::__construct($aModule);
+        $CNF = &$this->_oConfig->CNF;
+        $aRv = array('lvl:0' => _t('_bx_massmailer_segments_all'));
+        $oAccountQuery = BxDolAclQuery::getInstance();
+              
+        $aTmp = array();
+        $oAccountQuery->getLevels(array('type' => 'all_active_pair'), $aTmp);
+        foreach ($aTmp as $sKey => $sTmp){
+            if ($sKey != MEMBERSHIP_ID_NON_MEMBER && $sKey != MEMBERSHIP_ID_ACCOUNT)
+                $aRv['lvl:' . $sKey] = _t($sTmp);
+        };
+              
+        $aTmp = $this->_oDb->getSegments();
+        foreach ($aTmp as $sKey => $sTmp){
+            $aRv['cst:' . $sKey] = _t($sTmp);
+        };
+        $this->aSegments = $aRv;
+    }
+          
+    /**
+    * ACTION METHODS
+    */
+    public function actionTrack($sActionName, $sHash)
+    {
+        if (isset($sHash) && trim($sHash) != ""){
+            switch ($sActionName) {
+                case 'click':
+                    $sLink = $this->_oDb->updateDateClickForLink($sHash);
+                    if (strpos($sLink, '://') === false)
+                        $sLink = BX_DOL_URL_ROOT . $sLink;
+                    header('Location: ' . $sLink);
+                    break;
+                    
+                case 'seen':
+                    header('Content-Type: image/png');
+                    $this->_oDb->updateDateSeenForLetter($sHash);
+                    break;
+            }
+        }
+    }
+    
+    public function actionGetReportsData($sReportName, $sReportType, $sDateFrom, $sDateTo, $sSegment)
+    {
+        if($this->checkAllowed() !== CHECK_ACTION_RESULT_ALLOWED)
+            return '';
+        
+        header('Content-Type: application/json');
+        
+        $aColors = array('#3366CC', '#DC3912', '#FF9900', '#109618', '#990099');
+        $iDateFrom = strtotime($sDateFrom);
+        $iDateTo = strtotime($sDateTo);
+        $sType = "bar";
+        $bIsTimeX = false;
+        $iMinValueY = 0;
+        $iMaxValueY = 0;
+        $aValues = array('labels' => array(), 'values' => array(array('legend' => '', 'data' => array())), 'links' => array(), 'strings' => array(0 => _t('_bx_massmailer_txt_item'), 1 => _t('_bx_massmailer_txt_value')));
+        
+        switch ($sReportName) {
+            case "SUBSCRIBERS_INFO":
+                $sType = "line";
+                $bIsTimeX = true;
+                $aValues['strings'][0] = _t('_bx_massmailer_txt_date');
+                $aValues['strings'][1] = '';
+                $sSql = $this->getSqlBySegment($sSegment);
+                $aData = $this->_oDb->getAccountsByTermsStat($iDateFrom, $iDateTo, $sSql);
+                $aData2 = $this->_oDb->getAccountsByTermsStatUnsubscribe($iDateFrom, $iDateTo, $sSql);
+                $iValuePrev = $this->_oDb->getAccountsByTermsStatInitValue($iDateFrom, $sSql);
+                $iValuePrev2 = $this->_oDb->getAccountsByTermsStatInitValueUnsubscribe($iDateFrom, $sSql);
+                $aTmpDates = array();
+                $aTmpDates2 = array();
+                $aValues['values'][0]['legend'] = _t('_bx_massmailer_txt_subscribed');
+                $aValues['values'][1] = array('legend' => _t('_bx_massmailer_txt_unsubscribed') , 'data' => array());
+                foreach ($aData as $aValue) {
+                    $aTmpDates[$aValue['period']] = $aValue['count'];
+                }
+                foreach ($aData2 as $aValue) {
+                    $aTmpDates2[$aValue['period']] = $aValue['count'];
+                }
+                for ($i = $iDateFrom; $i < $iDateTo ; $i = $i + 86400 ){
+                    $sX = date('Y-m-d', $i);
+                    
+                    if (!array_key_exists($sX, $aTmpDates)){
+                        array_push($aValues['values'][0]['data'], array('x' => $sX, 'y' => $sReportType == 'content_total' ? $iValuePrev : 0));
+                        
+                    }
+                    else{
+                        array_push($aValues['values'][0]['data'], array('x' => $sX, 'y' => $sReportType == 'content_total' ? $iValuePrev : $aTmpDates[$sX]));
+                        $iValuePrev += $aTmpDates[$sX];
+                    }
+                    
+                    if (!array_key_exists($sX, $aTmpDates2)){
+                        array_push($aValues['values'][1]['data'], array('x' => $sX, 'y' => $sReportType == 'content_total' ? $iValuePrev2 : 0));
+                        
+                    }
+                    else{
+                        array_push($aValues['values'][1]['data'], array('x' => $sX, 'y' => $sReportType == 'content_total' ? $iValuePrev2 : $aTmpDates2[$sX]));
+                        $iValuePrev2 += $aTmpDates2[$sX];
+                    }
+                    
+                    if ($sReportType == 'content_total'){
+                        if ($iValuePrev > $iMaxValueY)
+                            $iMaxValueY = $iValuePrev;
+                        if ($iValuePrev2 > $iMaxValueY)
+                            $iMaxValueY = $iValuePrev2;
+                    }
+                    else{
+                        if (array_key_exists($sX, $aTmpDates) && $aTmpDates[$sX] > $iMaxValueY)
+                            $iMaxValueY = $aTmpDates[$sX];
+                        if (array_key_exists($sX, $aTmpDates2) && $aTmpDates2[$sX] > $iMaxValueY)
+                            $iMaxValueY = $aTmpDates2[$sX];
+                    }
+                }
+                break;
+            
+            case "CAMPAIGN_REPORT":
+                $aDataStat = $this->_oDb->getStatByCampaignId($sReportType);
+                $aValues['values'][0]['legend'] = _t('_bx_massmailer_txt_sent_total_title', $aDataStat['total']);
+                array_push($aValues['values'][0]['data'], $aDataStat['total']);
+                $aValues['values'][1] = array('legend' => _t('_bx_massmailer_txt_opened_total_title', $aDataStat['seen']) , 'data' => array($aDataStat['seen']));
+                $aValues['values'][2] = array('legend' => _t('_bx_massmailer_txt_unopened_total_title', $aDataStat['total'] - $aDataStat['seen']), 'data' => array($aDataStat['total'] - $aDataStat['seen']));
+                $aValues['values'][3] = array('legend' => _t('_bx_massmailer_txt_clicked_total_title', $aDataStat['clicked']), 'data' => array($aDataStat['clicked']));
+                $aValues['values'][4] = array('legend' => _t('_bx_massmailer_txt_unsubscribed_total_title', $aDataStat['unsubscribed']), 'data' => array($aDataStat['unsubscribed']));
+                $iMaxValueY = $aDataStat['total'];
+                break;
+        }
+        
+        $iMaxValueY = ceil($iMaxValueY * 1.1);
+        
+        $aDataForChartXAxes = array();
+        if ($bIsTimeX){
+            $sUnit = 'day';
+            $iInterval = ($iDateTo - $iDateFrom) / 86400;
+            if ($iInterval > 50)
+                $sUnit = 'week';
+            if ($iInterval > 100)
+                $sUnit = 'month';
+            
+            $aDataForChartXAxes = array(
+                'type' => 'time',
+                'time' => array(
+                    'tooltipFormat' => 'DD.MM.YYYY',
+                    'unit' => $sUnit,
+                 ),
+                'display' => true,
+                'distribution' => 'linear',
+                'ticks' => array(
+                    'display' => true,
+                    'autoSkip' => true,
+                )
+            );
+        }
+        else{
+            $aDataForChartXAxes = array(
+                'ticks' => array(
+                    'autoSkip' => false
+                ),
+                'display' => true
+            );
+        }
+        
+        $aDataForChartDatasets = array();
+        for($i = 0; $i < count($aValues['values']); $i++){
+            $aDataForChartDatasets[] = array(
+                'label' => $aValues['values'][$i]['legend'],
+                'fill' => false,
+                'backgroundColor' => $aColors[$i],
+                'borderColor' => $aColors[$i],
+                'borderWidth' => 1,
+                'data' => $aValues['values'][$i]['data']
+            );
+        }
+        
+        $aDataForChart = array(
+            'type' => $sType,
+            'data' => array(
+                'labels' => $aValues['labels'],
+                'datasets' => $aDataForChartDatasets
+            ),
+            'options' => array(
+                'legend' => array(
+                    'position' => 'bottom',
+                    'display' => count($aValues['values']) == 1 ? false : true
+                ),
+                'scales' => array(
+                    'yAxes' => array(
+                        array(
+                            'ticks' => array(
+                                'max' => $iMaxValueY,
+                                'min' => $iMinValueY,
+                                'stepSize' => $this->getReportStep($iMinValueY, $iMaxValueY),
+                                'autoSkip' => true
+                            )
+                        )
+                    ),
+                    'xAxes' => array($aDataForChartXAxes)
+                )
+            ),
+            'links' => $aValues['links'],
+            'strings' => $aValues['strings'],
+        );
+        
+        echo json_encode($aDataForChart);
+    }
+  
+    /**
+    * SERVICE METHODS
+    */
+
+    public function serviceGetSafeServices()
+    {
+        return array ();
+    }
+
+    /**
+    * @page service Service Calls
+    * @section bx_massmailer Mass mailer
+    * @subsection bx_massmailer-page_blocks Page Blocks
+     * @subsubsection bx_massmailer-campagn_subscribers campagn_subscribers
+    * 
+     * @code bx_srv('bx_massmailer', 'campagn_subscribers', [...]); @endcode
+    * 
+    * Get page block with the campagn's subscribers list
+    *
+    * @param $iContentId content ID.
+    * @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 BxMassMailerModule::serviceCampagnSubscribers
+    */
+    /** 
+    * @ref bx_massmailer-campagn_subscribers "entity_view"
+    */
+    public function serviceCampagnSubscribers ($iContentId = 0, $sDisplay = false)
+    {
+        if(!$iContentId)
+            $iContentId = bx_process_input(bx_get('id'), BX_DATA_INT);
+
+        if(!$iContentId)
+            return false;
+              
+        $aData = $this->_oDb->getLettersByCampaignId($iContentId);
+        if (count($aData) > 0)
+            return $this->_oTemplate->getSubscribers($aData);
+        return $iContentId;
+    }
+    
+    /**
+     * @page service Service Calls
+     * @section bx_massmailer Mass mailer
+     * @subsection bx_massmailer-page_blocks Page Blocks
+     * @subsubsection bx_massmailer-campagn_info campagn_info
+     * 
+     * @code bx_srv('bx_massmailer', 'campagn_info', [...]); @endcode
+     * 
+     * Get page block with the campagn info
+     *
+     * @param $iContentId content ID.
+     * @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 BxMassMailerModule::serviceCampagnInfo
+     */
+    /** 
+     * @ref bx_massmailer-campagn_info "campagn_info"
+     */
+    public function serviceCampagnInfo ($iContentId = 0, $sDisplay = false)
+    {
+        if(!$iContentId)
+            $iContentId = bx_process_input(bx_get('id'), BX_DATA_INT);
+
+        if(!$iContentId)
+            return false;
+        
+        return $this->_oTemplate->getInfo($iContentId);
+    }
+    
+    /**
+     * @page service Service Calls
+     * @section bx_massmailer Mass mailer
+     * @subsection bx_massmailer-page_blocks Page Blocks
+     * @subsubsection bx_massmailer-campagn_links campagn_links
+     * 
+     * @code bx_srv('bx_massmailer', 'campagn_links', [...]); @endcode
+     * 
+     * Get page block with the campagn links list
+     *
+     * @param $iContentId content ID
+     * @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 BxMassMailerModule::serviceCampagnLinks
+     */
+    /** 
+     * @ref bx_massmailer-campagn_links "campagn_links"
+     */
+    public function serviceCampagnLinks ($iContentId = 0, $sDisplay = false)
+    {
+        if(!$iContentId)
+            $iContentId = bx_process_input(bx_get('id'), BX_DATA_INT);
+
+        if(!$iContentId)
+            return false;
+        
+        $aData = $this->_oDb->getClicksByCampaignId($iContentId);
+        if (count($aData) > 0)
+            return $this->_oTemplate->getClicks($aData);
+        return $iContentId;
+    }
+    
+    /**
+     * @page service Service Calls
+     * @section bx_massmailer Mass mailer
+     * @subsection bx_massmailer-page_blocks Page Blocks
+     * @subsubsection bx_massmailer-total_subscribers total_subscribers
+     * 
+     * @code bx_srv('bx_massmailer', 'total_subscribers', [...]); @endcode
+     * 
+     * Get page block with subscribers charts
+     *
+     * @param $aParams an array with search params.
+     * @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 BxMassMailerModule::serviceTotalSubscribers
+     */
+    /** 
+     * @ref bx_massmailer-total_subscribers "total_subscribers"
+     */
+    public function serviceTotalSubscribers ()
+    {
+        if($this->checkAllowed() !== CHECK_ACTION_RESULT_ALLOWED)
+            return '';
+        
+        return $this->_oTemplate->getTotalSubscribers();
+    }
+    
+    /**
+     * @page service Service Calls
+     * @section bx_massmailer Mass mailer
+     * @subsection bx_massmailer-page_blocks Page Blocks
+     * @subsubsection bx_massmailer-entity_breadcrumb entity_breadcrumb
+     * 
+     * @code bx_srv('bx_massmailer', 'entity_breadcrumb', [...]); @endcode
+     * 
+     * Get page block with page's breadcrumbs
+     *
+     * @param $iContentId content ID
+     * @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 BxMassMailerModule::serviceEntityBreadcrumb
+     */
+    /** 
+     * @ref bx_massmailer-entity_breadcrumb "entity_breadcrumb"
+     */
+    public function serviceEntityBreadcrumb ($iContentId = 0)
+    {
+        $CNF = &$this->_oConfig->CNF;
+        $oPermalink = BxDolPermalinks::getInstance();
+        if (!$iContentId)
+            $iContentId = bx_process_input(bx_get('id'), BX_DATA_INT);
+        if (!$iContentId){
+            $aContentInfo[$CNF['FIELD_TITLE']] = _t('_bx_massmailer_txt_breadcrumb_title_new_campaign');
+            $aContentInfo['url'] = $oPermalink->permalink('page.php?i=' . $CNF['URI_ADD_CAMPAIGN']);
+        }
+        else{
+            $aContentInfo = $this->_oDb->getCampaignInfoById($iContentId);
+            if (!$aContentInfo)
+                return false;
+            $aContentInfo['url'] = $oPermalink->permalink('page.php?i=' . $CNF['URI_VIEW_CAMPAIGN'] . '&id=' . $aContentInfo[$CNF['FIELD_ID']]);
+        }
+        return $this->_oTemplate->entryBreadcrumb($aContentInfo);
+    }
+    
+    /**
+     * @page service Service Calls
+     * @section bx_massmailer Mass mailer
+     * @subsection bx_massmailer-page_blocks Page Blocks
+     * @subsubsection bx_massmailer-attributes attributes
+     * 
+     * @code bx_srv('bx_massmailer', 'attributes', [...]); @endcode
+     * 
+     * Get page block with attributes list
+     *
+     * @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 BxMassMailerModule::serviceAttributes
+     */
+    /** 
+     * @ref bx_massmailer-attributes "attributes"
+     */
+    public function serviceAttributes ()
+    {
+        $aAttributesParts = array();
+        $aAttributesParts['account'] = array(
+            _t('_bx_massmailer_txt_attribute_global'), 
+            array(
+                'email' => _t('_bx_massmailer_txt_attribute_email'), 
+                'account_name' => _t('_bx_massmailer_txt_attribute_account_name'), 
+                'account_id' => _t('_bx_massmailer_txt_attribute_account_id'), 
+                'reset_password_url' => _t('_bx_massmailer_txt_attribute_reset_password_url'),
+                'unsubscribe_url' => _t('_bx_massmailer_txt_attribute_unsubscribe_url')
+            )
+        );
+        $BxDolModuleQuery = BxDolModuleQuery::getInstance();
+        $aModules = $BxDolModuleQuery->getModulesBy(array('type' => 'modules', 'active' => 1));
+        foreach($aModules as $aModule){
+            if(BxDolRequest::serviceExists($aModule['name'], 'act_as_profile') && BxDolService::call($aModule['name'], 'act_as_profile') == true){
+                $oModule = BxDolModule::getInstance($aModule['name']);
+                $aTmp2 = array();
+                $aTmp = $oModule->serviceGetSearchableFieldsExtended('view');
+                foreach($aTmp as $sKey => $aField){
+                    $aTmp2[$sKey] = _t($aField['caption']);
+                }
+                $aAttributesParts[$aModule['name']] = array($aModule['title'], $aTmp2);
+            }
+        }
+        return $this->_oTemplate->getAttributes($aAttributesParts);
+    }
+    
+    /**
+     * @return CHECK_ACTION_RESULT_ALLOWED if access is granted or error message if access is forbidden. So make sure to make strict(===) checking.
+     */
+    public function checkAllowedAdd ($isPerformAction = false)
+    {
+        return $this->checkAllowed($isPerformAction);
+    }
+    
+    /**
+     * @return CHECK_ACTION_RESULT_ALLOWED if access is granted or error message if access is forbidden. So make sure to make strict(===) checking.
+     */
+    public function checkAllowedEdit ($aDataEntry, $isPerformAction = false)
+    {
+        return $this->checkAllowed($isPerformAction);
+    }
+    
+    /**
+     * @return CHECK_ACTION_RESULT_ALLOWED if access is granted or error message if access is forbidden. So make sure to make strict(===) checking.
+     */
+    public function checkAllowedEditAnyEntryForProfile ($isPerformAction = false, $iProfileId = false)
+    {
+        return $this->checkAllowed($isPerformAction);
+    }
+
+    /**
+     * @return CHECK_ACTION_RESULT_ALLOWED if access is granted or error message if access is forbidden. So make sure to make strict(===) checking.
+     */
+    public function checkAllowedDelete (&$aDataEntry, $isPerformAction = false)
+    {
+        return $this->checkAllowed($isPerformAction);
+    }
+          
+    public function getSegments($sKey = "")
+    {
+        if ($sKey == ""){
+            return $this->aSegments;
+        }
+        else{
+            if (isset($this->aSegments[$sKey]))
+                return $this->aSegments[$sKey];
+            return false;
+        }
+    }
+          
+    public function sendTest($sEmail, $iCampaignId)
+    {
+        $aTmp = $this->getDataForCampaign($iCampaignId);
+        $aTemplate = $aTmp[0];
+        $aCustomHeaders = $aTmp[1];
+              
+        if (!$aTemplate)
+            return false;
+        
+        return $this->sendLetter($sEmail, $iCampaignId, $aCustomHeaders, getLoggedId(), $aTemplate, false);
+    }
+          
+    public function sendAll($iCampaignId)
+    {
+        $aTmp = $this->getDataForCampaign($iCampaignId);
+        $aTemplate = $aTmp[0];
+        $aCustomHeaders = $aTmp[1];
+        $aCampaign = $aTmp[2];
+              
+        if (!$aTemplate)
+            return false;
+        
+        $this->_oDb->deleteCampaignData($iCampaignId);
+        $aAccounts = $this->getEmailsBySegment($aCampaign['segments'], $aCampaign['is_one_per_account']);
+        foreach ($aAccounts as $aAccountInfo){
+            $this->sendLetter($aAccountInfo['email'], $iCampaignId, $aCustomHeaders, $aAccountInfo['account_id'], $aTemplate, true);
+            $this->_oDb->addEmailToSentListForCampaign($iCampaignId, $aAccountInfo['email']);
+        }
+              
+        $this->_oDb->sendCampaign($iCampaignId);
+        return true;
+    }
+    
+    private function sendLetter($sEmail, $iCampaignId, $aCustomHeaders, $iAccountId, $aTemplate, $bAddToQueue)
+    {
+        $sLetterCode = $this->_oDb->addLetter($iCampaignId, $sEmail);
+        
+        $aMarkers = $this->addMarkers($iAccountId, $sLetterCode);
+        bx_alert($this->_aModule['name'], 'user_fields', $iCampaignId, $iAccountId, array('email' => $sEmail, 'markers' => &$aMarkers));
+        
+        $regexp = "<a\s[^>]*href=(\"??)([^\" >]*?)\\1[^>]*>(.*)<\/a>";
+        $aTemplate['Body'] = preg_replace_callback("/$regexp/siU",
+            function ($aMatch) use ($iCampaignId, $sLetterCode, $aMarkers) {
+                if ($aMatch[2] != '{unsubscribe_url}'){
+                    $sUrl = bx_replace_markers($aMatch[2], $aMarkers);
+                    $sLinkCode = $this->_oDb->addLink($sLetterCode, $sUrl, $aMatch[3], $iCampaignId);
+                    return str_replace($sUrl, BX_DOL_URL_ROOT . $this->_oConfig->getBaseUri() . 'track/click/' . $sLinkCode . "/", $aMatch[0]);
+                }
+                else{
+                    return $aMatch[0];
+                }
+            },
+            $aTemplate['Body']);
+        
+        $aMarkersInLetter = [];
+        preg_match_all("/\{[^\}]*\}/i", $aTemplate['Body'], $aMarkersInLetter);
+        if ($aMarkersInLetter[0]>0){
+            foreach ($aMarkersInLetter[0] as $sMarker){
+                $sMarker = str_replace(['{', '}'], '', $sMarker);
+                if (!array_key_exists($sMarker, $aMarkers)) {
+                    $aMarkers[$sMarker] = '';
+                }
+            }
+        }
+        
+        return sendMail($sEmail, $aTemplate['Subject'], $aTemplate['Body'], 0, $aMarkers, BX_EMAIL_MASS, 'html', false, $aCustomHeaders, $bAddToQueue);
+    }
+
+    public function getEmailCountInSegment($iCampaignId)
+    {
+        $aTmp = $this->getDataForCampaign($iCampaignId);
+        $aCampaign = $aTmp[2];
+        $aAccounts = $this->getEmailsBySegment($aCampaign['segments'], $aCampaign['is_one_per_account']);
+        return count($aAccounts);
+    }
+          
+    private function getEmailsBySegment($sSegment, $bIsOnePerAccount)
+    {
+        $sTerms = $this->getSqlBySegment($sSegment);
+        if ($bIsOnePerAccount){
+            $sTerms .= "AND `tp`.`id` = `ta`.`profile_id` ";
+        }
+        return $this->_oDb->getAccountsByTerms($sTerms);
+    }
+    
+    public function checkAllowed($isPerformAction = false)
+    {
+        $aCheck = checkActionModule($this->_iProfileId, 'use massmailer', $this->getName(), $isPerformAction);
+        if ($aCheck[CHECK_ACTION_RESULT] !== CHECK_ACTION_RESULT_ALLOWED)
+             return _t('_sys_txt_access_denied');
+        return CHECK_ACTION_RESULT_ALLOWED;
+    }
+    
+    private function getSqlBySegment($sSegment)
+    {
+        $sRv = '';
+        $sJoin = ' INNER ';
+        if (strpos($sSegment, 'lvl:') !== false){
+            $sLvl = str_replace('lvl:', '', $sSegment);
+            switch ($sLvl) {
+                case 0:
+                    $sRv = '';
+                    $sJoin = ' LEFT ';
+                    break;
+                case MEMBERSHIP_ID_UNCONFIRMED:
+                    $sRv = " AND `ta`.`email_confirmed` = 0 AND `ta`.`phone_confirmed` = 0 ";
+                    break;
+                case MEMBERSHIP_ID_SUSPENDED:
+                    $sRv = " AND `tp`.`status` = 'suspended' ";
+                    break;
+                case MEMBERSHIP_ID_PENDING:
+                    $sRv = " AND `tp`.`status` = 'pending' ";
+                    break;
+                case MEMBERSHIP_ID_STANDARD:
+                    $sRv = " AND `tp`.`id` NOT IN (SELECT `IDMember` FROM `sys_acl_levels_members`) ";
+                    break;
+                default:
+                    $sRv = $this->_oDb->prepareAsString(" AND `tp`.`id` IN (SELECT `IDMember` FROM `sys_acl_levels_members` WHERE IDLevel = ?) ", $sLvl);
+                    break;
+            }
+            $sRv .= " AND `tp`.`type` IN (" . $this->_oDb->implode_escape($this->getProfileModules()) . ")";
+        }
+        return $sJoin . " JOIN `sys_profiles` AS `tp` ON `tp`.`account_id`=`ta`.`id` " . $sRv;
+    }
+    
+    private function getProfileModules()
+    {
+        $aResult = array();
+        $BxDolModuleQuery = BxDolModuleQuery::getInstance();
+        $aModules = $BxDolModuleQuery->getModulesBy(array('type' => 'modules', 'active' => 1));
+        foreach($aModules as $aModule){
+            if(BxDolRequest::serviceExists($aModule['name'], 'act_as_profile') && BxDolService::call($aModule['name'], 'act_as_profile') == true){
+                array_push($aResult, $aModule['name']);
+            }
+        }
+        return $aResult;
+    }
+          
+    private function getDataForCampaign($iCampaignId)
+    {
+        $aCampaign = $this->_oDb->getCampaignInfoById($iCampaignId);
+        $oEmailTemplates = BxDolEmailTemplates::getInstance();
+        $aTemplate = $oEmailTemplates->parseTemplate('bx_massmailer_email', array('content' => $aCampaign['body']));
+        $aTemplate['Subject'] = $aCampaign['subject'];
+              
+        $aCustomHeaders = array();
+        $sFrom = $aCampaign['from_name'] != '' ? $aCampaign['from_name'] : getParam('site_title');
+        $aCustomHeaders['From'] = "=?UTF-8?B?" . base64_encode($sFrom) . "?= <" . getParam('site_email_notify') . ">" ;
+        if ($aCampaign['reply_to'] != ''){
+            $sFrom = $aCampaign['from_name'] != '' ? $aCampaign['from_name'] : getParam('site_title');
+            $aCustomHeaders['Reply-To'] = "=?UTF-8?B?" . base64_encode($sFrom) . '?= <' . bx_process_output($aCampaign['reply_to']) . '>';
+            $aCustomHeaders['X-Original-From'] = "=?UTF-8?B?" . base64_encode($sFrom) . '?= <' . bx_process_output($aCampaign['reply_to']) . '>';
+        }
+              
+        return array($aTemplate, $aCustomHeaders, $aCampaign);
+    }
+          
+    private function addMarkers($iAccountId, $sLetterCode)
+    {
+        $CNF = &$this->_oConfig->CNF;
+        $aMarkers = array();
+        
+        $oAccount = BxDolAccount::getInstance($iAccountId);
+        $aAccountInfo = $oAccount->getInfo();
+        $sAccountEmail = $oAccount->getEmail();
+        
+        $aMarkers['email'] = $sAccountEmail;
+        $aMarkers['account_name'] = $oAccount->getDisplayName();
+        $aMarkers['account_id'] = $oAccount->id();
+        
+        if ($aAccountInfo['profile_id'] > 0){
+            $oProfile = BxDolProfile::getInstance($aAccountInfo['profile_id']);
+            $sModule = $oProfile->getModule();
+            if (BxDolRequest::serviceExists($sModule, 'get_info')) {
+                $aProfileInfo = bx_srv($sModule, 'get_info', array($oProfile->getContentId(), false));
+                foreach ($aProfileInfo as $sKey => $sValue)
+                    if(!isset($aMarkers[$sKey]))
+                        $aMarkers[$sKey] = $sValue;
+            }
+        }    
+
+        $aMarkers['seen_image_url'] = BX_DOL_URL_ROOT . $this->_oConfig->getBaseUri() . 'track/seen/' . $sLetterCode . "/";
+        $aMarkers['unsubscribe_url'] = BX_DOL_URL_ROOT . $oAccount->getUnsubscribeLink(BX_EMAIL_MASS) . "&lhash=" . $sLetterCode;
+
+        $aMarkers['reset_password_url'] = '';
+        if(($sResetPasswordUrl = bx_get_reset_password_link($sAccountEmail)) !== false)
+            $aMarkers['reset_password_url'] = $sResetPasswordUrl . "&lhash=" . $sLetterCode;
+
+        return $aMarkers;
+    }
+    
+    private function getReportStep($iMin, $iMax)
+    {
+        $iCount = 10;
+        return ceil(($iMax - $iMin) / $iCount);
+    }
+}
+
+/** @} */

+ 183 - 0
modules/boonex/massmailer/updates/12.0.1_13.0.0/source/classes/BxMassMailerTemplate.php

@@ -0,0 +1,183 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    MassMailer Mass Mailer
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+class BxMassMailerTemplate extends BxBaseModGeneralTemplate
+{
+    function __construct(&$oConfig, &$oDb)
+    {
+        parent::__construct($oConfig, $oDb);
+    }
+    
+    function getSubscribers($aData)
+    {
+        $aList = array();
+        foreach($aData as $aItem){
+            $aList[] = array('email' => $aItem['email'], 'date_sent' => $aItem['date_sent'] > 0 ? bx_time_js($aItem['date_sent']) : '', 'date_seen' => $aItem['date_seen'] > 0 ? bx_time_js($aItem['date_seen']) : '', 'date_click' => $aItem['date_click'] > 0 ? bx_time_js($aItem['date_click']) : '');
+        }
+        
+        $this->addJs(array(BX_DIRECTORY_PATH_MODULES . 'boonex/massmailer/plugins/datatables/|datatables.min.js'));
+        $this->addCss(array('main.css', BX_DIRECTORY_PATH_MODULES . 'boonex/massmailer/plugins/datatables/|datatables.min.css'));
+        return $this->parseHtmlByName('campaign_subscribers.html', array(
+             'bx_repeat:items' => $aList,
+             'email_title' => _t('_bx_massmailer_txt_title_email'),
+             'date_sent_title' => _t('_bx_massmailer_txt_title_date_sent'),
+             'date_seen_title' => _t('_bx_massmailer_txt_title_date_seen'),
+             'date_click_title' => _t('_bx_massmailer_txt_title_date_click'),
+            ));
+    }
+    
+    function getClicks($aData)
+    {
+        $aList = array();
+        foreach($aData as $aItem){
+            $aList[] = array('title' => $aItem['title'], 'link' => $aItem['link'], 'last_click' => $aItem['last_click'] > 0 ? bx_time_js($aItem['last_click']) : '', 'click_count' => $aItem['click_count']);
+        }
+        
+        $this->addJs(array(BX_DIRECTORY_PATH_MODULES . 'boonex/massmailer/plugins/datatables/|datatables.min.js'));
+        $this->addCss(array('main.css', BX_DIRECTORY_PATH_MODULES . 'boonex/massmailer/plugins/datatables/|datatables.min.css'));
+        return $this->parseHtmlByName('campaign_clicks.html', array(
+             'bx_repeat:items' => $aList,
+             'title_title' => _t('_bx_massmailer_txt_title_title'),
+             'link_title' => _t('_bx_massmailer_txt_link_title'),
+             'click_count_title' => _t('_bx_massmailer_txt_click_count_title'),
+             'last_click_title' => _t('_bx_massmailer_txt_last_click_title'),
+            ));
+    }
+    
+    
+    
+    function getInfo($CampaignId)
+    {
+        $CNF = &$this->getModule()->_oConfig->CNF;
+        
+        $aData = $this->_oModule->_oDb->getCampaignInfoById($CampaignId);
+        $aDataStat = $this->_oModule->_oDb->getStatByCampaignId($CampaignId);
+        
+        $this->addJs(array('chart.min.js', 'chart.js', BX_DIRECTORY_PATH_MODULES . 'boonex/massmailer/plugins/daterangepicker/|daterangepicker.js'));
+        $this->addCss(array('main.css', BX_DIRECTORY_PATH_MODULES . 'boonex/massmailer/plugins/daterangepicker/|daterangepicker.css'));
+        
+        return $this->getJsCode('chart', array('sChartName' => 'CAMPAIGN_REPORT', 'sReportName' => $CampaignId)) . $this->parseHtmlByName('campaign_info.html', array(
+            'created_title' => _t('_bx_massmailer_txt_created_title'),
+            'subject_title' => _t('_bx_massmailer_txt_subject_title'),
+            'body_title' => _t('_bx_massmailer_txt_body_title'),
+            'sent_on_title' => _t('_bx_massmailer_txt_sent_on_title'),
+            'sent_to_title' => _t('_bx_massmailer_txt_sent_to_title'),
+            'sent_total_title' => _t('_bx_massmailer_txt_sent_total_title'),
+            'opened_total_title' => _t('_bx_massmailer_txt_opened_total_title'),
+            'unopened_total_title' => _t('_bx_massmailer_txt_unopened_total_title'),
+            'clicked_total_title' => _t('_bx_massmailer_txt_clicked_total_title'),
+            'reply_title' => _t('_bx_massmailer_txt_reply_title'),
+            'subject' => $aData[$CNF['FIELD_SUBJECT']],
+            'body' => $aData[$CNF['FIELD_BODY']],
+            'sent_on' => bx_time_js($aData[$CNF['FIELD_DATE_SENT']]),
+            'created' => bx_time_js($aData[$CNF['FIELD_ADDED']]),
+            'sent_to' => $this->getModule()->getSegments($aData[$CNF['FIELD_SEGMENTS']]),
+            'sent_total' => $aDataStat['total'],
+            'opened_total' => $aDataStat['seen'],
+            'unopened_total' => $aDataStat['total'] - $aDataStat['seen'],
+            'clicked_total' => $aDataStat['clicked'],
+            'bx_if:from_name' => array(
+                'condition' => $aData[$CNF['FIELD_FROM_NAME']] != '',
+                'content' => array(
+                    'from_name_title' => _t('_bx_massmailer_txt_from_name_title'),
+                    'from_name' => $aData[$CNF['FIELD_FROM_NAME']],
+                )
+            ),
+           'bx_if:reply' => array(
+                'condition' => $aData[$CNF['FIELD_REPLY_TO']] != '',
+                'content' => array(
+                    'reply_title' => _t('_bx_massmailer_txt_reply_title'),
+                    'reply' => $aData[$CNF['FIELD_REPLY_TO']],
+                )
+            ),
+        ));
+    }
+    
+    function getTotalSubscribers()
+    {
+        $CNF = &$this->getModule()->_oConfig->CNF;
+        
+        $this->addJs(array('chart.min.js', 'chart.js', BX_DIRECTORY_PATH_MODULES . 'boonex/massmailer/plugins/daterangepicker/|daterangepicker.js'));
+        $this->addCss(array('main.css', BX_DIRECTORY_PATH_MODULES . 'boonex/massmailer/plugins/daterangepicker/|daterangepicker.css'));
+        $sDate = date('d/m/Y', time() - 90 * 86400) . ' - ' . date('d/m/Y');
+        
+        $aSegments = $this->_oModule->getSegments();
+        $aTmp = array();
+        foreach($aSegments as $sKey => $aSegment){
+            $aTmp[$sKey] = $aSegment;
+        }
+        
+        $oForm = new BxTemplFormView(array());
+        
+        $aInputReport = array(
+            'type' => 'select',
+            'name' => 'report',
+            'attrs' => ['class' => 'bx_massmailer_report_selector'],
+            'value' => 'content_total',
+            'values' => [
+                'content_total' => _t('_bx_massmailer_txt_title_content_total'), 
+                'content_speed' => _t('_bx_massmailer_txt_title_content_speed')
+            ]
+        );
+        
+        $aInputSegments = array(
+            'type' => 'select',
+            'name' => 'segments',
+            'attrs' => ['class' => 'bx_massmailer_report_selector'],
+            'value' => 'content_total',
+            'values' => $aTmp
+        );
+        
+        $aInputInterval = array(
+            'type' => 'text',
+            'name' => 'interval',
+            'attrs' => ['class' => 'bx_massmailer_date_picker'],
+            'value' => $sDate
+        );
+        
+
+        return $this->getJsCode('chart', array('sChartName' => 'SUBSCRIBERS_INFO')) . $this->parseHtmlByName('subscribers_info.html', array(
+            'report' => $oForm->genInput($aInputReport),
+            'segments' => $oForm->genInput($aInputSegments),
+            'interval' => $oForm->genInput($aInputInterval),
+        ));
+    }
+    
+    public function entryBreadcrumb($aContentInfo, $aTmplVarsItems = array())
+    {
+        $CNF = &$this->getModule()->_oConfig->CNF;
+        $aTmplVarsItems = array(array(
+            'url' => $aContentInfo['url'],
+            'title' => bx_process_output($aContentInfo[$CNF['FIELD_TITLE']])
+        ));
+
+        return $this->parseHtmlByName('breadcrumb.html', array(
+            'url_home' => BX_DOL_URL_ROOT . BxDolPermalinks::getInstance()->permalink($CNF['URL_MANAGE_CAMPAIGNS']),
+            'icon_home' => $CNF['ICON'],
+            'bx_repeat:items' => $aTmplVarsItems
+        ));
+    }
+    
+    public function getAttributes($aAttributesParts)
+    {
+        $aList2 = array();
+        foreach($aAttributesParts as $aPart){
+            $aList = array();
+            foreach($aPart[1] as $sKey => $sItem){
+                $aList[] = array('title' => $sItem, 'attribute' => $sKey);
+            }
+            $aList2[] = array('title' => $aPart[0], 'list' => $this->parseHtmlByName('attributes_part.html', array('bx_repeat:items' => $aList)));
+        }
+        return $this->parseHtmlByName('attributes.html', array('bx_repeat:items' => $aList2));
+    }
+}
+
+/** @} */

+ 77 - 0
modules/boonex/massmailer/updates/12.0.1_13.0.0/source/install/config.php

@@ -0,0 +1,77 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    MassMailer Mass Mailer
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+$aConfig = array(
+
+    /**
+     * Main Section.
+     */
+    'type' => BX_DOL_MODULE_TYPE_MODULE,
+    'name' => 'bx_massmailer',
+    'title' => 'Mass mailer',
+    'note' => 'Mass mailer module.',
+    'version' => '13.0.0',
+    'vendor' => 'BoonEx',
+    'help_url' => 'http://feed.una.io/?section={module_name}',
+
+    'compatible_with' => array(
+        '13.0.0-A3'
+    ),
+
+    /**
+     * 'home_dir' and 'home_uri' - should be unique. Don't use spaces in 'home_uri' and the other special chars.
+     */
+    'home_dir' => 'boonex/massmailer/',
+    'home_uri' => 'massmailer',
+
+    'db_prefix' => 'bx_massmailer_',
+    'class_prefix' => 'BxMassMailer',
+
+    /**
+     * Category for language keys.
+     */
+    'language_category' => 'MassMailer',
+
+    /**
+     * 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,
+    ),
+    'enable_success' => array(
+        'clear_db_cache' => 1,
+    ),
+    'disable' => array (
+        'execute_sql' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'disable_failed' => array (
+        'clear_db_cache' => 1,
+    ),
+
+    /**
+     * Dependencies Section
+     */
+    'dependencies' => array(),
+);
+
+/** @} */

+ 10 - 0
modules/boonex/massmailer/updates/12.0.1_13.0.0/source/template/subscribers_info.html

@@ -0,0 +1,10 @@
+<div id="bx_massmailer_chart_container">
+    <div class="bx_massmailer_filters">
+        __segments__
+        __report__
+        __interval__
+    </div>
+    <div class="bx_massmailer_chart_cnt bx-def-margin-top">
+        <canvas class="bx_massmailer_chart"></canvas>
+    </div>
+</div>

+ 51 - 0
modules/boonex/notifications/updates/13.0.0_13.0.1/install/config.php

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

+ 13 - 0
modules/boonex/notifications/updates/13.0.0_13.0.1/install/installer.php

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

+ 13 - 0
modules/boonex/notifications/updates/13.0.0_13.0.1/install/langs/en.xml

@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources name="en" flag="gb" title="English">
+	<string_add name="_bx_ntfs_alert_action_group_content_updated"><![CDATA[Content was updated]]></string_add>
+	<string_add name="_bx_ntfs_alert_action_group_action_required"><![CDATA[Your action required]]></string_add>
+	<string_add name="_bx_ntfs_alert_action_pending_approval_personal"><![CDATA[New pending approval content]]></string_add>
+	<string_add name="_bx_ntfs_alert_action_approved_personal"><![CDATA[Your content was approved]]></string_add>
+	<string_add name="_bx_ntfs_txt_object_approved"><![CDATA[<b class="bx-ntfs-content-profile">{owner_name}</b> approved {entry_sample} <b class="bx-ntfs-content-entry">{entry_caption}</b>]]></string_add>
+	<string_add name="_bx_ntfs_txt_object_approved_in_context"><![CDATA[<b class="bx-ntfs-content-entry">{entry_caption}</b> {entry_sample} was approved in <b class="bx-ntfs-content-profile">{owner_name}</b>]]></string_add>
+	<string_add name="_bx_ntfs_txt_object_pending_approval"><![CDATA[<b class="bx-ntfs-content-profile">{owner_name}</b> added a pending approval {entry_sample} <b class="bx-ntfs-content-entry">{entry_caption}</b>]]></string_add>
+	<string_add name="_bx_ntfs_txt_subobject_added_in_context"><![CDATA[<b class="bx-ntfs-content-profile">{owner_name}</b> has got a {subentry_sample} <b class="bx-ntfs-content-entry">{entry_caption}</b>]]></string_add>
+
+	<string_upd name="_bx_ntfs_txt_object_added_in_context"><![CDATA[<b class="bx-ntfs-content-profile">{owner_name}</b> has got a {entry_sample} <b class="bx-ntfs-content-entry">{entry_caption}</b> added by <b class="bx-ntfs-content-profile">{object_owner_name}</b>]]></string_upd>
+</resources>

+ 254 - 0
modules/boonex/notifications/updates/13.0.0_13.0.1/source/classes/BxNtfsConfig.php

@@ -0,0 +1,254 @@
+<?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 $_iOwnerNameMaxLen;
+    protected $_iContentMaxLen;
+    protected $_iPushMaxLen;
+
+    protected $_aHandlersHiddenEmail;
+    protected $_aHandlersHiddenPush;
+
+    /**
+     * Group settings by action. Enabled by default.
+     */
+    protected $_bSettingsGrouped;
+    protected $_aSettingsTypes;
+
+    protected $_aModulesProfiles;
+    protected $_aModulesContexts;
+
+    protected $_iDeliveryTimeout;
+    protected $_iProcessedEvent;
+
+    /**
+     * Constructor
+     */
+    public function __construct($aModule)
+    {
+        parent::__construct($aModule);
+
+        $this->CNF = array (
+            // page URIs
+            'URL_HOME' => 'page.php?i=notifications-view',
+
+            // some params
+            'PARAM_QUEUE_ADD_THRESHOLD' => 0,
+
+            // objects
+            'OBJECT_MENU_SUBMENU' => 'bx_notifications_submenu', // main module submenu
+            'OBJECT_MENU_SETTINGS' => 'bx_notifications_settings', // settings submenu
+            'OBJECT_GRID_SETTINGS_ADMINISTRATION' => 'bx_notifications_settings_administration',
+            'OBJECT_GRID_SETTINGS_COMMON' => 'bx_notifications_settings_common',
+
+            // some language keys
+            'T' => array(
+                'setting_personal' => '_bx_ntfs_setting_type_personal',
+                'setting_follow_member' => '_bx_ntfs_setting_type_follow_member',
+                'setting_follow_context' => '_bx_ntfs_setting_type_follow_context',
+                'setting_other' => '_bx_ntfs_setting_type_other',
+            )
+        );
+
+        $this->_aPrefixes = array(
+            'style' => 'bx-ntfs',
+            'language' => '_bx_ntfs',
+            'option' => 'bx_notifications_'
+        );
+
+        $this->_iOwnerNameMaxLen = 21;
+        $this->_iContentMaxLen = 32;
+        $this->_iPushMaxLen = 190;
+
+        $this->_aHandlerDescriptor = array('module_name' => '', 'module_method' => '', 'module_class' => '');
+        $this->_sHandlersMethod = 'get_notifications_data';
+        $this->_aHandlersHiddenEmail = array();
+        $this->_aHandlersHiddenPush = array();
+
+        $this->_bSettingsGrouped = true;
+        $this->_aSettingsTypes = array(
+            BX_NTFS_STYPE_PERSONAL,
+            BX_NTFS_STYPE_FOLLOW_MEMBER,
+            BX_NTFS_STYPE_FOLLOW_CONTEXT,
+            //BX_NTFS_STYPE_OTHER           //TODO: May be it can be removed, because there is no events(alerts) for this type.
+        );
+
+        $this->_aModulesProfiles = false;
+        $this->_aModulesContexts = false;
+
+        $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'),
+    	    'preview' => (int)getParam($sOptionPrefix . 'events_per_preview')
+    	);
+
+        $this->_bSettingsGrouped = getParam($sOptionPrefix . 'enable_group_settings') == 'on';
+
+    	$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);
+    	}
+
+        $this->_iDeliveryTimeout = (int)getParam($sOptionPrefix . 'delivery_timeout');
+        $this->_iProcessedEvent = (int)getParam($sOptionPrefix . 'processed_event');
+    }
+
+    public function getOwnerNameMaxLen()
+    {
+        return $this->_iOwnerNameMaxLen;
+    }
+
+    public function getContentMaxLen()
+    {
+        return $this->_iContentMaxLen;
+    }
+
+    public function getPushMaxLen()
+    {
+        return $this->_iPushMaxLen;
+    }
+
+    public function getHandlersHidden($sType = '')
+    {
+        if(!in_array($sType, array('', 'email', 'push')))
+            return array();
+
+        return $this->{'_aHandlersHidden' . ucfirst($sType)};
+    }
+
+    public function isSettingsGrouped()
+    {
+        return $this->_bSettingsGrouped;
+    }
+
+    public function getSettingsTypes()
+    {
+        return $this->_aSettingsTypes;
+    }
+
+    public function getDeliveryTimeout()
+    {
+        return $this->_iDeliveryTimeout;
+    }
+
+    public function getProcessedEvent()
+    {
+        return $this->_iProcessedEvent;
+    }
+    
+    public function setProcessedEvent($iEvent)
+    {
+        $this->_iProcessedEvent = $iEvent;
+
+        setParam($this->getPrefix('option') . 'processed_event', $iEvent);
+    }
+
+    /**
+     * Ancillary functions
+     */
+    public function getViewUrl()
+    {
+        return BX_DOL_URL_ROOT . BxDolPermalinks::getInstance()->permalink('page.php?i=notifications-view');
+    }
+
+    public function getContentModule(&$aEvent)
+    {
+        $sModule = $aEvent['type'];
+        if($this->_oDb->isEnabledByName($sModule))
+            return $sModule;
+
+        $sModule = str_replace(array('_media', '_reactions'), array('', ''), $sModule);
+        if($this->_oDb->isEnabledByName($sModule))
+            return $sModule;
+
+        return '';
+    }
+
+    public function getContentObjectId(&$aEvent)
+    {
+        return !empty($aEvent['content']['object_id']) ? (int)$aEvent['content']['object_id'] : (int)$aEvent['object_id'];
+    }
+
+    public function getProfileBasedModules() 
+    {
+        if ($this->_aModulesProfiles !== false && $this->_aModulesContexts !== false)
+            return array($this->_aModulesProfiles, $this->_aModulesContexts);
+
+        if (getParam('sys_db_cache_enable')) {
+            $oDb = BxDolDb::getInstance();
+            $oCache = $oDb->getDbCacheObject();
+            $sCacheKey = $oDb->genDbCacheKey('bx_ntfs_profile_based_modules');
+            $aData = $oCache->getData($sCacheKey);
+            if (null === $aData) {
+                $aData = $this->_getProfileBasedModulesData();
+                $oCache->setData ($sCacheKey, $aData);
+            }
+        } 
+        else {
+            $aData = $this->_getProfileBasedModulesData();
+        }
+
+        return $aData;
+    }
+
+    protected function _getProfileBasedModulesData() 
+    {
+        $this->_aModulesProfiles = [];
+        $this->_aModulesContexts = [];
+
+        $aModules = BxDolModuleQuery::getInstance()->getModulesBy(['type' => 'modules']);
+        foreach($aModules as $aModule) {
+            if(!bx_is_srv($aModule['name'], 'act_as_profile'))
+                continue;
+
+            if(bx_srv($aModule['name'], 'act_as_profile'))
+                $this->_aModulesProfiles[] = $aModule['name'];
+            else
+                $this->_aModulesContexts[] = $aModule['name'];
+        }
+
+        return [$this->_aModulesProfiles, $this->_aModulesContexts];
+    }
+}
+
+/** @} */

+ 256 - 0
modules/boonex/notifications/updates/13.0.0_13.0.1/source/classes/BxNtfsGridSettingsAdministration.php

@@ -0,0 +1,256 @@
+<?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
+ * 
+ * @{
+ */
+
+require_once(BX_DOL_DIR_STUDIO_INC . 'utils.inc.php');
+
+class BxNtfsGridSettingsAdministration extends BxTemplGrid
+{
+    protected $_sModule;
+    protected $_oModule;
+
+    protected $_bAdministration;
+
+    protected $_bGrouped;
+    protected $_sDeliveryType;
+    protected $_sTitleMask;
+
+    protected $_sSource;
+
+    public function __construct ($aOptions, $oTemplate = false)
+    {
+        parent::__construct ($aOptions, $oTemplate);
+
+        $this->_sModule = 'bx_notifications';
+        $this->_oModule = BxDolModule::getInstance($this->_sModule);
+
+        $CNF = &$this->_oModule->_oConfig->CNF;
+
+        $this->_bAdministration = true;      
+
+        $this->_bGrouped = $this->_oModule->_oConfig->isSettingsGrouped();
+        if($this->_bGrouped)
+            $this->_aOptions['show_total_count'] = 0;
+
+        $this->_sDeliveryType = BX_BASE_MOD_NTFS_DTYPE_SITE;
+        $this->_sTitleMask = _t('_bx_ntfs_setting_title_mask', '%s', '%s');
+
+        $this->_sSource = '';
+
+        $sDeliveryType = bx_get('delivery_type');
+        if(!empty($sDeliveryType))
+            $this->setDeliveryType($sDeliveryType);
+
+        $this->init();
+    }
+
+    public function init()
+    {
+        if(!$this->_bGrouped && !isset($this->_aOptions['fields']['unit'], $this->_aOptions['fields']['type']))
+            $this->_aOptions['fields'] = bx_array_insert_after(array(
+                'unit' => array('title' => _t('_bx_ntfs_grid_column_title_unit'), 'width' => '10%', 'translatable' => 0 ,'chars_limit' => 0),
+                'type' => array('title' => _t('_bx_ntfs_grid_column_title_type'), 'width' => '20%', 'translatable' => 0 ,'chars_limit' => 0),
+            ), $this->_aOptions['fields'], 'switcher');
+    }
+
+    public function setGrouped($bGrouped)
+    {
+        $bReinit = $this->_bGrouped !== (boolean)$bGrouped;
+
+        $this->_bGrouped = $bGrouped;
+
+        if($bReinit)
+            $this->init();
+    }
+
+    public function setDeliveryType($sType)
+    {
+        $this->_sDeliveryType = bx_process_input($sType);
+        $this->_aQueryAppend['delivery_type'] = $this->_sDeliveryType;
+    }
+
+    public function performActionActivate()
+    {
+        parent::performActionEnable(1);
+    }
+
+    public function performActionDeactivate()
+    {
+        parent::performActionEnable(0);
+    }
+    
+    public function performActionChangeValue()
+    {
+        $aIds = bx_get('ids');
+        if(empty($aIds) || !is_array($aIds))
+            return echoJson(array());
+
+        $iId = array_shift($aIds);
+        $iValue = $this->_switcherChecked2State((int)bx_get('checked'));
+
+        if(!$this->_bGrouped)
+            $mixedResult = $this->_oModule->_oDb->updateSetting(array('value' => $iValue), array('id' => $iId));
+        else 
+            $mixedResult = $this->_oModule->_changeSettingsValueLike($iId, 'value', $iValue, $this->_bAdministration);
+
+        $aResult = array();
+        if($mixedResult === false)
+            $aResult = array('msg' => _t('_bx_ntfs_txt_err_cannot_perform'));
+        else if((int)$mixedResult == 0)
+            $aResult = array('msg' => _t('_bx_ntfs_txt_err_nothing_changed'));
+
+        return echoJson($aResult);
+    }
+
+    protected function _enable ($mixedId, $isChecked)
+    {
+        if(!$this->_bGrouped)
+            return parent::_enable($mixedId, $isChecked);
+
+        return $this->_oModule->enableSettingsLike($mixedId, $isChecked, $this->_bAdministration);
+    }
+
+    protected function _isCheckboxDisabled($aRow)
+    {
+        return false;
+    }
+
+    protected function _getFilterControls()
+    {
+        if($this->_bGrouped)
+            return '';
+
+        return parent::_getFilterControls();
+    }
+
+    protected function _getCellValue($mixedValue, $sKey, $aField, $aRow)
+    {
+        $sAttr = $this->_convertAttrs(
+            $aField, 'attr_cell',
+            'bx-def-padding-sec-bottom bx-def-padding-sec-top',
+            isset($aField['width']) ? 'width:' . $aField['width'] : false
+        );
+
+        $oForm = new BxTemplFormView(array(), $this->_oTemplate);
+        $oForm->addCssJs();
+        $aInput = array(
+            'type' => 'switcher',
+            'name' => $this->_sObject . '_change_value_' . $aRow[$this->_aOptions['field_id']],
+            'caption' => '',
+            'attrs' => array (
+                'bx_grid_action_single' => 'change_value',
+                'bx_grid_action_confirm' => '',
+                'bx_grid_action_data' => $aRow[$this->_aOptions['field_id']],
+            ),
+            'value' => $aRow[$this->_aOptions['field_id']],
+            'checked' => $this->_isSwitcherOn($mixedValue, $sKey, $aField, $aRow),
+        );
+        $sSwitcher = $oForm->genInput($aInput);
+        return '<td ' . $sAttr . '>' . $sSwitcher . '</td>';
+    }
+
+    protected function _getCellUnit($mixedValue, $sKey, $aField, $aRow)
+    {
+        return parent::_getCellDefault(_t($this->_oModule->_oConfig->getHandlersUnitTitle($mixedValue)), $sKey, $aField, $aRow);
+    }
+
+    protected function _getCellType($mixedValue, $sKey, $aField, $aRow)
+    {
+        $CNF = &$this->_oModule->_oConfig->CNF;
+
+        return parent::_getCellDefault(_t($CNF['T']['setting_' . $mixedValue]), $sKey, $aField, $aRow);
+    }
+
+    protected function _getCellTitle($mixedValue, $sKey, $aField, $aRow)
+    {
+        if(empty($mixedValue)) {
+            $mixedValueKey = $this->_oModule->_oConfig->getHandlersActionTitle($aRow['unit'], $aRow['action'], $aRow['type']);
+            $mixedValue = _t($mixedValueKey);
+
+            if(strcmp($mixedValueKey, $mixedValue) !== 0)
+                $this->_updateSettingTitle($mixedValueKey, $aRow);
+        }
+
+        if($this->_bGrouped) {
+            $sValueKey = '_bx_ntfs_alert_action_group_' . $aRow['group'];
+            $sValue = _t($sValueKey);
+            if(strcmp($sValueKey, $sValue) !== 0)
+                $mixedValue = $sValue;
+            else if($aRow['type'] == BX_NTFS_STYPE_OTHER)
+                $mixedValue = sprintf($this->_sTitleMask, _t($this->_oModule->_oConfig->getHandlersUnitTitle($aRow['unit'])), $mixedValue);
+
+            if(!$this->_isSettingsGroupValid($aRow))
+                $mixedValue = $this->_oTemplate->parseIcon('exclamation-triangle', array('class' => 'bx-def-margin-sec-right', 'title' => _t('_bx_ntfs_grid_column_title_title_warning'))) . $mixedValue;
+        }            
+
+        return parent::_getCellDefault($mixedValue, $sKey, $aField, $aRow);
+    }
+
+    protected function _getActionActivate($sType, $sKey, $a, $isSmall = false, $isDisabled = false, $aRow = array())
+    {
+    	return $this->_getActionDefault ($sType, $sKey, $a, $isSmall, $isDisabled, $aRow);
+    }
+
+    protected function _getActionDeactivate($sType, $sKey, $a, $isSmall = false, $isDisabled = false, $aRow = array())
+    {
+    	return $this->_getActionDefault ($sType, $sKey, $a, $isSmall, $isDisabled, $aRow);
+    }
+
+    protected function _getDataSql($sFilter, $sOrderField, $sOrderDir, $iStart, $iPerPage)
+    {
+        $this->_aOptions['source'] .= $this->_oModule->_oDb->prepareAsString(" AND `ts`.`delivery`=?", $this->_sDeliveryType);
+        if(!$this->_bGrouped)
+            return parent::_getDataSql($sFilter, $sOrderField, $sOrderDir, $iStart, $iPerPage);
+
+        $CNF = &$this->_oModule->_oConfig->CNF;
+
+        $aResult = array();
+        $this->_sSource = $this->_aOptions['source'];
+
+        $aTypes = $this->_oModule->_oConfig->getSettingsTypes();
+        foreach($aTypes as $sType) {
+            $this->_aOptions['source'] = $this->_sSource . $this->_oModule->_oDb->prepareAsString(" AND `ts`.`type`=?", $sType) . " GROUP BY `ts`.`group`";
+
+            $aRows = parent::_getDataSql($sFilter, $sOrderField, $sOrderDir, $iStart, $iPerPage);
+            if(empty($aRows) || !is_array($aRows)) 
+                continue;
+
+            $aResult[] = _t($CNF['T']['setting_' . $sType]);
+            $aResult = array_merge($aResult, $aRows);
+        }
+
+        return $aResult;
+    }
+
+    protected function _updateSettingTitle($sTitle, &$aRow)
+    {
+        return $this->_oModule->_oDb->updateSetting(array('title' => $sTitle), array('id' => $aRow['id']));
+    }
+    
+    protected function _isSettingsGroupValid(&$aRow)
+    {
+        if(!$this->_bGrouped)
+            return true;
+
+        $iEnabled = $iDisabled = 0;
+
+        $sSql = $this->_sSource . $this->_oModule->_oDb->prepareAsString(" AND `ts`.`group`=? AND `ts`.`type`=?", $aRow['group'], $aRow['type']);
+        $aItems = $this->_oModule->_oDb->getAll($sSql);
+        foreach($aItems as $aItem) 
+            if((int)$aItem['active'] != 0)
+                $iEnabled += 1;
+            else 
+                $iDisabled += 1;
+
+        return $iEnabled == 0 || $iDisabled == 0;
+    }
+}
+
+/** @} */

+ 94 - 0
modules/boonex/notifications/updates/13.0.0_13.0.1/source/classes/BxNtfsMenuPreview.php

@@ -0,0 +1,94 @@
+<?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 BxNtfsMenuPreview extends BxTemplMenuCustom
+{
+    protected $_sModule;
+    protected $_oModule;
+
+    protected $_sTmplContentPreviewItem;
+
+    protected $_iOwnerId;
+    protected $_aBrowseParams;
+
+    public function __construct($aObject, $oTemplate = false)
+    {
+        $this->_sModule = 'bx_notifications';
+        $this->_oModule = BxDolModule::getInstance($this->_sModule);
+
+        if(!$oTemplate)
+            $oTemplate = $this->_oModule->_oTemplate;
+
+        parent::__construct($aObject, $oTemplate);
+
+        if(empty($this->_sTmplContentPreviewItem))
+            $this->_sTmplContentPreviewItem = $this->_oTemplate->getHtml('menu_preview_item.html');
+
+        $this->_iOwnerId = $this->_oModule->getUserId();
+        $this->_aBrowseParams = array(
+            'last_read' => $this->_oModule->_oDb->getLastRead($this->_iOwnerId)
+        );
+    }
+
+    public function getMenuItems ()
+    {
+        $aItems = parent::getMenuItems();
+        if(empty($aItems) || !is_array($aItems))
+            return MsgBox(_t('_Empty'));
+
+        return $aItems;
+    }
+
+    public function getCode ()
+    {
+        return $this->_oTemplate->getAddedCss('', true) . $this->_oTemplate->parseHtmlByName('menu_preview.html', array(
+            'content' => parent::getCode()
+        ));
+    }
+
+    protected function getMenuItemsRaw ()
+    {
+        $aItems = $this->_oModule->serviceGetNotifications($this->_iOwnerId);
+        if(empty($aItems) || !is_array($aItems))
+            return array();
+
+        $aResults = array();
+        foreach($aItems as $iKey => $aItem) {
+            if(!$this->_oModule->_oTemplate->getPost($aItem))
+                continue;
+
+            $aItem['name'] = 'event';
+
+            $aResults[] = $aItem;
+        }
+
+        $iPerPage = $this->_oModule->_oConfig->getPerPage('preview');
+        if(count($aResults) > $iPerPage)
+            $aResults = array_slice($aResults, 0, $iPerPage);
+
+        $aFirst = reset($aItems);
+        $this->_oModule->_oDb->markAsRead($this->_iOwnerId, $aFirst['id']);
+
+        return array_merge($aResults, $this->_oQuery->getMenuItems());
+    }
+
+    protected function _getMenuItemDefault ($aItem)
+    {
+        return $this->_oTemplate->parseHtmlByContent($this->_sTmplContentPreviewItem, $aItem);
+    }
+
+    protected function _getMenuItemEvent($aItem)
+    {
+        return $this->_oTemplate->getPost($aItem, $this->_aBrowseParams);
+    }
+}
+
+/** @} */

+ 262 - 0
modules/boonex/notifications/updates/13.0.0_13.0.1/source/classes/BxNtfsResponse.php

@@ -0,0 +1,262 @@
+<?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)
+    {
+        bx_alert($this->_oModule->getName(), 'before_register_alert', 0, 0, array(
+            'unit' => $oAlert->sUnit,
+            'action' => $oAlert->sAction,
+            'alert' => &$oAlert,
+        ));
+
+    	$iObjectPrivacyView = $this->_getObjectPrivacyView($oAlert->aExtras);
+        if($iObjectPrivacyView == BX_DOL_PG_HIDDEN)
+            return;
+
+        $aHandler = $this->_oModule->_oConfig->getHandlers($oAlert->sUnit . '_' . $oAlert->sAction);
+        if(empty($aHandler) || !is_array($aHandler))
+            return;
+
+        $iSilentMode = $this->_oModule->getSilentMode($oAlert->aExtras);
+        if(in_array($iSilentMode, array(BX_BASE_MOD_NTFS_SLTMODE_ABSOLUTE, BX_NTFS_SLTMODE_ABSOLUTE)))
+            return;
+
+        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);
+                if(BxDolRequest::serviceExists($oAlert->sUnit, 'get_notifications_insert_data')) 
+                    $aDataItems = bx_srv($oAlert->sUnit, 'get_notifications_insert_data', [$oAlert, $aHandler, $aDataItems]);
+
+                foreach($aDataItems as $aDataItem) {
+                    $iId = $this->_oModule->_oDb->insertEvent($aDataItem);
+                    if(empty($iId))
+                        continue;
+
+                    $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);
+                if(BxDolRequest::serviceExists($oAlert->sUnit, 'get_notifications_delete_data')) 
+                    $aDataItems = bx_srv($oAlert->sUnit, 'get_notifications_delete_data', [$oAlert, $aHandler, $aDataItems]);
+
+                foreach($aDataItems as $aDataItem)
+                    $this->_oModule->_oDb->deleteEvent($aDataItem);
+                break;
+        }
+    }
+
+    protected function getInsertData(&$oAlert, &$aHandler)
+    {
+        $iOwnerId = $oAlert->iSender;
+        $iObjectPrivacyView = $this->_getObjectPrivacyView($oAlert->aExtras);
+
+        if($iObjectPrivacyView < 0)
+            $iOwnerId = abs($iObjectPrivacyView);
+        
+        $mixedSubobjectId = $this->_getSubObjectId($oAlert->aExtras);
+        if(!is_array($mixedSubobjectId))
+            $mixedSubobjectId = array($mixedSubobjectId);
+
+        $aResult = array();
+        foreach($mixedSubobjectId as $iSubobjectId)
+            $aResult[] = array(
+                'owner_id' => $iOwnerId,
+                'type' => $oAlert->sUnit,
+                'action' => $oAlert->sAction,
+                'object_id' => $oAlert->iObject,
+                'object_owner_id' => $this->_getObjectOwnerId($oAlert->aExtras),
+                'object_privacy_view' => $iObjectPrivacyView,
+                'subobject_id' => $iSubobjectId,
+                'content' => $this->_getContent($oAlert->aExtras),
+                'allow_view_event_to' => $this->_oModule->_oConfig->getPrivacyViewDefault('event'),
+                'processed' => 0
+    	    );
+
+    	return $aResult;
+    }
+
+    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)
+    {
+        $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' => $this->_getContent($oAlert->aExtras, array(
+                    'request' => empty($oAlert->aExtras['mutual']) ? 1 : 0
+                )),
+                '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' => $this->_getContent($oAlert->aExtras),
+                '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 _getObjectOwnerId($aExtras)
+    {
+        $iResult = parent::_getObjectOwnerId($aExtras);
+        if(!empty($iResult))
+            return $iResult;
+
+        if(isset($aExtras['meta']))
+            return (int)$aExtras['meta'];
+
+        return 0;
+    }
+
+    protected function _getContent($aExtras, $aAdd = array())
+    {
+        $aResult = array();
+
+        $iSilentMode = $this->_oModule->getSilentMode($aExtras);
+        if($iSilentMode != BX_BASE_MOD_NTFS_SLTMODE_DISABLED)
+            $aResult['silent_mode'] = $iSilentMode;
+
+        if(!empty($aAdd) && is_array($aAdd))
+            $aResult = array_merge($aResult, $aAdd);
+
+        return !empty($aResult) && is_array($aResult) ? serialize($aResult) : '';
+    }
+}
+
+/** @} */

+ 51 - 0
modules/boonex/notifications/updates/13.0.0_13.0.1/source/classes/BxNtfsStudioPage.php

@@ -0,0 +1,51 @@
+<?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 BxNtfsStudioPage extends BxBaseModNotificationsStudioPage
+{
+    public function __construct($sModule, $mixedPageName, $sPage = "")
+    {
+    	$this->_sModule = 'bx_notifications';
+
+        parent::__construct($sModule, $mixedPageName, $sPage);
+
+        $this->aMenuItems = array_merge($this->aMenuItems, array(
+            BX_BASE_MOD_NTFS_DTYPE_SITE => array('name' => BX_BASE_MOD_NTFS_DTYPE_SITE, 'icon' => 'globe', 'title' => '_bx_ntfs_lmi_cpt_site'),
+            BX_BASE_MOD_NTFS_DTYPE_EMAIL => array('name' => BX_BASE_MOD_NTFS_DTYPE_EMAIL, 'icon' => 'envelope', 'title' => '_bx_ntfs_lmi_cpt_email'),
+            BX_BASE_MOD_NTFS_DTYPE_PUSH => array('name' => BX_BASE_MOD_NTFS_DTYPE_PUSH, 'icon' => 'bullhorn', 'title' => '_bx_ntfs_lmi_cpt_push')
+        ));
+    }
+
+    protected function getSite()
+    {
+        return $this->_getDeliveryType(BX_BASE_MOD_NTFS_DTYPE_SITE);
+    }
+
+    protected function getEmail()
+    {
+        return $this->_getDeliveryType(BX_BASE_MOD_NTFS_DTYPE_EMAIL);
+    }
+
+    protected function getPush()
+    {
+        return $this->_getDeliveryType(BX_BASE_MOD_NTFS_DTYPE_PUSH);
+    }
+
+    protected function _getDeliveryType($sDeliveryType)
+    {
+        return $this->_oModule->getBlockSettings($sDeliveryType, array(
+            'grid' => $this->_oModule->_oConfig->CNF['OBJECT_GRID_SETTINGS_ADMINISTRATION'],
+            'template' => BxDolStudioTemplate::getInstance()
+        ));
+    }
+}
+
+/** @} */

+ 416 - 0
modules/boonex/notifications/updates/13.0.0_13.0.1/source/classes/BxNtfsTemplate.php

@@ -0,0 +1,416 @@
+<?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
+ *
+ * @{
+ */
+
+require_once(BX_DIRECTORY_PATH_INC . "design.inc.php");
+
+class BxNtfsTemplate extends BxBaseModNotificationsTemplate
+{
+    function __construct(&$oConfig, &$oDb)
+    {
+        parent::__construct($oConfig, $oDb);
+    }
+
+    public function getInclude($bIncludeCss = true, $mixedIncludeJs = false)
+    {
+        if($bIncludeCss)
+            $this->getAddedCss();
+
+        $sResult = '';
+        if(is_string($mixedIncludeJs) && !empty($mixedIncludeJs)) {
+            $this->getAddedJs();
+            
+            $sResult = $this->getJsCode($mixedIncludeJs);
+        }
+            
+        return $sResult;
+    }
+
+    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 getSettingsBlock($sDeliveryType, $aParams = array())
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        $iUserId = !empty($aParams['user_id']) ? (int)$aParams['user_id'] : bx_get_logged_profile_id();
+        $sGrid = !empty($aParams['grid']) ? $aParams['grid'] : $CNF['OBJECT_GRID_SETTINGS_COMMON'];
+        $oTemplate = !empty($aParams['template']) ? $aParams['template'] : $this;
+
+        $oGrid = BxDolGrid::getObjectInstance($sGrid, $oTemplate);
+        if(!$oGrid)
+            return '';
+
+        $oGrid->setDeliveryType($sDeliveryType);
+        if(method_exists($oGrid, 'setUserId'))
+            $oGrid->setUserId($iUserId);
+
+        return $oGrid->getCode();
+    }
+
+    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(!empty($aEvent['content']) && is_string($aEvent['content']))
+            $aEvent['content'] = unserialize($aEvent['content']);
+
+    	if((int)$aEvent['processed'] == 0)
+            $this->_processContent($aEvent);
+
+        if((int)$aEvent['processed'] == 0 || empty($aEvent['content']))
+            return '';
+
+        $sParamCheck = 'perform_privacy_check';
+        if(!isset($aBrowseParams[$sParamCheck]) || $aBrowseParams[$sParamCheck] === true) {
+            $sParamCheckFor = 'perform_privacy_check_for';
+            $iViewerId = !empty($aBrowseParams[$sParamCheckFor]) ? (int)$aBrowseParams[$sParamCheckFor] : 0;
+
+            $oPrivacyInt = BxDolPrivacy::getObjectInstance($this->_oConfig->getObject('privacy_view'));
+            if(!$oPrivacyInt->check($aEvent['id'], $iViewerId))
+                return '';
+
+            $oPrivacyExt = $this->_oConfig->getPrivacyObject($aEvent['type'] . '_' . $aEvent['action']);
+            if($oPrivacyExt !== false && !$oPrivacyExt->check($aEvent['id'], $iViewerId))
+                return '';
+
+            $sSrvModule = $this->_oConfig->getContentModule($aEvent);
+            $sSrvMethod = 'check_allowed_with_content_for_profile';
+            if($sSrvModule && BxDolRequest::serviceExists($sSrvModule, $sSrvMethod) && BxDolService::call($sSrvModule, $sSrvMethod, array('view', $this->_oConfig->getContentObjectId($aEvent), $iViewerId)) !== CHECK_ACTION_RESULT_ALLOWED)
+                return '';
+        }
+
+        $bShowRealProfile = !isset($aBrowseParams['show_real_profile']) || $aBrowseParams['show_real_profile'] === true;
+
+        $oOwner = $oModule->getObjectUser($aEvent['owner_id']);
+        if(!$bShowRealProfile && $oOwner instanceof BxDolProfileAnonymous)
+            $oOwner->setShowRealProfile($bShowRealProfile);
+
+        $aEvent['content']['owner_name'] = strmaxtextlen($oOwner->getDisplayName(), $this->_oConfig->getOwnerNameMaxLen());
+        $aEvent['content']['owner_link'] = $oOwner->getUrl();
+        $aEvent['content']['owner_icon'] = $oOwner->getThumb();
+
+        if(!empty($aEvent['content']['entry_caption'])) {
+            $sEntryCaption = bx_process_output($aEvent['content']['entry_caption'], BX_DATA_TEXT);
+            if(get_mb_substr($sEntryCaption, 0, 1) == '_')
+                $sEntryCaption = _t($sEntryCaption);
+
+            $aEvent['content']['entry_caption'] = strmaxtextlen($sEntryCaption, $this->_oConfig->getContentMaxLen());
+        }
+
+        $iObjectOwner = (int)$aEvent['object_owner_id'];
+        if(empty($iObjectOwner) && !empty($aEvent['content']['entry_author']))
+            $iObjectOwner = (int)$aEvent['content']['entry_author'];
+
+        $oObjectOwner = $oModule->getObjectUser($iObjectOwner);
+        if($oObjectOwner) {
+            if(!$bShowRealProfile && $oObjectOwner instanceof BxDolProfileAnonymous)
+                $oObjectOwner->setShowRealProfile($bShowRealProfile);
+
+            $aEvent['content']['object_owner_name'] = strmaxtextlen($oObjectOwner->getDisplayName(), $this->_oConfig->getOwnerNameMaxLen());
+            $aEvent['content']['object_owner_link'] = $oObjectOwner->getUrl();
+            $aEvent['content']['object_owner_icon'] = $oObjectOwner->getThumb();
+        }
+
+        foreach($aEvent['content'] as $sKey => $sValue) {
+            if(!is_string($sValue) || substr($sValue, 0, 1) != '_') 
+                continue;
+
+            $aCallParams = array($sValue);
+
+            $sKeyParams = $sKey . '_params';
+            if(isset($aEvent['content'][$sKeyParams]) && is_array($aEvent['content'][$sKeyParams])) {
+                foreach($aEvent['content'][$sKeyParams] as $iParamIndex => $sParamValue)
+                    if(is_string($sParamValue) && substr($sParamValue, 0, 1) == '_')
+                        $aEvent['content'][$sKeyParams][$iParamIndex] = _t($sParamValue);
+
+                $aCallParams = array_merge($aCallParams, $aEvent['content'][$sKeyParams]);
+                unset($aEvent['content'][$sKeyParams]);
+            }
+
+            $aEvent['content'][$sKey] = call_user_func_array('_t', $aCallParams);
+        }
+        
+        $bEventCanceled = false;
+
+        $sOwnerUnit = $oOwner->getUnit(0, ['template' => 'unit_wo_info_links']);
+
+        $bEventParsed = false;
+        bx_alert($this->_oConfig->getName(), 'get_notification', 0, 0, [
+            'event' => &$aEvent, 
+            'event_parsed' => &$bEventParsed, 
+            'event_canceled' => &$bEventCanceled,
+            'owner' => &$oOwner, 
+            'owner_unit' => &$sOwnerUnit, 
+            'browse_params' => $aBrowseParams
+        ]);
+        
+        if ($bEventCanceled)
+            return '';
+
+        if(!$bEventParsed) {
+            $mLk = '';
+            if(!empty($aEvent['content']['lang_key'])) {
+                $mLk = $aEvent['content']['lang_key'];
+                if(!is_string($mLk) && !(is_array($mLk) && isset($mLk['site'], $mLk['email'], $mLk['push'])))
+                    $mLk = '';
+            }
+
+            if(empty($mLk))
+                $mLk = $this->_getContentLangKey($aEvent);
+
+            if(is_array($mLk))
+                foreach($mLk as $sDeliveryType => $sLangKey)
+                    $aEvent['content_parsed'][$sDeliveryType] = $this->_parseContentLangKey($sLangKey, $aEvent);
+            else
+                $aEvent['content_parsed'] = $this->_parseContentLangKey($mLk, $aEvent);
+        }
+
+        // returns parsed content for React Jot
+        if(isset($aBrowseParams['return_parsed_content']))
+            return $aEvent;
+
+        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'),
+            'class' => !empty($aBrowseParams['last_read']) && $aEvent['id'] > $aBrowseParams['last_read'] ? ' bx-def-color-bg-box-active' : '', 
+            'id' => $aEvent['id'],
+            'author_unit' => $sOwnerUnit,
+            'link' => $this->_getContentLink($aEvent),
+            'content' => is_array($aEvent['content_parsed']) && isset($aEvent['content_parsed']['site']) ? $aEvent['content_parsed']['site'] : $aEvent['content_parsed'],
+            'date' => bx_time_js($aEvent['date']),
+        ));
+    }
+
+    public function getNotificationEmail($iRecipient, &$aEvent)
+    {
+        $sEvent = $this->getPost($aEvent, array('perform_privacy_check_for' => $iRecipient, 'show_real_profile' => false));
+        if(empty($sEvent) || empty($aEvent['content_parsed']))
+            return false;
+
+        $aContent = &$aEvent['content'];
+        return array(
+            'content' => $this->parseHtmlByName('et_new_event.html', array(
+                'icon_url' => !empty($aContent['owner_icon']) ? $aContent['owner_icon'] : $this->getIconUrl('std-icon.svg'),
+                'content_url' => $this->_getContentLink($aEvent),
+                'content' => is_array($aEvent['content_parsed']) && isset($aEvent['content_parsed']['email']) ? $aEvent['content_parsed']['email'] : $aEvent['content_parsed'],
+                'date' => bx_process_output($aEvent['date'], BX_DATA_DATE_TS),
+            )),
+            'settings' => !empty($aContent['settings']['email']) ? $aContent['settings']['email'] : array()
+        );
+    }
+
+    public function getNotificationPush($iRecipient, &$aEvent)
+    {
+        $sEvent = $this->getPost($aEvent, array('perform_privacy_check_for' => $iRecipient, 'show_real_profile' => false));
+        if(empty($sEvent) || empty($aEvent['content_parsed']))
+            return false;
+
+        $sMessage = is_array($aEvent['content_parsed']) && isset($aEvent['content_parsed']['push']) ? $aEvent['content_parsed']['push'] : $aEvent['content_parsed'];
+        $sMessage = preg_replace('/<\/?[a-zA-Z0-9=\'":;\(\)\s_-]+>/i', '"', $sMessage);
+        if($sMessage)
+            $sMessage = BxTemplFunctions::getInstance()->getStringWithLimitedLength(html_entity_decode($sMessage), $this->_oConfig->getPushMaxLen());
+
+        if(empty($sMessage))
+            return false;
+
+        $aContent = &$aEvent['content'];
+        return array(
+            'content' => array(
+                'url' => $this->_getContentLink($aEvent),
+                'message' => $sMessage,
+                'icon' => !empty($aContent['owner_icon']) ? $aContent['owner_icon'] : ''
+            ),
+            'settings' => !empty($aContent['settings']['push']) ? $aContent['settings']['push'] : array()
+        );
+    }
+
+    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;
+
+        bx_alert($this->_oConfig->getName(), 'get_content', 0, 0, array(
+            'event' => $aEvent,
+            'override_result' => &$aContent
+        ));
+
+        $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']);
+        }
+
+        if(!empty($aEvent['content'])) {
+            if(is_string($aEvent['content']))
+                $aEvent['content'] = unserialize($aEvent['content']);
+
+            if(is_array($aEvent['content']))
+                $aEvent['content'] = array_merge($aEvent['content'], $aContent);
+        }
+        else
+            $aEvent['content'] = $aContent;
+
+        $aEvent['processed'] = 1;
+
+        $aSet = array_merge($aSet, array(
+            'content' => serialize($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 _getContentLangKey(&$aEvent)
+    {
+        $bInContext = $this->_isInContext($aEvent);
+
+        if(!empty($aEvent['subobject_id']))
+            return '_bx_ntfs_txt_subobject_added' . ($bInContext ? '_in_context' : '');
+
+        $sKey = '';
+        switch($aEvent['action']) {
+            case 'pending_approval':
+                $sKey = '_bx_ntfs_txt_object_pending_approval';
+                break;
+
+            case 'publish_failed':
+                $sKey = '_bx_ntfs_txt_object_publish_failed';
+                break;
+
+            case 'publish_succeeded':
+                $sKey = '_bx_ntfs_txt_object_publish_succeeded';
+                break;
+
+            default:
+                $sKey = '_bx_ntfs_txt_object_' . $aEvent['action'] . ($bInContext ? '_in_context' : '');
+        }
+
+    	return $sKey;
+    }
+
+    protected function _parseContentLangKey($sLangKey, &$aEvent)
+    {
+        $aExclude = array(
+            'lang_key' => 1,
+            'settings' => 1
+        );
+
+        return $this->parseHtmlByContent(_t($sLangKey), array_diff_key($aEvent['content'], $aExclude), array('{', '}'));
+    }
+
+    protected function _getContentLink(&$aEvent)
+    {
+        return !empty($aEvent['subobject_id']) && !empty($aEvent['content']['subentry_url']) ? $aEvent['content']['subentry_url'] : $aEvent['content']['entry_url'];
+    }
+
+    protected function _isInContext(&$aEvent)
+    {
+        return (int)$aEvent['object_privacy_view'] < 0;
+    }
+}
+
+/** @} */

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

+ 137 - 0
modules/boonex/notifications/updates/13.0.0_13.0.1/source/install/langs/en.xml

@@ -0,0 +1,137 @@
+<?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_page_title_system_settings"><![CDATA[Notifications Settings]]></string>
+    <string name="_bx_ntfs_page_title_settings"><![CDATA[Notifications Settings]]></string>
+    <string name="_bx_ntfs_page_block_title_delivery"><![CDATA[Receive via]]></string>
+    <string name="_bx_ntfs_page_block_title_settings"><![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_title_settings"><![CDATA[Settings Submenu]]></string>
+    <string name="_bx_ntfs_menu_set_title_settings"><![CDATA[Settings Submenu]]></string>
+    <string name="_bx_ntfs_menu_item_title_system_notifications_site"><![CDATA[On Site]]></string>
+    <string name="_bx_ntfs_menu_item_title_notifications_site"><![CDATA[On Site]]></string>
+    <string name="_bx_ntfs_menu_item_title_system_notifications_email"><![CDATA[Email]]></string>
+    <string name="_bx_ntfs_menu_item_title_notifications_email"><![CDATA[Email]]></string>
+    <string name="_bx_ntfs_menu_item_title_system_notifications_push"><![CDATA[Push]]></string>
+    <string name="_bx_ntfs_menu_item_title_notifications_push"><![CDATA[Push]]></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_menu_item_title_system_preview"><![CDATA[Notifications]]></string>
+    <string name="_bx_ntfs_menu_item_title_preview"><![CDATA[]]></string>
+
+    <string name="_bx_ntfs_menu_title_preview"><![CDATA[Notifications Preview]]></string>
+    <string name="_bx_ntfs_menu_set_title_preview"><![CDATA[Notifications Preview]]></string>
+    <string name="_bx_ntfs_menu_item_title_system_more"><![CDATA[See all notifications]]></string>
+    <string name="_bx_ntfs_menu_item_title_more"><![CDATA[See all notifications]]></string>
+    <string name="_bx_ntfs_lmi_cpt_site"><![CDATA[On Site]]></string>
+    <string name="_bx_ntfs_lmi_cpt_email"><![CDATA[Email]]></string>
+    <string name="_bx_ntfs_lmi_cpt_push"><![CDATA[Push]]></string>
+
+    <string name="_bx_ntfs_options_category_system"><![CDATA[System]]></string>
+    <string name="_bx_ntfs_option_events_per_page"><![CDATA[Number of items per page]]></string>
+    <string name="_bx_ntfs_option_events_per_preview"><![CDATA[Number of items in preview]]></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_option_enable_group_settings"><![CDATA[Group Settings]]></string>
+    <string name="_bx_ntfs_option_delivery_timeout"><![CDATA[Delay before sending Email and/or Push notifications (in seconds)]]></string>
+    <string name="_bx_ntfs_option_processed_event"><![CDATA[The last processed event upon notifications sending]]></string>
+    <string name="_bx_ntfs_option_clear_interval"><![CDATA[Notification lifetime, in days (0 - no limit)]]></string>
+
+    <string name="_bx_ntfs_privacy_view"><![CDATA[View event]]></string>
+
+    <string name="_bx_ntfs_alert_action_group_content_updated"><![CDATA[Content was updated]]></string>
+    <string name="_bx_ntfs_alert_action_group_action_required"><![CDATA[Your action required]]></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_action_mention_added_personal"><![CDATA[Someone mentions you]]></string>
+    <string name="_bx_ntfs_alert_action_friendship_added_personal"><![CDATA[You get a new friend]]></string>
+    <string name="_bx_ntfs_alert_action_subscription_added_personal"><![CDATA[You get a new follower]]></string>
+    <string name="_bx_ntfs_alert_action_added_follow_member"><![CDATA[New content]]></string>
+    <string name="_bx_ntfs_alert_action_added_follow_context"><![CDATA[New content]]></string>
+    <string name="_bx_ntfs_alert_action_commentPost_personal"><![CDATA[Someone adds a comment on your content]]></string>
+    <string name="_bx_ntfs_alert_action_commentPost_follow_member"><![CDATA[New comments]]></string>
+    <string name="_bx_ntfs_alert_action_commentPost_follow_context"><![CDATA[New comments]]></string>
+    <string name="_bx_ntfs_alert_action_replyPost_personal"><![CDATA[Someone adds a reply to your comment]]></string>
+    <string name="_bx_ntfs_alert_action_doVote_personal"><![CDATA[Someone adds a like to your content]]></string>
+    <string name="_bx_ntfs_alert_action_doVote_follow_member"><![CDATA[New likes]]></string>
+    <string name="_bx_ntfs_alert_action_doVote_follow_context"><![CDATA[New likes]]></string>
+    <string name="_bx_ntfs_alert_action_doVoteUp_personal"><![CDATA[Someone adds an 'Up' vote to your content]]></string>
+    <string name="_bx_ntfs_alert_action_doVoteUp_follow_member"><![CDATA[New 'Up' votes]]></string>
+    <string name="_bx_ntfs_alert_action_doVoteUp_follow_context"><![CDATA[New 'Up' votes]]></string>
+    <string name="_bx_ntfs_alert_action_doVoteDown_personal"><![CDATA[Someone adds a 'Down' vote to your content]]></string>
+    <string name="_bx_ntfs_alert_action_doVoteDown_follow_member"><![CDATA[New 'Down' votes]]></string>
+    <string name="_bx_ntfs_alert_action_doVoteDown_follow_context"><![CDATA[New 'Down' votes]]></string>
+    <string name="_bx_ntfs_alert_action_fan_added_personal"><![CDATA[New fans]]></string>
+    <string name="_bx_ntfs_alert_action_fan_added_follow_member"><![CDATA[New fans]]></string>
+    <string name="_bx_ntfs_alert_action_fan_added_follow_context"><![CDATA[New fans]]></string>
+    <string name="_bx_ntfs_alert_action_join_request_personal"><![CDATA[New join requests]]></string>
+    <string name="_bx_ntfs_alert_action_join_request_follow_member"><![CDATA[New join requests]]></string>
+    <string name="_bx_ntfs_alert_action_join_request_follow_context"><![CDATA[New join requests]]></string>
+    <string name="_bx_ntfs_alert_action_join_invitation_notif_personal"><![CDATA[New join invitation]]></string>
+    <string name="_bx_ntfs_alert_action_timeline_post_common_personal"><![CDATA[New posts on Timeline]]></string>
+    <string name="_bx_ntfs_alert_action_timeline_post_common_follow_member"><![CDATA[New posts on Timeline]]></string>
+    <string name="_bx_ntfs_alert_action_timeline_post_common_follow_context"><![CDATA[New posts on Timeline]]></string>
+    <string name="_bx_ntfs_alert_action_publish_failed_personal"><![CDATA[Delayed publishing failed]]></string>
+    <string name="_bx_ntfs_alert_action_publish_succeeded_personal"><![CDATA[Delayed publishing succeeded]]></string>
+    <string name="_bx_ntfs_alert_action_pending_approval_personal"><![CDATA[New pending approval content]]></string>
+    <string name="_bx_ntfs_alert_action_approved_personal"><![CDATA[Your content was approved]]></string>
+
+    <string name="_bx_ntfs_setting_title_mask"><![CDATA[{0}: {1}]]></string>
+    <string name="_bx_ntfs_setting_type_personal"><![CDATA[Activity related to you]]></string>
+    <string name="_bx_ntfs_setting_type_follow_member"><![CDATA[Activity by members you follow]]></string>
+    <string name="_bx_ntfs_setting_type_follow_context"><![CDATA[Activity in spaces (groups, events, etc.) you follow]]></string>
+    <string name="_bx_ntfs_setting_type_other"><![CDATA[Other Activity]]></string>
+
+    <string name="_bx_ntfs_alert_module_sys_cmts"><![CDATA[Comments]]></string>
+    <string name="_bx_ntfs_alert_module_sys_cmts_reactions"><![CDATA[Comments' Reactions]]></string>
+    <string name="_bx_ntfs_alert_module_meta_mention"><![CDATA[Profiles Mentions]]></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_err_nothing_changed"><![CDATA[Nothing was changed.]]></string>
+    <string name="_bx_ntfs_txt_err_cannot_perform"><![CDATA[Cannot perform the action.]]></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_object_added_in_context"><![CDATA[<b class="bx-ntfs-content-profile">{owner_name}</b> has got a {entry_sample} <b class="bx-ntfs-content-entry">{entry_caption}</b> added by <b class="bx-ntfs-content-profile">{object_owner_name}</b>]]></string>
+    <string name="_bx_ntfs_txt_object_approved"><![CDATA[<b class="bx-ntfs-content-profile">{owner_name}</b> approved {entry_sample} <b class="bx-ntfs-content-entry">{entry_caption}</b>]]></string>
+    <string name="_bx_ntfs_txt_object_approved_in_context"><![CDATA[<b class="bx-ntfs-content-entry">{entry_caption}</b> {entry_sample} was approved in <b class="bx-ntfs-content-profile">{owner_name}</b>]]></string>
+    <string name="_bx_ntfs_txt_object_publish_failed"><![CDATA[Failed to publish your {entry_sample} <b class="bx-ntfs-content-entry">{entry_caption}</b>]]></string>
+    <string name="_bx_ntfs_txt_object_publish_succeeded"><![CDATA[Your {entry_sample} <b class="bx-ntfs-content-entry">{entry_caption}</b> was published successfully]]></string>
+    <string name="_bx_ntfs_txt_object_pending_approval"><![CDATA[<b class="bx-ntfs-content-profile">{owner_name}</b> added a pending approval {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_txt_subobject_added_in_context"><![CDATA[<b class="bx-ntfs-content-profile">{owner_name}</b> has got 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>
+
+    <string name="_bx_ntfs_grid_column_title_active"><![CDATA[Active]]></string>
+    <string name="_bx_ntfs_grid_column_title_unit"><![CDATA[Module]]></string>
+    <string name="_bx_ntfs_grid_column_title_type"><![CDATA[Type]]></string>
+    <string name="_bx_ntfs_grid_column_title_title"><![CDATA[Notification]]></string>
+    <string name="_bx_ntfs_grid_column_title_title_warning"><![CDATA[The setting's value is corrupted. It is recommended to enable/disable it and reload the page.]]></string>
+    <string name="_bx_ntfs_grid_column_title_value"><![CDATA[Default value]]></string>
+    <string name="_bx_ntfs_grid_action_title_activate"><![CDATA[Activate]]></string>
+    <string name="_bx_ntfs_grid_action_title_deactivate"><![CDATA[Deactivate]]></string>
+</resources>

+ 51 - 0
modules/boonex/oauth2/updates/13.0.0_13.0.1/install/config.php

@@ -0,0 +1,51 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ */
+
+$aConfig = array(
+    /**
+     * Main Section.
+     */
+    'title' => 'OAuth2 Server',
+    'version_from' => '13.0.0',
+    'version_to' => '13.0.1',
+    'vendor' => 'BoonEx',
+
+    'compatible_with' => array(
+        '13.0.0-A3'
+    ),
+
+    /**
+     * 'home_dir' and 'home_uri' - should be unique. Don't use spaces in 'home_uri' and the other special chars.
+     */
+    'home_dir' => 'boonex/oauth2/updates/update_13.0.0_13.0.1/',
+    'home_uri' => 'oauth2_update_1300_1301',
+
+    'module_dir' => 'boonex/oauth2/',
+    'module_uri' => 'oauth2',
+
+    'db_prefix' => 'bx_oauth_',
+    'class_prefix' => 'BxOAuth',
+
+    /**
+     * Installation/Uninstallation Section.
+     */
+    'install' => array(
+        'execute_sql' => 1,
+        'update_files' => 1,
+        'update_languages' => 0,
+        'clear_db_cache' => 1,
+    ),
+
+    /**
+     * Category for language keys.
+     */
+    'language_category' => 'OAuth2 Server',
+
+    /**
+     * Files Section
+     */
+    'delete_files' => array(),
+);

+ 23 - 0
modules/boonex/oauth2/updates/13.0.0_13.0.1/install/installer.php

@@ -0,0 +1,23 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ */
+
+class BxOAuthUpdater extends BxDolStudioUpdater
+{
+    function __construct($aConfig)
+    {
+        parent::__construct($aConfig);
+    }
+
+    public function actionExecuteSql($sOperation)
+    {
+        if($sOperation == 'install') {
+            if(!$this->oDb->isFieldExists('bx_oauth_scopes', 'id'))
+                $this->oDb->query("ALTER TABLE `bx_oauth_scopes` ADD `id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT FIRST");
+        }
+
+        return parent::actionExecuteSql($sOperation);
+    }
+}

+ 1 - 0
modules/boonex/oauth2/updates/13.0.0_13.0.1/install/sql/install.sql

@@ -0,0 +1 @@
+SET @sName = 'bx_oauth';

+ 68 - 0
modules/boonex/oauth2/updates/13.0.0_13.0.1/source/install/config.php

@@ -0,0 +1,68 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    OAuth2 OAuth2 server
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+$aConfig = array(
+    /**
+     * Main Section.
+     */
+    'type' => BX_DOL_MODULE_TYPE_MODULE,
+    'name' => 'bx_oauth',
+    'title' => 'OAuth2 Server',
+    'note' => 'Allow to use site user credentials and basic API',
+    'version' => '13.0.1',
+    'vendor' => 'BoonEx',
+    'help_url' => 'http://feed.una.io/?section={module_name}',
+
+    'compatible_with' => array(
+        '13.0.0-A3'
+    ),
+
+    /**
+     * 'home_dir' and 'home_uri' - should be unique. Don't use spaces in 'home_uri' and the other special chars.
+     */
+    'home_dir' => 'boonex/oauth2/',
+    'home_uri' => 'oauth2',
+
+    'db_prefix' => 'bx_oauth_',
+    'class_prefix' => 'BxOAuth',
+
+    /**
+     * Category for language keys.
+     */
+    'language_category' => 'OAuth2 Server',
+
+    /**
+     * Installation/Uninstallation Section.
+     */
+    'install' => array(
+        'execute_sql' => 1,
+        'update_languages' => 1,
+    ),
+    'uninstall' => array (
+        'execute_sql' => 1,
+        'update_languages' => 1,
+    ),
+    'enable' => array(
+        'execute_sql' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'disable' => array (
+        'execute_sql' => 1,
+        'clear_db_cache' => 1,
+    ),
+
+    /**
+     * Dependencies Section
+     */
+    'dependencies' => array(),
+);
+
+/** @} */

+ 78 - 0
modules/boonex/oauth2/updates/13.0.0_13.0.1/source/install/sql/install.sql

@@ -0,0 +1,78 @@
+
+CREATE TABLE IF NOT EXISTS `bx_oauth_access_tokens` (
+  `access_token` varchar(40) NOT NULL,
+  `client_id` varchar(80) NOT NULL,
+  `user_id` int(10) unsigned DEFAULT NULL,
+  `expires` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+  `scope` varchar(255) DEFAULT NULL,
+  PRIMARY KEY (`access_token`)
+);
+
+CREATE TABLE IF NOT EXISTS `bx_oauth_authorization_codes` (
+  `authorization_code` varchar(40) NOT NULL,
+  `client_id` varchar(80) NOT NULL,
+  `user_id` int(10) unsigned DEFAULT NULL,
+  `redirect_uri` varchar(255) DEFAULT NULL,
+  `expires` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+  `scope` varchar(255) DEFAULT NULL,
+  PRIMARY KEY (`authorization_code`),
+  KEY `user_id` (`user_id`)
+);
+
+CREATE TABLE IF NOT EXISTS `bx_oauth_clients` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `title` varchar(255) NOT NULL,
+  `client_id` varchar(80) NOT NULL,
+  `client_secret` varchar(80) DEFAULT NULL,
+  `redirect_uri` varchar(255) NOT NULL,
+  `grant_types` varchar(80) DEFAULT NULL,
+  `scope` varchar(255) DEFAULT NULL,
+  `parent_id` int(10) unsigned DEFAULT 0,
+  `user_id` int(10) unsigned DEFAULT 0,
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `client_id` (`client_id`)
+);
+
+CREATE TABLE IF NOT EXISTS `bx_oauth_allowed_origins` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `client_id` int(11) NOT NULL,
+  `url` varchar(255) NOT NULL,
+  PRIMARY KEY (`id`),
+  KEY `url` (`url`(191))
+);
+
+CREATE TABLE IF NOT EXISTS `bx_oauth_refresh_tokens` (
+  `refresh_token` varchar(40) NOT NULL,
+  `client_id` varchar(80) NOT NULL,
+  `user_id` int(10) unsigned DEFAULT NULL,
+  `expires` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+  `scope` varchar(255) DEFAULT NULL,
+  PRIMARY KEY (`refresh_token`),
+  KEY `user_id` (`user_id`)
+);
+
+CREATE TABLE IF NOT EXISTS `bx_oauth_scopes` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `scope` varchar(255)  DEFAULT NULL,
+  `is_default` tinyint(1) DEFAULT NULL,
+   PRIMARY KEY (`id`)
+);
+
+INSERT INTO `bx_oauth_scopes` (`scope`, `is_default`) VALUES
+('basic', 1),
+('service', 0),
+('market', 0);
+
+-- Studio page and widget
+
+INSERT INTO `sys_std_pages`(`index`, `name`, `header`, `caption`, `icon`) VALUES
+(3, 'bx_oauth', '_bx_oauth', '_bx_oauth', 'bx_oauth@modules/boonex/oauth2/|std-icon.svg');
+SET @iPageId = LAST_INSERT_ID();
+
+SET @iParentPageId = (SELECT `id` FROM `sys_std_pages` WHERE `name` = 'home');
+SET @iParentPageOrder = (SELECT MAX(`order`) FROM `sys_std_pages_widgets` WHERE `page_id` = @iParentPageId);
+INSERT INTO `sys_std_widgets` (`page_id`, `module`, `type`, `url`, `click`, `icon`, `caption`, `cnt_notices`, `cnt_actions`) VALUES
+(@iPageId, 'bx_oauth', 'integrations', '{url_studio}module.php?name=bx_oauth&page=settings', '', 'bx_oauth@modules/boonex/oauth2/|std-icon.svg', '_bx_oauth', '', 'a:4:{s:6:"module";s:6:"system";s:6:"method";s:11:"get_actions";s:6:"params";a:0:{}s:5:"class";s:18:"TemplStudioModules";}');
+INSERT INTO `sys_std_pages_widgets` (`page_id`, `widget_id`, `order`) VALUES
+(@iParentPageId, LAST_INSERT_ID(), IF(ISNULL(@iParentPageOrder), 1, @iParentPageOrder + 1));
+

+ 51 - 0
modules/boonex/organizations/updates/13.0.0_13.0.1/install/config.php

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

+ 44 - 0
modules/boonex/organizations/updates/13.0.0_13.0.1/install/installer.php

@@ -0,0 +1,44 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ */
+
+class BxOrgsUpdater extends BxDolStudioUpdater
+{
+    function __construct($aConfig)
+    {
+        parent::__construct($aConfig);
+    }
+
+    public function actionExecuteSql($sOperation)
+    {
+        if($sOperation == 'install') {
+            if(!$this->oDb->isFieldExists('bx_organizations_cmts', 'cmt_cf'))
+                $this->oDb->query("ALTER TABLE `bx_organizations_cmts` ADD `cmt_cf` int(11) NOT NULL default '1' AFTER `cmt_pinned`");
+
+            if(!$this->oDb->isFieldExists('bx_organizations_views_track', 'id'))
+                $this->oDb->query("ALTER TABLE `bx_organizations_views_track` ADD `id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT FIRST");
+
+            if(!$this->oDb->isFieldExists('bx_organizations_votes', 'id'))
+                $this->oDb->query("ALTER TABLE `bx_organizations_votes` ADD `id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT FIRST");
+
+            if(!$this->oDb->isFieldExists('bx_organizations_favorites_track', 'id'))
+                $this->oDb->query("ALTER TABLE `bx_organizations_favorites_track` ADD `id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT FIRST");
+
+            if(!$this->oDb->isFieldExists('bx_organizations_reports', 'id'))
+                $this->oDb->query("ALTER TABLE `bx_organizations_reports` ADD `id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT FIRST");
+
+            if(!$this->oDb->isFieldExists('bx_organizations_meta_keywords', 'id'))
+                $this->oDb->query("ALTER TABLE `bx_organizations_meta_keywords` ADD `id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT FIRST");
+
+            if(!$this->oDb->isFieldExists('bx_organizations_meta_mentions', 'id'))
+                $this->oDb->query("ALTER TABLE `bx_organizations_meta_mentions` ADD `id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT FIRST");
+
+            if(!$this->oDb->isFieldExists('bx_organizations_scores', 'id'))
+                $this->oDb->query("ALTER TABLE `bx_organizations_scores` ADD `id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT FIRST");
+        }
+
+        return parent::actionExecuteSql($sOperation);
+    }
+}

+ 8 - 0
modules/boonex/organizations/updates/13.0.0_13.0.1/install/langs/en.xml

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources name="en" flag="gb" title="English">
+	<string_add name="_bx_orgs_page_title_browse_familiar"><![CDATA[Organizations You May Know]]></string_add>
+	<string_add name="_bx_orgs_page_block_title_profile_friends_mutual"><![CDATA[Mutual Friends]]></string_add>
+	<string_add name="_bx_orgs_page_block_title_sys_familiar_profiles"><![CDATA[Familiar Organizations]]></string_add>
+    <string_add name="_bx_orgs_page_block_title_familiar_profiles"><![CDATA[Organizations You May Know]]></string_add>
+	<string_add name="_bx_orgs_txt_ntfs_join_request_for_owner"><![CDATA[<b class="bx-ntfs-content-entry">{subentry_sample}</b> sent a join request to your organization]]></string_add>
+</resources>

+ 40 - 0
modules/boonex/organizations/updates/13.0.0_13.0.1/install/sql/enable.sql

@@ -0,0 +1,40 @@
+-- PAGES
+DELETE FROM `sys_pages_blocks` WHERE `object`='bx_organizations_view_profile' AND `title` IN ('_bx_orgs_page_block_title_cover_block', '_bx_orgs_page_block_title_profile_friends_mutual');
+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', 0, 'bx_organizations', '_bx_orgs_page_block_title_sys_cover_block', '_bx_orgs_page_block_title_cover_block', 3, 2147483647, 'service', 'a:2:{s:6:\"module\";s:16:\"bx_organizations\";s:6:\"method\";s:12:\"entity_cover\";}', 0, 0, 1, 0),
+('bx_organizations_view_profile', 0, 'bx_organizations', '', '_bx_orgs_page_block_title_profile_friends_mutual', 11, 2147483647, 'service', 'a:2:{s:6:\"module\";s:16:\"bx_organizations\";s:6:\"method\";s:22:\"profile_friends_mutual\";}', 0, 0, 1, 0);
+
+
+DELETE FROM `sys_pages_blocks` WHERE `object`='' AND `module`='bx_organizations' AND `title`='_bx_orgs_page_block_title_cover_block';
+
+DELETE FROM `sys_pages_blocks` WHERE `object`='' AND `module`='bx_organizations' AND `title`='_bx_orgs_page_block_title_familiar_profiles';
+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_sys_familiar_profiles', '_bx_orgs_page_block_title_familiar_profiles', 11, 2147483647, 'service', 'a:3:{s:6:\"module\";s:16:\"bx_organizations\";s:6:\"method\";s:24:\"browse_familiar_profiles\";s:6:\"params\";a:4:{s:10:\"connection\";s:20:\"sys_profiles_friends\";s:9:\"unit_view\";s:4:\"unit\";s:13:\"empty_message\";b:0;s:13:\"ajax_paginate\";b:0;}}', 0, 1, 1, IFNULL(@iBlockOrder, 0) + 1);
+
+
+-- MENUS
+UPDATE `sys_menu_items` SET `onclick`='bx_menu_popup(''sys_set_acl_level'', window, {id:{value:''sys_acl_set_{profile_id}'', force:true}, closeOnOuterClick: false, removeOnClose: true, displayMode: ''box'', cssClass: ''''}, {profile_id: {profile_id}});' WHERE `set_name`='bx_organizations_view_actions' AND `name`='profile-set-acl-level';
+
+DELETE FROM `sys_menu_items` WHERE `set_name`='bx_organizations_view_actions_all' AND `name` IN ('social-sharing', 'social-sharing-facebook', 'social-sharing-twitter', 'social-sharing-pinterest');
+INSERT INTO `sys_menu_items`(`set_name`, `module`, `name`, `title_system`, `title`, `link`, `onclick`, `target`, `icon`, `addon`, `submenu_object`, `submenu_popup`, `visible_for_levels`, `visibility_custom`, `active`, `copyable`, `order`) VALUES 
+('bx_organizations_view_actions_all', 'bx_organizations', 'social-sharing', '_sys_menu_item_title_system_social_sharing', '_sys_menu_item_title_social_sharing', 'javascript:void(0)', 'oBxDolPage.share(this, \'{url_encoded}\')', '', 'share', '', '', 0, 2147483647, '', 1, 0, 300);
+
+
+DELETE FROM `sys_menu_items` WHERE `set_name`='bx_organizations_snippet_meta' AND `name`='friends-mutual';
+INSERT INTO `sys_menu_items`(`set_name`, `module`, `name`, `title_system`, `title`, `link`, `onclick`, `target`, `icon`, `submenu_object`, `visible_for_levels`, `visibility_custom`, `active`, `copyable`, `editable`, `order`) VALUES
+('bx_organizations_snippet_meta', 'bx_organizations', 'friends-mutual', '_sys_menu_item_title_system_sm_friends_mutual', '_sys_menu_item_title_sm_friends_mutual', '', '', '', '', '', 2147483647, '', 0, 0, 1, 0);
+
+UPDATE `sys_menu_items` SET `collapsed`='0' WHERE `set_name`='sys_profile_followings' AND `name`='organizations';
+
+
+-- METATAGS
+UPDATE `sys_objects_metatags` SET `module`='bx_organizations' WHERE `object`='bx_organizations';
+
+
+-- CATEGORY
+UPDATE `sys_objects_category` SET `module`='bx_organizations' WHERE `object`='bx_organizations_cats';
+
+
+-- CONNECTIONS
+UPDATE `sys_objects_connection` SET `profile_initiator`='1', `profile_content`='1' WHERE `object`='bx_organizations_fans';

+ 2 - 0
modules/boonex/organizations/updates/13.0.0_13.0.1/install/sql/install.sql

@@ -0,0 +1,2 @@
+-- FORMS
+UPDATE `sys_form_inputs` SET `type`='price' WHERE `object`='bx_organizations_price' AND `name`='price';

+ 311 - 0
modules/boonex/organizations/updates/13.0.0_13.0.1/source/classes/BxOrgsConfig.php

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

+ 26 - 0
modules/boonex/organizations/updates/13.0.0_13.0.1/source/classes/BxOrgsFormEntry.php

@@ -0,0 +1,26 @@
+<?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->_bAllowChangeUserForAdmins = true;
+        
+        $this->MODULE = 'bx_organizations';
+        parent::__construct($aInfo, $oTemplate);
+    }
+}
+
+/** @} */

+ 150 - 0
modules/boonex/organizations/updates/13.0.0_13.0.1/source/classes/BxOrgsModule.php

@@ -0,0 +1,150 @@
+<?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
+ *
+ * @{
+ */
+
+define('BX_ORGANIZATIONS_ACTION_SWITCH_TO_PROFILE', 'switch_to_profile');
+
+/**
+ * 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 serviceGetSearchResultUnit ($iContentId, $sUnitTemplate = '')
+    {
+        if(empty($sUnitTemplate))
+            $sUnitTemplate = 'unit_with_cover.html';
+
+        return parent::serviceGetSearchResultUnit($iContentId, $sUnitTemplate);
+    }
+
+    /**
+     * @see BxBaseModProfileModule::serviceGetSpaceTitle
+     */ 
+    public function serviceGetSpaceTitle()
+    {
+		$aExcludeModules = explode(',', getParam('sys_hide_post_to_context_for_privacy'));
+		if (in_array($this->_aModule['name'], $aExcludeModules))
+              return BxBaseModProfileModule::serviceGetSpaceTitle();
+		else
+			return _t($this->_oConfig->CNF['T']['txt_sample_single']);
+    }
+    
+    /**
+     * @see iBxDolProfileService::serviceGetParticipatingProfiles
+     */ 
+    public function serviceGetParticipatingProfiles($iProfileId, $aConnectionObjects = false)
+    {
+		$aExcludeModules = explode(',', getParam('sys_hide_post_to_context_for_privacy'));
+        if (false === $aConnectionObjects){
+			if (in_array($this->_aModule['name'], $aExcludeModules)){
+				$aConnectionObjects = array('sys_profiles_friends');
+            }
+            else{
+                $aConnectionObjects = array('sys_profiles_subscriptions');
+                if (isset($this->_oConfig->CNF['OBJECT_CONNECTIONS'])){
+                    $aConnectionObjects = array($this->_oConfig->CNF['OBJECT_CONNECTIONS'], 'sys_profiles_subscriptions');
+                }
+            }
+        } 
+        return BxBaseModProfileModule::serviceGetParticipatingProfiles($iProfileId, $aConnectionObjects);
+    }
+    
+    public function servicePrepareFields ($aFieldsProfile)
+    {
+        $a = parent::_servicePrepareFields($aFieldsProfile, array('org_cat' => 35), array(
+            'org_desc' => 'description',
+        ));
+        if (!empty($a['fullname'])) {
+            $a['org_name'] = $a['fullname'];
+            unset($a['fullname']);
+        }
+        return $a;
+    }
+
+    public function serviceGetTimelineData()
+    {
+    	return BxBaseModProfileModule::serviceGetTimelineData();
+    }
+
+    public function serviceGetNotificationsInsertData($oAlert, $aHandler, $aDataItems)
+    {
+        if($oAlert->sAction != 'join_request' || empty($aDataItems) || !is_array($aDataItems))
+            return $aDataItems;
+
+        $aDataItem = reset($aDataItems);
+        $aDataItem['owner_id'] = $oAlert->aExtras['performer_id'];
+
+        $aDataItems[] = $aDataItem;
+        return $aDataItems;
+    }
+
+    public function serviceGetNotificationsJoinRequest($aEvent)
+    {
+        if($aEvent['owner_id'] == $aEvent['object_owner_id'])
+            return parent::serviceGetNotificationsJoinRequest($aEvent);
+
+        return $this->_serviceGetNotification($aEvent, $this->_oConfig->CNF['T']['txt_ntfs_join_request_for_owner']);
+    }
+
+    public function onFanRemovedFromAdmins($iGroupProfileId, $iProfileId)
+    {
+        if (!($oProfile = BxDolProfile::getInstance($iProfileId)))
+            return false;
+        $oAccount = $oProfile->getAccountObject();
+        $oAccount->updateProfileContextAuto();
+    }
+
+    public function isAllowedActionByRole($sAction, $aDataEntry, $iGroupProfileId, $iProfileId)
+    {
+        $bResult = parent::isAllowedActionByRole($sAction, $aDataEntry, $iGroupProfileId, $iProfileId);
+        if(!$bResult)
+            return $bResult;
+
+        $iProfileRole = $this->_oDb->getRole($iGroupProfileId, $iProfileId);
+
+        switch($sAction) {
+            case BX_ORGANIZATIONS_ACTION_SWITCH_TO_PROFILE:
+                $bResult = $this->isRole($iProfileRole, BX_BASE_MOD_GROUPS_ROLE_ADMINISTRATOR) || $this->isRole($iProfileRole, BX_BASE_MOD_GROUPS_ROLE_MODERATOR);
+                break;
+        }
+
+        return $bResult;
+    }
+
+    public function checkAllowedCompose (&$aDataEntry, $isPerformAction = false)
+    {
+        return BxBaseModProfileModule::checkAllowedCompose ($aDataEntry, $isPerformAction);
+    }
+
+    public function checkAllowedContact($aDataEntry, $isPerformAction = false)
+    {
+        return BxBaseModProfileModule::checkAllowedContact($aDataEntry, $isPerformAction);
+    }
+}
+
+/** @} */

+ 29 - 0
modules/boonex/organizations/updates/13.0.0_13.0.1/source/classes/BxOrgsPrivacyNotifications.php

@@ -0,0 +1,29 @@
+<?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);
+    }
+
+    public function checkGroupMember($iGroupProfileId, $iViewerId)
+    {
+        if($iGroupProfileId == $iViewerId)
+            return true;
+
+        return parent::checkGroupMember($iGroupProfileId, $iViewerId);
+    }
+}
+
+/** @} */

+ 249 - 0
modules/boonex/organizations/updates/13.0.0_13.0.1/source/classes/BxOrgsSearchResult.php

@@ -0,0 +1,249 @@
+<?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)
+    {
+        $aUnitViews = array('gallery' => 'unit_with_cover.html', 'showcase' => 'unit_with_cover_showcase.html');
+        if(!empty($aParams['unit_views']) && is_array($aParams['unit_views']))
+            $aParams['unit_views'] = array_merge($aUnitViews, $aParams['unit_views']);
+        else
+            $aParams['unit_views'] = $aUnitViews;
+
+        parent::__construct($sMode, $aParams);
+
+        $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' => 'active',
+            'rss' => array(
+                'title' => '',
+                'link' => '',
+                'image' => '',
+                'profile' => 0,
+                'fields' => array (
+                    'Guid' => 'link',
+                    'Link' => 'link',
+                    'Title' => 'org_name',
+                    'DateTimeUTS' => 'added',
+                    'Desc' => 'org_name',
+                    'Image' => '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;
+
+        $this->_setAccountConfirmationConditions($aParams);
+
+        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->aCurrent['restriction']['fans2'] = array('value' => 1, 'field' => 'mutual', '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 'familiar':
+                if($this->_setFamiliarConnectionsConditions($aParams)) {
+                    $this->aCurrent['title'] = _t('_bx_orgs_page_title_browse_familiar');
+                    unset($this->aCurrent['rss']);
+                }
+                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 'recommended':
+                $this->sBrowseUrl = BxDolPermalinks::getInstance()->permalink($CNF['URL_HOME']);
+                $this->aCurrent['title'] = _t('_bx_groups_page_title_browse_recommended');
+                $this->aCurrent['restriction']['featured']['value'] = '0';
+                $this->aCurrent['rss']['link'] = 'modules/?r=groups/rss/' . $sMode;
+                $this->aCurrent['sorting'] = 'recommended';
+                $this->_setConditionsForRecommended();
+                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 'recommended':
+                return array('order' => ' ORDER BY RAND() ');
+            case 'none':
+                return array();
+			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',
+        );
+    }
+}
+
+/** @} */

+ 152 - 0
modules/boonex/organizations/updates/13.0.0_13.0.1/source/install/config.php

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

+ 569 - 0
modules/boonex/organizations/updates/13.0.0_13.0.1/source/install/langs/en.xml

@@ -0,0 +1,569 @@
+<?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[Organization moderation]]></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_enable_profile_activation_letter"><![CDATA[Enable profile activation letter]]></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_homepage"><![CDATA[Homepage]]></string>
+    <string name="_bx_orgs_option_redirect_aadd_custom_url"><![CDATA[URL for 'Custom Page' redirect]]></string>
+    <string name="_bx_orgs_option_activation_on"><![CDATA[Auto-activate after creation & editing]]></string>
+    <string name="_bx_orgs_option_activation_add"><![CDATA[Manually activate after editing, auto-activate after creation]]></string>
+    <string name="_bx_orgs_option_activation_edit"><![CDATA[Manually activate after creating, auto-activate after editing]]></string>
+    <string name="_bx_orgs_option_activation_off"><![CDATA[Activate manually after creation & editing]]></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_members_mode"><![CDATA[Special mode for organization members]]></string>
+    <string name="_bx_orgs_option_members_mode_multi_roles"><![CDATA[Multi Roles]]></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_option_enable_subscribe_wo_join"><![CDATA[Allow to follow without join]]></string>
+    <string name="_bx_orgs_option_auto_activation_for_categories"><![CDATA[Auto activation for categories]]></string>
+    <string name="_bx_orgs_option_per_page_for_favorites_lists"><![CDATA[Number of favorite lists per page]]></string>
+    <string name="_bx_orgs_option_internal_notifications"><![CDATA[Use internal notifications]]></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[Approval required to join]]></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_entry_input_allow_view_favorite_list"><![CDATA[Visibility]]></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_allow_post_to"><![CDATA[Who can post to my profile]]></string>
+    <string name="_bx_orgs_form_profile_input_allow_post_to"><![CDATA[Who can post to my profile]]></string>
+    <string name="_bx_orgs_form_profile_input_sys_allow_contact_to"><![CDATA[Who can contact me]]></string>
+    <string name="_bx_orgs_form_profile_input_allow_contact_to"><![CDATA[Who can contact me]]></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[Profile name is mandatory and and cannot start with @]]></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_entry_input_sys_multicat"><![CDATA[Categories]]></string>
+    <string name="_bx_orgs_form_entry_input_multicat"><![CDATA[Categories]]></string>
+    <string name="_bx_orgs_form_entry_input_multicat_err"><![CDATA[Please select category]]></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_picture_search"><![CDATA[With photo]]></string>
+    <string name="_bx_orgs_form_profile_input_online_search"><![CDATA[Online only]]></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_form_profile_input_sys_profile_ip"><![CDATA[IP]]></string>
+    <string name="_bx_orgs_form_profile_input_profile_ip"><![CDATA[IP]]></string>
+    <string name="_bx_orgs_form_profile_input_sys_date_added"><![CDATA[Added]]></string>
+    <string name="_bx_orgs_form_profile_input_date_added"><![CDATA[Added]]></string>
+    <string name="_bx_orgs_form_profile_input_sys_date_changed"><![CDATA[Updated]]></string>
+    <string name="_bx_orgs_form_profile_input_date_changed"><![CDATA[Updated]]></string>
+    <string name="_bx_orgs_form_profile_input_sys_friends_count"><![CDATA[Friends count]]></string>
+    <string name="_bx_orgs_form_profile_input_friends_count"><![CDATA[Friends count]]></string>
+    <string name="_bx_orgs_form_profile_input_sys_followers_count"><![CDATA[Followers count]]></string>
+    <string name="_bx_orgs_form_profile_input_followers_count"><![CDATA[Followers count]]></string>
+
+    <string name="_bx_orgs_form_price"><![CDATA[Price]]></string>
+    <string name="_bx_orgs_form_price_display_add"><![CDATA[Add]]></string>
+    <string name="_bx_orgs_form_price_display_edit"><![CDATA[Edit]]></string>
+    <string name="_bx_orgs_form_price_input_sys_id"><![CDATA[ID]]></string>
+    <string name="_bx_orgs_form_price_input_sys_role_id"><![CDATA[Role ID]]></string>
+    <string name="_bx_orgs_form_price_input_sys_name"><![CDATA[Name]]></string>
+    <string name="_bx_orgs_form_price_input_name"><![CDATA[Name]]></string>
+    <string name="_bx_orgs_form_price_input_inf_name"><![CDATA[Unique value which will be used in back end and API calls]]></string>
+    <string name="_bx_orgs_form_price_input_err_name"><![CDATA[You need to enter a unique value here]]></string>
+    <string name="_bx_orgs_form_price_input_sys_period"><![CDATA[Period]]></string>
+    <string name="_bx_orgs_form_price_input_period"><![CDATA[Period]]></string>
+    <string name="_bx_orgs_form_price_input_inf_period"><![CDATA[Use 0 for lifetime]]></string>
+    <string name="_bx_orgs_form_price_input_sys_period_unit"><![CDATA[Period unit]]></string>
+    <string name="_bx_orgs_form_price_input_period_unit"><![CDATA[Period unit]]></string>
+    <string name="_bx_orgs_form_price_input_inf_period_unit"><![CDATA[Leave empty for lifetime level.]]></string>
+    <string name="_bx_orgs_form_price_input_err_period_unit"><![CDATA[You need to select a period unit here.]]></string>
+    <string name="_bx_orgs_form_price_input_sys_price"><![CDATA[Price]]></string>
+    <string name="_bx_orgs_form_price_input_price"><![CDATA[Price]]></string>
+    <string name="_bx_orgs_form_price_input_inf_price"><![CDATA[Use 0 or leave empty to create free level.]]></string>
+    <string name="_bx_orgs_form_price_input_sys_do_submit"><![CDATA[Submit]]></string>
+    <string name="_bx_orgs_form_price_input_do_submit"><![CDATA[Submit]]></string>
+    <string name="_bx_orgs_form_price_input_sys_do_cancel"><![CDATA[Cancel]]></string>
+    <string name="_bx_orgs_form_price_input_do_cancel"><![CDATA[Cancel]]></string>
+
+	<string name="_bx_orgs_acl_action_create_profile"><![CDATA[Create Organization's Profile]]></string>
+        <string name="_bx_orgs_acl_action_use_paid_join"><![CDATA[Use paid join]]></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_join_profile"><![CDATA[Join Organization]]></string>
+	<string name="_bx_orgs_page_title_join_profile"><![CDATA[Join Organization]]></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_familiar"><![CDATA[Organizations You May Know]]></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_profile_relations"><![CDATA[Relationships]]></string>
+    <string name="_bx_orgs_page_title_profile_relations"><![CDATA[Relationships]]></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_profile_pricing"><![CDATA[Pricing]]></string>
+	<string name="_bx_orgs_page_title_profile_pricing"><![CDATA[Pricing]]></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_entries_favorites"><![CDATA[Favorites Organizations]]></string>
+    <string name="_bx_orgs_page_title_entries_favorites"><![CDATA[Favorites Organizations]]></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_join_profile"><![CDATA[Join Organization]]></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_system_profile_pricing"><![CDATA[Pricing]]></string>
+        <string name="_bx_orgs_page_block_title_profile_pricing"><![CDATA[Pricing]]></string>
+        <string name="_bx_orgs_page_block_title_profile_pricing_link"><![CDATA[Pricing of <a href="{profile_link}">{display_name}</a>]]></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_profile_friends_mutual"><![CDATA[Mutual 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_system_profile_relations"><![CDATA[Relationships]]></string>
+    <string name="_bx_orgs_page_block_title_profile_relations"><![CDATA[Relationships]]></string>
+    <string name="_bx_orgs_page_block_title_system_profile_related_me"><![CDATA[Relationships with Me]]></string>
+    <string name="_bx_orgs_page_block_title_profile_related_me"><![CDATA[Relationships with Me]]></string>
+    <string name="_bx_orgs_page_block_title_profile_comments"><![CDATA[Comments]]></string>
+    <string name="_bx_orgs_page_block_title_entry_reports"><![CDATA[Reports]]></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_sys_active_profiles"><![CDATA[Active Organizations]]></string>
+    <string name="_bx_orgs_page_block_title_sys_multicats"><![CDATA[Organizations Categories(Multi)]]></string>
+    <string name="_bx_orgs_page_block_title_multicats"><![CDATA[Organizations Categories]]></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_sys_familiar_profiles"><![CDATA[Familiar Organizations]]></string>
+    <string name="_bx_orgs_page_block_title_familiar_profiles"><![CDATA[Organizations You May Know]]></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_favorites_entries"><![CDATA[Favorite List]]></string>
+    <string name="_bx_orgs_page_block_title_favorites_entries"><![CDATA["{title}" List]]></string>
+    <string name="_bx_orgs_page_block_title_favorites_entries_info"><![CDATA[Info]]></string>
+    <string name="_bx_orgs_page_block_title_favorites_entries_actions"><![CDATA[Favorites List Actions]]></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_page_block_title_sys_featured_entries_view_showcase"><![CDATA[Featured Organizations (Showcase View)]]></string>
+    <string name="_bx_orgs_page_block_title_featured_entries_view_showcase"><![CDATA[Featured Organizations]]></string>
+    <string name="_bx_orgs_page_block_title_sys_recommended_entries_view_showcase"><![CDATA[Recommended Organizations (Showcase View)]]></string>
+    <string name="_bx_orgs_page_block_title_recommended_entries_view_showcase"><![CDATA[Recommended Organizations]]></string>
+    <string name="_bx_orgs_page_block_title_sys_active_entries_view_showcase"><![CDATA[Active Organizations (Showcase View)]]></string>
+    <string name="_bx_orgs_page_block_title_active_entries_view_showcase"><![CDATA[Active Organizations]]></string>
+    <string name="_bx_orgs_page_block_title_sys_cover_block"><![CDATA[Cover]]></string>
+    <string name="_bx_orgs_page_block_title_cover_block"><![CDATA[Cover]]></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_title_view_profile_meta"><![CDATA[Organization Meta]]></string>
+    <string name="_bx_orgs_menu_set_title_view_profile_meta"><![CDATA[Organization Meta]]></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_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_clear_reports"><![CDATA[Clear reports]]></string>
+    <string name="_bx_orgs_menu_item_title_clear_reports"><![CDATA[Clear reports]]></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_pricing"><![CDATA[Edit Pricing]]></string>
+    <string name="_bx_orgs_menu_item_title_edit_pricing"><![CDATA[Edit Pricing]]></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_relations"><![CDATA[Relationships]]></string>
+    <string name="_bx_orgs_menu_item_title_view_profile_relations"><![CDATA[Relationships]]></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_profile_more_auto"><![CDATA[More]]></string>
+    <string name="_bx_orgs_menu_item_title_view_profile_more_auto"><![CDATA[More]]></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_pay_and_join"><![CDATA[Pay & Join]]></string>
+    <string name="_bx_orgs_menu_item_title_pay_and_join"><![CDATA[Pay & Join]]></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_relation_add"><![CDATA[Add Relationship]]></string>
+    <string name="_bx_orgs_menu_item_title_relation_add"><![CDATA[Add Relationship]]></string>
+    <string name="_bx_orgs_menu_item_title_system_relation_delete"><![CDATA[Remove Relationship]]></string>
+    <string name="_bx_orgs_menu_item_title_relation_delete"><![CDATA[Remove Relationship]]></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[Friend requests]]></string>
+    <string name="_bx_orgs_menu_item_title_system_relations"><![CDATA[Relationships]]></string>
+    <string name="_bx_orgs_menu_item_title_relations"><![CDATA[Relationships]]></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[Organizations]]></string>
+    <string name="_bx_orgs_menu_item_title_system_favorites"><![CDATA[Favorite Organizations]]></string>
+    <string name="_bx_orgs_menu_item_title_favorites"><![CDATA[Favorite organizations]]></string>
+    <string name="_bx_orgs_menu_item_title_system_subscriptions"><![CDATA[Following]]></string>
+    <string name="_bx_orgs_menu_item_title_subscriptions"><![CDATA[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[Followers]]></string>
+    <string name="_bx_orgs_menu_item_title_system_relations"><![CDATA[Relationships]]></string>
+    <string name="_bx_orgs_menu_item_title_relations"><![CDATA[Relationships]]></string>
+    <string name="_bx_orgs_menu_item_title_system_related_me"><![CDATA[Relationships with Me]]></string>
+    <string name="_bx_orgs_menu_item_title_related_me"><![CDATA[Relationships with Me]]></string>
+    <string name="_bx_orgs_menu_item_title_system_followings"><![CDATA[Organizations]]></string>
+    <string name="_bx_orgs_menu_item_title_followings"><![CDATA[Organizations]]></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]]></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_select_one_filter2"><![CDATA[All]]></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_unconfirmed"><![CDATA[Unconfirmed]]></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 Logged]]></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_clear_reports"><![CDATA[Clear reports]]></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_title_adm_audit_content"><![CDATA[Audit actions with profile]]></string>
+    <string name="_bx_orgs_grid_action_title_adm_audit_profile"><![CDATA[Audit profile's 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_grid_column_title_name"><![CDATA[Name]]></string>
+    <string name="_bx_orgs_grid_column_title_role_id"><![CDATA[Role]]></string>
+    <string name="_bx_orgs_grid_column_title_period"><![CDATA[Period]]></string>
+    <string name="_bx_orgs_grid_column_title_price"><![CDATA[Price]]></string>
+    <string name="_bx_orgs_grid_action_title_add"><![CDATA[Add]]></string>
+    <string name="_bx_orgs_grid_action_title_edit"><![CDATA[Edit]]></string>
+    <string name="_bx_orgs_grid_action_title_delete"><![CDATA[Delete]]></string>
+    <string name="_bx_orgs_grid_action_title_buy"><![CDATA[Buy]]></string>
+    <string name="_bx_orgs_grid_action_title_buy_title"><![CDATA[One-time payment]]></string>
+    <string name="_bx_orgs_grid_action_title_subscribe"><![CDATA[Subscribe]]></string>
+    <string name="_bx_orgs_grid_action_title_subscribe_title"><![CDATA[Create a subscription with recurring billing]]></string>
+    <string name="_bx_orgs_grid_action_title_choose"><![CDATA[Choose]]></string>
+    <string name="_bx_orgs_grid_action_title_choose_title"><![CDATA[Switch to the level for free]]></string>
+    <string name="_bx_orgs_popup_title_price_add"><![CDATA[Add Pricing Plan]]></string>
+    <string name="_bx_orgs_popup_title_price_edit"><![CDATA[Edit Pricing Plan]]></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_orgs_pre_lists_roles"><![CDATA[Organization roles]]></string>
+    <string name="_bx_orgs_role_regular"><![CDATA[Regular]]></string>
+    <string name="_bx_orgs_role_administrator"><![CDATA[Administrator]]></string>
+    <string name="_bx_orgs_role_moderator"><![CDATA[Moderator]]></string>
+
+    <string name="_bx_orgs_pre_lists_period_units"><![CDATA[Billing Interval]]></string>
+    <string name="_bx_orgs_period_unit_day"><![CDATA[day]]></string>
+    <string name="_bx_orgs_period_unit_week"><![CDATA[week]]></string>
+    <string name="_bx_orgs_period_unit_month"><![CDATA[month]]></string>
+    <string name="_bx_orgs_period_unit_year"><![CDATA[year]]></string>
+
+    <string name="_bx_organizations_alert_action_fan_added"><![CDATA[member joined]]></string>
+    <string name="_bx_organizations_alert_action_join_invitation_notif"><![CDATA[join invitation]]></string>
+    <string name="_bx_organizations_alert_action_join_request"><![CDATA[join request]]></string>
+    <string name="_bx_organizations_alert_action_profile_cover_changed"><![CDATA[cover changed]]></string>
+    <string name="_bx_organizations_alert_action_profile_picture_changed"><![CDATA[picture changed]]></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_invitation"><![CDATA[<b class="bx-ntfs-content-profile">{owner_name}</b> organization's representative invites <b class="bx-ntfs-content-entry">{subentry_sample}</b> to join organization]]></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_join_request_for_owner"><![CDATA[<b class="bx-ntfs-content-entry">{subentry_sample}</b> sent a join request to your organization]]></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_sample_vote_single"><![CDATA[vote to organization]]></string>
+    <string name="_bx_orgs_txt_sample_score_up_single"><![CDATA[score up vote to organization]]></string>
+    <string name="_bx_orgs_txt_sample_score_down_single"><![CDATA[score down vote to organization]]></string>
+    <string name="_bx_orgs_txt_sample_pp_single"><![CDATA[profile picture]]></string>
+    <string name="_bx_orgs_txt_sample_pp_single_with_article"><![CDATA[a profile picture]]></string>
+    <string name="_bx_orgs_txt_sample_pc_single"><![CDATA[profile cover]]></string>
+    <string name="_bx_orgs_txt_sample_pc_single_with_article"><![CDATA[a profile cover]]></string>
+    <string name="_bx_orgs_txt_sample_pi_action"><![CDATA[changed {0}]]></string>
+    <string name="_bx_orgs_txt_sample_pi_action_user"><![CDATA[{0} changed {1}]]></string>
+    <string name="_bx_orgs_txt_N_friends"><![CDATA[{0} friends]]></string>
+    <string name="_bx_orgs_txt_role"><![CDATA[Role]]></string>
+    <string name="_bx_orgs_txt_role_added"><![CDATA[Added]]></string>
+    <string name="_bx_orgs_txt_role_expired"><![CDATA[Expires]]></string>
+    <string name="_bx_orgs_txt_set_role"><![CDATA[Set Role]]></string>
+    <string name="_bx_orgs_txt_private_organization"><![CDATA[Private organization]]></string>
+    <string name="_bx_orgs_ps_group_title_participants"><![CDATA[Employees]]></string>
+    <string name="_bx_orgs_txt_n_unit"><![CDATA[{0} ({1})]]></string>
+    <string name="_bx_orgs_txt_cart_item_title"><![CDATA[{0}: {1} ({2} {3})]]></string>
+
+    <string name="_bx_orgs_msg_performed"><![CDATA[The action was successfully performed.]]></string>
+    <string name="_bx_orgs_err_price_duplicate"><![CDATA[Similar pricing plan is already exists.]]></string>
+    <string name="_bx_orgs_err_cannot_perform"><![CDATA[An error appeared. Please report.]]></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_set_role"><![CDATA[Organization member status was changed]]></string>
+    <string name="_bx_orgs_email_set_role_subject"><![CDATA[Your organization status was changed]]></string>
+    <string name="_bx_orgs_email_set_role_body"><![CDATA[{email_header}
+<p>Your status in <a href="{EntryUrl}">{EntryTitle}</a> organization was changed to <b>{Role}</b>.</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>

+ 746 - 0
modules/boonex/organizations/updates/13.0.0_13.0.1/source/install/sql/enable.sql

@@ -0,0 +1,746 @@
+
+-- 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', 'select', 'a:2:{s:6:"module";s:16:"bx_organizations";s:6:"method";s:22:"get_options_activation";}', '', '', 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:4:{s:11:"purchasable";b:0;s:6:"active";b:1;s:9:"translate";b:1;s:22:"filter_out_auto_levels";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', '6', @iCategId, '_bx_orgs_option_num_connections_quick', 'digit', '', '', '', 10),
+('bx_organizations_per_page_browse', '24', @iCategId, '_bx_orgs_option_per_page_browse', 'digit', '', '', '', 11),
+('bx_organizations_num_rss', '10', @iCategId, '_bx_orgs_option_num_rss', 'digit', '', '', '', 12),
+('bx_organizations_per_page_browse_showcase', '32', @iCategId, '_sys_option_per_page_browse_showcase', 'digit', '', '', '', 15),
+('bx_organizations_per_page_browse_recommended', '10', @iCategId, '_sys_option_per_page_browse_recommended', 'digit', '', '', '', 16),
+('bx_organizations_per_page_for_favorites_lists', '5', @iCategId, '_bx_orgs_option_per_page_for_favorites_lists', 'digit', '', '', '', 17),
+('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_members_mode', '', @iCategId, '_bx_orgs_option_members_mode', 'select', 'a:2:{s:6:"module";s:16:"bx_organizations";s:6:"method";s:24:"get_options_members_mode";}', '', '', 25),
+('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),
+('bx_organizations_enable_subscribe_wo_join', '', @iCategId, '_bx_orgs_option_enable_subscribe_wo_join', 'checkbox', '', '', '', 32),
+('bx_organizations_enable_profile_activation_letter', 'on', @iCategId, '_bx_orgs_option_enable_profile_activation_letter', 'checkbox', '', '', '', 33),
+('bx_organizations_auto_activation_for_categories', 'on', @iCategId, '_bx_orgs_option_auto_activation_for_categories', 'checkbox', '', '', '', 35),
+('bx_organizations_internal_notifications', '', @iCategId, '_bx_orgs_option_internal_notifications', 'checkbox', '', '', '', 40);
+
+-- 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', 0, 'bx_organizations', '_bx_orgs_page_block_title_sys_cover_block', '_bx_orgs_page_block_title_cover_block', 3, 2147483647, 'service', 'a:2:{s:6:\"module\";s:16:\"bx_organizations\";s:6:\"method\";s:12:\"entity_cover\";}', 0, 0, 1, 0),
+('bx_organizations_view_profile', 0, 'bx_organizations', '', '_bx_orgs_page_block_title_profile_friends_mutual', 11, 2147483647, 'service', 'a:2:{s:6:\"module\";s:16:\"bx_organizations\";s:6:\"method\";s:22:\"profile_friends_mutual\";}', 0, 0, 1, 0),
+('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_related_me', 11, 2147483647, 'service', 'a:2:{s:6:"module";s:16:"bx_organizations";s:6:"method";s:18:"profile_related_me";}', 0, 1, 0, 0),
+('bx_organizations_view_profile', 2, 'bx_organizations', '', '_bx_orgs_page_block_title_profile_relations', 11, 2147483647, 'service', 'a:2:{s:6:"module";s:16:"bx_organizations";s:6:"method";s:17:"profile_relations";}', 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, 1),
+('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, 0, 0),
+('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),
+('bx_organizations_view_profile', 2, 'bx_organizations', '', '_bx_orgs_page_block_title_entry_reports', 11, 2147483647, 'service', 'a:2:{s:6:\"module\";s:16:\"bx_organizations\";s:6:\"method\";s:14:\"entity_reports\";}', 0, 0, 1, 6);
+
+
+-- 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: join 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_join_profile', 'join-organization-profile', '_bx_orgs_page_title_sys_join_profile', '_bx_orgs_page_title_join_profile', 'bx_organizations', 5, 2147483647, 1, 'page.php?i=join-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_join_profile', 1, 'bx_organizations', '_bx_orgs_page_block_title_join_profile', 11, 2147483647, 'service', 'a:3:{s:6:"module";s:16:"bx_organizations";s:6:"method";s:11:"entity_join";s:6:"params";a:1:{i:0;s:12:"{profile_id}";}}', 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: manage profile pricing
+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_pricing', 'edit-organization-pricing', '_bx_orgs_page_title_sys_profile_pricing', '_bx_orgs_page_title_profile_pricing', 'bx_organizations', 5, 2147483647, 1, 'page.php?i=edit-organization-pricing', '', '', '', 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_pricing', 1, 'bx_organizations', '_bx_orgs_page_block_title_system_profile_pricing', '_bx_orgs_page_block_title_profile_pricing_link', 11, 2147483647, 'service', 'a:3:{s:6:"module";s:16:"bx_organizations";s:6:"method";s:14:"entity_pricing";s:6:"params";a:1:{i:0;s:12:"{profile_id}";}}', 0, 0, 1, 1);
+
+-- 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:3:{s:6:"module";s:16:"bx_organizations";s:6:"method";s:21:"browse_favorite_lists";s:6:"params";a:2:{s:10:"profile_id";s:12:"{profile_id}";s:6:"params";a:3:{s:9:"unit_view";s:8:"showcase";s:13:"empty_message";b:0;s:13:"ajax_paginate";b:0;}}}', 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: profile relations
+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_relations', 'organization-profile-relations', '_bx_orgs_page_title_sys_profile_relations', '_bx_orgs_page_title_profile_relations', 'bx_organizations', 5, 2147483647, 1, 'page.php?i=organization-profile-relations', '', '', '', 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_relations', 1, 'bx_organizations', '_bx_orgs_page_block_title_system_profile_relations', '_bx_orgs_page_block_title_profile_relations', 11, 2147483647, 'service', 'a:3:{s:6:"module";s:6:"system";s:6:"method";s:15:"relations_table";s:5:"class";s:23:"TemplServiceConnections";}', 0, 0, 1, 1),
+('bx_organizations_profile_relations', 1, 'bx_organizations', '_bx_orgs_page_block_title_system_profile_related_me', '_bx_orgs_page_block_title_profile_related_me', 11, 2147483647, 'service', 'a:3:{s:6:"module";s:6:"system";s:6:"method";s:16:"related_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_system`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `active`, `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, 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, 1),
+('bx_organizations_home', 1, 'bx_organizations', '_bx_orgs_page_block_title_sys_multicats', '_bx_orgs_page_block_title_multicats', 11, 2147483647, 'service', 'a:2:{s:6:"module";s:16:"bx_organizations";s:6:"method";s:21:"categories_multi_list";}', 0, 0, 0, 2);
+
+-- 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:2:{s:9:"unit_view";s:7:"gallery";s:13:"empty_message";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:21:"browse_favorite_lists";s:6:"params";a:2:{s:10:"profile_id";s:12:"{profile_id}";s:6:"params";a:3:{s:9:"unit_view";s:8:"showcase";s:13:"empty_message";b:0;s:13:"ajax_paginate";b:0;}}}', 0, 1, 1, 2),
+('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: favorites by list
+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_favorites', '_bx_orgs_page_title_sys_entries_favorites', '_bx_orgs_page_title_entries_favorites', 'bx_organizations', 12, 2147483647, 1, 'organizations-favorites', 'page.php?i=organizations-favorites', '', '', '', 0, 1, 0, 'BxOrgsPageListEntry', 'modules/boonex/organizations/classes/BxOrgsPageListEntry.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_favorites', 2, 'bx_organizations', '_bx_orgs_page_block_title_sys_favorites_entries', '_bx_orgs_page_block_title_favorites_entries', 11, 2147483647, 'service', 'a:3:{s:6:"module";s:16:"bx_organizations";s:6:"method";s:15:"browse_favorite";s:6:"params";a:2:{s:10:"profile_id";s:12:"{profile_id}";s:6:"params";a:3:{s:9:"unit_view";s:7:"gallery";s:13:"empty_message";b:0;s:13:"ajax_paginate";b:0;}}}', 0, 1, 1),
+('bx_organizations_favorites', 3, 'bx_organizations', '', '_bx_orgs_page_block_title_favorites_entries_info', 11, 2147483647, 'service', 'a:2:{s:6:"module";s:16:"bx_organizations";s:6:"method";s:19:"favorites_list_info";}', 0, 0, 0),
+('bx_organizations_favorites', 3, 'bx_organizations', '', '_bx_orgs_page_block_title_favorites_entries_actions', 13, 2147483647, 'service', 'a:2:{s:6:"module";s:16:"bx_organizations";s:6:"method";s:22:"favorites_list_actions";}', 0, 0, 1);
+
+
+-- 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_system`, `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),
+('sys_home', 1, 'bx_organizations', '_bx_orgs_page_block_title_sys_recommended_entries_view_showcase', '_bx_orgs_page_block_title_recommended_entries_view_showcase', 11, 2147483647, 'service', 'a:3:{s:6:\"module\";s:16:\"bx_organizations\";s:6:\"method\";s:18:\"browse_recommended\";s:6:\"params\";a:3:{s:9:\"unit_view\";s:8:\"showcase\";s:13:\"empty_message\";b:0;s:13:\"ajax_paginate\";b:0;}}', 1, 0, 0, IFNULL(@iBlockOrder, 0) + 2);
+
+-- 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),
+('', 0, 'bx_organizations', '_bx_orgs_page_block_title_sys_featured_entries_view_showcase', '_bx_orgs_page_block_title_featured_entries_view_showcase', 11, 2147483647, 'service', 'a:3:{s:6:\"module\";s:16:\"bx_organizations\";s:6:\"method\";s:15:\"browse_featured\";s:6:\"params\";a:3:{s:9:\"unit_view\";s:8:\"showcase\";s:13:\"empty_message\";b:0;s:13:\"ajax_paginate\";b:0;}}', 0, 1, 1, IFNULL(@iBlockOrder, 0) + 2),
+('', 0, 'bx_organizations', '_bx_orgs_page_block_title_sys_recommended_entries_view_showcase', '_bx_orgs_page_block_title_recommended_entries_view_showcase', 11, 2147483647, 'service', 'a:3:{s:6:\"module\";s:16:\"bx_organizations\";s:6:\"method\";s:18:\"browse_recommended\";s:6:\"params\";a:3:{s:9:\"unit_view\";s:8:\"showcase\";s:13:\"empty_message\";b:0;s:13:\"ajax_paginate\";b:0;}}', 0, 1, 1, IFNULL(@iBlockOrder, 0) + 3),
+('', 0, 'bx_organizations', '_bx_orgs_page_block_title_sys_active_entries_view_showcase', '_bx_orgs_page_block_title_active_entries_view_showcase', 11, 2147483647, 'service', 'a:3:{s:6:\"module\";s:16:\"bx_organizations\";s:6:\"method\";s:22:\"browse_active_profiles\";s:6:\"params\";a:3:{s:9:\"unit_view\";s:16:\"showcase_wo_info\";s:13:\"empty_message\";b:0;s:13:\"ajax_paginate\";b:0;}}', 0, 1, 1, IFNULL(@iBlockOrder, 0) + 4),
+('', 0, 'bx_organizations', '_bx_orgs_page_block_title_sys_active_profiles', '_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:3:{s:9:\"unit_view\";s:12:\"unit_wo_info\";s:13:\"empty_message\";b:0;s:13:\"ajax_paginate\";b:0;}}', 0, 1, 1, IFNULL(@iBlockOrder, 0) + 5),
+('', 0, 'bx_organizations', '_bx_orgs_page_block_title_sys_familiar_profiles', '_bx_orgs_page_block_title_familiar_profiles', 11, 2147483647, 'service', 'a:3:{s:6:\"module\";s:16:\"bx_organizations\";s:6:\"method\";s:24:\"browse_familiar_profiles\";s:6:\"params\";a:4:{s:10:\"connection\";s:20:\"sys_profiles_friends\";s:9:\"unit_view\";s:4:\"unit\";s:13:\"empty_message\";b:0;s:13:\"ajax_paginate\";b:0;}}', 0, 1, 1, IFNULL(@iBlockOrder, 0) + 6);
+
+-- MENU
+
+-- MENU: add to site menu
+SET @iSiteMenuOrder = (SELECT `order` FROM `sys_menu_items` WHERE `set_name` = 'sys_site' AND `active` = 1 AND `order` < 9999 ORDER BY `order` DESC LIMIT 1);
+INSERT INTO `sys_menu_items` (`set_name`, `module`, `name`, `title_system`, `title`, `link`, `onclick`, `target`, `icon`, `submenu_object`, `visible_for_levels`, `active`, `copyable`, `order`) VALUES 
+('sys_site', 'bx_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, 'BxOrgsMenuViewActions', 'modules/boonex/organizations/classes/BxOrgsMenuViewActions.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`, `visibility_custom`, `active`, `copyable`, `editable`, `order`) VALUES 
+('bx_organizations_view_actions', 'bx_organizations', 'join-organization-profile', '_bx_orgs_menu_item_title_system_pay_and_join', '_bx_orgs_menu_item_title_pay_and_join', 'page.php?i=join-organization-profile&profile_id={profile_id}', '', '', 'sign-in-alt', '', 0, 2147483647, 'a:3:{s:6:"module";s:16:"bx_organizations";s:6:"method";s:22:"is_paid_join_avaliable";s:6:"params";a:1:{i:0;s:12:"{profile_id}";}}', 1, 0, 0, 4),
+('bx_organizations_view_actions', 'bx_organizations', 'profile-fan-add', '_bx_orgs_menu_item_title_system_become_fan', '{title_add_fan}', 'javascript:void(0)', 'bx_conn_action(this, \'bx_organizations_fans\', \'add\', \'{profile_id}\')', '', 'sign-in-alt', '', 0, 2147483647, 'a:3:{s:6:"module";s:16:"bx_organizations";s:6:"method";s:22:"is_free_join_avaliable";s:6:"params";a:1:{i:0;s:12:"{profile_id}";}}', 1, 0, 0, 5),
+('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-relation-add', '_bx_orgs_menu_item_title_system_relation_add', '_bx_orgs_menu_item_title_relation_add', 'javascript:void(0)', 'bx_menu_popup(''sys_add_relation'', window, {}, {profile_id: {profile_id}});', '', 'sync', '', 0, 2147483647, '', 1, 0, 1, 15),
+('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, {id:{value:''sys_acl_set_{profile_id}'', force:true}, closeOnOuterClick: false, removeOnClose: true, displayMode: ''box'', cssClass: ''''}, {profile_id: {profile_id}});', '', 'certificate', '', 0, 2147483647, '', 1, 0, 1, 30),
+('bx_organizations_view_actions', 'bx_organizations', 'profile-set-badges', '_sys_menu_item_title_system_set_badges', '_sys_menu_item_title_set_badges', 'javascript:void(0)', 'bx_menu_popup(''sys_set_badges'', window, {}, {module: ''bx_organizations'', content_id: {content_id}});', '', 'check-circle', '', 0, 192, 'a:2:{s:6:"module";s:16:"bx_organizations";s:6:"method";s:19:"is_badges_avaliable";}', 1, 0, 1, 40),
+('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, 'BxOrgsMenuViewActions', 'modules/boonex/organizations/classes/BxOrgsMenuViewActions.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`, `visibility_custom`, `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}\')', '', 'sign-out-alt', '', 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-minus', '', 2147483647, '', 1, 0, 10),
+('bx_organizations_view_actions_more', 'bx_organizations', 'profile-relation-remove', '_bx_orgs_menu_item_title_system_relation_delete', '_bx_orgs_menu_item_title_relation_delete', 'javascript:void(0)', 'bx_conn_action(this, \'sys_profiles_relations\', \'remove\', \'{profile_id}\')', '', 'sync', '', 2147483647, '', 1, 0, 15),
+('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}', '', '', 'edit', '', 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-alt', '', 2147483647, '', 1, 0, 30),
+('bx_organizations_view_actions_more', 'bx_organizations', 'edit-organization-pricing', '_bx_orgs_menu_item_title_system_edit_pricing', '_bx_orgs_menu_item_title_edit_pricing', 'page.php?i=edit-organization-pricing&profile_id={profile_id}', '', '', 'money-check-alt', '', 2147483647, 'a:3:{s:6:"module";s:16:"bx_organizations";s:6:"method";s:20:"is_pricing_avaliable";s:6:"params";a:1:{i:0;s:12:"{profile_id}";}}', 1, 0, 41),
+('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-friends', '', 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}', '', '', 'user-times', '', 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', '', '', 'trash', '', 128, '', 1, 0, 60);
+
+-- MENU: all 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_organizations_view_actions_all', '_sys_menu_title_view_actions', 'bx_organizations_view_actions_all', 'bx_organizations', 15, 0, 1, 'BxOrgsMenuViewActionsAll', 'modules/boonex/organizations/classes/BxOrgsMenuViewActionsAll.php');
+
+INSERT INTO `sys_menu_sets`(`set_name`, `module`, `title`, `deletable`) VALUES 
+('bx_organizations_view_actions_all', 'bx_organizations', '_sys_menu_set_title_view_actions', 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`, `visibility_custom`, `active`, `copyable`, `order`) VALUES 
+('bx_organizations_view_actions_all', 'bx_organizations', 'join-organization-profile', '_bx_orgs_menu_item_title_system_pay_and_join', '', '', '', '', '', '', '', 0, 2147483647, '', 1, 0, 5),
+('bx_organizations_view_actions_all', 'bx_organizations', 'profile-fan-add', '_bx_orgs_menu_item_title_system_become_fan', '', '', '', '', '', '', '', 0, 2147483647, '', 1, 0, 10),
+('bx_organizations_view_actions_all', 'bx_organizations', 'profile-fan-remove', '_bx_orgs_menu_item_title_system_leave_organization', '', '', '', '', '', '', '', 0, 2147483647, '', 1, 0, 20),
+('bx_organizations_view_actions_all', 'bx_organizations', 'profile-friend-add', '_bx_orgs_menu_item_title_system_befriend', '', '', '', '', '', '', '', 0, 2147483647, '', 1, 0, 30),
+('bx_organizations_view_actions_all', 'bx_organizations', 'profile-friend-remove', '_bx_orgs_menu_item_title_system_unfriend', '', '', '', '', '', '', '', 0, 2147483647, '', 1, 0, 40),
+('bx_organizations_view_actions_all', 'bx_organizations', 'profile-relation-add', '_bx_orgs_menu_item_title_system_relation_add', '', '', '', '', '', '', '', 0, 2147483647, '', 1, 0, 43),
+('bx_organizations_view_actions_all', 'bx_organizations', 'profile-relation-remove', '_bx_orgs_menu_item_title_system_relation_delete', '', '', '', '', '', '', '', 0, 2147483647, '', 1, 0, 47),
+('bx_organizations_view_actions_all', 'bx_organizations', 'profile-subscribe-add', '_bx_orgs_menu_item_title_system_subscribe', '', '', '', '', '', '', '', 0, 2147483647, '', 1, 0, 50),
+('bx_organizations_view_actions_all', 'bx_organizations', 'profile-subscribe-remove', '_bx_orgs_menu_item_title_system_unsubscribe', '', '', '', '', '', '', '', 0, 2147483647, '', 1, 0, 60),
+('bx_organizations_view_actions_all', 'bx_organizations', 'profile-set-acl-level', '_sys_menu_item_title_system_set_acl_level', '', '', '', '', '', '', '', 0, 2147483647, '', 1, 0, 70),
+('bx_organizations_view_actions_all', 'bx_organizations', 'profile-set-badges', '_sys_menu_item_title_system_set_badges', '', '', '', '', '', '', '', 0, 192, 'a:2:{s:6:"module";s:16:"bx_organizations";s:6:"method";s:19:"is_badges_avaliable";}', 1, 0, 80),
+('bx_organizations_view_actions_all', 'bx_organizations', 'comment', '_sys_menu_item_title_system_va_comment', '', '', '', '', '', '', '', 0, 2147483647, '', 0, 0, 200),
+('bx_organizations_view_actions_all', 'bx_organizations', 'view', '_sys_menu_item_title_system_va_view', '', '', '', '', '', '', '', 0, 2147483647, '', 0, 0, 210),
+('bx_organizations_view_actions_all', 'bx_organizations', 'vote', '_sys_menu_item_title_system_va_vote', '', '', '', '', '', '', '', 0, 2147483647, '', 1, 0, 215),
+('bx_organizations_view_actions_all', 'bx_organizations', 'score', '_sys_menu_item_title_system_va_score', '', '', '', '', '', '', '', 0, 2147483647, '', 1, 0, 220),
+('bx_organizations_view_actions_all', 'bx_organizations', 'favorite', '_sys_menu_item_title_system_va_favorite', '', '', '', '', '', '', '', 0, 2147483647, '', 1, 0, 230),
+('bx_organizations_view_actions_all', 'bx_organizations', 'feature', '_sys_menu_item_title_system_va_feature', '', '', '', '', '', '', '', 0, 2147483647, '', 1, 0, 240),
+('bx_organizations_view_actions_all', 'bx_organizations', 'report', '_sys_menu_item_title_system_va_report', '', '', '', '', '', '', '', 0, 2147483647, '', 1, 0, 260),
+('bx_organizations_view_actions_all', 'bx_organizations', 'notes', '_sys_menu_item_title_system_va_notes', '_sys_menu_item_title_va_notes', 'javascript:void(0)', 'javascript:bx_get_notes(this,  ''{module_uri}'', {content_id});', '', 'exclamation-triangle', '', '', 0, 2147483647, '', 1, 0, 280),
+('bx_organizations_view_actions_all', 'bx_organizations', 'audit', '_sys_menu_item_title_system_va_audit', '_sys_menu_item_title_va_audit', 'page.php?i=dashboard-audit&module=bx_organizations&content_id={content_id}', '', '', 'history', '', '', 0, 192, '', 1, 0, 290),
+('bx_organizations_view_actions_all', 'bx_organizations', 'social-sharing', '_sys_menu_item_title_system_social_sharing', '_sys_menu_item_title_social_sharing', 'javascript:void(0)', 'oBxDolPage.share(this, \'{url_encoded}\')', '', 'share', '', '', 0, 2147483647, '', 1, 0, 300),
+('bx_organizations_view_actions_all', 'bx_organizations', 'edit-organization-cover', '_bx_orgs_menu_item_title_system_edit_cover', '', '', '', '', '', '', '', 0, 2147483647, '', 1, 0, 400),
+('bx_organizations_view_actions_all', 'bx_organizations', 'edit-organization-profile', '_bx_orgs_menu_item_title_system_edit_profile', '', '', '', '', '', '', '', 0, 2147483647, '', 1, 0, 410),
+('bx_organizations_view_actions_all', 'bx_organizations', 'edit-organization-pricing', '_bx_orgs_menu_item_title_system_edit_pricing', '', '', '', '', '', '', '', 0, 2147483647, '', 1, 0, 415),
+('bx_organizations_view_actions_all', 'bx_organizations', 'invite-to-organization', '_bx_orgs_menu_item_title_system_invite', '', '', '', '', '', '', '', 0, 2147483647, '', 1, 0, 420),
+('bx_organizations_view_actions_all', 'bx_organizations', 'delete-organization-profile', '_bx_orgs_menu_item_title_system_delete_profile', '', '', '', '', '', '', '', 0, 2147483647, '', 1, 0, 430),
+('bx_organizations_view_actions_all', 'bx_organizations', 'delete-organization-account', '_bx_orgs_menu_item_title_system_delete_account', '', '', '', '', '', '', '', 0, 128, '', 1, 0, 440),
+('bx_organizations_view_actions_all', 'bx_organizations', 'delete-organization-account-content', '_bx_orgs_menu_item_title_system_delete_account_content', '', '', '', '', '', '', '', 0, 128, '', 1, 0, 450),
+('bx_organizations_view_actions_all', 'bx_organizations', 'more-auto', '_sys_menu_item_title_system_va_more_auto', '_sys_menu_item_title_va_more_auto', 'javascript:void(0)', '', '', 'ellipsis-v', '', '', 0, 2147483647, '', 1, 0, 9999);
+
+-- MENU: meta (counters) 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_organizations_view_meta', '_bx_orgs_menu_title_view_profile_meta', 'bx_organizations_view_meta', 'bx_organizations', 15, 0, 1, 'BxOrgsMenuViewMeta', 'modules/boonex/organizations/classes/BxOrgsMenuViewMeta.php');
+
+INSERT INTO `sys_menu_sets`(`set_name`, `module`, `title`, `deletable`) VALUES 
+('bx_organizations_view_meta', 'bx_organizations', '_bx_orgs_menu_set_title_view_profile_meta', 0);
+
+INSERT INTO `sys_menu_items`(`set_name`, `module`, `name`, `title_system`, `title`, `link`, `onclick`, `target`, `icon`, `submenu_object`, `submenu_popup`, `visible_for_levels`, `visibility_custom`, `active`, `copyable`, `order`) VALUES 
+('bx_organizations_view_meta', 'bx_organizations', 'membership', '_sys_menu_item_title_system_vm_membership', '_sys_menu_item_title_vm_membership', '', '', '', '', '', 0, 2147483647, '', 1, 0, 10),
+('bx_organizations_view_meta', 'bx_organizations', 'badges', '_sys_menu_item_title_system_vm_badges', '_sys_menu_item_title_vm_badges', '', '', '', '', '', 0, 2147483647, '', 1, 0, 20),
+('bx_organizations_view_meta', 'bx_organizations', 'members', '_sys_menu_item_title_system_sm_members', '_sys_menu_item_title_sm_members', '', '', '', '', '', 0, 2147483647, '', 1, 0, 30),
+('bx_organizations_view_meta', 'bx_organizations', 'subscribers', '_sys_menu_item_title_system_sm_subscribers', '_sys_menu_item_title_sm_subscribers', '', '', '', '', '', 0, 2147483647, '', 1, 0, 40),
+('bx_organizations_view_meta', 'bx_organizations', 'views', '_sys_menu_item_title_system_sm_views', '_sys_menu_item_title_sm_views', '', '', '', '', '', 0, 2147483647, '', 1, 0, 50),
+('bx_organizations_view_meta', 'bx_organizations', 'votes', '_sys_menu_item_title_system_sm_votes', '_sys_menu_item_title_sm_votes', '', '', '', '', '', 0, 2147483647, '', 1, 0, 60),
+('bx_organizations_view_meta', 'bx_organizations', 'comments', '_sys_menu_item_title_system_sm_comments', '_sys_menu_item_title_sm_comments', '', '', '', '', '', 0, 2147483647, '', 1, 0, 70);
+
+-- 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', 18, 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`, `addon`, `submenu_object`, `submenu_popup`, `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', '', '', 0, 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', '', '', 0, 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}', '', '', 'users col-blue3', '', '', 0, 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}', '', '', 'users col-blue3', '', '', 0, 2147483647, 1, 0, 4),
+('bx_organizations_view_submenu', 'bx_organizations', 'organization-profile-relations', '_bx_orgs_menu_item_title_system_view_profile_relations', '_bx_orgs_menu_item_title_view_profile_relations', 'page.php?i=organization-profile-relations&profile_id={profile_id}', '', '', 'sync col-blue3', '', '', 0, 2147483647, 1, 0, 5),
+('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', '', '', 0, 2147483647, 1, 0, 6),
+('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}', '', '', '', '', '', 0, 2147483647, 0, 0, 7),
+('bx_organizations_view_submenu', 'bx_organizations', 'more-auto', '_bx_orgs_menu_item_title_system_view_profile_more_auto', '_bx_orgs_menu_item_title_view_profile_more_auto', 'javascript:void(0)', '', '', 'ellipsis-v', '', '', 0, 2147483647, 1, 0, 9999);
+
+-- 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`, `visibility_custom`, `active`, `copyable`, `editable`, `order`) VALUES
+('bx_organizations_snippet_meta', 'bx_organizations', 'friends-mutual', '_sys_menu_item_title_system_sm_friends_mutual', '_sys_menu_item_title_sm_friends_mutual', '', '', '', '', '', 2147483647, '', 0, 0, 1, 0),
+('bx_organizations_snippet_meta', 'bx_organizations', 'date', '_sys_menu_item_title_system_sm_date', '_sys_menu_item_title_sm_date', '', '', '', '', '', 2147483647, '', 0, 0, 1, 1),
+('bx_organizations_snippet_meta', 'bx_organizations', 'category', '_sys_menu_item_title_system_sm_category', '_sys_menu_item_title_sm_category', '', '', '', '', '', 2147483647, '', 0, 0, 1, 5),
+('bx_organizations_snippet_meta', 'bx_organizations', 'tags', '_sys_menu_item_title_system_sm_tags', '_sys_menu_item_title_sm_tags', '', '', '', '', '', 2147483647, '', 0, 0, 1, 10),
+('bx_organizations_snippet_meta', 'bx_organizations', 'views', '_sys_menu_item_title_system_sm_views', '_sys_menu_item_title_sm_views', '', '', '', '', '', 2147483647, '', 0, 0, 1, 15),
+('bx_organizations_snippet_meta', 'bx_organizations', 'comments', '_sys_menu_item_title_system_sm_comments', '_sys_menu_item_title_sm_comments', '', '', '', '', '', 2147483647, '', 0, 0, 1, 20),
+('bx_organizations_snippet_meta', 'bx_organizations', 'members', '_sys_menu_item_title_system_sm_members', '_sys_menu_item_title_sm_members', '', '', '', '', '', 2147483647, '', 1, 0, 1, 25),
+('bx_organizations_snippet_meta', 'bx_organizations', 'friends', '_sys_menu_item_title_system_sm_friends', '_sys_menu_item_title_sm_friends', '', '', '', '', '', 2147483647, '', 1, 0, 1, 30),
+('bx_organizations_snippet_meta', 'bx_organizations', 'subscribers', '_sys_menu_item_title_system_sm_subscribers', '_sys_menu_item_title_sm_subscribers', '', '', '', '', '', 2147483647, '', 0, 0, 1, 35),
+('bx_organizations_snippet_meta', 'bx_organizations', 'membership', '_sys_menu_item_title_system_sm_membership', '_sys_menu_item_title_sm_membership', '', '', '', '', '', 2147483647, '', 0, 0, 1, 40),
+('bx_organizations_snippet_meta', 'bx_organizations', 'nl', '_sys_menu_item_title_system_sm_nl', '_sys_menu_item_title_sm_nl', '', '', '', '', '', 2147483647, '', 1, 0, 1, 45),
+('bx_organizations_snippet_meta', 'bx_organizations', 'join-paid', '_sys_menu_item_title_system_sm_join_paid', '_sys_menu_item_title_sm_join_paid', '', '', '', '', '', 2147483647, 'a:3:{s:6:"module";s:16:"bx_organizations";s:6:"method";s:33:"is_paid_join_avaliable_by_content";s:6:"params";a:1:{i:0;s:12:"{content_id}";}}', 1, 0, 1, 50),
+('bx_organizations_snippet_meta', 'bx_organizations', 'join', '_sys_menu_item_title_system_sm_join', '_sys_menu_item_title_sm_join', '', '', '', '', '', 2147483647, 'a:3:{s:6:"module";s:16:"bx_organizations";s:6:"method";s:33:"is_free_join_avaliable_by_content";s:6:"params";a:1:{i:0;s:12:"{content_id}";}}', 1, 0, 1, 55),
+('bx_organizations_snippet_meta', 'bx_organizations', 'leave', '_sys_menu_item_title_system_sm_leave', '_sys_menu_item_title_sm_leave', '', '', '', '', '', 2147483647, '', 0, 0, 1, 60),
+('bx_organizations_snippet_meta', 'bx_organizations', 'befriend', '_sys_menu_item_title_system_sm_befriend', '_sys_menu_item_title_sm_befriend', '', '', '', '', '', 2147483647, '', 1, 0, 1, 65),
+('bx_organizations_snippet_meta', 'bx_organizations', 'unfriend', '_sys_menu_item_title_system_sm_unfriend', '_sys_menu_item_title_sm_unfriend', '', '', '', '', '', 2147483647, '', 0, 0, 1, 70),
+('bx_organizations_snippet_meta', 'bx_organizations', 'subscribe', '_sys_menu_item_title_system_sm_subscribe', '_sys_menu_item_title_sm_subscribe', '', '', '', '', '', 2147483647, '', 0, 0, 1, 75),
+('bx_organizations_snippet_meta', 'bx_organizations', 'unsubscribe', '_sys_menu_item_title_system_sm_unsubscribe', '_sys_menu_item_title_sm_unsubscribe', '', '', '', '', '', 2147483647, '', 0, 0, 1, 80);
+
+-- MENU: notifications menu in account popup
+SET @iNotifMenuOrder = (SELECT IFNULL(MAX(`order`), 0) 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`, `visibility_custom`, `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, @iNotifMenuOrder + 1),
+('sys_account_notifications', 'bx_organizations', 'notifications-relation-requests', '_bx_orgs_menu_item_title_system_relations', '_bx_orgs_menu_item_title_relations', 'page.php?i=organization-profile-relations&profile_id={member_id}', '', '', 'sync col-blue3', '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:22:"sys_profiles_relations";}s:5:"class";s:23:"TemplServiceConnections";}', '', 2147483646, 'a:2:{s:6:"module";s:16:"bx_organizations";s:6:"method";s:19:"is_enable_relations";}', 1, 0, @iNotifMenuOrder + 2);
+
+-- 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-subscriptions&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),
+('sys_profile_stats', 'bx_organizations', 'profile-stats-relations', '_bx_orgs_menu_item_title_system_relations', '_bx_orgs_menu_item_title_relations', 'page.php?i=organization-profile-relations&profile_id={member_id}#relations', '', '_self', 'sync col-blue3', 'a:4:{s:6:"module";s:6:"system";s:6:"method";s:25:"get_connected_content_num";s:6:"params";a:3:{i:0;s:22:"sys_profiles_relations";i:1;i:0;i:2;i:1;}s:5:"class";s:23:"TemplServiceConnections";}', '', 2147483646, 1, 0, @iNotifMenuOrder + 6),
+('sys_profile_stats', 'bx_organizations', 'profile-stats-related-me', '_bx_orgs_menu_item_title_system_related_me', '_bx_orgs_menu_item_title_related_me', 'page.php?i=organization-profile-relations&profile_id={member_id}#related-me', '', '_self', 'sync col-blue3', 'a:4:{s:6:"module";s:6:"system";s:6:"method";s:28:"get_connected_initiators_num";s:6:"params";a:3:{i:0;s:22:"sys_profiles_relations";i:1;i:0;i:2;i:1;}s:5:"class";s:23:"TemplServiceConnections";}', '', 2147483646, 1, 0, @iNotifMenuOrder + 7);
+
+-- MENU: profile followings
+SET @iFollowingsMenuOrder = (SELECT IFNULL(MAX(`order`), 0) FROM `sys_menu_items` WHERE `set_name`='sys_profile_followings' LIMIT 1);
+INSERT INTO `sys_menu_items`(`set_name`, `module`, `name`, `title_system`, `title`, `link`, `onclick`, `target`, `icon`, `addon`, `submenu_object`, `visible_for_levels`, `collapsed`, `active`, `copyable`, `order`) VALUES 
+('sys_profile_followings', 'bx_organizations', 'organizations', '_bx_orgs_menu_item_title_system_followings', '_bx_orgs_menu_item_title_followings', 'javascript:void(0)', '', '_self', 'briefcase col-red2', '', '', 2147483647, 0, 1, 0, @iFollowingsMenuOrder + 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_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', 'far trash-alt', '', 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', 'far trash-alt', '', 2147483647, 1, 0, 2),
+('bx_organizations_menu_manage_tools', 'bx_organizations', 'clear-reports', '_bx_corgs_menu_item_title_system_clear_reports', '_bx_orgs_menu_item_title_clear_reports', 'javascript:void(0)', 'javascript:{js_object}.onClickClearReports({content_id});', '_self', 'eraser', '', 2147483647, 1, 0, 3);
+
+-- 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', 'briefcase', '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', 'use paid join', NULL, '_bx_orgs_acl_action_use_paid_join', '', 1, 1);
+SET @iIdActionUsePaidJoin = 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();
+
+INSERT INTO `sys_acl_actions` (`Module`, `Name`, `AdditionalParamName`, `Title`, `Desc`, `Countable`, `DisabledForLevels`) VALUES
+('bx_organizations', 'delete any entry', NULL, '_bx_orgs_acl_action_delete_any_profile', '', 1, 3);
+SET @iIdActionProfileDeleteAny = 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),
+
+-- use paid join
+(@iStandard, @iIdActionUsePaidJoin),
+(@iModerator, @iIdActionUsePaidJoin),
+(@iAdministrator, @iIdActionUsePaidJoin),
+(@iPremium, @iIdActionUsePaidJoin),
+
+-- 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),
+
+-- any profile delete
+(@iAdministrator, @iIdActionProfileDeleteAny);
+
+
+-- METATAGS
+INSERT INTO `sys_objects_metatags` (`object`, `module`, `table_keywords`, `table_locations`, `table_mentions`, `override_class_name`, `override_class_file`) VALUES
+('bx_organizations', 'bx_organizations', 'bx_organizations_meta_keywords', 'bx_organizations_meta_locations', 'bx_organizations_meta_mentions', '', '');
+
+
+-- CATEGORY
+INSERT INTO `sys_objects_category` (`object`, `module`, `search_object`, `form_object`, `list_name`, `table`, `field`, `join`, `where`, `override_class_name`, `override_class_file`) VALUES
+('bx_organizations_cats', 'bx_organizations', '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`, `profile_initiator`, `profile_content`, `type`, `override_class_name`, `override_class_file`) VALUES
+('bx_organizations_fans', 'bx_organizations_fans', 1, 1, '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`, `responsive`, `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, 1, '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', 'role', '_bx_orgs_txt_role', '10%', '', 15),
+('bx_organizations_fans', 'role_added', '_bx_orgs_txt_role_added', '10%', '', 16),
+('bx_organizations_fans', 'role_expired', '_bx_orgs_txt_role_expired', '10%', '', 17),
+('bx_organizations_fans', 'actions', '', '20%', '', 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', 'set_role', '_bx_orgs_txt_set_role', '', 0, 20),
+('bx_organizations_fans', 'single', 'set_role_submit', '', '', 0, 21),
+('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`, `tp`.`id` as `profile_id` 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,email', '', 'like', 'reports', '', 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', 'reports', '_sys_txt_reports_title', '5%', 0, '', '', 3),
+('bx_organizations_administration', 'fullname', '_bx_orgs_grid_column_title_adm_fullname', '25%', 0, '', '', 4),
+('bx_organizations_administration', 'last_online', '_bx_orgs_grid_column_title_adm_last_online', '20%', 1, '25', '', 5),
+('bx_organizations_administration', 'account', '_bx_orgs_grid_column_title_adm_account', '20%', 0, '25', '', 6),
+('bx_organizations_administration', 'actions', '', '20%', 0, '', '', 7),
+('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', 'clear_reports', '_bx_orgs_grid_action_title_adm_clear_reports', '', 0, 1, 3),
+('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_administration', 'single', 'audit_content', '_bx_orgs_grid_action_title_adm_audit_content', 'search', 1, 0, 3),
+('bx_organizations_administration', 'single', 'audit_profile', '_bx_orgs_grid_action_title_adm_audit_profile', 'search-location', 1, 0, 4),
+('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);
+
+-- GRIDS: Pricing
+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_prices_manage', 'Sql', 'SELECT * FROM `bx_organizations_prices` WHERE 1 ', 'bx_organizations_prices', 'id', 'order', '', '', 100, NULL, 'start', '', 'period,period_unit,price', '', 'like', '', '', 2147483647, 'BxOrgsGridPricesManage', 'modules/boonex/organizations/classes/BxOrgsGridPricesManage.php'),
+('bx_organizations_prices_view', 'Sql', 'SELECT * FROM `bx_organizations_prices` WHERE 1 ', 'bx_organizations_prices', 'id', 'order', '', '', 100, NULL, 'start', '', 'period,period_unit,price', '', 'like', '', '', 2147483647, 'BxOrgsGridPricesView', 'modules/boonex/organizations/classes/BxOrgsGridPricesView.php');
+
+INSERT INTO `sys_grid_fields` (`object`, `name`, `title`, `width`, `translatable`, `chars_limit`, `params`, `order`) VALUES
+('bx_organizations_prices_manage', 'checkbox', '_sys_select', '1%', 0, '', '', 1),
+('bx_organizations_prices_manage', 'order', '', '1%', 0, '', '', 2),
+('bx_organizations_prices_manage', 'name', '_bx_orgs_grid_column_title_name', '38%', 0, 32, '', 3),
+('bx_organizations_prices_manage', 'price', '_bx_orgs_grid_column_title_price', '20%', 0, 16, '', 4),
+('bx_organizations_prices_manage', 'period', '_bx_orgs_grid_column_title_period', '20%', 0, 16, '', 5),
+('bx_organizations_prices_manage', 'actions', '', '20%', 0, '', '', 6),
+
+('bx_organizations_prices_view', 'role_id', '_bx_orgs_grid_column_title_role_id', '40%', 0, 32, '', 1),
+('bx_organizations_prices_view', 'price', '_bx_orgs_grid_column_title_price', '20%', 0, 16, '', 2),
+('bx_organizations_prices_view', 'period', '_bx_orgs_grid_column_title_period', '20%', 0, 16, '', 3),
+('bx_organizations_prices_view', 'actions', '', '20%', 0, '', '', 4);
+
+INSERT INTO `sys_grid_actions` (`object`, `type`, `name`, `title`, `icon`, `icon_only`, `confirm`, `order`) VALUES
+('bx_organizations_prices_manage', 'independent', 'add', '_bx_orgs_grid_action_title_add', '', 0, 0, 1),
+('bx_organizations_prices_manage', 'single', 'edit', '_bx_orgs_grid_action_title_edit', 'pencil-alt', 1, 0, 1),
+('bx_organizations_prices_manage', 'single', 'delete', '_bx_orgs_grid_action_title_delete', 'remove', 1, 1, 2),
+('bx_organizations_prices_manage', 'bulk', 'delete', '_bx_orgs_grid_action_title_delete', '', 0, 1, 1),
+
+('bx_organizations_prices_view', 'single', 'buy', '_bx_orgs_grid_action_title_buy', 'cart-plus', 0, 0, 1),
+('bx_organizations_prices_view', 'single', 'subscribe', '_bx_orgs_grid_action_title_subscribe', 'credit-card', 0, 0, 2),
+('bx_organizations_prices_view', 'single', 'choose', '_bx_orgs_grid_action_title_choose', 'far check-square', 0, 0, 3);
+
+
+-- 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_score', @iHandler),
+('bx_organizations', 'timeline_report', @iHandler),
+('bx_organizations', 'timeline_repost', @iHandler),
+('bx_organizations', 'timeline_pin', @iHandler),
+('bx_organizations', 'timeline_promote', @iHandler);
+
+
+-- PRIVACY 
+INSERT INTO `sys_objects_privacy` (`object`, `module`, `action`, `title`, `default_group`, `spaces`, `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'),
+('bx_organizations_allow_post_to', 'bx_organizations', 'post', '_bx_orgs_form_profile_input_allow_post_to', '5', '', 'bx_organizations_data', 'id', 'author', 'BxOrgsPrivacyPost', 'modules/boonex/organizations/classes/BxOrgsPrivacyPost.php'),
+('bx_organizations_allow_contact_to', 'bx_organizations', 'contact', '_bx_orgs_form_profile_input_allow_contact_to', '3', '', 'bx_organizations_data', 'id', 'author', 'BxOrgsPrivacyContact', 'modules/boonex/organizations/classes/BxOrgsPrivacyContact.php'),
+('bx_organizations_allow_view_favorite_list', 'bx_organizations', 'view_favorite_list', '_bx_orgs_form_entry_input_allow_view_favorite_list', '3', '', 'bx_organizations_favorites_lists', 'id', 'author_id', 'BxOrgsPrivacy', 'modules/boonex/organizations/classes/BxOrgsPrivacy.php');
+
+
+-- EMAIL TEMPLATES
+INSERT INTO `sys_email_templates` (`Module`, `NameSystem`, `Name`, `Subject`, `Body`) VALUES
+('bx_organizations', '_bx_orgs_email_friend_request', 'bx_organizations_friend_request', '_bx_orgs_email_friend_request_subject', '_bx_orgs_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_set_role', 'bx_organizations_set_role', '_bx_orgs_email_set_role_subject', '_bx_orgs_email_set_role_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');
+
+
+-- CRON
+INSERT INTO `sys_cron_jobs` (`name`, `time`, `class`, `file`, `service_call`) VALUES
+('bx_organizations_pruning', '0 0 * * *', 'BxOrgsCronPruning', 'modules/boonex/organizations/classes/BxOrgsCronPruning.php', '');

+ 554 - 0
modules/boonex/organizations/updates/13.0.0_13.0.1/source/install/sql/install.sql

@@ -0,0 +1,554 @@
+
+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,
+  `multicat` text NOT NULL,
+  `org_desc` text NOT NULL,
+  `labels` text NOT NULL,
+  `location` text NOT NULL,
+  `views` int(11) NOT NULL default '0',
+  `rate` float NOT NULL default '0',
+  `votes` int(11) NOT NULL default '0',
+  `score` int(11) NOT NULL default '0',
+  `sc_up` int(11) NOT NULL default '0',
+  `sc_down` int(11) NOT NULL default '0',
+  `favorites` int(11) NOT NULL default '0',
+  `comments` int(11) NOT NULL default '0',
+  `reports` int(11) NOT NULL default '0',
+  `featured` int(11) NOT NULL default '0',
+  `join_confirmation` tinyint(4) NOT NULL DEFAULT '1',
+  `allow_view_to` varchar(16) NOT NULL DEFAULT '3',
+  `allow_post_to` varchar(16) NOT NULL DEFAULT '5',
+  `allow_contact_to` varchar(16) NOT NULL DEFAULT '3',
+  `status` enum('active','awaiting','hidden') NOT NULL DEFAULT 'active',
+  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` bigint(20) NOT NULL,
+  `added` int(11) NOT NULL,
+  `modified` int(11) NOT NULL,
+  `private` int(11) NOT NULL,
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `remote_id` (`remote_id`)
+);
+
+CREATE TABLE IF NOT EXISTS `bx_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` bigint(20) NOT NULL,
+  `added` int(11) NOT NULL,
+  `modified` int(11) NOT NULL,
+  `private` int(11) NOT NULL,
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `remote_id` (`remote_id`)
+);
+
+-- TABLE: comments
+CREATE TABLE IF NOT EXISTS `bx_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(11) NOT NULL DEFAULT '0',
+  `cmt_level` int(11) NOT NULL DEFAULT '0',
+  `cmt_text` text NOT NULL,
+  `cmt_mood` tinyint(4) NOT NULL DEFAULT '0',
+  `cmt_rate` int(11) NOT NULL DEFAULT '0',
+  `cmt_rate_count` int(11) NOT NULL DEFAULT '0',
+  `cmt_time` int(11) unsigned NOT NULL DEFAULT '0',
+  `cmt_replies` int(11) NOT NULL DEFAULT '0',
+  `cmt_pinned` int(11) NOT NULL default '0',
+  `cmt_cf` int(11) NOT NULL default '1',
+  PRIMARY KEY (`cmt_id`),
+  KEY `cmt_object_id` (`cmt_object_id`,`cmt_parent_id`),
+  FULLTEXT KEY `search_fields` (`cmt_text`)
+);
+
+CREATE TABLE IF NOT EXISTS `bx_organizations_cmts_notes` (
+  `cmt_id` int(11) NOT NULL AUTO_INCREMENT,
+  `cmt_parent_id` int(11) NOT NULL DEFAULT '0',
+  `cmt_vparent_id` int(11) NOT NULL DEFAULT '0',
+  `cmt_object_id` int(11) NOT NULL DEFAULT '0',
+  `cmt_author_id` int(11) NOT NULL DEFAULT '0',
+  `cmt_level` int(11) NOT NULL DEFAULT '0',
+  `cmt_text` text NOT NULL,
+  `cmt_mood` tinyint(4) NOT NULL DEFAULT '0',
+  `cmt_rate` int(11) NOT NULL DEFAULT '0',
+  `cmt_rate_count` int(11) NOT NULL DEFAULT '0',
+  `cmt_time` int(11) unsigned NOT NULL DEFAULT '0',
+  `cmt_replies` int(11) NOT NULL DEFAULT '0',
+  `cmt_pinned` int(11) NOT NULL default '0',
+  PRIMARY KEY (`cmt_id`),
+  KEY `cmt_object_id` (`cmt_object_id`,`cmt_parent_id`),
+  FULLTEXT KEY `search_fields` (`cmt_text`)
+);
+
+-- TABLE: VIEWS
+CREATE TABLE IF NOT EXISTS `bx_organizations_views_track` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `object_id` int(11) NOT NULL default '0',
+  `viewer_id` int(11) NOT NULL default '0',
+  `viewer_nip` int(11) unsigned NOT NULL default '0',
+  `date` int(11) NOT NULL default '0',
+  PRIMARY KEY (`id`),
+  KEY `id` (`object_id`,`viewer_id`,`viewer_nip`)
+);
+
+-- TABLE: VOTES
+CREATE TABLE IF NOT EXISTS `bx_organizations_votes` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `object_id` int(11) NOT NULL default '0',
+  `count` int(11) NOT NULL default '0',
+  `sum` int(11) NOT NULL default '0',
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `object_id` (`object_id`)
+);
+
+CREATE TABLE IF NOT EXISTS `bx_organizations_votes_track` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `object_id` int(11) NOT NULL default '0',
+  `author_id` int(11) NOT NULL default '0',
+  `author_nip` int(11) unsigned NOT NULL default '0',
+  `value` tinyint(4) NOT NULL default '0',
+  `date` int(11) NOT NULL default '0',
+  PRIMARY KEY (`id`),
+  KEY `vote` (`object_id`, `author_nip`)
+);
+
+-- TABLE: favorites
+CREATE TABLE IF NOT EXISTS `bx_organizations_favorites_track` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `object_id` int(11) NOT NULL default '0',
+  `author_id` int(11) NOT NULL default '0',
+  `list_id` int(11) NOT NULL default '0',
+  `date` int(11) NOT NULL default '0',
+  PRIMARY KEY (`id`),
+  KEY `id` (`object_id`,`author_id`)
+);
+
+CREATE TABLE IF NOT EXISTS `bx_organizations_favorites_lists` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `title` varchar(255) NOT NULL,
+  `author_id` int(11) NOT NULL default '0',
+  `date` int(11) NOT NULL default '0',
+  `allow_view_favorite_list_to` varchar(16) NOT NULL DEFAULT '3',
+   PRIMARY KEY (`id`)
+);
+
+-- TABLE: reports
+CREATE TABLE IF NOT EXISTS `bx_organizations_reports` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `object_id` int(11) NOT NULL default '0',
+  `count` int(11) NOT NULL default '0',
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `object_id` (`object_id`)
+);
+
+CREATE TABLE IF NOT EXISTS `bx_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',
+  `checked_by` int(11) NOT NULL default '0',
+  `status` tinyint(11) NOT NULL default '0',
+  PRIMARY KEY (`id`),
+  KEY `report` (`object_id`, `author_nip`)
+);
+
+-- TABLE: metas
+CREATE TABLE IF NOT EXISTS `bx_organizations_meta_keywords` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `object_id` int(10) unsigned NOT NULL,
+  `keyword` varchar(255) NOT NULL,
+  PRIMARY KEY (`id`),
+  KEY `object_id` (`object_id`),
+  KEY `keyword` (`keyword`)
+);
+
+CREATE TABLE 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))
+);
+
+CREATE TABLE `bx_organizations_meta_mentions` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `object_id` int(10) unsigned NOT NULL,
+  `profile_id` int(10) unsigned NOT NULL,
+  PRIMARY KEY (`id`),
+  KEY `object_id` (`object_id`),
+  KEY `profile_id` (`profile_id`)
+);
+
+-- TABLE: 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`)
+);
+
+-- 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,
+  `role` int(10) unsigned NOT NULL default '0',
+  `order` varchar(32) NOT NULL default '',
+  `added` int(11) unsigned NOT NULL default '0',
+  `expired` int(11) unsigned NOT NULL default '0',
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `admin` (`group_profile_id`,`fan_id`)
+);
+
+-- TABLE: scores
+CREATE TABLE IF NOT EXISTS `bx_organizations_scores` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `object_id` int(11) NOT NULL default '0',
+  `count_up` int(11) NOT NULL default '0',
+  `count_down` int(11) NOT NULL default '0',
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `object_id` (`object_id`)
+);
+
+CREATE TABLE IF NOT EXISTS `bx_organizations_scores_track` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `object_id` int(11) NOT NULL default '0',
+  `author_id` int(11) NOT NULL default '0',
+  `author_nip` int(11) unsigned NOT NULL default '0',
+  `type` varchar(8) NOT NULL default '',
+  `date` int(11) NOT NULL default '0',
+  PRIMARY KEY (`id`),
+  KEY `vote` (`object_id`, `author_nip`)
+);
+
+-- TABLE: Pricing
+CREATE TABLE IF NOT EXISTS `bx_organizations_prices` (
+  `id` int(11) NOT NULL auto_increment,
+  `profile_id` int(11) NOT NULL default '0',
+  `role_id` int(11) unsigned NOT NULL default '0',
+  `name` varchar(128) NOT NULL default '',
+  `period` int(11) unsigned NOT NULL default '1',
+  `period_unit` varchar(32) NOT NULL default '',
+  `price` float unsigned NOT NULL default '1',
+  `order` int(11) NOT NULL,
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `name` (`name`),
+  UNIQUE KEY `type` (`profile_id`, `role_id`,`period`, `period_unit`)
+);
+
+
+-- 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_avatar_big', '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:"30";s:1:"h";s:2:"30";s:13:"square_resize";s:1:"1";}', '0'),
+('bx_organizations_thumb', 'Resize', 'a:3:{s:1:"w";s:2:"50";s:1:"h";s:2:"50";s:13:"square_resize";s:1:"1";}', '0'),
+('bx_organizations_avatar', 'Resize', 'a:3:{s:1:"w";s:3:"100";s:1:"h";s:3:"100";s:13:"square_resize";s:1:"1";}', '0'),
+('bx_organizations_avatar_big', 'Resize', 'a:3:{s:1:"w";s:3:"200";s:1:"h";s:3:"200";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:2:{s:1:"w";s:3:"960";s:1:"h";s:3:"480";}', '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', 'allow_post_to', 5, '', 0, 'custom', '_bx_orgs_form_profile_input_sys_allow_post_to', '_bx_orgs_form_profile_input_allow_post_to', '', 0, 0, 0, '', '', '', '', '', '', '', '', 1, 0),
+('bx_organization', 'bx_organizations', 'allow_contact_to', 3, '', 0, 'custom', '_bx_orgs_form_profile_input_sys_allow_contact_to', '_bx_orgs_form_profile_input_allow_contact_to', '', 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, 1, '', '', '', '', '', '', 'XssHtml', '', 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', 'multicat', '', '', 0, 'custom', '_bx_orgs_form_entry_input_sys_multicat', '_bx_orgs_form_entry_input_multicat', '', 1, 0, 0, '', '', '', 'avail', '', '_bx_orgs_form_entry_input_multicat_err', 'Xss', '', 1, 0),
+('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, '', '', '', 'ProfileName', '', '_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', '', 0, 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', '', 0, 0),
+('bx_organization', 'bx_organizations', 'profile_ip', '', '', 0, 'text', '_bx_orgs_form_profile_input_sys_profile_ip', '_bx_orgs_form_profile_input_profile_ip', '', 0, 0, 0, '', '', '', '', '', '', 'Xss', '', 0, 0),
+('bx_organization', 'bx_organizations', 'labels', '', '', 0, 'custom', '_sys_form_input_sys_labels', '_sys_form_input_labels', '', 0, 0, 0, '', '', '', '', '', '', '', '', 1, 0),
+('bx_organization', 'bx_organizations', 'added', '', '', 0, 'datetime', '_bx_orgs_form_profile_input_sys_date_added', '_bx_orgs_form_profile_input_date_added', '', 0, 0, 0, '', '', '', '', '', '', '', '', 1, 0),
+('bx_organization', 'bx_organizations', 'changed', '', '', 0, 'datetime', '_bx_orgs_form_profile_input_sys_date_changed', '_bx_orgs_form_profile_input_date_changed', '', 0, 0, 0, '', '', '', '', '', '', '', '', 1, 0),
+('bx_organization', 'bx_organizations', 'friends_count', '', '', 0, 'text', '_bx_orgs_form_profile_input_sys_friends_count', '_bx_orgs_form_profile_input_friends_count', '', 0, 0, 0, '', '', '', '', '', '', '', '', 1, 0),
+('bx_organization', 'bx_organizations', 'followers_count', '', '', 0, 'text', '_bx_orgs_form_profile_input_sys_followers_count', '_bx_orgs_form_profile_input_followers_count', '', 0, 0, 0, '', '', '', '', '', '', '', '', 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', 'allow_post_to', 2147483647, 1, 9),
+('bx_organization_add', 'allow_contact_to', 2147483647, 1, 10),
+('bx_organization_add', 'do_submit', 2147483647, 1, 11),
+
+('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', 'allow_post_to', 2147483647, 1, 8),
+('bx_organization_edit', 'allow_contact_to', 2147483647, 1, 9),
+('bx_organization_edit', 'do_submit', 2147483647, 1, 10),
+
+('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', 'profile_ip', 192, 1, 5),
+('bx_organization_view', 'added', 192, 1, 6),
+('bx_organization_view', 'changed', 192, 1, 7),
+('bx_organization_view', 'friends_count', 2147483647, 1, 8),
+('bx_organization_view', 'followers_count', 2147483647, 1, 9),
+
+('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, 0, 3),
+('bx_organization_view_full', 'profile_email', 192, 1, 4),
+('bx_organization_view_full', 'profile_status', 192, 1, 5);
+
+-- FORMS: Price
+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_organizations_price', 'bx_organizations', '_bx_orgs_form_price', '', '', 'do_submit', 'bx_organizations_prices', 'id', '', '', '', 0, 1, 'BxOrgsFormPrice', 'modules/boonex/organizations/classes/BxOrgsFormPrice.php');
+
+INSERT INTO `sys_form_displays` (`display_name`, `module`, `object`, `title`, `view_mode`) VALUES
+('bx_organizations_price_add', 'bx_organizations', 'bx_organizations_price', '_bx_orgs_form_price_display_add', 0),
+('bx_organizations_price_edit', 'bx_organizations', 'bx_organizations_price', '_bx_orgs_form_price_display_edit', 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_organizations_price', 'bx_organizations', 'id', '', '', 0, 'hidden', '_bx_orgs_form_price_input_sys_id', '', '', 1, 0, 0, '', '', '', '', '', '', 'Int', '', 1, 0),
+('bx_organizations_price', 'bx_organizations', 'role_id', '', '', 0, 'hidden', '_bx_orgs_form_price_input_sys_role_id', '', '', 1, 0, 0, '', '', '', '', '', '', 'Int', '', 1, 0),
+('bx_organizations_price', 'bx_organizations', 'name', '', '', 0, 'text', '_bx_orgs_form_price_input_sys_name', '_bx_orgs_form_price_input_name', '_bx_orgs_form_price_input_inf_name', 1, 0, 0, '', '', '', 'Avail', '', '_bx_orgs_form_price_input_err_name', 'Xss', '', 1, 0),
+('bx_organizations_price', 'bx_organizations', 'period', '', '', 0, 'text', '_bx_orgs_form_price_input_sys_period', '_bx_orgs_form_price_input_period', '_bx_orgs_form_price_input_inf_period', 1, 0, 0, '', '', '', '', '', '', 'Int', '', 1, 0),
+('bx_organizations_price', 'bx_organizations', 'period_unit', '', '#!bx_organizations_period_units', 0, 'select', '_bx_orgs_form_price_input_sys_period_unit', '_bx_orgs_form_price_input_period_unit', '_bx_orgs_form_price_input_inf_period_unit', 1, 0, 0, '', '', '', '', '', '', 'Xss', '', 1, 0),
+('bx_organizations_price', 'bx_organizations', 'price', '', '', 0, 'price', '_bx_orgs_form_price_input_sys_price', '_bx_orgs_form_price_input_price', '_bx_orgs_form_price_input_inf_price', 1, 0, 0, '', '', '', '', '', '', 'Float', '', 1, 0),
+('bx_organizations_price', 'bx_organizations', 'controls', '', 'do_submit,do_cancel', 0, 'input_set', '', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 1, 0),
+('bx_organizations_price', 'bx_organizations', 'do_submit', '_bx_orgs_form_price_input_do_submit', '', 0, 'submit', '_bx_orgs_form_price_input_sys_do_submit', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 1, 0),
+('bx_organizations_price', 'bx_organizations', 'do_cancel', '_bx_orgs_form_price_input_do_cancel', '', 0, 'button', '_bx_orgs_form_price_input_sys_do_cancel', '', '', 0, 0, 0, 'a:2:{s:7:"onclick";s:45:"$(''.bx-popup-applied:visible'').dolPopupHide()";s:5:"class";s:22:"bx-def-margin-sec-left";}', '', '', '', '', '', '', '', 1, 0);
+
+INSERT INTO `sys_form_display_inputs` (`display_name`, `input_name`, `visible_for_levels`, `active`, `order`) VALUES
+('bx_organizations_price_add', 'id', 2147483647, 0, 1),
+('bx_organizations_price_add', 'role_id', 2147483647, 1, 2),
+('bx_organizations_price_add', 'name', 2147483647, 1, 3),
+('bx_organizations_price_add', 'price', 2147483647, 1, 4),
+('bx_organizations_price_add', 'period', 2147483647, 1, 5),
+('bx_organizations_price_add', 'period_unit', 2147483647, 1, 6),
+('bx_organizations_price_add', 'controls', 2147483647, 1, 7),
+('bx_organizations_price_add', 'do_submit', 2147483647, 1, 8),
+('bx_organizations_price_add', 'do_cancel', 2147483647, 1, 9),
+
+('bx_organizations_price_edit', 'id', 2147483647, 1, 1),
+('bx_organizations_price_edit', 'role_id', 2147483647, 1, 2),
+('bx_organizations_price_edit', 'name', 2147483647, 1, 3),
+('bx_organizations_price_edit', 'price', 2147483647, 1, 4),
+('bx_organizations_price_edit', 'period', 2147483647, 1, 5),
+('bx_organizations_price_edit', 'period_unit', 2147483647, 1, 6),
+('bx_organizations_price_edit', 'controls', 2147483647, 1, 7),
+('bx_organizations_price_edit', 'do_submit', 2147483647, 1, 8),
+('bx_organizations_price_edit', 'do_cancel', 2147483647, 1, 9);
+
+-- 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', '');
+
+INSERT INTO `sys_form_pre_lists`(`key`, `title`, `module`, `use_for_sets`) VALUES
+('bx_organizations_roles', '_bx_orgs_pre_lists_roles', 'bx_organizations', '1');
+
+INSERT INTO `sys_form_pre_values`(`Key`, `Value`, `Order`, `LKey`, `LKey2`) VALUES
+('bx_organizations_roles', '0', 1, '_bx_orgs_role_regular', ''),
+('bx_organizations_roles', '1', 2, '_bx_orgs_role_administrator', ''),
+('bx_organizations_roles', '2', 3, '_bx_orgs_role_moderator', '');
+
+INSERT INTO `sys_form_pre_lists`(`key`, `title`, `module`, `use_for_sets`) VALUES
+('bx_organizations_period_units', '_bx_orgs_pre_lists_period_units', 'bx_organizations', '0');
+
+INSERT INTO `sys_form_pre_values`(`Key`, `Value`, `Order`, `LKey`, `LKey2`) VALUES
+('bx_organizations_period_units', '', 0, '_sys_please_select', ''),
+('bx_organizations_period_units', 'day', 1, '_bx_orgs_period_unit_day', ''),
+('bx_organizations_period_units', 'week', 2, '_bx_orgs_period_unit_week', ''),
+('bx_organizations_period_units', 'month', 3, '_bx_orgs_period_unit_month', ''),
+('bx_organizations_period_units', 'year', 4, '_bx_orgs_period_unit_year', '');
+
+-- COMMENTS
+INSERT INTO `sys_objects_cmts` (`Name`, `Module`, `Table`, `CharsPostMin`, `CharsPostMax`, `CharsDisplayMax`, `Html`, `PerView`, `PerViewReplies`, `BrowseType`, `IsBrowseSwitch`, `PostFormPosition`, `NumberOfLevels`, `IsDisplaySwitch`, `IsRatable`, `ViewingThreshold`, `IsOn`, `RootStylePrefix`, `BaseUrl`, `ObjectVote`, `TriggerTable`, `TriggerFieldId`, `TriggerFieldAuthor`, `TriggerFieldTitle`, `TriggerFieldComments`, `ClassName`, `ClassFile`) VALUES
+('bx_organizations', 'bx_organizations', 'bx_organizations_cmts', 1, 5000, 1000, 3, 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', 'BxOrgsCmts', 'modules/boonex/organizations/classes/BxOrgsCmts.php'),
+('bx_organizations_notes', 'bx_organizations', 'bx_organizations_cmts_notes', 1, 5000, 1000, 0, 5, 3, 'tail', 1, 'bottom', 1, 1, 1, -3, 1, 'cmt', 'page.php?i=view-post&id={object_id}', '', 'bx_organizations_data', 'id', 'author', 'org_name', '', 'BxTemplCmtsNotes', '');
+
+
+-- VIEWS
+INSERT INTO `sys_objects_view` (`name`, `module`, `table_track`, `period`, `is_on`, `trigger_table`, `trigger_field_id`, `trigger_field_author`, `trigger_field_count`, `class_name`, `class_file`) VALUES 
+('bx_organizations', 'bx_organizations', 'bx_organizations_views_track', '86400', '1', 'bx_organizations_data', 'id', 'author', 'views', '', '');
+
+
+-- VOTES
+INSERT INTO `sys_objects_vote` (`Name`, `TableMain`, `TableTrack`, `PostTimeout`, `MinValue`, `MaxValue`, `IsUndo`, `IsOn`, `TriggerTable`, `TriggerFieldId`, `TriggerFieldAuthor`, `TriggerFieldRate`, `TriggerFieldRateCount`, `ClassName`, `ClassFile`) VALUES 
+('bx_organizations', 'bx_organizations_votes', 'bx_organizations_votes_track', '604800', '1', '1', '0', '1', 'bx_organizations_data', 'id', '', 'rate', 'votes', 'BxOrgsVote', 'modules/boonex/organizations/classes/BxOrgsVote.php');
+
+
+-- SCORES
+INSERT INTO `sys_objects_score` (`name`, `module`, `table_main`, `table_track`, `post_timeout`, `is_on`, `trigger_table`, `trigger_field_id`, `trigger_field_author`, `trigger_field_score`, `trigger_field_cup`, `trigger_field_cdown`, `class_name`, `class_file`) VALUES 
+('bx_organizations', 'bx_organizations', 'bx_organizations_scores', 'bx_organizations_scores_track', '604800', '0', 'bx_organizations_data', 'id', 'author', 'score', 'sc_up', 'sc_down', '', '');
+
+
+-- FAFORITES
+INSERT INTO `sys_objects_favorite` (`name`, `table_track`, `table_lists`, `is_on`, `is_undo`, `is_public`, `base_url`, `trigger_table`, `trigger_field_id`, `trigger_field_author`, `trigger_field_count`, `class_name`, `class_file`) VALUES 
+('bx_organizations', 'bx_organizations_favorites_track', 'bx_organizations_favorites_lists', '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`, `module`, `is_on`, `is_undo`, `base_url`, `trigger_table`, `trigger_field_id`, `trigger_field_author`, `trigger_field_flag`, `class_name`, `class_file`) VALUES 
+('bx_organizations', '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`, `module`, `table_main`, `table_track`, `is_on`, `base_url`, `object_comment`, `trigger_table`, `trigger_field_id`, `trigger_field_author`, `trigger_field_count`, `class_name`, `class_file`) VALUES 
+('bx_organizations', 'bx_organizations', 'bx_organizations_reports', 'bx_organizations_reports_track', '1', 'page.php?i=view-organization-profile&id={object_id}', 'bx_organizations_notes', 'bx_organizations_data', 'id', 'author', 'reports', 'BxOrgsReport', 'modules/boonex/organizations/classes/BxOrgsReport.php');
+
+
+-- 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`, `type`, `url`, `click`, `icon`, `caption`, `cnt_notices`, `cnt_actions`) VALUES
+(@iPageId, 'bx_organizations', 'users', '{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));

+ 51 - 0
modules/boonex/payment/updates/13.0.0_13.0.1/install/config.php

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

+ 23 - 0
modules/boonex/payment/updates/13.0.0_13.0.1/install/installer.php

@@ -0,0 +1,23 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ */
+
+class BxPaymentUpdater extends BxDolStudioUpdater
+{
+    function __construct($aConfig)
+    {
+        parent::__construct($aConfig);
+    }
+
+    public function actionExecuteSql($sOperation)
+    {
+        if($sOperation == 'install') {
+            if(!$this->oDb->isFieldExists('bx_payment_user_values', 'id'))
+                $this->oDb->query("ALTER TABLE `bx_payment_user_values` ADD `id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT FIRST");
+        }
+
+        return parent::actionExecuteSql($sOperation);
+    }
+}

+ 4 - 0
modules/boonex/payment/updates/13.0.0_13.0.1/install/langs/en.xml

@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources name="en" flag="gb" title="English">
+	<string_add name="_bx_payment_cbee_msg_charged"><![CDATA[Payment was successfully processed.]]></string_add>
+</resources>

+ 5 - 0
modules/boonex/payment/updates/13.0.0_13.0.1/install/sql/install.sql

@@ -0,0 +1,5 @@
+SET @sName = 'bx_payment';
+
+
+-- TABLES
+UPDATE `bx_payment_providers` SET `for_single`='1' WHERE `name`='chargebee_v3';

+ 1707 - 0
modules/boonex/payment/updates/13.0.0_13.0.1/source/classes/BxPaymentModule.php

@@ -0,0 +1,1707 @@
+<?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_RESULT_SUCCESS', 0);
+
+/*
+ * Subscriptions: statuses.
+ */
+define('BX_PAYMENT_SBS_STATUS_SCHEDULED', 'scheduled');
+define('BX_PAYMENT_SBS_STATUS_TRIAL', 'trial');
+define('BX_PAYMENT_SBS_STATUS_ACTIVE', 'active');
+define('BX_PAYMENT_SBS_STATUS_UNPAID', 'unpaid');
+define('BX_PAYMENT_SBS_STATUS_PAUSED', 'paused');
+define('BX_PAYMENT_SBS_STATUS_CANCELED', 'canceled');
+define('BX_PAYMENT_SBS_STATUS_UNKNOWN', 'unknown');
+
+/*
+ * Subscriptions: period units.
+ */
+define('BX_PAYMENT_SBS_PU_YEAR', 'year');
+define('BX_PAYMENT_SBS_PU_MONTH', 'month');
+define('BX_PAYMENT_SBS_PU_WEEK', 'week');
+define('BX_PAYMENT_SBS_PU_DAY', 'day');
+define('BX_PAYMENT_SBS_PU_HOUR', 'hour');
+define('BX_PAYMENT_SBS_PU_MINUTE', 'minute');
+
+/*
+ * Invoice: statuses.
+ */
+define('BX_PAYMENT_INV_STATUS_UNPAID', 'unpaid');
+define('BX_PAYMENT_INV_STATUS_PAID', 'paid');
+define('BX_PAYMENT_INV_STATUS_OVERDUE', 'overdue');
+
+
+/**
+ * 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)
+        ));
+    }
+
+    public function actionGetFilterValuesItem($iSellerId, $iModuleId)
+    {
+        $sItems = '<option value="">' . _t('_bx_payment_txt_all_items') . '</option>';
+
+        if(empty($iSellerId) || empty($iModuleId))
+            return echoJson(array('code' => 1, 'content' => $sItems));
+
+        $aItems = $this->callGetCartItems((int)$iModuleId, array($iSellerId));
+
+        $this->_oConfig->sortByColumn('title', $aItems);
+
+        foreach($aItems as $aItem)
+            $sItems .= '<option value="' . $aItem['id'] . '">' . $aItem['title'] . '</option>';
+
+        echoJson(array('code' => 0, 'content' => $sItems));
+    }
+
+    public function serviceGetSafeServices()
+    {
+        $a = parent::serviceGetSafeServices();
+        return array_merge($a, array (
+            'GetBlockJoin' => 'BxPaymentJoin',
+            'GetBlockCarts' => 'BxPaymentCart',
+            'GetBlockCart' => 'BxPaymentCart',
+            'GetBlockCartHistory' => 'BxPaymentCart',
+            'GetBlockListMy' => 'BxPaymentSubscriptions',
+            'GetBlockHistory' => 'BxPaymentSubscriptions',
+        ));
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_payment Payment
+     * @subsection bx_payment-purchase_processing Purchase Processing
+     * @subsubsection bx_payment-get_modules_with_payments get_modules_with_payments
+     * 
+     * @code bx_srv('bx_payment', 'get_modules_with_payments', []); @endcode
+     * 
+     * Get modules with payments functionality
+     *
+     * @return array with modules names
+     * 
+     * @see BxPaymentModule::serviceGetModulesWithPayments
+     */
+    /** 
+     * @ref bx_payment-get_modules_with_payments "get_modules_with_payments"
+     */
+    public function serviceGetModulesWithPayments()
+    {
+        return $this->_oDb->getModulesWithPayments();
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_payment Payment
+     * @subsection bx_payment-purchase_processing Purchase Processing
+     * @subsubsection bx_payment-is_credits_only is_credits_only
+     * 
+     * @code bx_srv('bx_payment', 'is_credits_only'); @endcode
+     * 
+     * Check whether the 'Credits Only' mode is enabled or not.
+     *
+     * @return boolean value determining the result of checking.
+     * 
+     * @see BxPaymentModule::serviceIsCreditsOnly
+     */
+    /** 
+     * @ref bx_payment-is_credits_only "is_credits_only"
+     */
+    public function serviceIsCreditsOnly()
+    {
+        return $this->_oConfig->isCreditsOnly();
+    }
+
+    /**
+     * @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;
+    }
+
+    /** 
+     * @deprecated since version 11.0.0
+     * 
+     * @see BxPaymentModule::serviceIsProviderOptions
+     */
+    public function serviceIsPaymentProvider($iVendorId, $sVendorProvider, $sPaymentType = '')
+    {
+    	return $this->serviceIsProviderOptions($iVendorId, $sVendorProvider, $sPaymentType);
+    }
+
+    /** 
+     * @deprecated since version 11.0.0
+     * 
+     * @see BxPaymentModule::serviceGetProviderOptions
+     */
+    public function serviceGetPaymentProvider($iVendorId, $sVendorProvider, $sPaymentType = '')
+    {
+    	return $this->serviceGetProviderOptions($iVendorId, $sVendorProvider, $sPaymentType);
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_payment Payment
+     * @subsection bx_payment-purchase_processing Purchase Processing
+     * @subsubsection bx_payment-is_provider_options is_provider_options
+     * 
+     * @code bx_srv('bx_payment', 'is_provider_options', [...]); @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::serviceIsProviderOptions
+     */
+    /** 
+     * @ref bx_payment-is_provider_options "is_provider_options"
+     */
+    public function serviceIsProviderOptions($iVendorId, $sVendorProvider, $sPaymentType = '')
+    {
+    	$aProvider = $this->serviceGetProviderOptions($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_provider_options get_provider_options
+     * 
+     * @code bx_srv('bx_payment', 'get_provider_options', [...]); @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::serviceGetProviderOptions
+     */
+    /** 
+     * @ref bx_payment-get_provider_options "get_provider_options"
+     */
+    public function serviceGetProviderOptions($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;
+    }
+
+    public function serviceGetMenuAddonManageTools()
+    {
+        return array(
+            'counter1_value' => (int)$this->_oDb->getInvoices(array('type' => 'status', 'status' => BX_PAYMENT_INV_STATUS_PAID, 'count' => true)), 
+            'counter1_caption' => _t('_bx_payment_menu_item_title_admt_addon_counter1_caption'), 
+            'counter2_value' => (int)$this->_oDb->getInvoices(array('type' => 'status', 'status' => BX_PAYMENT_INV_STATUS_OVERDUE, 'count' => true)), 
+            'counter2_caption' => _t('_bx_payment_menu_item_title_admt_addon_counter2_caption'), 
+            'counter3_value' => (int)$this->_oDb->getInvoices(array('type' => 'all_count'))
+        );
+    }
+
+    public function serviceGetBlockCheckoutOffline()
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        $oBuyer = BxDolProfile::getInstance();
+        if(!$oBuyer)
+            return MsgBox(_t('_bx_payment_err_required_login'));
+        
+        $iSeller = (int)bx_get('seller');
+        $oSeller = BxDolProfile::getInstance($iSeller);
+        if(!$oSeller)
+            return MsgBox(_t('_bx_payment_err_unknown_vendor'));
+
+        $aData = array(
+            'seller' => $iSeller,
+            'currency' => array(
+                'code' => bx_process_input(bx_get('currency_code')),
+                'sign' => bx_process_input(bx_get('currency_sign')),
+            ),
+            'amount' => (float)bx_get('amount'),
+            'return_url' => bx_process_input(bx_get('return_url')),
+        );
+
+        if(empty($aData['currency']['code']))
+            $aData['currency']['code'] = $this->_oConfig->getDefaultCurrencyCode();
+
+        if(empty($aData['currency']['sign']))
+            $aData['currency']['sign'] = $this->_oConfig->getDefaultCurrencySign();
+
+        $sItems = '';
+        $iItemsCount = (int)bx_get('items_count');
+        for($i = 0; $i < $iItemsCount; $i++) {
+            $aItem = array(
+                'title' => bx_process_input(bx_get('item_title_' . $i)),
+                'quantity' => (int)bx_get('item_quantity_' . $i)
+            );
+
+            $sItems .= _t('_bx_payment_txt_checkout_item', $aItem['title'], $aItem['quantity']);
+            $aData['items'][] = $aItem;
+        }
+
+        $aTemplate = BxDolEmailTemplates::getInstance()->parseTemplate($this->_oConfig->getPrefix('general') . 'checkout_offline', array(
+            'profile_name' => $oBuyer->getDisplayName(),
+            'profile_link' => $oBuyer->getUrl(),
+            'items' => $sItems,
+            'amount' => $aData['currency']['sign'] . sprintf("%.2f", (float)($aData['amount'])),
+            'date' => bx_time_js(time(), BX_FORMAT_DATE, true),
+            'pending_orders_link' => $this->getObjectOrders()->serviceGetPendingOrdersUrl()
+        ), 0, $iSeller);
+
+        $sEmail = '';
+        $oProvider = $this->getObjectProvider($CNF['OBJECT_PP_OFFLINE'], $iSeller);
+        if($oProvider !== false && $oProvider->isActive())
+            $sEmail = $oProvider->getOption('checkout_email');
+
+        if(empty($sEmail))
+            $sEmail = $oBuyer->getAccountObject()->getEmail();
+
+        if(!sendMail($sEmail, $aTemplate['Subject'], $aTemplate['Body'], 0, array(), BX_EMAIL_SYSTEM))
+            return MsgBox(_t('_bx_payment_err_cannot_perform'));
+
+        return $this->_oTemplate->displayBlockCheckoutOffline($oBuyer, $oSeller, $aData);
+    }
+
+    /**
+     * 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)
+    {
+        echoJson($this->getObjectCart()->serviceDeleteFromCart($iSellerId, $iModuleId, $iItemId));
+    }
+
+    /**
+     * Isn't used yet.
+     */
+    public function actionEmptyCart($iSellerId)
+    {
+        echoJson($this->getObjectCart()->serviceDeleteFromCart($iSellerId));
+    }
+
+    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;
+
+        $sItemAddons = '';
+        if(bx_get('item_addons') !== false) {
+            $sItemAddons = bx_process_input(bx_get('item_addons'));
+            if(is_array($sItemAddons))
+                $sItemAddons = $this->_oConfig->a2s($sItemAddons);
+        }
+
+        $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();
+        }
+
+        echoJson($this->getObjectSubscriptions()->serviceSubscribeWithAddons($iSellerId, $sSellerProvider, $iModuleId, $iItemId, $iItemCount, $sItemAddons, $sRedirect, $aCustom));
+    }
+
+    public function actionSubscriptionGetDetails($iId)
+    {
+        echoJson($this->_oTemplate->displaySubscriptionGetDetails($iId));
+    }
+
+    public function actionSubscriptionChangeDetails($iId)
+    {
+        echoJson($this->_oTemplate->displaySubscriptionChangeDetails($iId));
+    }
+
+    public function actionSubscriptionGetBilling($iId)
+    {
+        echoJson($this->_oTemplate->displaySubscriptionGetBilling($iId));
+    }
+
+    public function actionSubscriptionChangeBilling($iId)
+    {
+        echoJson($this->_oTemplate->displaySubscriptionChangeBilling($iId));
+    }
+
+    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);
+
+        $mixedResult = $this->isAllowedManage($aPending);
+        if($mixedResult !== true)
+            return echoJson(array('code' => 2, 'message' => $mixedResult));
+
+        $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_add'], 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')));
+    }
+
+    public function actionSubscriptionCancel($iId, $mixedGridObject = false)
+    {
+        $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);
+
+        $mixedResult = $this->isAllowedManage($aPending);
+        if($mixedResult !== true)
+            return echoJson(array('code' => 2, 'message' => $mixedResult));
+
+        if(!$this->getObjectSubscriptions()->cancel($iId))
+            return echoJson($aResult);
+
+        if(empty($mixedGridObject) && bx_get('grid') !== false)
+            $mixedGridObject = bx_process_input(bx_get('grid'));
+
+        if(!empty($mixedGridObject) && $aPending['client_id'] == $this->getProfileId()) {
+            $oGrid = BxDolGrid::getObjectInstance($mixedGridObject, $this->_oTemplate);
+            $oGrid->addQueryParam('client_id', $aPending['client_id']);
+
+            return echoJson(array('object' => $mixedGridObject, 'grid' => $oGrid->getCode(false), 'blink' => array($iId)));
+        }
+        else
+            return echoJson(array('code' => 0, 'message' => _t('_bx_payment_msg_successfully_performed')));
+    }
+
+    /**
+     * 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;
+    }
+
+    public function actionInitializeCheckoutJson($sType)
+    {
+    	if(!$this->isLogged())
+            return echoJson(['code' => 1, 'message' => _t($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 === false)
+                return echoJson(['code' => 2, 'message' => _t($this->_sLangsPrefix . 'err_cannot_perform')]);
+            if(is_string($mixedResult))
+                return echoJson(['code' => 3, 'message' => $mixedResult]);
+            else if(is_array($mixedResult))
+                return echoJson($mixedResult);
+        }
+
+        return echoJson(['code' => 0, 'redirect' => $this->_oConfig->getUrl('URL_CART')]);
+    }
+
+    /**
+     * @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(!empty($aItemInfo) && is_array($aItemInfo)) {
+                    if(!empty($aItemInfo['addons']) && is_array($aItemInfo['addons']))
+                        foreach($aItemInfo['addons'] as $sAddon => $aAddon)
+                            $this->callRegisterCartItem((int)$aAddon['module_id'], array($aInfo['client_id'], $aInfo['vendor_id'], $aAddon['id'], $aAddon['quantity'], $this->_oConfig->getLicense(), $aCartItemCustom));
+
+                    $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($aItem['author_id'], $aItem['module_id'], $aItem['id']));
+                $aCartItemCustom = $this->_oConfig->getCustom($sCartItem, $aCartCustoms);
+                $this->_oConfig->putCustom($sCartItem, $aCartItemCustom, $aCustoms);
+            }
+        }
+
+        $this->alert('before_pending', 0, bx_get_logged_profile_id(), array(
+            'client_id' => $this->_iUserId,
+            'type' => &$sType,
+            'provider' => &$sProvider,
+            'cart_info' => &$aInfo,
+            'custom' => &$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) {
+            $sStatus = BX_PAYMENT_SBS_STATUS_UNPAID;
+            if(isset($aResult['paid']) && $aResult['paid'])
+                $sStatus = BX_PAYMENT_SBS_STATUS_ACTIVE;
+            else if(isset($aResult['trial']) && $aResult['trial'])
+                $sStatus = BX_PAYMENT_SBS_STATUS_TRIAL;
+
+            $aSubscription = array(
+                'customer_id' => $aResult['customer_id'], 
+                'subscription_id' => $aResult['subscription_id'],
+                'status' => $sStatus
+            );
+
+            if(!$this->getObjectSubscriptions()->register($aPending, $aSubscription))
+                return $this->_oTemplate->displayPageCodeError($this->_sLangsPrefix . 'err_already_registered');
+        }
+
+        $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);
+
+        $this->alert('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'],
+            'result' => &$aResult,
+        ));
+
+        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();
+    }
+    
+    /**
+     * The method is needed to pass direct action calls to necessary Payment Provider.
+     */
+    public function actionCall($sProvider, $sAction, $mixedVendorId = BX_PAYMENT_EMPTY_ID)
+    {
+        $oProvider = $this->getObjectProvider($sProvider, $mixedVendorId);
+        if($oProvider === false)
+            BxDolRequest::methodNotFound($sAction, $this->getName());
+
+         $sMethod = 'action' . bx_gen_method_name($sAction);
+         if(!method_exists($oProvider, $sMethod))
+             BxDolRequest::methodNotFound($sAction, $this->getName());
+
+        return call_user_func_array(array($oProvider, $sMethod), array_slice(func_get_args(), 2));
+    }
+
+    public function onProfileJoin($iProfileId)
+    {
+    	$this->getObjectJoin()->onProfileJoin($iProfileId);
+    }
+
+    public function onProfileDelete($iProfileId)
+    {
+        //--- Cancel subscriptions
+        $aSubscriptions = $this->_oDb->getSubscription(['type' => 'mixed_ext', 'conditions' => ['client_id' => $iProfileId]]);
+        if(!empty($aSubscriptions) && is_array($aSubscriptions)) 
+            foreach($aSubscriptions as $aSubscription)
+                $this->getObjectSubscriptions()->cancel($aSubscription['pending_id']);
+
+        //--- Clean DB
+        $this->_oDb->onProfileDelete($iProfileId);
+    }
+
+    public function isAllowedPurchase($aItem, $bPerform = false)
+    {
+        $iUserId = (int)$this->getProfileId();
+
+        $aItemInfo = $this->callGetCartItem((int)$aItem['module_id'], array($aItem['item_id'], isset($aItem['custom']) ? $aItem['custom'] : array()));
+        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((int)$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 isAllowedManage($aPending, $bPerform = false)
+    {
+        $iUserId = (int)$this->getProfileId();
+
+        if($iUserId == $aPending['client_id'] || $iUserId == $aPending['seller_id'] || isAdmin())
+            return true;
+
+        $aCheckResult = checkActionModule($iUserId, 'manage any purchase', $this->getName(), $bPerform);
+        if($aCheckResult[CHECK_ACTION_RESULT] == CHECK_ACTION_RESULT_ALLOWED)
+            return true;
+
+        return $aCheckResult[CHECK_ACTION_MESSAGE];
+    }
+
+    public function isAllowedManageInvoices($bPerform = false)
+    {
+        if(BxDolAcl::getInstance()->isMemberLevelInSet(array(MEMBERSHIP_ID_MODERATOR, MEMBERSHIP_ID_ADMINISTRATOR)) || isAdmin())
+            return true;
+
+        return _t('_sys_txt_access_denied');
+    }
+
+    public function checkData($iClientId, $iSellerId, $iModuleId, $iItemId, $iItemCount, $aCustom = array())
+    {
+    	$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, 'custom' => $aCustom));
+        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'],
+                'author_id' => $aItem['vendor_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;
+    }
+
+    /**
+     * @deprecated since version 12.0.0
+     * 
+     * @use BxPaymentSubscriptions::register instead.
+     */
+    public function registerSubscription($aPending, $aParams = array())
+    {
+        return $this->getObjectSubscriptions()->register($aPending, $aParams);
+    }
+
+    /**
+     * @deprecated since version 12.0.0
+     * 
+     * @use BxPaymentSubscriptions::cancelLocal instead.
+     */
+    public function cancelSubscription($mixedPending)
+    {
+        return $this->getObjectSubscriptions()->cancelLocal($mixedPending);
+    }
+
+    public function processCommissions()
+    {
+        if(!defined('BX_DOL_CRON_EXECUTE'))
+            return;
+
+        $CNF = &$this->_oConfig->CNF;
+
+        if((int)date('j') == $this->_oConfig->getInvoiceIssueDay())
+            $this->_invoicesIssue();
+
+        $this->_invoicesCheck();
+    }
+
+    protected function _invoicesIssue()
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        $sInvoiceNameMask = 'INV-%d-%d-%d';
+
+        $iMonth = date('m');
+        $iYear = date('Y');
+        $iPeriodStart = mktime(0, 0, 0, $iMonth-1, 1, $iYear);
+        $iPeriodEnd = mktime(23, 59, 59, $iMonth, 0, $iYear);
+        $iDateIssue = time();
+        $iDateDue = $iDateIssue + 86400 * $this->_oConfig->getInvoiceLifetime();
+
+        $aCommissionsInfo = array();
+        $aAclLevels = BxDolAcl::getInstance()->getMemberships(false, true, false, true);
+        foreach($aAclLevels as $iAclLevelId => $sAclLevelTitle)
+            $aCommissionsInfo[$iAclLevelId] = $this->_oDb->getCommissions(array('type' => 'acl_id', 'acl_id' => $iAclLevelId));
+
+        $iMainSellerId = $this->_oConfig->getSiteAdmin();
+
+        $aVendors = $this->_oDb->getOrderProcessed(array('type' => 'income', 'period_start' => $iPeriodStart, 'period_end' => $iPeriodEnd));
+        foreach($aVendors as $aVendor) {
+            $iVendorId = (int)$aVendor['id'];
+            if($iVendorId == $iMainSellerId)
+                continue;
+
+            $aInvoice = $this->_oDb->getInvoices(array('type' => 'committent_id', 'committent_id' => $iVendorId, 'period_start' => $iPeriodStart, 'period_end' => $iPeriodEnd));
+            if(!empty($aInvoice) && is_array($aInvoice))
+                continue;
+
+            $aVendorAcl = BxDolAcl::getInstance()->getMemberMembershipInfo($iVendorId);
+            $aCommissions = $aCommissionsInfo[$aVendorAcl['id']];
+
+            $fCommission = 0;
+            foreach($aCommissions as $aCommission) {
+                if((float)$aCommission['percentage'] > 0)
+                    $fCommission += (float)$aVendor['amount'] * (float)$aCommission['percentage'] / 100;
+
+                if((float)$aCommission['installment'] > 0)
+                    $fCommission += (float)$aCommission['installment'];
+            }
+            
+            $this->alert('calculate_commission', 0, 0, array(
+                'vendor' => $aVendor,
+                'commissions' => $aCommissions,
+                'override_result' => &$fCommission,
+            ));
+
+            $this->_oDb->insertInvoice(array(
+                'name' => sprintf($sInvoiceNameMask, $iMainSellerId, $iVendorId, $this->_oDb->getInvoices(array(
+                    'type' => 'index', 
+                    'commissionaire_id' => $iMainSellerId, 
+                    'committent_id' => $iVendorId
+                ))),
+                'commissionaire_id' => $iMainSellerId, 
+                'committent_id' => $iVendorId,
+                'amount' => $fCommission,
+                'period_start' => $iPeriodStart,
+                'period_end' => $iPeriodEnd,
+                'date_issue' => $iDateIssue,
+                'date_due' => $iDateDue,
+                'status' => BX_PAYMENT_INV_STATUS_UNPAID
+            ));
+        }
+    }
+
+    protected function _invoicesCheck()
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        $sPrefix = $this->_oConfig->getPrefix('general');
+        $oEmailTemplates = BxDolEmailTemplates::getInstance();
+
+        //--- Process expiring invoices.
+        $aInvoices = $this->_oDb->getInvoices(array('type' => 'expiring'));
+        if(!empty($aInvoices) && is_array($aInvoices))
+            foreach($aInvoices as $aInvoice) {
+                if((int)$aInvoice['ntf_exp'] > 0)
+                    continue;
+
+                $oCommittent = BxDolProfile::getInstance($aInvoice['committent_id']);
+                if(!$oCommittent)
+                    continue;
+
+                $bResult = sendMailTemplate($sPrefix . 'expiring_notification_committent', 0, (int)$aInvoice['committent_id'], array(
+                    'invoice' => $aInvoice['name'],
+                    'days' => $this->_oConfig->getInvoiceExpirationNotify(),
+                    'period_start' => $this->_oConfig->formatDate($aInvoice['period_start']),
+                    'period_end' => $this->_oConfig->formatDate($aInvoice['period_end']),
+                    'date_issue' => $this->_oConfig->formatDateTime($aInvoice['date_issue']),
+                    'date_due' => $this->_oConfig->formatDateTime($aInvoice['date_due']),
+                ), BX_EMAIL_NOTIFY, true);
+
+                if($bResult)
+                    $this->_oDb->updateInvoice($aInvoice['id'], array('ntf_exp' => 1));
+            }
+
+        //--- Process overdue invoices.
+        $aInvoices = $this->_oDb->getInvoices(array('type' => 'overdue'));
+        if(!empty($aInvoices) && is_array($aInvoices))
+            foreach($aInvoices as $aInvoice) {
+                if((int)$aInvoice['ntf_due'] > 0 && $aInvoice['status'] == BX_PAYMENT_INV_STATUS_OVERDUE)
+                    continue;
+
+                $oCommittent = BxDolProfile::getInstance($aInvoice['committent_id']);
+                if(!$oCommittent)
+                    continue;
+
+                $bResult = sendMailTemplate($sPrefix . 'overdue_notification_committent', 0, (int)$aInvoice['committent_id'], array(
+                    'invoice' => $aInvoice['name'],
+                    'period_start' => $this->_oConfig->formatDate($aInvoice['period_start']),
+                    'period_end' => $this->_oConfig->formatDate($aInvoice['period_end']),
+                    'date_issue' => $this->_oConfig->formatDateTime($aInvoice['date_issue']),
+                    'date_due' => $this->_oConfig->formatDateTime($aInvoice['date_due']),
+                ), BX_EMAIL_NOTIFY, true);
+
+                $this->_oDb->updateInvoice($aInvoice['id'], array(
+                    'status' => BX_PAYMENT_INV_STATUS_OVERDUE, 
+                    'ntf_due' => $bResult ? 1 : 0
+                ));
+            }
+    }
+
+    public function processTimeTracker()
+    {
+        if(!defined('BX_DOL_CRON_EXECUTE'))
+            return;
+
+        $aSubscriptions = $this->_oDb->getSubscription(array(
+            'type' => 'time_tracker',
+            'status_active' => BX_PAYMENT_SBS_STATUS_ACTIVE,
+            'status_trial' => BX_PAYMENT_SBS_STATUS_TRIAL,
+            'status_unpaid' => BX_PAYMENT_SBS_STATUS_UNPAID,
+            'pay_attempts_max' => $this->_oConfig->getPayAttemptsMax(),
+            'pay_attempts_interval' => $this->_oConfig->getPayAttemptsInterval()
+        ));
+
+        if(empty($aSubscriptions) || !is_array($aSubscriptions))
+            return;
+
+        foreach($aSubscriptions as $aSubscription) {
+            $aPending = $this->_oDb->getOrderPending(array('type' => 'id', 'id' => (int)$aSubscription['pending_id']));
+            if(empty($aPending) || !is_array($aPending) || $aPending['type'] != BX_PAYMENT_TYPE_RECURRING) {
+                $this->log($aSubscription, 'Time Tracker', 'Cannot process subscription.');
+                continue;
+            }
+
+            $oProvider = $this->getObjectProvider($aPending['provider'], $aPending['seller_id']);
+            if($oProvider === false || !$oProvider->isActive() || !method_exists($oProvider, 'makePayment')) {
+                $this->log($aSubscription, 'Time Tracker', 'Payment provider unavailable or incorrect.');
+                continue;
+            }
+
+            if(!$oProvider->makePayment($aPending)) {
+                $this->log($aSubscription, 'Time Tracker', 'Payment cannot be processed.');
+                continue;
+            }
+
+            if(!$this->getObjectSubscriptions()->prolong($aPending)) {
+                $this->log($aSubscription, 'Time Tracker', 'Cannot prolong subscription.');
+                continue;
+            }
+
+            if(!$this->registerPayment($aPending)) {
+                $this->log($aSubscription, 'Time Tracker', 'Cannot register payment.');
+                continue;
+            }
+        }
+    }
+
+    public function onPaymentRegisterBefore($aPending, $aResult = array())
+    {
+        $this->alert('before_register_payment', 0, $aPending['client_id'], array('pending' => $aPending));
+    }
+
+    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);
+        }
+
+        $this->alert('register_payment', 0, $aPending['client_id'], array('pending' => $aPending));
+    }
+
+    public function onPaymentRefund($aPending, $aResult = array())
+    {
+        $this->alert('refund_payment', 0, $aPending['client_id'], array('pending' => $aPending));
+    }
+
+    public function onSubscriptionCreate($aPending, $aSubscription, $aResult = array())
+    {
+        $aItems = $this->_oConfig->descriptorsM2A($aPending['items']);
+        $this->isAllowedPurchase(array('module_id' => $aItems[0]['module_id'], 'item_id' => $aItems[0]['item_id']), true);
+
+        $this->alert('create_subscription', 0, $aPending['client_id'], array(
+            'pending' => $aPending,
+            'subscription' => $aSubscription
+        ));
+    }
+
+    public function onSubscriptionProlong($aPending, $aSubscription, $aResult = array())
+    {
+        $this->alert('prolong_subscription', 0, $aPending['client_id'], array(
+            'pending' => $aPending,
+            'subscription' => $aSubscription
+        ));
+    }
+
+    public function onSubscriptionOverdue($aPending, $aSubscription, $aResult = array())
+    {
+        $this->alert('overdue_subscription', 0, $aPending['client_id'], array(
+            'pending' => $aPending,
+            'subscription' => $aSubscription
+        ));
+    }
+
+    public function onSubscriptionCancel($aPending, $aSubscription, $aResult = array())
+    {
+        $this->alert('cancel_subscription', 0, $aPending['client_id'], array(
+            'pending' => $aPending,
+            'subscription' => $aSubscription
+        ));
+    }
+
+    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);
+    }
+
+    public function getProviderButtonJs($aCartItem, $aProvider, $sRedirect = '', $aCustom = array())
+    {
+        $aButtonJs = array();
+        $iClientId = $this->getProfileId();
+
+        $sItemAddons = '';
+        if(count($aCartItem) == 5)
+            $sItemAddons = array_pop($aCartItem);
+
+        list($iSellerId, $iModuleId, $iItemId, $iItemCount) = $aCartItem;
+
+        $oProvider = $this->getObjectProvider($aProvider['name'], $iSellerId);
+        if($oProvider !== false && method_exists($oProvider, 'getButtonRecurring')) {
+            $aParams = array(
+                'sObjNameCart' => $this->_oConfig->getJsObject('cart'),
+                'iSellerId' => $iSellerId,
+                'iModuleId' => $iModuleId,
+                'iItemId' => $iItemId,
+                'iItemCount' => $iItemCount,
+                'sItemAddons' => $sItemAddons,
+                'sRedirect' => $sRedirect,
+                'sCustom' => base64_encode(serialize($aCustom))
+            );
+
+            $aCartInfo = $this->getObjectCart()->getInfo(BX_PAYMENT_TYPE_RECURRING, $iClientId, $iSellerId, $this->_oConfig->descriptorA2S($aCartItem));
+            if(!empty($aCartInfo['items_price']) && !empty($aCartInfo['items']) && is_array($aCartInfo['items'])) {
+                $aItem = array_shift($aCartInfo['items']);
+
+                $aParams = array_merge($aParams, array(
+                    'iAmount' => (int)round(100 * (float)$aCartInfo['items_price']),
+                    'sItemName' => $aItem['name'],
+                    'sItemTitle' => $aItem['title']
+                ));
+            }
+
+            $aButtonJs = $oProvider->getButtonRecurringJs($iClientId, $iSellerId, $aParams);
+        }
+
+        if(empty($aButtonJs) || !is_array($aButtonJs))
+            $aButtonJs = $this->getObjectSubscriptions()->serviceGetSubscribeJs($iSellerId, $aProvider['name'], $iModuleId, $iItemId, $iItemCount, $sRedirect, $aCustom);
+
+        return $aButtonJs;
+    }
+
+    /**
+     * Integration with itslef which is needed to pay an invoice.
+     */
+
+    /**
+     * @page service Service Calls
+     * @section bx_payment Payment
+     * @subsection bx_payment-payments Payments
+     * @subsubsection bx_payment-get_payment_data get_payment_data
+     * 
+     * @code bx_srv('bx_payment', '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 BxPaymentModule::serviceGetPaymentData
+     */
+    /** 
+     * @ref bx_payment-get_payment_data "get_payment_data"
+     */
+    public function serviceGetPaymentData()
+    {
+        return $this->_aModule;
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_payment Payment
+     * @subsection bx_payment-payments Payments
+     * @subsubsection bx_payment-get_cart_item get_cart_item
+     * 
+     * @code bx_srv('bx_payment', 'get_cart_item', [...]); @endcode
+     * 
+     * Get an array with prodict's description. Is used in Shopping Cart in payments processing module.
+     * 
+     * @param $mixedItemId product's ID or Unique Name.
+     * @return an array with prodict's description. Empty array is returned if something is wrong.
+     * 
+     * @see BxPaymentModule::serviceGetCartItem
+     */
+    /** 
+     * @ref bx_payment-get_cart_item "get_cart_item"
+     */
+    public function serviceGetCartItem($mixedItemId)
+    {
+    	$CNF = &$this->_oConfig->CNF;
+
+        if(!$mixedItemId)
+            return array();
+
+        if(is_numeric($mixedItemId))
+            $aItem = $this->_oDb->getInvoices(array('type' => 'id', 'id' => (int)$mixedItemId));
+        else 
+            $aItem = $this->_oDb->getInvoices(array('type' => 'name', 'name' => $mixedItemId));
+
+        if(empty($aItem) || !is_array($aItem))
+            return array();
+
+        $oCommissionaire = BxDolProfile::getInstanceMagic($aItem['commissionaire_id']);
+
+        return array (
+            'id' => $aItem['id'],
+            'author_id' => $aItem['commissionaire_id'],
+            'name' => $aItem['name'],
+            'title' => _t('_bx_payment_txt_invoice_title', $aItem['name'], $oCommissionaire->getDisplayName()),
+            'description' => _t('_bx_payment_txt_invoice_description', bx_process_output($aItem['period_start'], BX_DATA_DATE_TS_UTC), bx_process_output($aItem['period_end'], BX_DATA_DATE_TS_UTC)),
+            'url' => '',
+            'price_single' => $aItem['amount'],
+            'price_recurring' => '',
+            'period_recurring' => 0,
+            'period_unit_recurring' => '',
+            'trial_recurring' => ''
+        );
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_payment Payment
+     * @subsection bx_payment-payments Payments
+     * @subsubsection bx_payment-get_cart_items get_cart_items
+     * 
+     * @code bx_srv('bx_payment', 'get_cart_items', [...]); @endcode
+     * 
+     * Get an array with prodicts' descriptions by seller. Is used in Manual Order Processing in payments processing module.
+     * 
+     * @param $iCommissionaireId commissionaire ID.
+     * @return an array with prodicts' descriptions. Empty array is returned if something is wrong or seller doesn't have any products.
+     * 
+     * @see BxPaymentModule::serviceGetCartItems
+     */
+    /** 
+     * @ref bx_payment-get_cart_items "get_cart_items"
+     */
+    public function serviceGetCartItems($iCommissionaireId)
+    {
+    	$CNF = &$this->_oConfig->CNF;
+
+        $iCommissionaireId = (int)$iCommissionaireId;
+        if(empty($iCommissionaireId))
+            return array();
+
+        $sCommissionaireName = BxDolProfile::getInstanceMagic($iCommissionaireId)->getDisplayName();
+
+        $aItems = $this->_oDb->getInvoices(array('type' => 'commissionaire_id', 'commissionaire_id' => $iCommissionaireId));      
+
+        $aResult = array();
+        foreach($aItems as $aItem)
+            $aResult[] = array(
+                'id' => $aItem['id'],
+                'author_id' => $aItem['commissionaire_id'],
+                'name' => $aItem['name'],
+                'title' => _t('_bx_payment_txt_invoice_title', $aItem['name'], $sCommissionaireName),
+                'description' => _t('_bx_payment_txt_invoice_description', bx_process_output($aItem['period_start'], BX_DATA_DATE_TS_UTC), bx_process_output($aItem['period_end'], BX_DATA_DATE_TS_UTC)),
+                'url' => '',
+                'price_single' => $aItem['amount'],
+                'price_recurring' => '',
+                'period_recurring' => 0,
+                'period_unit_recurring' => '',
+                'trial_recurring' => ''
+            );
+
+        return $aResult;
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_payment Payment
+     * @subsection bx_payment-payments Payments
+     * @subsubsection bx_payment-register_cart_item register_cart_item
+     * 
+     * @code bx_srv('bx_payment', 'register_cart_item', [...]); @endcode
+     * 
+     * Register a processed single time payment inside the Payment 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 BxPaymentModule::serviceRegisterCartItem
+     */
+    /** 
+     * @ref bx_payment-register_cart_item "register_cart_item"
+     */
+    public function serviceRegisterCartItem($iClientId, $iSellerId, $iItemId, $iItemCount, $sOrder, $sLicense)
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+    	$aItem = $this->serviceGetCartItem($iItemId);
+        if(empty($aItem) || !is_array($aItem))
+            return array();
+
+        if(!$this->_oDb->updateInvoice($iItemId, array('status' => BX_PAYMENT_INV_STATUS_PAID)))
+            return array();
+
+        $this->alert('invoice_marked_as_paid', 0, false, array(
+            'product_id' => $iItemId,
+            'profile_id' => $iClientId,
+            'order' => $sOrder,
+            'license' => $sLicense,
+            'type' => BX_PAYMENT_TYPE_SINGLE,
+            'count' => $iItemCount,
+            'duration' => '',
+            'trial' => ''
+        ));
+
+        return $aItem;
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_payment Payment
+     * @subsection bx_payment-payments Payments
+     * @subsubsection bx_payment-unregister_cart_item unregister_cart_item
+     * 
+     * @code bx_srv('bx_payment', 'unregister_cart_item', [...]); @endcode
+     * 
+     * Unregister an earlier processed single time payment inside the Payment 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 BxPaymentModule::serviceUnregisterCartItem
+     */
+    /** 
+     * @ref bx_payment-unregister_cart_item "unregister_cart_item"
+     */
+    public function serviceUnregisterCartItem($iClientId, $iSellerId, $iItemId, $iItemCount, $sOrder, $sLicense)
+    {
+        if(!$this->_oDb->updateInvoice($iItemId, array('status' => BX_PAYMENT_INV_STATUS_UNPAID)))
+            return false;
+
+        $this->alert('invoice_marked_as_unpaid', 0, false, array(
+            'product_id' => $iItemId,
+            'profile_id' => $iClientId,
+            'order' => $sOrder,
+            'license' => $sLicense,
+            'type' => BX_PAYMENT_TYPE_SINGLE,
+            'count' => $iItemCount
+        ));
+
+    	return true;
+    }
+    
+}
+
+/** @} */

+ 239 - 0
modules/boonex/payment/updates/13.0.0_13.0.1/source/classes/BxPaymentOrders.php

@@ -0,0 +1,239 @@
+<?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) && bx_get('type') !== false)
+            $sType = bx_process_input(bx_get('type'));
+        
+        if(empty($sType) || !in_array($sType, array(BX_PAYMENT_ORDERS_TYPE_PENDING, BX_PAYMENT_ORDERS_TYPE_PROCESSED)))
+            $sType = 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 serviceProcessOrder($iSellerId, $iClientId, $iModuleId, $aItems, $sType, $sOrder)
+    {
+        $mixedResult = $this->addOrder(array(
+            'client_id' => $iClientId,
+            'seller_id' => $iSellerId,
+            'provider' => 'manual',
+            'type' => $sType,
+            'order' => $sOrder,
+            'error_code' => 0,
+            'error_msg' => 'Manually processed',        		
+            'module_id' => $iModuleId,
+            'items' => $aItems
+        ));
+
+        if(is_array($mixedResult))
+            return false;
+
+        return $this->_oModule->registerPayment((int)$mixedResult);
+    }
+
+    public function serviceProcessOrderByPending($iPendingId, $sOrder)
+    {
+        $this->_oModule->_oDb->updateOrderPending($iPendingId, array(
+            'order' => $sOrder,
+            'error_code' => 0,
+            'error_msg' => 'Manually processed'
+        ));
+
+        return $this->_oModule->registerPayment($iPendingId);
+    }
+
+    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(
+                'author_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;
+
+        $this->_oModule->alert('cancel_order', $aOrder['id'], $aOrder['seller_id'], array(
+            'type' => $sType,
+            'order' => $aOrder
+        ));
+
+        return true;
+    }
+}
+
+/** @} */

+ 539 - 0
modules/boonex/payment/updates/13.0.0_13.0.1/source/classes/BxPaymentProviderChargebee.php

@@ -0,0 +1,539 @@
+<?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('CBEE_MODE_LIVE', 1);
+define('CBEE_MODE_TEST', 2);
+
+use ChargeBee\ChargeBee\Environment;
+use ChargeBee\ChargeBee\Models\Addon;
+use ChargeBee\ChargeBee\Models\Customer;
+use ChargeBee\ChargeBee\Models\HostedPage;
+use ChargeBee\ChargeBee\Models\Subscription;
+use ChargeBee\ChargeBee\Models\Invoice;
+
+class BxPaymentProviderChargebee extends BxBaseModPaymentProvider implements iBxBaseModPaymentProvider
+{
+    protected $_iMode;
+    protected $_bCheckAmount;
+
+    function __construct($aConfig)
+    {
+    	$this->MODULE = 'bx_payment';
+
+        parent::__construct($aConfig);   
+
+        $this->_aSbsStatuses = array(
+            'future' => BX_PAYMENT_SBS_STATUS_SCHEDULED, 
+            'in_trial' => BX_PAYMENT_SBS_STATUS_TRIAL, 
+            'active' => BX_PAYMENT_SBS_STATUS_ACTIVE, 
+            'non_renewing' => BX_PAYMENT_SBS_STATUS_ACTIVE, 
+            'paused' => BX_PAYMENT_SBS_STATUS_PAUSED,
+            'canceled' => BX_PAYMENT_SBS_STATUS_CANCELED,
+        );
+    }
+
+    public function initOptions($aOptions)
+    {
+    	parent::initOptions($aOptions);
+
+    	$this->_iMode = (int)$this->getOption('mode');
+        $this->_bCheckAmount = $this->getOption('check_amount') == 'on';
+        $this->_bUseSsl = $this->getOption('ssl') == 'on';
+    }
+
+    public function initializeCheckout($iPendingId, $aCartInfo)
+    {
+    	$aItem = array_shift($aCartInfo['items']);
+    	if(empty($aItem) || !is_array($aItem))
+            return $this->_sLangsPrefix . 'err_empty_items';
+
+        $aClient = $this->_oModule->getProfileInfo();
+        $aVendor = $this->_oModule->getProfileInfo($aCartInfo['vendor_id']);
+
+        $oPage = $this->createHostedPageRecurring($aItem, $aClient, $aVendor, $iPendingId);
+        if($oPage === false)
+            return $this->_sLangsPrefix . 'err_cannot_perform';
+
+        return array(
+            'code' => 0,
+            'eval' => $this->_oModule->_oConfig->getJsObject('cart') . '.onSubscribeSubmit(oData);',
+            'redirect' => $oPage->url
+        );
+    }
+
+    public function finalizeCheckout(&$aData)
+    {
+        $sPageId = bx_process_input($aData['id']);
+        $iPendingId = bx_process_input($aData['pending_id'], BX_DATA_INT);
+
+        if(empty($sPageId) || empty($iPendingId))
+            return array('code' => 1, 'message' => $this->_sLangsPrefix . 'err_wrong_data');
+
+        $oPage = $this->retreiveHostedPage($sPageId);
+        if($oPage === false)
+                return $this->_sLangsPrefix . 'err_cannot_perform';
+
+        $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');
+
+        $oCustomer = $oPage->content()->customer();
+        $oSubscription = $oPage->content()->subscription();
+
+        $aResult = array(
+            'code' => BX_PAYMENT_RESULT_SUCCESS,
+            'message' => $this->_sLangsPrefix . 'cbee_msg_subscribed',
+            'pending_id' => $iPendingId,
+            'customer_id' => $oCustomer->id,
+            'subscription_id' => $oSubscription->id,
+            'client_name' => _t($this->_sLangsPrefix . 'txt_buyer_name_mask', $oCustomer->firstName, $oCustomer->lastName),
+            'client_email' => $oCustomer->email,
+            'paid' => false,
+            'trial' => $oSubscription->status == 'in_trial',
+        );
+
+        //--- Update pending transaction ---//
+        $this->_oModule->_oDb->updateOrderPending($iPendingId, array(
+            'order' => $oSubscription->id,
+            'error_code' => $aResult['code'],
+            'error_msg' => _t($aResult['message'])
+        ));
+
+        return $aResult;
+    }
+
+    public function notify()
+    {
+        $iResult = $this->_processEvent();
+        http_response_code($iResult);
+    }
+
+    public function cancelRecurring($iPendingId, $sCustomerId, $sSubscriptionId)
+    {
+        return $this->deleteSubscription($sSubscriptionId);
+    }
+
+    public function createHostedPageSingle($aItem, $aClient, $aVendor = array(), $iPendingId = 0)
+    {
+        $oPage = false;
+
+        try {
+            $aPage = [
+                'embed' => false, //--- Note. 'embed' should be disabled to allow payments via PayPal
+                'charges' => [
+                    [
+                        'amount' => $aItem['amount'], 
+                        'description' => $aItem['description'],
+                    ]
+                ],
+                'customer' => [
+                    'email' => $aClient['email'],
+                    'firstName' => $aClient['name']
+                ],
+            ];
+
+            if(!empty($aItem['addons']) && is_array($aItem['addons']))
+                $aPage['addons'] = $aItem['addons'];
+
+            if(!empty($aVendor) && is_array($aVendor) && !empty($aVendor))
+                $aPage['redirectUrl'] = bx_append_url_params($this->getReturnDataUrl($aVendor['id']), array(
+                    'pending_id' => $iPendingId
+                ));
+
+            Environment::configure($this->_getSite(), $this->_getApiKey());
+            $oResult = HostedPage::checkoutOneTime($aPage);
+
+            $oPage = $oResult->hostedPage();
+        }
+        catch (Exception $oException) {
+            $iError = $oException->getCode();
+            $sError = $oException->getMessage();
+
+            $this->log('Create Hosted Page Error: ' . $sError . '(' . $iError . ')');
+
+            return false;
+        }
+
+        return $oPage;
+    }
+
+    public function createHostedPageRecurring($aItem, $aClient, $aVendor = array(), $iPendingId = 0)
+    {
+        $oPage = false;
+
+        try {
+            $aPage = [
+                'embed' => false, //--- Note. 'embed' should be disabled to allow payments via PayPal
+                'subscription' => [
+                    'planId' => $aItem['name']
+                ],
+                'customer' => [
+                    'email' => $aClient['email'],
+                    'firstName' => $aClient['name']
+                ], 
+            ];
+
+            if(!empty($aItem['addons']) && is_array($aItem['addons']))
+                $aPage['addons'] = $aItem['addons'];
+
+            if(!empty($aVendor) && is_array($aVendor) && !empty($aVendor))
+                $aPage['redirectUrl'] = bx_append_url_params($this->getReturnDataUrl($aVendor['id']), array(
+                    'pending_id' => $iPendingId
+                ));
+
+            Environment::configure($this->_getSite(), $this->_getApiKey());
+            $oResult = HostedPage::checkoutNew($aPage);
+
+            $oPage = $oResult->hostedPage();
+        }
+        catch (Exception $oException) {
+            $iError = $oException->getCode();
+            $sError = $oException->getMessage();
+
+            $this->log('Create Hosted Page Error: ' . $sError . '(' . $iError . ')');
+
+            return false;
+        }
+
+        return $oPage;
+    }
+
+    public function retreiveHostedPage($sPageId)
+    {
+        $oPage = null;
+
+        try {
+            Environment::configure($this->_getSite(), $this->_getApiKey());
+            $oResult = HostedPage::retrieve($sPageId);
+
+            $oPage = $oResult->hostedPage();
+        }
+        catch (Exception $oException) {
+            $iError = $oException->getCode();
+            $sError = $oException->getMessage();
+
+            $this->log('Retrieve Hosted Page Error: ' . $sError . '(' . $iError . ')');
+
+            return false;
+        }
+
+        return $oPage;
+    }
+
+    public function retrieveSubscription($sSubscriptionId)
+    {
+        $oSubscription = null;
+
+        try {
+            Environment::configure($this->_getSite(), $this->_getApiKey());
+            $oResult = Subscription::retrieve($sSubscriptionId);
+
+            $oSubscription = $oResult->subscription();
+            if($oSubscription->id != $sSubscriptionId)
+                return false;
+        }
+        catch (Exception $oException) {
+            $iError = $oException->getCode();
+            $sError = $oException->getMessage();
+
+            $this->log('Retrieve Subscription Error: ' . $sError . '(' . $iError . ')');
+
+            return false;
+        }
+
+        return $oSubscription;
+    }
+
+    public function getSubscription($iPendingId, $sCustomerId, $sSubscriptionId)
+    {
+        $oSubscription = $this->retrieveSubscription($sSubscriptionId);
+        if($oSubscription === false)
+            return array();
+
+        $sStatus = $oSubscription->status;
+        $sStatus = isset($this->_aSbsStatuses[$sStatus]) ? $this->_aSbsStatuses[$sStatus] : BX_PAYMENT_SBS_STATUS_UNKNOWN;
+
+        return array(
+            'status' => $sStatus,
+            'created' => $oSubscription->createdAt,
+            'started' => $oSubscription->startedAt,
+            'trial_start' => $oSubscription->trialStart,
+            'trial_end' => $oSubscription->trialEnd,
+            'cperiod_start' => $oSubscription->currentTermStart,
+            'cperiod_end' => $oSubscription->currentTermEnd,
+        );
+    }
+    
+    public function deleteSubscription($sSubscriptionId)
+    {
+        try {
+            Environment::configure($this->_getSite(), $this->_getApiKey());
+            $oResult = Subscription::cancel($sSubscriptionId);
+
+            $oSubscription = $oResult->subscription();
+            if($oSubscription->status != 'cancelled')
+                return false;
+        }
+        catch (Exception $oException) {
+            $aError = $oException->getJsonBody();
+
+            $this->log('Delete Subscription Error: ' . $aError['error']['message']);
+            $this->log($aError);
+
+            return false;
+        }
+
+        $this->onDeleteSubscription($sSubscriptionId, $oSubscription->getValues());
+
+        return true;
+    }
+
+    public function retrieveInvoice($sInvoiceId)
+    {
+        $oInvoice = null;
+
+        try {
+            Environment::configure($this->_getSite(), $this->_getApiKey());
+            $oResult = Invoice::retrieve($sInvoiceId);
+
+            $oInvoice = $oResult->invoice();
+            if($oInvoice->id != $sInvoiceId)
+                return false;
+        }
+        catch (Exception $oException) {
+            $iError = $oException->getCode();
+            $sError = $oException->getMessage();
+
+            $this->log('Retrieve Invoice Error: ' . $sError . '(' . $iError . ')');
+
+            return false;
+        }
+
+        return $oInvoice;
+    }
+
+    public function retrieveAddons($sStatus = 'active', $iLimit = 0)
+    {
+        $aAddons = array();
+
+        try {
+            $aParams = array();
+            if(!empty($sStatus))
+                $aParams['status[is]'] = $sStatus;
+            if(!empty($iLimit))
+                $aParams['limit'] = $iLimit;
+            
+            Environment::configure($this->_getSite(), $this->_getApiKey());
+            $oResults = Addon::all($aParams);
+
+            foreach($oResults as $oResult)
+                $aAddons[] = $oResult->addon();
+        }
+        catch (Exception $oException) {
+            $iError = $oException->getCode();
+            $sError = $oException->getMessage();
+
+            $this->log('Retrieve Addons Error: ' . $sError . '(' . $iError . ')');
+
+            return false;
+        }
+
+        return $aAddons;
+    }
+
+    public function getAddons($sStatus = 'active', $iLimit = 0)
+    {
+        $aAddons = $this->retrieveAddons($sStatus, $iLimit);
+        if(empty($aAddons) || !is_array($aAddons))
+            return array();
+
+        $aResult = array();
+        foreach($aAddons as $oAddon)
+            $aResult[] = $oAddon->getValues();
+
+        return $aResult;
+    }
+
+    public function retrieveAddon($sId)
+    {
+        $oAddon = null;
+
+        try {
+            Environment::configure($this->_getSite(), $this->_getApiKey());
+            $oResult = Addon::retrieve($sId);
+
+            $oAddon = $oResult->addon();
+            if($oAddon->id != $sId)
+                return false;
+        }
+        catch (Exception $oException) {
+            $iError = $oException->getCode();
+            $sError = $oException->getMessage();
+
+            $this->log('Retrieve Addon Error: ' . $sError . '(' . $iError . ')');
+
+            return false;
+        }
+
+        return $oAddon;
+    }
+
+    public function getAddon($sId)
+    {
+        $oAddon = $this->retrieveAddon($sId);
+        if($oAddon === false)
+            return array();
+
+        return $oAddon->getValues();
+    }
+
+    public function retrieveCustomer($sCustomerId)
+    {
+        $oCustomer = null;
+
+        try {
+            Environment::configure($this->_getSite(), $this->_getApiKey());
+            $oResult = Customer::retrieve($sCustomerId);
+
+            $oCustomer = $oResult->customer();
+            if($oCustomer->id != $sCustomerId)
+                    return false;
+        }
+        catch (Exception $oException) {
+            $iError = $oException->getCode();
+            $sError = $oException->getMessage();
+
+            $this->log('Retrieve Customer Error: ' . $sError . '(' . $iError . ')');
+
+            return false;
+        }
+
+        return $oCustomer;
+    }
+
+    public function onDeleteSubscription($sSubscriptionId, $aSubscription)
+    {
+        bx_alert($this->_oModule->_oConfig->getName(), $this->_sName . '_cancel_subscription', 0, false, array(
+            'subscription_id' => $sSubscriptionId,
+            'subscription_info' => $aSubscription
+        ));
+    }
+
+
+    protected function _getSite()
+    {
+        return $this->_iMode == CBEE_MODE_LIVE ? $this->getOption('live_site') : $this->getOption('test_site');
+    }
+
+    protected function _getApiKey()
+    {
+        return $this->_iMode == CBEE_MODE_LIVE ? $this->getOption('live_api_key') : $this->getOption('test_api_key');
+    }
+
+    protected function _processEvent()
+    {
+        $sInput = @file_get_contents("php://input");
+        $aEvent = json_decode($sInput, true);
+        if(empty($aEvent) || !is_array($aEvent)) 
+            return 404;
+
+        $sType = $aEvent['event_type'];
+        if(!in_array($sType, array('payment_succeeded', ' payment_refunded', 'subscription_cancelled')))
+            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 _processEventPaymentSucceeded(&$aEvent)
+    {
+        $mixedResult = $this->_getDataTransaction($aEvent, 'success');
+        if($mixedResult === false)
+            return false;
+
+        list($aPending, $aTransaction) = $mixedResult;
+
+        $fTransactionAmount = (float)$aTransaction['amount'] / 100;
+        $sTransactionCurrency = strtoupper($aTransaction['currency_code']);
+        if($this->_bCheckAmount && ((float)$aPending['amount'] != $fTransactionAmount || strcasecmp($this->_oModule->_oConfig->getDefaultCurrencyCode(), $sTransactionCurrency) !== 0))
+            return false;
+
+        if($aPending['type'] == BX_PAYMENT_TYPE_RECURRING)
+            $this->_oModule->getObjectSubscriptions()->prolong($aPending);
+
+        return $this->_oModule->registerPayment($aPending);
+    }
+
+    protected function _processEventPaymentRefunded(&$aEvent)
+    {
+        $mixedResult = $this->_getDataTransaction($aEvent);
+        if($mixedResult === false)
+            return false;
+
+        list($aPending) = $mixedResult;
+        return $this->_oModule->refundPayment($aPending);
+    }
+
+    protected function _processEventSubscriptionCancelled(&$aEvent)
+    {
+        $mixedResult = $this->_getDataSubscription($aEvent);
+        if($mixedResult === false)
+            return false;
+
+        list($aPending, $aSubscription) = $mixedResult;
+        $this->onDeleteSubscription($aSubscription['id'], $aSubscription);
+
+        return $this->_oModule->getObjectSubscriptions()->cancelLocal($aPending);
+    }
+
+    protected function _getDataTransaction(&$aEvent, $sWithStatusCheck = '')
+    {
+        $aTransaction = $aEvent['content']['transaction'];
+        if(empty($aTransaction) || (!empty($sWithStatusCheck) && $aTransaction['status'] != $sWithStatusCheck))
+            return false;
+
+        $sOrder = '';
+        if(isset($aTransaction['subscription_id']))
+            $sOrder = $aTransaction['subscription_id'];
+        else if(isset($aTransaction['id']))
+            $sOrder = $aTransaction['id'];
+
+        if(empty($sOrder))
+            return false;
+
+        $aPending = $this->_oModule->_oDb->getOrderPending(['type' => 'order', 'order' => $sOrder]);
+        if(empty($aPending) || !is_array($aPending))
+            return false;
+
+        return array($aPending, $aTransaction);
+    }
+
+    protected function _getDataSubscription(&$aEvent, $sWithStatusCheck = '')
+    {
+        $aSubscription = $aEvent['content']['subscription'];
+        if(empty($aSubscription) || (!empty($sWithStatusCheck) && $aSubscription['status'] != $sWithStatusCheck))
+            return false;
+
+        $aPending = $this->_oModule->_oDb->getOrderPending(array('type' => 'order', 'order' => $aSubscription['id']));
+        if(empty($aPending) || !is_array($aPending))
+            return false;
+
+        return array($aPending, $aSubscription);
+    }
+}
+
+/** @} */

+ 410 - 0
modules/boonex/payment/updates/13.0.0_13.0.1/source/classes/BxPaymentProviderChargebeeV3.php

@@ -0,0 +1,410 @@
+<?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('BxPaymentProviderChargebee.php');
+
+use ChargeBee\ChargeBee\Models\PortalSession;
+
+class BxPaymentProviderChargebeeV3 extends BxPaymentProviderChargebee
+{
+    function __construct($aConfig)
+    {
+        $this->MODULE = 'bx_payment';
+
+        parent::__construct($aConfig);
+
+        $this->_aIncludeJs = array(
+            'https://js.chargebee.com/v2/chargebee.js',
+            'main.js',
+            'chargebee_v3.js'
+        );
+
+        $this->_aIncludeCss = array(
+            'chargebee_v3.css'
+        );
+    }
+
+    public function actionGetHostedPageSingle($iClientId, $iVendorId)
+    {
+        $this->initOptionsByVendor($iVendorId);
+
+        $aCartInfo = $this->_oModule->getObjectCart()->getInfo(BX_PAYMENT_TYPE_SINGLE, $iClientId, $iVendorId);
+
+        $aItem = [
+            'amount' => 100 * $aCartInfo['items_price'], 
+            'description' => _t($this->_sLangsPrefix . 'txt_payment_to', $aCartInfo['vendor_name'])
+        ];
+
+        $mixedItemAddons = bx_process_input(bx_get('addons'));
+        if(!empty($mixedItemAddons)) {
+            $aItemAddons = is_array($mixedItemAddons) ? $mixedItemAddons : $this->_oModule->_oConfig->s2a($mixedItemAddons);
+
+            foreach($aItemAddons as $sItemAddon)
+                if(!isset($aItem['addons'][$sItemAddon]))
+                    $aItem['addons'][$sItemAddon] = array(
+                        'id' => $sItemAddon,
+                        'quantity' => 1
+                    );
+                else 
+                    $aItem['addons'][$sItemAddon]['quantity'] += 1;
+
+            $aItem['addons'] = array_values($aItem['addons']);
+        }
+
+        $aClient = $this->_oModule->getProfileInfo($iClientId);
+
+        $oPage = $this->createHostedPageSingle($aItem, $aClient);
+        if($oPage === false)
+            return echoJson(array());
+
+        header('Content-type: text/html; charset=utf-8');
+        echo $oPage->toJson();
+    }
+
+    public function actionGetHostedPageRecurring($iClientId, $iVendorId, $sItemName)
+    {
+        $this->initOptionsByVendor($iVendorId);
+
+        $aItem = array('name' => $sItemName);
+
+        $mixedItemAddons = bx_process_input(bx_get('addons'));
+        if(!empty($mixedItemAddons)) {
+            $aItemAddons = is_array($mixedItemAddons) ? $mixedItemAddons : $this->_oModule->_oConfig->s2a($mixedItemAddons);
+
+            foreach($aItemAddons as $sItemAddon)
+                if(!isset($aItem['addons'][$sItemAddon]))
+                    $aItem['addons'][$sItemAddon] = array(
+                        'id' => $sItemAddon,
+                        'quantity' => 1
+                    );
+                else 
+                    $aItem['addons'][$sItemAddon]['quantity'] += 1;
+
+            $aItem['addons'] = array_values($aItem['addons']);
+        }
+        $aClient = $this->_oModule->getProfileInfo($iClientId);
+
+        $oPage = $this->createHostedPageRecurring($aItem, $aClient);
+        if($oPage === false)
+            return echoJson(array());
+
+        header('Content-type: text/html; charset=utf-8');
+        echo $oPage->toJson();
+    }
+
+    public function actionGetPortal($iPendingId)
+    {
+    	if(!isLogged())
+            return echoJson(array());
+
+    	$aPending = $this->_oModule->_oDb->getOrderPending(array('type' => 'id', 'id' => $iPendingId));
+    	if(empty($aPending) || !is_array($aPending))
+            return echoJson(array());
+
+    	$this->initOptionsByVendor((int)$aPending['seller_id']);
+
+    	$aSubscription = $this->_oModule->_oDb->getSubscription(array('type' => 'pending_id', 'pending_id' => $iPendingId));
+    	if(empty($aSubscription) || !is_array($aSubscription))
+            return echoJson(array());
+
+    	$oPortal = $this->getPortal($aSubscription['customer_id'], $aSubscription['subscription_id']);
+    	if($oPortal === false)
+            return echoJson(array());
+
+    	header('Content-type: text/html; charset=utf-8');
+    	echo $oPortal->toJson();
+    }
+
+    public function addJsCss()
+    {
+    	if(!$this->isActive())
+            return;
+
+        $this->_oModule->_oTemplate->addJs($this->_aIncludeJs);
+        $this->_oModule->_oTemplate->addCss($this->_aIncludeCss);
+    }
+
+    public function getJsObject($aParams = array())
+    {
+        $sJsObject = $this->_oModule->_oConfig->getJsObject($this->_sName);
+        if(isset($aParams['iModuleId'], $aParams['iSellerId'], $aParams['iItemId']))
+            $sJsObject .= '_' . md5($aParams['iModuleId'] . '-' . $aParams['iSellerId'] . '-' . $aParams['iItemId']);
+        
+        return $sJsObject;
+    }
+
+    public function initializeCheckout($iPendingId, $aCartInfo, $sRedirect = '')
+    {
+        $sPageId = bx_process_input(bx_get('page_id'));
+        if(empty($sPageId) || empty($iPendingId))
+            return $this->_sLangsPrefix . 'err_wrong_data';
+
+    	$aItem = array_shift($aCartInfo['items']);
+    	if(empty($aItem) || !is_array($aItem))
+            return $this->_sLangsPrefix . 'err_empty_items';
+
+        $aClient = $this->_oModule->getProfileInfo();
+        $aVendor = $this->_oModule->getProfileInfo($aCartInfo['vendor_id']);
+
+        $oPage = $this->retreiveHostedPage($sPageId);
+        if($oPage === false)
+            return $this->_sLangsPrefix . 'err_cannot_perform';
+
+        $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';
+
+        $aResult = [];
+        switch($aPending['type']) {
+            case BX_PAYMENT_TYPE_SINGLE:
+                $oInvoice = $oPage->content()->invoice();
+
+                $aResult = [
+                    'code' => 0,
+                    'eval' => $this->_oModule->_oConfig->getJsObject('cart') . '.onCartCheckout(oData);',
+                    'link' => $this->getReturnDataUrl($aVendor['id'], [
+                        'order_id' => $oInvoice->id,
+                        'customer_id' => $oInvoice->customerId,
+                        'pending_id' => $aPending['id'],
+                        'redirect' => $sRedirect
+                    ])
+                ];
+                break;
+
+            case BX_PAYMENT_TYPE_RECURRING:
+                $aResult = [
+                    'code' => 0,
+                    'eval' => $this->_oModule->_oConfig->getJsObject('cart') . '.onSubscribeSubmit(oData);',
+                    'redirect' => $this->getReturnDataUrl($aVendor['id'], [
+                        'order_id' => $oPage->content()->subscription()->id,
+                        'customer_id' => $oPage->content()->customer()->id,
+                        'pending_id' => $aPending['id'],
+                        'redirect' => $sRedirect
+                    ])
+                ];
+                break;
+        }
+
+        return $aResult;
+    }
+
+    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');
+
+        $oCustomer = $this->retrieveCustomer($sCustomerId);
+        if($oCustomer === false)
+            return array('code' => 4, 'message' => $this->_sLangsPrefix . 'err_cannot_perform');
+
+        $sOrder = '';
+        $aResult = [
+            'code' => BX_PAYMENT_RESULT_SUCCESS,
+            'message' => '',
+            'pending_id' => $iPendingId,
+            'client_name' => _t($this->_sLangsPrefix . 'txt_buyer_name_mask', $oCustomer->firstName, $oCustomer->lastName),
+            'client_email' => $oCustomer->email,
+            'paid' => false,
+            'redirect' => $sRedirect
+        ];
+
+        switch($aPending['type']) {
+            case BX_PAYMENT_TYPE_SINGLE:
+                $oInvoice = $this->retrieveInvoice($sOrderId);
+                if($oInvoice === false || empty($oInvoice->linkedPayments))
+                    return ['code' => 4, 'message' => $this->_sLangsPrefix . 'err_cannot_perform'];
+
+                $sOrder = $oInvoice->linkedPayments[0]->txnId;
+                $aResult = array_merge($aResult, [
+                    'message' => $this->_sLangsPrefix . 'cbee_msg_charged',
+                    'paid' => $oInvoice->status == 'paid',
+                ]);
+                break;
+
+            case BX_PAYMENT_TYPE_RECURRING:
+                $oSubscription = $this->retrieveSubscription($sOrderId);
+                if($oSubscription === false)
+                    return ['code' => 4, 'message' => $this->_sLangsPrefix . 'err_cannot_perform'];
+
+                $sOrder = $oSubscription->id;
+                $aResult = array_merge($aResult, [
+                    'message' => $this->_sLangsPrefix . 'cbee_msg_subscribed',
+                    'customer_id' => $oCustomer->id,
+                    'subscription_id' => $oSubscription->id,
+                    'trial' => $oSubscription->status == 'in_trial',
+                ]);
+
+                break;
+        }
+
+        //--- Update pending transaction ---//
+        $this->_oModule->_oDb->updateOrderPending($iPendingId, [
+            'order' => $sOrder,
+            'error_code' => $aResult['code'],
+            'error_msg' => _t($aResult['message'])
+        ]);
+
+        return $aResult;
+    }
+
+    public function getPortal($sCustomerId, $sSubscriptionId)
+    {
+    	$oPortal = false;
+
+    	try {
+            Environment::configure($this->_getSite(), $this->_getApiKey());
+            $oResult = PortalSession::create(array(
+                'customer' => array(
+                    'id' => $sCustomerId
+                )
+            ));
+
+            $oPortal = $oResult->portalSession();
+    	}
+    	catch (Exception $oException) {
+            $iError = $oException->getCode();
+            $sError = $oException->getMessage();
+
+            $this->log('Get Portal Error: ' . $sError . '(' . $iError . ')');
+
+            return false;
+    	}
+
+    	return $oPortal;
+    }
+
+    public function getJsCode($aParams = array())
+    {
+    	$sSite = '';
+    	bx_alert($this->_oModule->_oConfig->getName(), $this->_sName . '_get_js_code', 0, 0, array(
+            'site' => &$sSite,
+            'params' => &$aParams
+    	));
+
+    	return $this->_oModule->_oTemplate->getJsCode($this->_sName, array_merge(array(
+            'sProvider' => $this->_sName,
+            'sSite' => !empty($sSite) ? $sSite : $this->_getSite()
+    	), $aParams));
+    }
+
+    public function getButtonSingle($iClientId, $iVendorId, $aParams = [])
+    {
+        $oCart = $this->_oModule->getObjectCart();
+        $aCartInfo = $oCart->getInfo(BX_PAYMENT_TYPE_SINGLE, $iClientId, (int)$iVendorId);
+        if(empty($aCartInfo) || !is_array($aCartInfo))
+            return '';
+
+        $aItems = [];
+        $aCartItems = $oCart->getCartItems($iClientId, $iVendorId);
+        foreach($aCartItems as $aCartItem)
+            $aItems[] = $this->_oModule->_oConfig->descriptorA2S($aCartItem);
+
+    	return $this->_getButton(BX_PAYMENT_TYPE_SINGLE, $iClientId, $iVendorId, array_merge($aParams, [
+            'iSellerId' => $iVendorId,
+            'aItems' => $aItems
+    	]));
+    }
+
+    public function getButtonSingleJs($iClientId, $iVendorId, $aParams = [])
+    {
+        $oCart = $this->_oModule->getObjectCart();
+        $aCartInfo = $oCart->getInfo(BX_PAYMENT_TYPE_SINGLE, $iClientId, (int)$iVendorId);
+        if(empty($aCartInfo) || !is_array($aCartInfo))
+            return '';
+
+        $aItems = [];
+        $aCartItems = $oCart->getCartItems($iClientId, $iVendorId);
+        foreach($aCartItems as $aCartItem)
+            $aItems[] = $this->_oModule->_oConfig->descriptorA2S($aCartItem);
+
+    	return $this->_getButtonJs(BX_PAYMENT_TYPE_SINGLE, $iClientId, $iVendorId, array_merge($aParams, [
+            'iSellerId' => $iVendorId,
+            'aItems' => $aItems
+    	]));
+    }
+
+    public function getButtonRecurring($iClientId, $iVendorId, $aParams = array())
+    {
+        return $this->_getButton(BX_PAYMENT_TYPE_RECURRING, $iClientId, $iVendorId, $aParams);
+    }
+
+    public function getButtonRecurringJs($iClientId, $iVendorId, $aParams = array())
+    {
+        return $this->_getButtonJs(BX_PAYMENT_TYPE_RECURRING, $iClientId, $iVendorId, $aParams);
+    }
+
+    protected function _getButton($sType, $iClientId, $iVendorId, $aParams = array())
+    {
+        list($sJsCode, $sJsMethod) = $this->_getButtonJs($sType, $iClientId, $iVendorId, $aParams);        
+
+        return $this->_oModule->_oTemplate->parseHtmlByName('cbee_v3_button_' . $sType . '.html', array(
+            'type' => $sType,
+            'link' => 'javascript:void(0)',
+            'caption' => _t($this->_sLangsPrefix . 'cbee_txt_checkout_with_' . $sType, $this->_sCaption),
+            'onclick' => $sJsMethod,
+            'js_object' => $this->_oModule->_oConfig->getJsObject($this->_sName),
+            'js_code' => $sJsCode
+        ));
+    }
+    
+    protected function _getButtonJs($sType, $iClientId, $iVendorId, $aParams = array())
+    {
+        $sSite = '';
+        bx_alert($this->_oModule->_oConfig->getName(), $this->_sName . '_get_button', 0, $iClientId, array(
+            'type' => &$sType, 
+            'site' => &$sSite,
+            'params' => &$aParams
+        ));
+
+        $sJsMethod = '';
+        $sJsObject = $this->getJsObject($aParams);
+        switch($sType) {
+            case BX_PAYMENT_TYPE_SINGLE:
+                $sJsMethod = $sJsObject . '.checkout(this)';
+                break;
+
+            case BX_PAYMENT_TYPE_RECURRING:
+                $sJsMethod = $sJsObject . '.subscribe(this)';
+                break;
+        }
+
+        return array($this->_oModule->_oTemplate->getJsCode($this->_sName, array_merge(array(
+            'js_object' => $sJsObject,
+            'sProvider' => $this->_sName,
+            'sSite' => !empty($sSite) ? $sSite : $this->_getSite(),
+            'iClientId' => $iClientId
+        ), $aParams)), $sJsMethod);
+    }
+
+    public function getMenuItemsActionsRecurring($iClientId, $iVendorId, $aParams = array())
+    {
+        if(empty($aParams['id']))
+            return array();
+
+        $sPrefix = 'bx-payment-strp-';
+        $sJsObject = $this->_oModule->_oConfig->getJsObject($this->_sName);
+
+        return array(
+            array('id' => $sPrefix . 'manager', 'name' => $sPrefix . 'manager', 'class' => '', 'link' => 'javascript:void(0)', 'onclick' => "javascript:return " . $sJsObject . ".manage(this, '" . $aParams['id'] . "')", 'target' => '_self', 'title' => _t('_bx_payment_cbee_menu_item_title_manager'))
+        );
+    }
+}
+
+/** @} */

+ 783 - 0
modules/boonex/payment/updates/13.0.0_13.0.1/source/classes/BxPaymentProviderPayPalApi.php

@@ -0,0 +1,783 @@
+<?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
+ *
+ * @{
+ */
+
+/*
+ * 1. Set up server-side SDK:
+ * https://developer.paypal.com/docs/business/checkout/server-side-api-calls/set-up-sdk/
+ * 
+ * 2. Orders API
+ * https://developer.paypal.com/docs/api/orders/v2
+ * 
+ * 2.1. Checkout SDK in GitHUB
+ * https://github.com/paypal/Checkout-PHP-SDK/
+ * 
+ * 3. Subscriptions:
+ * https://developer.paypal.com/docs/subscriptions/
+ * https://developer.paypal.com/docs/business/subscriptions/
+ * 
+ * 3.1. API
+ * https://developer.paypal.com/docs/api/subscriptions/v1
+ * https://developer.paypal.com/docs/api/catalog-products/v1
+ * 
+ * 3.2. Integration
+ * https://developer.paypal.com/docs/subscriptions/integrate/
+ * 
+ * 3.3 WebHooks
+ * https://developer.paypal.com/docs/api-basics/notifications/webhooks/rest/
+ * 
+ */
+
+use PayPalCheckoutSdk\Core\PayPalHttpClient;
+use PayPalCheckoutSdk\Core\SandboxEnvironment;
+use PayPalCheckoutSdk\Core\ProductionEnvironment;
+use PayPalCheckoutSdk\Orders\OrdersCreateRequest;
+use PayPalCheckoutSdk\Orders\OrdersCaptureRequest;
+
+define('PP_API_MODE_LIVE', 1);
+define('PP_API_MODE_TEST', 2);
+define('PP_API_MODE_DEFAULT', PP_API_MODE_LIVE);
+
+define('PP_API_SBS_STATUS_APPROVAL_PENDING', 'APPROVAL_PENDING');
+define('PP_API_SBS_STATUS_APPROVED', 'APPROVED');
+define('PP_API_SBS_STATUS_ACTIVE', 'ACTIVE');
+
+class BxPaymentProviderPayPalApi extends BxBaseModPaymentProvider implements iBxBaseModPaymentProvider
+{
+    protected $_oSession;
+    protected $_sSessionKeyOrder;
+    protected $_sSessionKeySubscription;
+
+    protected $_bCheckAmount;
+    protected $_iMode;
+    protected $_sEndpoint;
+    protected $_sToken;
+
+    function __construct($aConfig)
+    {
+    	$this->MODULE = 'bx_payment';
+
+        parent::__construct($aConfig);
+
+        $this->_oSession = BxDolSession::getInstance();
+        $this->_sSessionKeyOrder = $this->MODULE . '_' . $this->_sPrefix . 'order';
+        $this->_sSessionKeySubscription = $this->MODULE . '_' . $this->_sPrefix . 'subscription';
+
+        $this->_bCheckAmount = true;
+        $this->_iMode = (int)$this->getOption('mode');
+        $this->_sEndpoint = 'https://api-m' . ($this->_iMode == PP_API_MODE_TEST ? '.sandbox' : '') . '.paypal.com/';
+    }
+
+    public function initializeCheckout($iPendingId, $aCartInfo)
+    {
+        if(empty($aCartInfo['items']) || !is_array($aCartInfo['items']))
+            return $this->_sLangsPrefix . 'err_empty_items';
+
+        $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:
+                $mixedResult = $this->_createOrder($iPendingId, $aCartInfo);
+                if($mixedResult === false)
+                    return $this->_sLangsPrefix . 'err_cannot_perform';
+
+                $this->_setSessionOrder($mixedResult['order']);
+                header("Location: " . $mixedResult['redirect']);
+                exit;
+
+            case BX_PAYMENT_TYPE_RECURRING:
+                $mixedResult = $this->_createSubscription($iPendingId, $aCartInfo);
+                if(is_string($mixedResult))
+                    return $mixedResult;
+
+                $this->_setSessionSubscription($mixedResult['subscription']);
+                return array(
+                    'code' => 0,
+                    'redirect' => $mixedResult['redirect'],
+                );
+        }
+    }
+
+    public function finalizeCheckout(&$aData)
+    {
+        $sMethod = '_finalizeCheckout' . bx_gen_method_name(!empty($aData['subscription_id']) && !empty('ba_token') ? BX_PAYMENT_TYPE_RECURRING : BX_PAYMENT_TYPE_SINGLE);
+
+        $aResult = $this->$sMethod($aData);
+        if(!isset($aResult['code']) || (int)$aResult['code'] != BX_PAYMENT_RESULT_SUCCESS) {
+            $this->log($aResult, 'Finalize Checkout Failed:');
+            $this->log($aData, 'Finalize Checkout Input:');
+        }
+
+        return $aResult;
+    }
+
+    public function notify()
+    {
+        $iResult = $this->_processEvent();
+        http_response_code($iResult);
+    }
+
+    public function getClientId()
+    {
+        return $this->getOption($this->_getMode() . '_client_id');
+    }
+
+    public function getSecret()
+    {
+        return $this->getOption($this->_getMode() . '_secret');
+    }
+
+    public function getMenuItemsActionsRecurring($iClientId, $iVendorId, $aParams = array())
+    {
+        return array();
+    }
+
+    protected function _finalizeCheckoutSingle(&$aData)
+    {
+        $sOrder = '';
+        if(!empty($aData['token']))
+            $sOrder = bx_process_input($aData['token']);
+        if(empty($sOrder))
+            $sOrder = $this->_getSessionOrder();
+        if(empty($sOrder))
+            return array('code' => 1, 'message' => $this->_sLangsPrefix . 'err_empty_order');
+
+        $mixedResult = $this->_captureOrder($sOrder);
+        if($mixedResult === false)
+            return array('code' => 2, 'message' => $this->_sLangsPrefix . 'pp_api_err_cannot_capture');
+
+        $aResult = array(
+            'code' => BX_PAYMENT_RESULT_SUCCESS, 
+            'message' => $this->_sLangsPrefix . 'pp_api_msg_captured',
+            'pending_id' => $mixedResult['pending_id'],
+            'client_name' => _t($this->_sLangsPrefix . 'txt_buyer_name_mask', $mixedResult['client_first_name'], $mixedResult['client_last_name']),
+            'client_email' => $mixedResult['client_email'],
+            'paid' => true
+        );
+
+        //--- Update pending transaction
+        $this->_oModule->_oDb->updateOrderPending($aResult['pending_id'], array(
+            'order' => $mixedResult['order'],
+            'error_code' => $aResult['code'],
+            'error_msg' => _t($aResult['message'])
+        ));
+
+        return $aResult;
+    }
+
+    protected function _finalizeCheckoutRecurring(&$aData)
+    {
+        $sSubscription = '';
+        if(!empty($aData['subscription_id']))
+            $sSubscription = bx_process_input($aData['subscription_id']);
+        if(empty($sSubscription))
+            $sSubscription = $this->_getSessionSubscription();
+        if(empty($sSubscription))
+            return array('code' => 1, 'message' => $this->_sLangsPrefix . 'pp_api_err_no_subscription');
+
+        $aSubscription = $this->_getSubscription($sSubscription);
+        if(empty($aSubscription) || !in_array($aSubscription['status'], array(PP_API_SBS_STATUS_APPROVAL_PENDING, PP_API_SBS_STATUS_APPROVED, PP_API_SBS_STATUS_ACTIVE)))
+            return array('code' => 2, 'message' => $this->_sLangsPrefix . 'pp_api_err_no_subscription');
+
+        $aSubscriber = $this->_getClientInfo($aSubscription['subscriber']);
+        list($bPaid, $bTrial) = $this->_getBillingStatus($aSubscription['billing_info']);
+
+        $aResult = array(
+            'code' => BX_PAYMENT_RESULT_SUCCESS, 
+            'message' => $this->_sLangsPrefix . 'pp_api_msg_subscribed',
+            'pending_id' => $aSubscription['custom_id'],
+            'customer_id' => $aSubscription['subscriber']['payer_id'], 
+            'subscription_id' => $sSubscription,
+            'client_name' => _t($this->_sLangsPrefix . 'txt_buyer_name_mask', $aSubscriber['client_first_name'], $aSubscriber['client_last_name']),
+            'client_email' => $aSubscriber['client_email'],
+            'paid' => $bPaid,
+            'trial' => $bTrial,
+        );
+
+        if($aSubscription['status'] == PP_API_SBS_STATUS_APPROVAL_PENDING)       
+            $aResult = array_merge($aResult, array(
+                'code' => 3,
+                'message' => $this->_sLangsPrefix . 'pp_api_err_subscription_not_confirmed'
+            ));
+
+        //--- Update pending transaction
+        $this->_oModule->_oDb->updateOrderPending($aResult['pending_id'], array(
+            'order' => $sSubscription,
+            'error_code' => $aResult['code'],
+            'error_msg' => _t($aResult['message'])
+        ));
+
+        return $aResult;
+    }
+
+    /**
+     * Methods which use common HTTPS calls to process Recurring time payments.
+     */
+    protected function _createSubscription($iPendingId, $aCartInfo, $sReturnType = 'approve')
+    {
+        $aItem = array_shift($aCartInfo['items']);
+        if(empty($aItem) || !is_array($aItem))
+            return $this->_sLangsPrefix . 'pp_api_err_no_item';
+
+        $aItem['price_currency'] = $aCartInfo['vendor_currency_code'];
+
+        $aProduct = $this->_getProduct($aItem['name']);
+        if(empty($aProduct)) {
+            $aProduct = $this->_createProduct($aItem);
+            if($aProduct === false)
+                return $this->_sLangsPrefix . 'err_cannot_perform';
+        }
+
+        $aProductPlan = array();
+
+        $aPlans = $this->_getPlans($aProduct['id']);
+        if(!empty($aPlans)) 
+            foreach($aPlans as $aPlan)
+                if(strcmp($aPlan['name'], $aItem['name']) == 0) {
+                    $aProductPlan = $aPlan;
+                    break;
+                }
+        
+        if(empty($aProductPlan) || !is_array($aProductPlan)) {
+            $aProductPlan = $this->_createPlan($aProduct['id'], $aItem);
+            if($aProductPlan === false)
+                return $this->_sLangsPrefix . 'err_cannot_perform';
+        }
+
+        $mixedResult = $this->_apiCallAuthorized($this->_sEndpoint . 'v1/billing/subscriptions', array(
+            'plan_id' => $aProductPlan['id'],
+            'custom_id' => $iPendingId,
+            'application_context' => array(
+                'cancel_url' => $aItem['url'],
+                'return_url' => $this->getReturnDataUrl($aCartInfo['vendor_id'])
+            )
+        ));
+
+        if($mixedResult === false || empty($mixedResult['id']) || empty($mixedResult['links'])) {
+            $this->log($mixedResult, 'Create Subscription:');
+
+            return $this->_sLangsPrefix . 'err_cannot_perform';
+        }
+
+        $mixedLink = false;
+        foreach($mixedResult['links'] as $aLink)
+            if($aLink['rel'] == $sReturnType) {
+                $mixedLink = $aLink['href'];
+                break;
+            }
+
+        return array(
+            'subscription' => $mixedResult['id'],
+            'redirect' => $mixedLink
+        );
+    }
+
+    protected function _getSubscription($sSubscriptionId)
+    {
+        $mixedResult = $this->_apiCallAuthorized($this->_sEndpoint . 'v1/billing/subscriptions/' . $sSubscriptionId, array(), array(), 'get');
+        if($mixedResult === false || !isset($mixedResult['id'])) {
+            $this->log($mixedResult, 'Get Subscription:');
+
+            return array();
+        }
+
+        return $mixedResult;
+    }
+
+    protected function _createProduct($aItem)
+    {
+        if(empty($aItem['description']))
+            $aItem['description'] = _t('_bx_payment_txt_payment_description', getParam('site_title'));
+        $aItem['description'] = strmaxtextlen($aItem['description'], 60, '...');
+
+        $mixedResult = $this->_apiCallAuthorized($this->_sEndpoint . 'v1/catalogs/products', array(
+            'id' => $aItem['name'],
+            'name' => $aItem['title'],
+            'description' => $aItem['description'],
+            'type' => 'DIGITAL',
+            'home_url' => $aItem['url'],
+        ), array(
+            'PayPal-Request-Id: bx_prod_' . $aItem['name']
+        ));
+
+        if($mixedResult === false || !isset($mixedResult['id'])) {
+            $this->log($mixedResult, 'Create Product:');
+
+            return false;
+        }
+
+        return $mixedResult;
+    }
+    
+    protected function _getProduct($sProductId)
+    {
+        $mixedResult = $this->_apiCallAuthorized($this->_sEndpoint . 'v1/catalogs/products/' . $sProductId, array(), array(), 'get');
+        if($mixedResult === false || !isset($mixedResult['id'])) {
+            $this->log($mixedResult, 'Get Product:');
+
+            return array();
+        }
+
+        return $mixedResult;
+    }
+
+    protected function _createPlan($sProductId, $aItem)
+    {
+        $aCycles = array();
+
+        $sIntervalUnit = $this->_getIntervalUnit($aItem['period_unit_recurring']);
+        if($sIntervalUnit === false)
+            return false;
+
+        $iSequence = 1;
+
+        $iTrial = $this->_oModule->_oConfig->getTrial(BX_PAYMENT_TYPE_RECURRING, $aItem);
+        if(!empty($iTrial)) 
+            $aCycles[] = array(
+                'frequency' => array(
+                    'interval_unit' => $this->_getIntervalUnit(BX_PAYMENT_SBS_PU_DAY),
+                    'interval_count' => $iTrial
+                ),
+                'tenure_type' => 'TRIAL',
+                'sequence' => $iSequence++,
+                'total_cycles' => 1,
+            );
+
+        $aCycles[] = array(
+            'frequency' => array(
+                'interval_unit' => $sIntervalUnit,
+                'interval_count' => (int)$aItem['period_recurring']
+            ),
+            'tenure_type' => 'REGULAR',
+            'sequence' => $iSequence,
+            'total_cycles' => 0,
+            'pricing_scheme' => array(
+                'fixed_price' => array(
+                    'value' => $this->_oModule->_oConfig->getPrice(BX_PAYMENT_TYPE_RECURRING, $aItem),
+                    'currency_code' => $aItem['price_currency']
+                )
+            )
+        );
+
+        $mixedResult = $this->_apiCallAuthorized($this->_sEndpoint . 'v1/billing/plans', array(
+            'product_id' => $sProductId,
+            'name' => $aItem['name'],
+            'description' => $aItem['title'],
+            'billing_cycles' => $aCycles,
+            'payment_preferences' => array(
+                'auto_bill_outstanding' => true,
+                'setup_fee' => array(
+                    'value' => 0,
+                    'currency_code' => $aItem['price_currency']
+                ),
+                'setup_fee_failure_action' => 'CONTINUE',
+                'payment_failure_threshold' => 3
+            ),
+        ), array(
+            'PayPal-Request-Id: bx_plan_' . $aItem['name']
+        ));
+
+        if($mixedResult === false || !isset($mixedResult['id'])) {
+            $this->log($mixedResult, 'Create Plan:');
+
+            return false;
+        }
+
+        return $mixedResult;
+    }
+
+    protected function _getPlan($sPlanId)
+    {
+        $mixedResult = $this->_apiCallAuthorized($this->_sEndpoint . 'v1/billing/plans/' . $sPlanId, array(), array(), 'get');
+        if($mixedResult === false || !isset($mixedResult['id'])) {
+            $this->log($mixedResult, 'Get Plan:');
+
+            return array();
+        }
+
+        return $mixedResult;
+    }
+
+    protected function _getPlans($sProductId, $iStart = false, $iPerPage = false)
+    {
+        $aParams = array(
+            'product_id' => $sProductId,
+        );
+        
+        if($iStart !== false)
+            $aParams['page'] = (int)$iStart >= 1 && (int)$iStart <= 100000 ? $iStart : 1;
+        if($iPerPage !== false)
+            $aParams['page_size'] = (int)$iPerPage >= 1 && (int)$iPerPage <= 20 ? $iPerPage : 20;
+
+        $mixedResult = $this->_apiCallAuthorized($this->_sEndpoint . 'v1/billing/plans', $aParams, array(), 'get');
+        if(empty($mixedResult) || !is_array($mixedResult) || !isset($mixedResult['plans'])) {
+            $this->log($mixedResult, 'Get Plans:');
+
+            return array();
+        }
+
+        return $mixedResult['plans'];
+    }
+
+    protected function _getToken()
+    {
+        $mixedResult = $this->_apiCall($this->_sEndpoint . 'v1/oauth2/token', array(
+            'grant_type' => 'client_credentials'
+        ), array(), 'post', array(
+            'user' => $this->getClientId(),
+            'password' => $this->getSecret()
+        ));
+
+        if($mixedResult === false || empty($mixedResult['access_token'])) {
+            $this->log($mixedResult, 'Get Token:');
+
+            return false;
+        }
+
+        return $mixedResult['access_token'];
+    }
+
+    protected function _apiCallAuthorized($sEndpoint, $aParams = array(), $aHeaders = array(), $sMethod = 'post-json')
+    {
+        if(!$this->_sToken)
+            $this->_sToken = $this->_getToken();
+
+        $aHeaders = array_merge(array(
+            'Authorization: Bearer ' . $this->_sToken,
+            'Prefer: return=representation'
+        ), $aHeaders);
+
+        return $this->_apiCall($sEndpoint, $aParams, $aHeaders, $sMethod);
+    }
+
+    protected function _apiCall($sEndpoint, $aParams = array(), $aHeaders = array(), $sMethod = 'post-json', $aBasicAuth = array())
+    {
+        $sHttpCode = null;
+        $aHeaders = array_merge(array(
+            'Accept: application/json',
+            'Content-Type: application/json'
+        ), $aHeaders);
+
+        $sResult = bx_file_get_contents($sEndpoint, $aParams, $sMethod, $aHeaders, $sHttpCode, $aBasicAuth);
+        if(empty($sResult))
+            return false;
+
+        return json_decode($sResult, true);
+    }
+
+    protected function _getIntervalUnit($sPeriodUnit)
+    {
+        $aIntervalUnits = array(
+            BX_PAYMENT_SBS_PU_DAY => 'DAY',
+            BX_PAYMENT_SBS_PU_WEEK => 'WEEK',
+            BX_PAYMENT_SBS_PU_MONTH => 'MONTH',
+            BX_PAYMENT_SBS_PU_YEAR => 'YEAR'
+        );
+
+        return isset($aIntervalUnits[$sPeriodUnit]) ? $aIntervalUnits[$sPeriodUnit] : false;
+    }
+
+
+    /**
+     * Methods which use 'Checkout SDK' to process Single time payments.
+     */
+    protected function _getClient()
+    {
+        $sClientId = $this->getClientId();
+        $sSecret = $this->getSecret();
+
+        if($this->_iMode == PP_API_MODE_LIVE)
+            $oEnvironment = new ProductionEnvironment($sClientId, $sSecret);
+        else 
+            $oEnvironment = new SandboxEnvironment($sClientId, $sSecret);
+
+        return new PayPalHttpClient($oEnvironment);
+    }
+
+    protected function _createOrder($iPendingId, $aCartInfo, $sReturnType = 'approve')
+    {
+        $aItems = array();
+        foreach($aCartInfo['items'] as $aItem)
+            $aItems[] = array(
+                'name' => $aItem['title'],
+                'unit_amount' => array(
+                    'value' => $this->_oModule->_oConfig->getPrice(BX_PAYMENT_TYPE_SINGLE, $aItem),
+                    'currency_code' => $aCartInfo['vendor_currency_code']
+                ),
+                'quantity' => $aItem['quantity']
+            );
+
+        $oRequest = new OrdersCreateRequest();
+        $oRequest->prefer('return=representation');
+        $oRequest->body = array(
+            'intent' => 'CAPTURE',
+            'purchase_units' => array(
+                array(
+                    'reference_id' => $iPendingId,
+                    'amount' => array(
+                        'currency_code' => $aCartInfo['vendor_currency_code'],
+                        'value' => sprintf("%.2f", (float)$aCartInfo['items_price']),
+                        'breakdown' => array(
+                            'item_total' => array(
+                                'currency_code' => $aCartInfo['vendor_currency_code'],
+                                'value' => sprintf("%.2f", (float)$aCartInfo['items_price']),
+                            )
+                        )
+                    ),
+                    'items' => $aItems
+                )
+            ),
+            'application_context' => array(
+                'cancel_url' => $this->_oModule->getObjectCart()->serviceGetCartUrl($aCartInfo['vendor_id']),
+                'return_url' => $this->getReturnDataUrl($aCartInfo['vendor_id'])
+            )
+        );
+
+        try {
+            $oResponse = $this->_getClient()->execute($oRequest);
+            if($oResponse->statusCode != 201)
+                return false;
+
+            $mixedLink = false;
+            foreach($oResponse->result->links as $oLink)
+                if($oLink->rel == $sReturnType) {
+                    $mixedLink = $oLink->href;
+                    break;
+                }
+
+            return array(
+                'order' => $oResponse->result->id,
+                'redirect' => $mixedLink,
+            );
+        }
+        catch (HttpException $oException) {
+            return $this->_processException('Create Order Error: ', $oException);
+        }
+    }
+
+    protected function _captureOrder($sOrderId)
+    {
+        $oRequest = new OrdersCaptureRequest($sOrderId);
+
+        try {
+            $oResponse = $this->_getClient()->execute($oRequest);
+            if($oResponse->statusCode != 201 || strcmp(strtolower($oResponse->result->status), 'completed') != 0)
+                return false;
+
+            $oPurchase = current($oResponse->result->purchase_units);
+            $oCapture = current($oPurchase->payments->captures);
+            return array_merge(array(
+                'pending_id' => (int)$oPurchase->reference_id,
+                'order' => $oCapture->id,
+            ), $this->_getClientInfo($oResponse->result->payer));
+        }
+        catch (HttpException $oException) {
+            return $this->_processException('Capture Order Error: ', $oException);
+        }
+    }
+
+    protected function _processException($sMessage, &$oException)
+    {
+        $aError = $oException->getJsonBody();
+
+        $sDescription = $aError['error']['message'];
+        if(empty($sDescription))
+            $sDescription = $oException->getMessage();
+
+        $this->log($sMessage . $sDescription);
+        $this->log($aError);
+
+        return false;
+    }
+
+    /**
+     * Methods to process WebHooks
+     */
+    protected function _processEvent()
+    {
+        $sInput = @file_get_contents("php://input");
+        $aEvent = json_decode($sInput, true);
+        if(empty($aEvent) || !is_array($aEvent)) 
+            return 404;
+
+        $sType = $aEvent['event_type'];
+        if(!in_array($sType, array('PAYMENT.SALE.COMPLETED', 'PAYMENT.CAPTURE.REFUNDED', 'BILLING.SUBSCRIPTION.CANCELLED')))
+            return 200;
+
+        $this->log($aEvent, 'Webhooks: ' . (!empty($sType) ? $sType : ''));
+
+        $sMethod = '_processEvent' . bx_gen_method_name(strtolower($sType), array('.', '_', '-'));
+    	if(!method_exists($this, $sMethod))
+            return 200;
+
+    	return $this->$sMethod($aEvent) ? 200 : 403;
+    }
+
+    protected function _processEventPaymentSaleCompleted($aEvent)
+    {
+        $mixedResult = $this->_getEventData($aEvent);
+        if($mixedResult === false)
+            return false;
+
+        list($aPending, $aEventData) = $mixedResult;
+
+        $fChargeAmount = (float)$aEventData['amount']['total'];
+        $sChargeCurrency = strtoupper($aEventData['amount']['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->getObjectSubscriptions()->prolong($aPending);
+
+        return $this->_oModule->registerPayment($aPending);
+    }
+
+    protected function _processEventPaymentCaptureRefunded($aEvent)
+    {
+        $mixedResult = $this->_getEventData($aEvent);
+        if($mixedResult === false)
+            return false;
+
+        list($aPending, $aEventData) = $mixedResult;
+        return $this->_oModule->refundPayment($aPending);
+    }
+
+    protected function _processEventBillingSubscriptionCancelled($aEvent)
+    {
+        $mixedResult = $this->_getEventData($aEvent);
+        if($mixedResult === false)
+            return false;
+
+        list($aPending, $aEventData) = $mixedResult;
+        return $this->_oModule->getObjectSubscriptions()->cancelLocal($aPending);
+    }
+
+    protected function _getEventData($aEvent)
+    {
+        if(empty($aEvent['resource']) || !is_array($aEvent['resource']))
+            return false;
+
+        $aData = $aEvent['resource'];
+        if(empty($aData['billing_agreement_id']))
+            return false;       
+
+        $aPending = $this->_oModule->_oDb->getOrderPending(array('type' => 'order', 'order' => $aData['billing_agreement_id']));
+        if(empty($aPending) || !is_array($aPending))
+            return false;
+
+        return array($aPending, $aData);
+    }
+
+    /**
+     * Common methods for internal usage.
+     */
+    protected function _getMode()
+    {
+        if(empty($this->_iMode))
+            $this->_iMode = (int)$this->getOption('mode');
+
+        $aModeI2S = array(
+            PP_API_MODE_LIVE => 'live',
+            PP_API_MODE_TEST => 'test'
+        );
+
+        return isset($aModeI2S[$this->_iMode]) ? $aModeI2S[$this->_iMode] : $aModeI2S[PP_API_MODE_DEFAULT];
+    }
+
+    protected function _getSessionOrder()
+    {
+        return $this->_oSession->getUnsetValue($this->_sSessionKeyOrder);
+    }
+
+    protected function _setSessionOrder($sValue)
+    {
+        $this->_oSession->setValue($this->_sSessionKeyOrder, $sValue);
+    }
+
+    protected function _getSessionSubscription()
+    {
+        return $this->_oSession->getUnsetValue($this->_sSessionKeySubscription);
+    }
+
+    protected function _setSessionSubscription($sValue)
+    {
+        $this->_oSession->setValue($this->_sSessionKeySubscription, $sValue);
+    }
+
+    /**
+     * Retrieve 'Client Info' from a 'getSubscription' call's response.
+     */
+    protected function _getClientInfo($mixedClient)
+    {
+        $_sName = 'name';
+        $_sFirst = 'given_name';
+        $_sLast = 'surname';
+        $_sEmail = 'email_address';
+
+        $aResult = [];
+        if(is_object($mixedClient))
+            $aResult = [
+                'client_first_name' => $mixedClient->$_sName->$_sFirst,
+                'client_last_name' => $mixedClient->$_sName->$_sLast,
+                'client_email' => $mixedClient->$_sEmail,
+            ];
+        else
+            $aResult = [
+                'client_first_name' => $mixedClient[$_sName][$_sFirst],
+                'client_last_name' => $mixedClient[$_sName][$_sLast],
+                'client_email' => $mixedClient[$_sEmail],
+            ];
+
+        return $aResult;
+    }
+
+    /**
+     * Retrieve 'Billing Status' from a 'getSubscription' call's response.
+     */
+    protected function _getBillingStatus($mixedBillingInfo)
+    {
+        $bTrial = $bPaid = false;
+
+        $_sCycles = 'cycle_executions';
+        $_sCycleType = 'tenure_type';
+        $_sCyclesCompleted = 'cycles_completed';
+        $_sCyclesTotal = 'total_cycles';
+
+        $bByObject = is_object($mixedBillingInfo);
+        $aCycles = $bByObject ? $mixedBillingInfo->$_sCycles : $mixedBillingInfo[$_sCycles];
+        if(empty($aCycles) || !is_array($aCycles))
+            return [$bPaid, $bTrial];
+
+        foreach($aCycles as $mixedCycle) {
+            $sCycleType = $bByObject ? $mixedCycle->$_sCycleType : $mixedCycle[$_sCycleType];
+            $iCyclesCompleted = $bByObject ? $mixedCycle->$_sCyclesCompleted : (int)$mixedCycle[$_sCyclesCompleted];
+            $iCyclesTotal = $bByObject ? $mixedCycle->$_sCyclesTotal : (int)$mixedCycle[$_sCyclesTotal];
+
+            switch($sCycleType) {
+                case 'TRIAL':
+                    if($iCyclesCompleted < $iCyclesTotal) {
+                        $bTrial = true;
+                        break 2;
+                    }
+                    break;
+                
+                case 'REGULAR':
+                    $bPaid = true;
+                    break 2;
+            }
+        }
+
+        return [$bPaid, $bTrial];
+    }
+}
+
+/** @} */

+ 472 - 0
modules/boonex/payment/updates/13.0.0_13.0.1/source/classes/BxPaymentProviderStripe.php

@@ -0,0 +1,472 @@
+<?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('BxPaymentProviderStripeBasic.php');
+
+class BxPaymentProviderStripe extends BxPaymentProviderStripeBasic implements iBxBaseModPaymentProvider
+{
+    function __construct($aConfig)
+    {
+        parent::__construct($aConfig);
+
+        $this->_aIncludeJs = array(
+            'https://checkout.stripe.com/checkout.js',
+            'stripe.js'
+        );
+    }
+
+    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 getCheckoutParamsSingle($aParams, &$oGrid)
+    {
+    	if(bx_get('token') !== false)
+            $aParams['token'] = bx_process_input(bx_get('token'));
+
+    	return $aParams;
+    }
+
+    public function getVerificationCodeCharge($iVendorId, $iCustomerId, $fAmount, $sCurrency)
+    {
+        $sCode = $this->_getVerificationCodeCharge($iVendorId, $iCustomerId, $fAmount, $sCurrency);
+
+        bx_alert($this->_oModule->_oConfig->getName(), $this->_sName . '_get_code_charge', 0, false, array(
+            'provider' => $this,
+            'vendor_id' => $iVendorId, 
+            'customer_id' => $iCustomerId,
+            'amount' => $fAmount,
+            'currency' => $sCurrency,
+            'override_result' => &$sCode
+        ));
+
+        return $sCode;
+    }
+
+    public function checkVerificationCodeCharge($iVendorId, $iCustomerId, $aResult)
+    {
+        $bCheckResult = $this->_checkVerificationCodeCharge($iVendorId, $iCustomerId, $aResult);
+
+        bx_alert($this->_oModule->_oConfig->getName(), $this->_sName . '_verify_charge', 0, false, array(
+            'provider' => $this,
+            'vendor_id' => $iVendorId, 
+            'customer_id' => $iCustomerId,
+            'result' => $aResult,
+            'override_result' => &$bCheckResult
+        ));
+
+        return $bCheckResult;
+    }
+
+    public function getVerificationCodeSubscription($iVendorId, $iCustomerId, $sSubscription, $sCurrency)
+    {
+        $sCode = $this->_getVerificationCodeSubscription($iVendorId, $iCustomerId, $sSubscription, $sCurrency);
+
+        bx_alert($this->_oModule->_oConfig->getName(), $this->_sName . '_get_code_subscription', 0, false, array(
+            'provider' => $this,
+            'vendor_id' => $iVendorId, 
+            'customer_id' => $iCustomerId,
+            'subscription' => $sSubscription,
+            'currency' => $sCurrency,
+            'override_result' => &$sCode
+        ));
+
+        return $sCode;
+    }
+    
+    public function checkVerificationCodeSubscription($iVendorId, $iCustomerId, $aResult)
+    {
+        $bCheckResult = $this->_checkVerificationCodeSubscription($iVendorId, $iCustomerId, $aResult);
+
+        bx_alert($this->_oModule->_oConfig->getName(), $this->_sName . '_verify_subscription', 0, false, array(
+            'provider' => $this,
+            'vendor_id' => $iVendorId, 
+            'customer_id' => $iCustomerId,
+            'result' => $aResult,
+            'override_result' => &$bCheckResult
+        ));
+
+        return $bCheckResult;
+    }
+
+    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 _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(!$this->checkVerificationCodeCharge($aCartInfo['vendor_id'], $aClient['id'], $aResult))
+            return false;
+
+        return array(
+            'pending' => $iPendingId,
+            'amount' =>(float)$aResult['amount'] / 100,
+            'customer' => $this->_oCustomer->id,
+            'order' => $aResult['id']
+        );
+    }
+
+    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;
+
+        if(!$this->checkVerificationCodeSubscription($aCartInfo['vendor_id'], $aClient['id'], $aResult))
+            return false;
+
+        return array(
+            'pending' => $iPendingId,
+            'amount' =>(float)$aCartInfo['items_price'],
+            'customer' => $this->_oCustomer->id, 
+            'order' => $aResult['id'],
+            'trial' => $bTrial
+        );
+    }
+
+    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 _getButtonJs($sType, $iClientId, $iVendorId, $aParams = array())
+    {
+        $sClientEmail = '';
+    	if(!empty($iClientId) && ($oClient = BxDolProfile::getInstance($iClientId)) !== false)
+            $sClientEmail = $oClient->getAccountObject()->getEmail();
+
+        $sPublicKey = '';
+    	bx_alert($this->_oModule->_oConfig->getName(), $this->_sName . '_get_button', 0, $iClientId, array(
+            'type' => &$sType, 
+            'public_key' => &$sPublicKey
+        ));
+
+        $sJsMethod = '';
+        $sJsObject = $this->getJsObject($aParams);
+        switch($sType) {
+            case BX_PAYMENT_TYPE_SINGLE:
+                $sJsMethod = $sJsObject . '.checkout(this)';
+                break;
+
+            case BX_PAYMENT_TYPE_RECURRING:
+                $sJsMethod = $sJsObject . '.subscribe(this)';
+                break;
+        }
+
+        return array($this->_oModule->_oTemplate->getJsCode($this->_sName, array_merge(array(
+            'js_object' => $sJsObject,
+            'sProvider' => $this->_sName,
+            'sPublicKey' => !empty($sPublicKey) ? $sPublicKey : $this->_getPublicKey(),
+            'sVendorName' => '',
+            'sVendorCurrency' => '',
+            'sVendorIcon' => '',
+            'sClientEmail' => $sClientEmail,
+        ), $aParams)), $sJsMethod);
+    }
+    
+    protected function _getVerificationCodeCharge($iVendorId, $iCustomerId, $fAmount, $sCurrency)
+    {
+        return md5(implode('#-#', array(
+            (int)$iVendorId,
+            (int)$iCustomerId,
+            (float)$fAmount,
+            strtoupper($sCurrency)
+        )));
+    }
+
+    protected function _checkVerificationCodeCharge($iVendorId, $iCustomerId, $aResult)
+    {
+        return !empty($aResult['metadata']['verification']) && $aResult['metadata']['verification'] == $this->getVerificationCodeCharge($iVendorId, $iCustomerId, $aResult['amount'], $aResult['currency']);
+    }
+
+    protected function _getVerificationCodeSubscription($iVendorId, $iCustomerId, $sSubscription, $sCurrency)
+    {
+        return md5(implode('#-#', array(
+            (int)$iVendorId,
+            (int)$iCustomerId,
+            strtoupper($sSubscription),
+            strtoupper($sCurrency)
+        )));
+    }
+
+    protected function _checkVerificationCodeSubscription($iVendorId, $iCustomerId, $aResult)
+    {
+        return !empty($aResult['metadata']['verification']) && $aResult['metadata']['verification'] == $this->getVerificationCodeSubscription($iVendorId, $iCustomerId, $aResult['plan']['id'], $aResult['plan']['currency']);
+    }
+}
+
+/** @} */

+ 620 - 0
modules/boonex/payment/updates/13.0.0_13.0.1/source/classes/BxPaymentProviderStripeBasic.php

@@ -0,0 +1,620 @@
+<?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('STRP_MODE_LIVE', 1);
+define('STRP_MODE_TEST', 2);
+
+class BxPaymentProviderStripeBasic extends BxBaseModPaymentProvider
+{
+    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->_aSbsStatuses = array(
+            'incomplete' => BX_PAYMENT_SBS_STATUS_UNPAID, 
+            'incomplete_expired' => BX_PAYMENT_SBS_STATUS_UNPAID, 
+            'trialing' => BX_PAYMENT_SBS_STATUS_TRIAL, 
+            'active' => BX_PAYMENT_SBS_STATUS_ACTIVE, 
+            'past_due' => BX_PAYMENT_SBS_STATUS_UNPAID,
+            'unpaid' => BX_PAYMENT_SBS_STATUS_UNPAID,
+            'canceled' => BX_PAYMENT_SBS_STATUS_CANCELED,
+        );
+
+        $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->_bProrate = false;
+
+        $this->_aIncludeJs = array(
+            'main.js',
+        );
+
+        $this->_aIncludeCss = array(
+            'stripe.css'
+        );
+
+        $this->_oCustomer = null;
+
+        \Stripe\Stripe::setApiKey($this->_getSecretKey());
+    }
+
+    public function initOptions($aOptions)
+    {
+    	parent::initOptions($aOptions);
+
+    	$this->_iMode = (int)$this->getOption('mode');
+    	$this->_bCheckAmount = $this->getOption('check_amount') == 'on';
+    	$this->_bUseSsl = $this->getOption('ssl') == 'on';
+    }
+
+    public function addJsCss()
+    {
+    	if(!$this->isActive())
+    		return;
+
+        $this->_oModule->_oTemplate->addJs($this->_aIncludeJs);
+        $this->_oModule->_oTemplate->addCss($this->_aIncludeCss);
+    }
+
+    public function getJsObject($aParams = array())
+    {
+        $sJsObject = $this->_oModule->_oConfig->getJsObject($this->_sName);
+        if(isset($aParams['iModuleId'], $aParams['iSellerId'], $aParams['iItemId']))
+            $sJsObject .= '_' . md5($aParams['iModuleId'] . '-' . $aParams['iSellerId'] . '-' . $aParams['iItemId']);
+        
+        return $sJsObject;
+    }
+
+    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 getButtonSingleJs($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->_getButtonJs(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 getButtonRecurringJs($iClientId, $iVendorId, $aParams = array())
+    {
+    	$aVendor = $this->_oModule->getVendorInfo((int)$iVendorId);
+
+        return $this->_getButtonJs(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 '';
+
+        $sName = '';
+        if(!empty($aSubscription['plan']['name']))
+            $sName = $aSubscription['plan']['name'];
+        else if(!empty($aSubscription['plan']['product'])){
+            $oProduct = $this->_retrieveProduct($aSubscription['plan']['product']);
+            if($oProduct !== false) 
+                $sName = $oProduct->name;
+        }
+
+        $sNone = _t('_bx_payment_txt_none');
+        return $this->_oModule->_oTemplate->parseHtmlByName('strp_details_recurring.html', array(
+            'plan' => $sName,
+            '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'], BX_FORMAT_DATE_TIME, true),
+            'started' => !empty($aSubscription['start']) ? bx_time_js($aSubscription['start'], BX_FORMAT_DATE_TIME, true) : $sNone,
+            'trial_start' => !empty($aSubscription['trial_start']) ? bx_time_js($aSubscription['trial_start'], BX_FORMAT_DATE_TIME, true) : $sNone,
+            'trial_end' => !empty($aSubscription['trial_end']) ? bx_time_js($aSubscription['trial_end'], BX_FORMAT_DATE_TIME, true) : $sNone,
+            'cperiod_start' => !empty($aSubscription['current_period_start']) ? bx_time_js($aSubscription['current_period_start'], BX_FORMAT_DATE_TIME, true) : $sNone,
+            'cperiod_end' => !empty($aSubscription['current_period_end']) ? bx_time_js($aSubscription['current_period_end'], BX_FORMAT_DATE_TIME, true) : $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;
+
+            $sItems = $this->_oModule->_oConfig->descriptorA2S(array($iVendorId, $iModuleId, $aItem['id'], $iItemCount));
+            if(!$this->_oModule->_oDb->updateOrderPending($iPendingId, array('items' => $sItems)))
+                return $aResultError;
+
+            $this->_oModule->callReregisterSubscriptionItem($iModuleId, array($aPending['client_id'], $aPending['seller_id'], $iItemId, $aItem['id'], $aPending['order']));
+
+            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 getSubscription($iPendingId, $sCustomerId, $sSubscriptionId)
+    {
+        $oSubscription = $this->_retrieveSubscription($sCustomerId, $sSubscriptionId);
+        if($oSubscription === false)
+            return array();
+
+        $aSubscription = $oSubscription->jsonSerialize();
+        if(empty($aSubscription) || !is_array($aSubscription))
+            return array();
+
+        $sStatus = isset($this->_aSbsStatuses[$aSubscription['status']]) ? $this->_aSbsStatuses[$aSubscription['status']] : BX_PAYMENT_SBS_STATUS_UNKNOWN;
+
+        return array(
+            'status' => $sStatus,
+            'created' => $aSubscription['created'],
+            'started' => !empty($aSubscription['start']) ? $aSubscription['start'] : 0,
+            'trial_start' => !empty($aSubscription['trial_start']) ? $aSubscription['trial_start'] : 0,
+            'trial_end' => !empty($aSubscription['trial_end']) ? $aSubscription['trial_end'] : 0,
+            'cperiod_start' => !empty($aSubscription['current_period_start']) ? $aSubscription['current_period_start'] : 0,
+            'cperiod_end' => !empty($aSubscription['current_period_end']) ? $aSubscription['current_period_end'] : 0,
+        );
+    }
+
+    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 _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 _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 _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;
+    }
+
+    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 _retrieveProduct($sId)
+    {
+        $oProduct = null;
+        bx_alert($this->_oModule->_oConfig->getName(), $this->_sName . '_retrieve_product', 0, false, array(
+            'product_id' => &$sId,
+            'product_object' => &$oProduct
+        ));
+
+        if(!empty($oProduct))
+            return $oProduct;
+
+        try {
+            $oProduct = \Stripe\Product::retrieve($sId);
+        }
+        catch (Exception $oException) {
+            return $this->_processException('Retrieve Product Error: ', $oException);
+        }
+
+        return $oProduct;
+    }
+
+    protected function _listPlans($iLimit = 100)
+    {
+        if($iLimit <= 0)
+            $iLimit = 1;
+        if($iLimit > 100)
+            $iLimit = 100;
+
+        try {
+            $oPlans = \Stripe\Plan::all(array('limit' => $iLimit));
+        }
+        catch (Exception $oException) {
+            return $this->_processException('List Plans Error: ', $oException);
+        }
+
+        return $oPlans;
+    }
+
+    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->getObjectSubscriptions()->prolong($aPending);
+
+        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->getObjectSubscriptions()->cancelLocal($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 _getButton($sType, $iClientId, $iVendorId, $aParams = array())
+    {
+        list($sJsCode, $sJsMethod) = $this->_getButtonJs($sType, $iClientId, $iVendorId, $aParams);
+
+    	return $this->_oModule->_oTemplate->parseHtmlByName('strp_button_' . $sType . '.html', array(
+            'type' => $sType,
+            'caption' => _t($this->_sLangsPrefix . 'strp_txt_checkout_with_' . $sType, $this->_sCaption),  
+            'onclick' => $sJsMethod,
+            'js_object' => $this->_oModule->_oConfig->getJsObject($this->_sName),
+            'js_code' => $sJsCode,
+    	));
+    }
+}
+
+/** @} */

+ 610 - 0
modules/boonex/payment/updates/13.0.0_13.0.1/source/classes/BxPaymentProviderStripeV3.php

@@ -0,0 +1,610 @@
+<?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('BxPaymentProviderStripeBasic.php');
+
+class BxPaymentProviderStripeV3 extends BxPaymentProviderStripeBasic implements iBxBaseModPaymentProvider
+{
+    protected $_oStripe;
+
+    function __construct($aConfig)
+    {
+        parent::__construct($aConfig);
+
+        $this->_aIncludeJs = array(
+            'stripe_v3.js'
+        );
+
+        $this->_oStripe = null;
+    }
+
+    public function actionGetSessionRecurring()
+    {
+        $aClient = $this->_oModule->getProfileInfo();
+
+        $aParams = array(
+            'seller_id' => (int)bx_get('seller_id'),
+            'seller_provider' => bx_process_input(bx_get('seller_provider')),
+            'module_id' => (int)bx_get('module_id'),
+            'item_id' => (int)bx_get('item_id'),
+            'item_count' => (int)bx_get('item_count'),
+            'item_addons' => bx_get('item_addons'),
+            'redirect' => bx_process_input(bx_get('redirect')),
+            'custom' => bx_process_input(bx_get('custom')),
+        );
+
+        $aItems = array($this->_oModule->_oConfig->descriptorA2S(array(
+            'seller_id' => $aParams['seller_id'],
+            'module_id' => $aParams['module_id'],
+            'item_id' => $aParams['item_id'],
+            'item_count' => $aParams['item_count'],
+        )));
+
+        $oCart = $this->_oModule->getObjectCart();
+        $aCartInfo = $oCart->getInfo(BX_PAYMENT_TYPE_RECURRING, $aClient['id'], $aParams['seller_id'], $aItems);
+        if(empty($aCartInfo) || !is_array($aCartInfo))
+            return echoJson(array('msg' => _t('_bx_payment_err_nothing_selected')));
+
+        $aItem = reset($aCartInfo['items']);
+
+        $aSessionParams = array(
+            'cancel_url' => $aItem['url'],
+            'success_url' => bx_append_url_params($this->_oModule->_oConfig->getUrl('URL_SUBSCRIBE_JSON'), array_merge($aParams, array(
+                'session_id' => '{CHECKOUT_SESSION_ID}'
+            )))
+        );
+
+        $sSessionId = $this->_createSession(BX_PAYMENT_TYPE_RECURRING, $aSessionParams, $aClient, $aCartInfo);
+        if($sSessionId === false)
+            return echoJson(array('msg' => _t('_bx_payment_err_cannot_perform')));
+
+        $sJsObject = $this->getJsObject(array(
+            'iModuleId' => $aParams['module_id'],
+            'iSellerId' => $aParams['seller_id'],
+            'iItemId' => $aParams['item_id']
+        ));
+
+        return echoJson(array(
+            'code' => 0, 
+            'session_id' => $sSessionId,
+            'eval' => $sJsObject . '.onSubscribe(oData);'
+        ));
+    }
+
+    public function initializeCheckout($iPendingId, $aCartInfo, $sRedirect = '')
+    {
+        $sSessionId = bx_process_input(bx_get('session_id'));
+
+    	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:
+                $mixedResult = $this->_getSession(BX_PAYMENT_TYPE_SINGLE, $sSessionId);
+                if($mixedResult === false || $mixedResult['status'] != 'paid')
+                    return $this->_sLangsPrefix . 'err_cannot_perform';
+
+                header("Location: " . $this->getReturnDataUrl($aVendor['id'], array(
+                    'order_id' => $mixedResult['order_id'],
+                    'customer_id' => $mixedResult['customer_id'], 
+                    'pending_id' => $aPending['id'],
+                    'redirect' => $sRedirect
+                )));
+                exit;
+
+            case BX_PAYMENT_TYPE_RECURRING:
+                $mixedResult = $this->_getSession(BX_PAYMENT_TYPE_RECURRING, $sSessionId);
+                if($mixedResult === false)
+                    return $this->_sLangsPrefix . 'err_cannot_perform';
+
+                header("Location: " . $this->getReturnDataUrl($aVendor['id'], array(
+                    'order_id' => $mixedResult['order_id'],
+                    'customer_id' => $mixedResult['customer_id'],
+                    'pending_id' => $aPending['id'],
+                    'redirect' => $sRedirect
+                )));
+                exit;
+        }
+    }
+
+    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);
+                $oPaymentIntent = $this->_retrievePaymentIntent($sOrderId);
+                if($oCustomer === false || $oPaymentIntent === false)
+                    return array('code' => 4, 'message' => $this->_sLangsPrefix . 'err_cannot_perform');
+
+                $aCustomer = $oCustomer->jsonSerialize();
+                $aPaymentIntent = $oPaymentIntent->jsonSerialize();
+                if(empty($aCustomer) || !is_array($aCustomer) || empty($aPaymentIntent) || !is_array($aPaymentIntent))
+                    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' => $aPaymentIntent['status'] == 'succeeded'
+                ));
+                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'],
+                    'paid' => $this->isSubscriptionStatus(BX_PAYMENT_SBS_STATUS_ACTIVE, $aSubscription),
+                    'trial' => $this->isSubscriptionStatus(BX_PAYMENT_SBS_STATUS_TRIAL, $aSubscription)
+                ));
+                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 getButtonSingle($iClientId, $iVendorId, $aParams = array())
+    {
+        if(!isset($aParams['sAction']))
+            return '';
+
+        return $aParams['sAction'] . parent::getButtonSingle($iClientId, $iVendorId, $aParams);
+    }
+
+    public function overwriteCheckoutParamsSingle($aParams, &$oGrid)
+    {
+        $aClient = $this->_oModule->getProfileInfo();
+
+        $oCart = $this->_oModule->getObjectCart();
+        $aCartInfo = $oCart->getInfo(BX_PAYMENT_TYPE_SINGLE, $aClient['id'], $aParams['seller_id'], $aParams['items']);
+        if(empty($aCartInfo) || !is_array($aCartInfo))
+            return array('msg' => _t('_bx_payment_err_nothing_selected'));
+
+        $aSessionParams = array(
+            'cancel_url' => $oCart->serviceGetCartUrl($aParams['seller_id']),
+            'success_url' => bx_append_url_params($this->_oModule->_oConfig->getUrl('URL_CART_CHECKOUT'), array_merge($aParams, array(
+                'session_id' => '{CHECKOUT_SESSION_ID}'
+            )))
+        );
+
+        $sSessionId = $this->_createSession(BX_PAYMENT_TYPE_SINGLE, $aSessionParams, $aClient, $aCartInfo);
+        if($sSessionId === false)
+            return array('msg' => _t('_bx_payment_err_cannot_perform'));
+
+        return array(
+            'eval' => $this->_oModule->_oConfig->getJsObject($this->_sName) . '.onCartCheckout(oData);', 
+            'session_id' => $sSessionId
+        );
+    }
+
+    public function createTax($sName, $fPercentage, $bInclusive = false)
+    {
+        $oTax = null;
+        $aTax = [
+            'display_name' => $sName,
+            'percentage' => $fPercentage,
+            'inclusive' => $bInclusive,
+        ];
+
+        bx_alert($this->_oModule->_oConfig->getName(), $this->_sName . '_create_tax', 0, false, array(
+            'tax_object' => &$oTax, 
+            'tax_params' => &$aTax
+        ));
+
+        try {
+            if(empty($oTax))
+                $oTax = $this->_getStripe()->taxRates->create($aTax);
+        }
+        catch (Exception $oException) {
+            return $this->_processException('Create Tax Error: ', $oException);
+        }
+
+        $aResult = $oTax->jsonSerialize();
+        if(empty($aResult) || !is_array($aResult))
+            return false;
+
+        return $aResult['id'];
+    }
+
+    public function retrieveTax($sId)
+    {
+        $oTax = null;
+        bx_alert($this->_oModule->_oConfig->getName(), $this->_sName . '_retrieve_tax', 0, false, array(
+            'tax_id' => &$sId,
+            'tax_object' => &$oTax
+        ));
+
+        try {
+            if(empty($oTax))
+                $oTax = $this->_getStripe()->taxRates->retrieve($sId);
+        }
+        catch (Exception $oException) {
+            return $this->_processException('Retrieve Tax Error: ', $oException);
+        }
+
+        return $oTax;
+    }
+
+    public function getVerificationCodeSession($iVendorId, $iCustomerId, $fAmount, $sCurrency)
+    {
+        $sCode = $this->_getVerificationCodeSession($iVendorId, $iCustomerId, $fAmount, $sCurrency);
+
+        bx_alert($this->_oModule->_oConfig->getName(), $this->_sName . '_get_code_session', 0, false, array(
+            'provider' => $this,
+            'vendor_id' => $iVendorId, 
+            'customer_id' => $iCustomerId,
+            'amount' => $fAmount,
+            'currency' => $sCurrency,
+            'override_result' => &$sCode
+        ));
+
+        return $sCode;
+    }
+
+    public function checkVerificationCodeSession($iVendorId, $iCustomerId, $aResult)
+    {
+        $bCheckResult = $this->_checkVerificationCodeSession($iVendorId, $iCustomerId, $aResult);
+
+        bx_alert($this->_oModule->_oConfig->getName(), $this->_sName . '_verify_session', 0, false, array(
+            'provider' => $this,
+            'vendor_id' => $iVendorId, 
+            'customer_id' => $iCustomerId,
+            'result' => $aResult,
+            'override_result' => &$bCheckResult
+        ));
+
+        return $bCheckResult;
+    }
+
+    protected function _getStripe()
+    {
+        if(empty($this->_oStripe))
+            $this->_oStripe = new \Stripe\StripeClient($this->_getSecretKey());
+
+        return $this->_oStripe;
+    }
+            
+    /*
+     * Related Docs: https://stripe.com/docs/api/customers/retrieve
+     */
+    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 = $this->_getStripe()->customers->retrieve($sId);
+        }
+        catch (Exception $oException) {
+            return $this->_processException('Retrieve Customer Error: ', $oException);
+        }
+
+        return $oCustomer;
+    }
+
+    /*
+     * Related Docs: https://stripe.com/docs/api/checkout/sessions/create
+     */
+    protected function _createSession($sType, $aParams, &$aClient, &$aCartInfo)
+    {
+        $iAmountPrecision = 2;
+        $fAmount = 100 * round((float)$aCartInfo['items_price'], $iAmountPrecision);
+
+        $sMode = '';
+        $aLineItems = array();
+        $aMetaItems = array();
+
+        switch($sType) {
+            case BX_PAYMENT_TYPE_SINGLE:
+                $sMode = 'payment';
+
+                foreach($aCartInfo['items'] as $aItem) {
+                    $aProductData = array(
+                        'name' => $aItem['title']
+                    );
+                    if(!empty($aItem['description']))
+                        $aProductData['description'] = strmaxtextlen(strip_tags($aItem['description']), 60, '...');
+
+                    $aLineItems[] = array(
+                        'price_data' => array(
+                            'currency' => $aCartInfo['vendor_currency_code'],
+                            'product_data' => $aProductData,
+                            'unit_amount' => 100 * round($this->_oModule->_oConfig->getPrice($sType, $aItem), $iAmountPrecision),
+                        ),
+                        'quantity' => $aItem['quantity'],
+                    );
+
+                    $aMetaItems[] = array('v' => $aCartInfo['vendor_id'], 'c' => $aClient['id'], 'm' => $aItem['module_id'], 'i' => $aItem['id']);
+                }
+                break;
+
+            case BX_PAYMENT_TYPE_RECURRING:
+                $sMode = 'subscription';
+
+                foreach($aCartInfo['items'] as $aItem) {
+                    $aLineItems[] = array(
+                        'price' => $aItem['name'],
+                        'quantity' => $aItem['quantity'],
+                    );
+
+                    $aMetaItems[] = array('v' => $aCartInfo['vendor_id'], 'c' => $aClient['id'], 'm' => $aItem['module_id'], 'i' => $aItem['id']);
+                }
+                break;
+        }
+
+        $oSession = null;
+        $aSession = array(
+            'payment_method_types' => ['card'],
+            'customer_email' => !empty($aClient['email']) ? $aClient['email'] : '',
+            'line_items' => $aLineItems,
+            'mode' => $sMode,
+            'success_url' => $aParams['success_url'],
+            'cancel_url' => $aParams['cancel_url'],
+            'metadata' => array(
+                'vendor' => $aCartInfo['vendor_id'],
+                'client' => $aClient['id'],
+                'type' => $sType, 
+                'items' => serialize($aMetaItems),
+                'verification' => $this->getVerificationCodeSession($aCartInfo['vendor_id'], $aClient['id'], $fAmount, $aCartInfo['vendor_currency_code'])
+            )
+        );
+
+        bx_alert($this->_oModule->_oConfig->getName(), $this->_sName . '_create_session', 0, false, array(
+            'session_object' => &$oSession, 
+            'session_params' => &$aSession
+        ));
+
+        try {
+            if(empty($oSession))
+                $oSession = $this->_getStripe()->checkout->sessions->create($aSession);
+        }
+        catch (Exception $oException) {
+            return $this->_processException('Create Session Error: ', $oException);
+        }
+
+        $aResult = $oSession->jsonSerialize();
+        if(empty($aResult) || !is_array($aResult))
+            return false;
+
+        if(!$this->checkVerificationCodeSession($aCartInfo['vendor_id'], $aClient['id'], $aResult))
+            return false;
+
+        return $aResult['id'];
+    }
+
+    protected function _getSession($sType, $sId)
+    {
+        $oSession = $this->_retrieveSession($sId);
+        if($oSession === false)
+            return array();
+
+        $aSession = $oSession->jsonSerialize();
+        if(empty($aSession) || !is_array($aSession))
+            return array();
+
+        $aResult = array(
+            'id' => $aSession['id'],
+            'order_id' => $aSession['payment_intent'],
+            'customer_id' => $aSession['customer'],
+            'status' => $aSession['payment_status']
+        );
+
+        switch($sType) {
+            case BX_PAYMENT_TYPE_SINGLE:
+                $aResult['order_id'] = $aSession['payment_intent'];
+                break;
+
+            case BX_PAYMENT_TYPE_RECURRING:
+                $aResult['order_id'] = $aSession['subscription'];
+                break;
+        }
+
+        return $aResult;
+    }
+
+    /*
+     * Related Docs: https://stripe.com/docs/api/checkout/sessions/retrieve
+     */
+    protected function _retrieveSession($sId) {
+        $oSession = null;
+        bx_alert($this->_oModule->_oConfig->getName(), $this->_sName . '_retrieve_session', 0, false, array(
+            'session_id' => &$sId,
+            'session_object' => &$oSession
+        ));
+
+        try {
+            if(empty($oSession))
+                $oSession = $this->_getStripe()->checkout->sessions->retrieve($sId);
+        }
+        catch (Exception $oException) {
+            return $this->_processException('Retrieve Session Error: ', $oException);
+        }
+
+        return $oSession;
+    }
+    
+    /*
+     * Related Docs: https://stripe.com/docs/api/payment_intents/retrieve
+     */
+    protected function _retrievePaymentIntent($sId) {
+        $oPaymentIntent = null;
+        bx_alert($this->_oModule->_oConfig->getName(), $this->_sName . '_retrieve_payment_intent', 0, false, array(
+            'payment_intent_id' => &$sId,
+            'payment_intent_object' => &$oPaymentIntent
+        ));
+
+        try {
+            if(empty($oPaymentIntent))
+                $oPaymentIntent = $this->_getStripe()->paymentIntents->retrieve($sId);
+        }
+        catch (Exception $oException) {
+            return $this->_processException('Retrieve Payment Intent Error: ', $oException);
+        }
+
+        return $oPaymentIntent;
+    }
+    
+    /*
+     * Related Docs: https://stripe.com/docs/api/subscriptions/retrieve
+     */
+    protected function _retrieveSubscription($sCustomerId, $sSubscriptionId)
+    {
+        $oSubscription = null;
+        bx_alert($this->_oModule->_oConfig->getName(), $this->_sName . '_retrieve_subscription', 0, false, array(
+            'subscription_id' => &$sId,
+            'subscription_object' => &$oSubscription
+        ));
+
+        try {
+            if(empty($oSubscription))
+                $oSubscription = $this->_getStripe()->subscriptions->retrieve($sSubscriptionId);
+        }
+        catch (Exception $oException) {
+            return $this->_processException('Retrieve Subscription Error: ', $oException);
+        }
+
+        return $oSubscription;
+    }
+
+    protected function _getButton($sType, $iClientId, $iVendorId, $aParams = array())
+    {
+        list($sJsCode, $sJsMethod) = $this->_getButtonJs($sType, $iClientId, $iVendorId, $aParams);
+
+    	if($sType == BX_PAYMENT_TYPE_SINGLE)
+            return $sJsCode;
+
+        return parent::_getButton($sType, $iClientId, $iVendorId);
+    }
+
+    protected function _getButtonJs($sType, $iClientId, $iVendorId, $aParams = array())
+    {
+        $sClientEmail = '';
+    	if(!empty($iClientId) && ($oClient = BxDolProfile::getInstance($iClientId)) !== false)
+            $sClientEmail = $oClient->getAccountObject()->getEmail();
+
+        $sPublicKey = '';
+    	bx_alert($this->_oModule->_oConfig->getName(), $this->_sName . '_get_button', 0, $iClientId, array(
+            'type' => &$sType, 
+            'public_key' => &$sPublicKey
+        ));
+
+        $sJsMethod = '';
+        $sJsObject = $this->getJsObject($aParams);
+        switch($sType) {
+            case BX_PAYMENT_TYPE_SINGLE:
+                $sJsMethod = 'void(0)';
+                break;
+
+            case BX_PAYMENT_TYPE_RECURRING:
+                $sJsMethod = $sJsObject . '.subscribe(this)';
+                break;
+        }
+
+        return array($this->_oModule->_oTemplate->getJsCode($this->_sName, array_merge(array(
+            'js_object' => $sJsObject,
+            'sProvider' => $this->_sName,
+            'sPublicKey' => !empty($sPublicKey) ? $sPublicKey : $this->_getPublicKey(),
+            'sVendorName' => '',
+            'sVendorCurrency' => '',
+            'sVendorIcon' => '',
+            'sClientEmail' => $sClientEmail,
+        ), $aParams)), $sJsMethod);
+    }
+
+    protected function _getVerificationCodeSession($iVendorId, $iCustomerId, $fAmount, $sCurrency)
+    {
+        return md5(implode('#-#', array(
+            (int)$iVendorId,
+            (int)$iCustomerId,
+            (float)$fAmount,
+            strtoupper($sCurrency)
+        )));
+    }
+
+    protected function _checkVerificationCodeSession($iVendorId, $iCustomerId, $aResult)
+    {
+        return !empty($aResult['metadata']['verification']) && $aResult['metadata']['verification'] == $this->getVerificationCodeSession($iVendorId, $iCustomerId, $aResult['amount_total'], $aResult['currency']);
+    }
+
+    protected function _processException($sMessage, &$oException)
+    {
+        if(method_exists($oException, 'getError')) {
+            $sError = $oException->getError()->message;
+            $aError = $oException->getError()->toArray();
+        }
+        else { 
+            $sError = $oException->getMessage();
+            $aError = array();
+        }
+
+        $this->log($sMessage . $sError);
+        if(!empty($aError))
+            $this->log($aError);
+
+        return false;
+    }
+}
+
+/** @} */

+ 527 - 0
modules/boonex/payment/updates/13.0.0_13.0.1/source/classes/BxPaymentTemplate.php

@@ -0,0 +1,527 @@
+<?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 addJsCssInvoices()
+    {
+    	$this->addCss(array('invoices.css'));
+    }
+
+    public function displayBlockCheckoutOffline($oBuyer, $oSeller, $aData)
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        $sTxtQt = _t('_bx_payment_txt_checkout_qt');
+
+        $aTmplVarsItems = array();
+        foreach($aData['items'] as $iIndex => $aItem)
+            $aTmplVarsItems[] = array(
+                'item_index' => $iIndex + 1,
+                'item_title' => $aItem['title'],
+                'item_quantity' => $aItem['quantity'] . $sTxtQt
+            );
+
+        $this->addCss(array('checkout.css'));
+        return $this->parseHtmlByName('checkout_offline.html', array(
+            'message' => _t('_bx_payment_txt_checkout_for', $oSeller->getDisplayName()),
+            'bx_repeat:items' => $aTmplVarsItems,
+            'amount' => $aData['currency']['sign'] . sprintf("%.2f", (float)($aData['amount'])),
+            'redirect_url' => $aData['return_url']
+        ));
+    }
+
+    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())
+    {
+        return $this->displaySubscribeJsWithAddons($iVendorId, $sVendorProvider, $iModuleId, $iItemId, $iItemCount, '', $sRedirect, $aCustom);
+    }
+
+    public function displaySubscribeJsWithAddons($iVendorId, $sVendorProvider, $iModuleId, $iItemId, $iItemCount = 1, $sItemAddons = '', $sRedirect = '', $aCustom = array())
+    {
+        $aSellerProviders = $this->_oDb->getVendorInfoProvidersRecurring($iVendorId);
+        if(empty($sVendorProvider) && count($aSellerProviders) == 1) {
+            $aCartItem = array($iVendorId, $iModuleId, $iItemId, $iItemCount, $sItemAddons);
+
+            $this->addJsCssCart(BX_PAYMENT_TYPE_RECURRING, $iVendorId);
+            return $this->getModule()->getProviderButtonJs($aCartItem, array_shift($aSellerProviders), $sRedirect, $aCustom);
+        }
+
+        return array(
+            $this->displayCartJs(BX_PAYMENT_TYPE_RECURRING, $iVendorId),
+            $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)) : ''
+            ))
+        );
+    }
+
+    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)
+    {
+        $sGrid = $this->_oConfig->getObject('grid_' . $sType);
+        $oGrid = BxDolGrid::getObjectInstance($sGrid);
+        if(!$oGrid || empty($iSellerId))
+            return MsgBox(_t($this->_sLangsPrefix . 'msg_no_results'));
+
+        $oGrid->addQueryParam('seller_id', $iSellerId);
+
+        $this->addJsCssOrders();
+        return $this->displayJsCode($sType, array(
+            'sObjNameGrid' => $sGrid,
+            'sParamsDivider' => $this->_oConfig->getDivider('DIVIDER_GRID_FILTERS'),
+            'sTextSearchInput' => _t('_sys_grid_search')
+        )) . $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']);
+
+        $aTmplVarsLicense = array();
+        if(in_array($sType, array(BX_PAYMENT_ORDERS_TYPE_PROCESSED, BX_PAYMENT_ORDERS_TYPE_HISTORY)))
+            $aTmplVarsLicense = array(
+                'txt_license' => _t($this->_sLangsPrefix . 'txt_license'),
+                'license' => $aOrder['license']
+            );
+
+        $bTmplVarsShowSlrAtr = !empty($aOrder['author_id']) && $aOrder['seller_id'] != $aOrder['author_id'];
+
+        $aTmplVarsAuthor = array();
+        if($bTmplVarsShowSlrAtr) {
+            $aAuthor = $oModule->getProfileInfo((int)$aOrder['author_id']);
+
+            $aTmplVarsAuthor = array(
+                'txt_author' => _t($this->_sLangsPrefix . 'txt_author'),
+                'author_name' => $aAuthor['name'],
+                'author_url' => $aAuthor['link'],
+            );
+        }
+
+        $aTmplVarsSeller = array(
+            'txt_seller' => _t($this->_sLangsPrefix . 'txt_seller'),
+            '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']
+                )
+            ),
+        );
+        
+        $aResult = array_merge(array(
+            'txt_client' => _t($this->_sLangsPrefix . 'txt_client'),
+            '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_seller' => array(
+                'condition' => $bTmplVarsShowSlrAtr,
+                'content' => $aTmplVarsSeller
+            ),
+            'bx_if:show_license' => array(
+                'condition' => !empty($aTmplVarsLicense),
+                'content' => $aTmplVarsLicense
+            ),
+            'order' => $aOrder['order'],
+            'provider' => _t('_bx_payment_txt_name_' . $aOrder['provider']),
+            'error' => $aOrder['error_msg'],
+            'date' => bx_time_js($aOrder['date'], BX_FORMAT_DATE_TIME, true),
+            'bx_if:show_author' => array(
+                'condition' => $bTmplVarsShowSlrAtr,
+                'content' => $aTmplVarsAuthor
+            ),
+            'bx_repeat:items' => array()
+        ), $aTmplVarsSeller);
+
+        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 displayBlockInvoices()
+    {
+        $sGrid = $this->_oConfig->getObject('grid_invoices');
+        $oGrid = BxDolGrid::getObjectInstance($sGrid);
+        if(!$oGrid)
+            return MsgBox(_t($this->_sLangsPrefix . 'msg_no_results'));
+
+        $this->addJsCssInvoices();
+        return $oGrid->getCode();
+    }
+
+    public function displayItems($sType, $aItems = array())
+    {
+        $aTmplVarsItems = array();
+
+        $oForm = new BxTemplFormView(array());
+
+        if(!empty($aItems) && is_array($aItems))
+            foreach($aItems as $aItem) {
+                $fPrice = $this->_oConfig->getPrice($sType, $aItem);
+
+                $aInputHidden = array(
+                    'type' => 'hidden',
+                    'name' => 'item-price-' . $aItem['id'],
+                    'value' => $fPrice
+                );
+                $aInputCheckbox = array(
+                    'type' => 'checkbox',
+                    'name' => 'items[]',
+                    'value' => $aItem['id']
+                );
+                $aInputText = array(
+                    'type' => 'text',
+                    'name' => 'item-quantity-' . $aItem['id'],
+                    'value' => 1
+                );
+
+                $aTmplVarsItems[$aItem['name']] = array(
+                    'id' => $aItem['id'],
+                    'price' => $fPrice,
+                    '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']
+                        )
+                    ),
+                    'input_hidden' => $oForm->genRow($aInputHidden),
+                    'input_checkbox' => $oForm->genRow($aInputCheckbox),
+                    'input_text' => $oForm->genRow($aInputText),
+                );
+            }
+
+        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();
+
+        $aTmplVarsProviders = array();
+        foreach($aProviders as $sProvider => $aProvider) {
+            list($sJsCode, $sJsOnclick) = $oModule->getProviderButtonJs($aCartItem, $aProvider, $sRedirect, $aCustom);
+
+            $sCaptionKey = '_bx_payment_txt_subscribe_' . $aProvider['name'];
+            $sCaptionValue = _t($sCaptionKey);
+            if(strcmp($sCaptionKey, $sCaptionValue) == 0)
+                $sCaptionValue = _t($aProvider['caption']);
+
+            $aTmplVarsProviders[] = array(
+                'button' => $this->parseHtmlByName('providers_select_button.html', array(
+                    'onclick' => $sJsOnclick,
+                    'title' => _t('_bx_payment_txt_checkout_with', $sCaptionValue),
+                    'js_code' => $sJsCode
+                ))
+            );
+        }
+
+        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)
+    {
+        $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 $aResult;
+
+        $aSubscription = $this->_oDb->getSubscription(array('type' => 'pending_id', 'pending_id' => $iId));
+        if(empty($aSubscription) || !is_array($aSubscription))
+            return $aResult;
+
+        $mixedResult = $this->getModule()->isAllowedManage($aPending);
+        if($mixedResult !== true)
+            return array('code' => 2, 'message' => $mixedResult);
+            
+        $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 $aResult;
+
+        $mixedContent = $oProvider->$sMethod($iId, $aSubscription['customer_id'], $aSubscription['subscription_id']);
+        if(empty($mixedContent))
+            return $aResult;
+        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/13.0.0_13.0.1/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' => '13.0.1',
+    'vendor' => 'Boonex',
+    'help_url' => 'http://feed.una.io/?section={module_name}',
+
+    'compatible_with' => array(
+        '13.0.0-A3'
+    ),
+
+    /**
+     * '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(),
+);
+
+/** @} */

+ 768 - 0
modules/boonex/payment/updates/13.0.0_13.0.1/source/install/langs/en.xml

@@ -0,0 +1,768 @@
+<?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_options_category_general"><![CDATA[General]]></string>
+    <string name="_bx_payment_options_category_commissions"><![CDATA[Commissions]]></string>
+    <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[Main seller (To sell on behalf of the site)]]></string>
+    <string name="_bx_payment_option_credits_only"><![CDATA[Pay with Credits only mode ('Credits' app should be installed).]]></string>
+    <string name="_bx_payment_option_single_seller"><![CDATA[Single seller mode (To sell everything on behalf of the 'Main seller').]]></string>
+    <string name="_bx_payment_option_inv_issue_day"><![CDATA[Day of month when invoices are automatically generated (1, 2, 3, etc)]]></string>
+    <string name="_bx_payment_option_inv_lifetime"><![CDATA[Due date - days after invoice date]]></string>
+    <string name="_bx_payment_option_inv_expiraction_notify"><![CDATA[Number of days before invoice expiration to notify payer]]></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>
+
+    <string name="_bx_payment_page_title_sys_invoices"><![CDATA[Invoices]]></string>
+    <string name="_bx_payment_page_title_invoices"><![CDATA[Invoices]]></string>
+    <string name="_bx_payment_page_block_title_invoices"><![CDATA[Invoices]]></string>
+    
+    <string name="_bx_payment_page_title_sys_checkout_offline"><![CDATA[Offline Checkout]]></string>
+    <string name="_bx_payment_page_title_checkout_offline"><![CDATA[Offline Checkout]]></string>
+    <string name="_bx_payment_page_block_title_sys_checkout_offline"><![CDATA[Offline Checkout]]></string>
+    <string name="_bx_payment_page_block_title_checkout_offline"><![CDATA[]]></string>
+
+    <!-- MENUS -->
+    <string name="_bx_payment_lmi_cpt_providers"><![CDATA[Providers]]></string>
+    <string name="_bx_payment_lmi_cpt_commissions"><![CDATA[Commissions]]></string>
+
+    <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_item_title_system_admt_invoices"><![CDATA[Invoices]]></string>
+    <string name="_bx_payment_menu_item_title_admt_invoices"><![CDATA[Invoices]]></string>
+    <string name="_bx_payment_menu_item_title_admt_addon_counter1_caption"><![CDATA[paid]]></string>
+    <string name="_bx_payment_menu_item_title_admt_addon_counter2_caption"><![CDATA[overdue]]></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_request_cancelation"><![CDATA[Request Cancellation]]></string>
+    <string name="_bx_payment_menu_item_title_sbs_request_cancelation"><![CDATA[Request Cancellation]]></string>
+    <string name="_bx_payment_menu_item_title_system_sbs_cancel"><![CDATA[Cancel Subscription]]></string>
+    <string name="_bx_payment_menu_item_title_sbs_cancel"><![CDATA[Cancel Subscription]]></string>
+
+    <!-- GRIDS -->
+    <string name="_bx_payment_grid_column_title_pdrs_caption"><![CDATA[Caption]]></string>
+    <string name="_bx_payment_grid_column_title_pdrs_description"><![CDATA[Description]]></string>
+    <string name="_bx_payment_grid_column_title_pdrs_for_visitor"><![CDATA[For visitors]]></string>
+    <string name="_bx_payment_grid_column_title_pdrs_for_single"><![CDATA[One Time]]></string>
+    <string name="_bx_payment_grid_column_title_pdrs_for_recurring"><![CDATA[Recurring]]></string>
+    <string name="_bx_payment_grid_column_title_pdrs_single_seller"><![CDATA[Single Seller]]></string>
+    <string name="_bx_payment_grid_column_title_pdrs_time_tracker"><![CDATA[Time Tracker]]></string>
+    <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_author_id"><![CDATA[Author]]></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_item"><![CDATA[Product]]></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_client_email"><![CDATA[Email]]></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_status"><![CDATA[Status]]></string>
+    <string name="_bx_payment_grid_column_title_sbs_date"><![CDATA[Date]]></string>
+    <string name="_bx_payment_grid_column_title_sbs_date_add"><![CDATA[Created]]></string>
+    <string name="_bx_payment_grid_column_title_sbs_date_next"><![CDATA[Next Payment]]></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_column_title_cms_caption"><![CDATA[Caption]]></string>
+    <string name="_bx_payment_grid_column_title_cms_description"><![CDATA[Description]]></string>
+    <string name="_bx_payment_grid_column_title_cms_acl_id"><![CDATA[Membership]]></string>
+    <string name="_bx_payment_grid_column_title_cms_percentage"><![CDATA[Percentage]]></string>
+    <string name="_bx_payment_grid_column_title_cms_installment"><![CDATA[Fixed fee]]></string>
+    <string name="_bx_payment_grid_column_title_inv_commissionaire_id"><![CDATA[Payee]]></string>
+    <string name="_bx_payment_grid_column_title_inv_committent_id"><![CDATA[Payer]]></string>
+    <string name="_bx_payment_grid_column_title_inv_name"><![CDATA[Name]]></string>
+    <string name="_bx_payment_grid_column_title_inv_period_start"><![CDATA[Period start]]></string>
+    <string name="_bx_payment_grid_column_title_inv_period_end"><![CDATA[Period end]]></string>
+    <string name="_bx_payment_grid_column_title_inv_amount"><![CDATA[Amount]]></string>
+    <string name="_bx_payment_grid_column_title_inv_date_issue"><![CDATA[Issue date]]></string>
+    <string name="_bx_payment_grid_column_title_inv_date_due"><![CDATA[Due date]]></string>
+    <string name="_bx_payment_grid_column_title_inv_status"><![CDATA[Status]]></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_sbs_delete"><![CDATA[Remove]]></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_grid_action_title_cms_add"><![CDATA[Add]]></string>
+    <string name="_bx_payment_grid_action_title_cms_edit"><![CDATA[Edit]]></string>
+    <string name="_bx_payment_grid_action_title_cms_delete"><![CDATA[Delete]]></string>
+    <string name="_bx_payment_grid_action_title_inv_edit"><![CDATA[Edit]]></string>
+    <string name="_bx_payment_grid_action_title_inv_delete"><![CDATA[Delete]]></string>
+    <string name="_bx_payment_grid_action_title_inv_pay"><![CDATA[Pay]]></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>
+    <string name="_bx_payment_popup_title_cms_add"><![CDATA[Add Monthly Commission]]></string>
+    <string name="_bx_payment_popup_title_cms_edit"><![CDATA[Edit Monthly Commission]]></string>
+    <string name="_bx_payment_popup_title_inv_edit"><![CDATA[Edit Invoice]]></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_details_form"><![CDATA[Details Form]]></string>
+    <string name="_bx_payment_form_details_display_edit"><![CDATA[Edit Details Display]]></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>
+    
+    <string name="_bx_payment_form_commissions_form"><![CDATA[Commissions Form]]></string>
+    <string name="_bx_payment_form_commissions_display_add"><![CDATA[Add Commission Display]]></string>
+    <string name="_bx_payment_form_commissions_display_edit"><![CDATA[Edit Commission Display]]></string>
+    <string name="_bx_payment_form_commissions_input_caption_sys"><![CDATA[Caption]]></string>
+    <string name="_bx_payment_form_commissions_input_caption"><![CDATA[Caption]]></string>
+    <string name="_bx_payment_form_commissions_input_caption_err"><![CDATA[This field is essential. Please, fill it in.]]></string>
+    <string name="_bx_payment_form_commissions_input_description_sys"><![CDATA[Description]]></string>
+    <string name="_bx_payment_form_commissions_input_description"><![CDATA[Description]]></string>
+    <string name="_bx_payment_form_commissions_input_acl_id_sys"><![CDATA[Membership Level]]></string>
+    <string name="_bx_payment_form_commissions_input_acl_id"><![CDATA[Membership Level]]></string>
+    <string name="_bx_payment_form_commissions_input_percentage_sys"><![CDATA[Percentage]]></string>
+    <string name="_bx_payment_form_commissions_input_percentage"><![CDATA[Percentage]]></string>
+    <string name="_bx_payment_form_commissions_input_installment_sys"><![CDATA[Fixed fee]]></string>
+    <string name="_bx_payment_form_commissions_input_installment"><![CDATA[Fixed fee]]></string>
+    <string name="_bx_payment_form_commissions_input_submit_sys"><![CDATA[Submit]]></string>
+    <string name="_bx_payment_form_commissions_input_submit"><![CDATA[Submit]]></string>
+    <string name="_bx_payment_form_commissions_input_cancel_sys"><![CDATA[Cancel]]></string>
+    <string name="_bx_payment_form_commissions_input_cancel"><![CDATA[Cancel]]></string>
+    
+    <string name="_bx_payment_form_invoices_form"><![CDATA[Invoices Form]]></string>
+    <string name="_bx_payment_form_invoices_display_edit"><![CDATA[Edit Invoice Display]]></string>
+    <string name="_bx_payment_form_invoices_input_amount_sys"><![CDATA[Amount]]></string>
+    <string name="_bx_payment_form_invoices_input_amount"><![CDATA[Amount]]></string>
+    <string name="_bx_payment_form_invoices_input_amount_err"><![CDATA[This field is essential. Please, fill it in.]]></string>
+    <string name="_bx_payment_form_invoices_input_date_due_sys"><![CDATA[Due date]]></string>
+    <string name="_bx_payment_form_invoices_input_date_due"><![CDATA[Due date]]></string>
+    <string name="_bx_payment_form_invoices_input_date_due_err"><![CDATA[This field is essential. Please, fill it in.]]></string>
+    <string name="_bx_payment_form_invoices_input_status_sys"><![CDATA[Status]]></string>
+    <string name="_bx_payment_form_invoices_input_status"><![CDATA[Status]]></string>
+    <string name="_bx_payment_form_invoices_input_submit_sys"><![CDATA[Submit]]></string>
+    <string name="_bx_payment_form_invoices_input_submit"><![CDATA[Submit]]></string>
+    <string name="_bx_payment_form_invoices_input_cancel_sys"><![CDATA[Cancel]]></string>
+    <string name="_bx_payment_form_invoices_input_cancel"><![CDATA[Cancel]]></string>
+
+    <string name="_bx_payment_form_input_email_err_cor_or_emp"><![CDATA[Use correct email address or leave empty.]]></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>
+    <string name="_bx_payment_acl_action_manage_any_purchase"><![CDATA[Manage Any Purchase]]></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>
+
+    <string name="_bx_payment_et_txt_name_expiration_notification_seller"><![CDATA[Subscription expiration notification (for seller).]]></string>
+    <string name="_bx_payment_et_txt_subject_expiration_notification_seller"><![CDATA[Subscription expiration notification.]]></string>
+    <string name="_bx_payment_et_txt_body_expiration_notification_seller"><![CDATA[{email_header}
+<p>Hello,</p>
+<p>A subscription purchased by '{profile_name}' expired.</p>
+<p>Subscription info:<br />ID: {sibscription_id}<br />Customer: {sibscription_customer}<br />Date: {sibscription_date}</p>
+<p><b>Note</b>. An associated data will be removed shortly.</p>
+{email_footer}]]></string>
+
+    <string name="_bx_payment_et_txt_name_expiration_notification_client"><![CDATA[Subscription expiration notification (for client).]]></string>
+    <string name="_bx_payment_et_txt_subject_expiration_notification_client"><![CDATA[Subscription expiration notification.]]></string>
+    <string name="_bx_payment_et_txt_body_expiration_notification_client"><![CDATA[{email_header}
+<p>Hello,</p>
+<p>Your subscription purchased from '{profile_name}' expired.</p>
+<p>Subscription info:<br />ID: {sibscription_id}<br />Customer: {sibscription_customer}<br />Date: {sibscription_date}</p>
+<p><b>Note</b>. An associated data will be removed shortly.</p>
+{email_footer}]]></string>
+
+    <string name="_bx_payment_et_txt_name_expiring_notification_committent"><![CDATA[Invoice expiring notification.]]></string>
+    <string name="_bx_payment_et_txt_subject_expiring_notification_committent"><![CDATA[Invoice expiring notification.]]></string>
+    <string name="_bx_payment_et_txt_body_expiring_notification_committent"><![CDATA[{email_header}
+<p>Hello,</p>
+<p>Your invoice '{invoice}' is expiring in '{days}' day(s).</p>
+<p>Invoice info:<br />Period start: {period_start}<br />Period end: {period_end}<br />Issue date: {date_issue}<br />Due date: {date_due}</p>
+{email_footer}]]></string>
+
+    <string name="_bx_payment_et_txt_name_overdue_notification_committent"><![CDATA[Overdue invoice notification.]]></string>
+    <string name="_bx_payment_et_txt_subject_overdue_notification_committent"><![CDATA[Overdue invoice notification.]]></string>
+    <string name="_bx_payment_et_txt_body_overdue_notification_committent"><![CDATA[{email_header}
+<p>Hello,</p>
+<p>Your invoice '{invoice}' is overdue '{date_due}'.</p>
+<p>Invoice info:<br />Period start: {period_start}<br />Period end: {period_end}<br />Issue date: {date_issue}<br />Due date: {date_due}</p>
+{email_footer}]]></string>
+
+    <string name="_bx_payment_et_txt_name_checkout_offline"><![CDATA[Offline checkout attempt.]]></string>
+    <string name="_bx_payment_et_txt_subject_checkout_offline"><![CDATA[An attempt to pay with cash.]]></string>
+    <string name="_bx_payment_et_txt_body_checkout_offline"><![CDATA[{email_header}
+<p>Hello,</p>
+<p>A site member <a href="{profile_link}">{profile_name}</a> wanted to pay you with cash for:</p>
+<p>{items}</p>
+<p>Amount: {amount}<br />Date: {date}</p>
+<p>Go to the <a href="{pending_orders_link}">pending orders page</a> to process the order once the payment is received.</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_performed"><![CDATA[The action was successfully performed.]]></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_msg_confirm_cancelation"><![CDATA[Are you sure you want to cancel your subscription?]]></string>
+        <string name="_bx_payment_msg_single_seller"><![CDATA[Single seller mode is enabled. <a href="{0}">Got to</a> single shopping cart.]]></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[Buying from your own store is not permitted.]]></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>
+	<string name="_bx_payment_err_already_registered"><![CDATA[Subscription with the same data was already registered.]]></string>
+        <string name="_bx_payment_err_not_supported"><![CDATA[Operation isn't supported.]]></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_checkout_with_cash"><![CDATA[Checkout with cash]]></string>
+        <string name="_bx_payment_txt_checkout_for"><![CDATA[A message was sent to the seller ({0}), that you want to pay with cash for the following items. He should contact you shortly.]]></string>
+        <string name="_bx_payment_txt_checkout_qt"><![CDATA[qt.]]></string>
+        <string name="_bx_payment_txt_checkout_item"><![CDATA[{0} ({1}qt.)<br />]]></string>
+	<string name="_bx_payment_txt_client"><![CDATA[Client]]></string>
+        <string name="_bx_payment_txt_license"><![CDATA[License]]></string>
+	<string name="_bx_payment_txt_seller"><![CDATA[Seller]]></string>
+        <string name="_bx_payment_txt_author"><![CDATA[Author]]></string>
+	<string name="_bx_payment_txt_order"><![CDATA[Order ID]]></string>
+        <string name="_bx_payment_txt_price"><![CDATA[Price]]></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>
+        <string name="_bx_payment_txt_unsubscribe_yes"><![CDATA[Cancel automatically]]></string>
+        <string name="_bx_payment_txt_unsubscribe_no"><![CDATA[Do not cancel]]></string>
+        <string name="_bx_payment_txt_all_authors"><![CDATA[All Authors]]></string>
+        <string name="_bx_payment_txt_all_clients"><![CDATA[All Clients]]></string>
+        <string name="_bx_payment_txt_all_modules"><![CDATA[All Modules]]></string>
+        <string name="_bx_payment_txt_all_items"><![CDATA[All Items]]></string>
+        <string name="_bx_payment_txt_status_scheduled"><![CDATA[Scheduled]]></string>
+        <string name="_bx_payment_txt_status_trial"><![CDATA[Trial]]></string>
+        <string name="_bx_payment_txt_status_active"><![CDATA[Active]]></string>
+        <string name="_bx_payment_txt_status_paid"><![CDATA[Paid]]></string>
+        <string name="_bx_payment_txt_status_unpaid"><![CDATA[Unpaid]]></string>
+        <string name="_bx_payment_txt_status_overdue"><![CDATA[Overdue]]></string>
+        <string name="_bx_payment_txt_status_paused"><![CDATA[Paused]]></string>
+        <string name="_bx_payment_txt_status_canceled"><![CDATA[Canceled]]></string>
+        <string name="_bx_payment_txt_status_unknown"><![CDATA[Unknown]]></string>
+        <string name="_bx_payment_txt_invoice_title"><![CDATA[Invoice {0} from {1}]]></string>
+        <string name="_bx_payment_txt_invoice_description"><![CDATA[For a period between {0} and {1}]]></string>
+        <string name="_bx_payment_txt_payment_description"><![CDATA[Payment on {0} site.]]></string>
+
+        <!-- Offline payment provider -->
+	<string name="_bx_payment_off_cpt"><![CDATA[Offline]]></string>
+	<string name="_bx_payment_off_dsc"><![CDATA[For offline payments like cash, etransfer, etc.]]></string>
+	<string name="_bx_payment_off_active_cpt"><![CDATA[Active]]></string>
+	<string name="_bx_payment_off_active_dsc"><![CDATA[Activate(Deactivate) provider]]></string>
+        <string name="_bx_payment_off_checkout_email_cpt"><![CDATA[Email]]></string>
+        <string name="_bx_payment_off_checkout_email_dsc"><![CDATA[Email to send notifications about checkout attempts to. Leave empty to receive notifications on your profile email.]]></string>
+        <string name="_bx_payment_off_err_not_available"><![CDATA[Offline payment provider isn't available for online payments.]]></string>
+        <string name="_bx_payment_txt_name_offline"><![CDATA[Cash]]></string>
+	<string name="_bx_payment_txt_cart_offline"><![CDATA[Cash]]></string>
+
+        <!-- Credits payment provider -->
+	<string name="_bx_payment_cdt_cpt"><![CDATA[Credits]]></string>
+	<string name="_bx_payment_cdt_dsc"><![CDATA[Credits payment provider]]></string>
+	<string name="_bx_payment_cdt_active_cpt"><![CDATA[Active]]></string>
+	<string name="_bx_payment_cdt_active_dsc"><![CDATA[Activate(Deactivate) provider]]></string>
+        <string name="_bx_payment_cdt_msg_charged"><![CDATA[Payment was successfully processed.]]></string>
+        <string name="_bx_payment_cdt_msg_subscribed"><![CDATA[Thank you! Subscription created. Please, check your email for further instructions.]]></string>
+        <string name="_bx_payment_cdt_err_not_available"><![CDATA[Checkout with Credits isn't available now.]]></string>
+        <string name="_bx_payment_cdt_err_wrong_transaction"><![CDATA[Transaction verification failed.]]></string>
+        <string name="_bx_payment_txt_name_credits"><![CDATA[Credits]]></string>
+	<string name="_bx_payment_txt_cart_credits"><![CDATA[Credits]]></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>
+
+        <!-- PayPal API payment provider -->
+	<string name="_bx_payment_pp_api_cpt"><![CDATA[PayPal API]]></string>
+	<string name="_bx_payment_pp_api_dsc"><![CDATA[PayPal payment provider (API based integration)]]></string>
+	<string name="_bx_payment_pp_api_active_cpt"><![CDATA[Active]]></string>
+	<string name="_bx_payment_pp_api_active_dsc"><![CDATA[Activate(Deactivate) provider]]></string>
+        <string name="_bx_payment_pp_api_hidden_cpt"><![CDATA[Hidden]]></string>
+	<string name="_bx_payment_pp_api_hidden_dsc"><![CDATA[Hide provider if you don't want to accept new payments but already have active subscriptions.]]></string>
+	<string name="_bx_payment_pp_api_mode_cpt"><![CDATA[Mode]]></string>
+	<string name="_bx_payment_pp_api_mode_dsc"><![CDATA[Mode to process payments]]></string>
+	<string name="_bx_payment_pp_api_mode_live"><![CDATA[live]]></string>
+	<string name="_bx_payment_pp_api_mode_test"><![CDATA[test]]></string>
+        <string name="_bx_payment_pp_api_live_account_cpt"><![CDATA[Account (live)]]></string>
+        <string name="_bx_payment_pp_api_live_account_dsc"><![CDATA[Email address which is used to access your PayPal account.]]></string>
+        <string name="_bx_payment_pp_api_live_client_id_cpt"><![CDATA[Client ID (live)]]></string>
+        <string name="_bx_payment_pp_api_live_client_id_dsc"><![CDATA[A part of application's credentials.]]></string>
+        <string name="_bx_payment_pp_api_live_secret_cpt"><![CDATA[Secret (live)]]></string>
+        <string name="_bx_payment_pp_api_live_secret_dsc"><![CDATA[A part of application's credentials.]]></string>
+        <string name="_bx_payment_pp_api_test_account_cpt"><![CDATA[Account (test)]]></string>
+        <string name="_bx_payment_pp_api_test_account_dsc"><![CDATA[Email address which is used to access your PayPal account.]]></string>
+        <string name="_bx_payment_pp_api_test_client_id_cpt"><![CDATA[Client ID (test)]]></string>
+        <string name="_bx_payment_pp_api_test_client_id_dsc"><![CDATA[A part of application's credentials.]]></string>
+        <string name="_bx_payment_pp_api_test_secret_cpt"><![CDATA[Secret (test)]]></string>
+        <string name="_bx_payment_pp_api_test_secret_dsc"><![CDATA[A part of application's credentials.]]></string>
+        <string name="_bx_payment_pp_api_return_data_url_cpt"><![CDATA[Data return URL]]></string>
+        <string name="_bx_payment_pp_api_notify_url_cpt"><![CDATA[Webhooks URL]]></string>
+        <string name="_bx_payment_pp_api_err_cannot_capture"><![CDATA[Can't finalize checkout.]]></string>
+        <string name="_bx_payment_pp_api_err_no_item"><![CDATA[There is nothing to subscribe.]]></string>
+        <string name="_bx_payment_pp_api_err_no_subscription"><![CDATA[The subscription data isn't available or incorrect.]]></string>
+        <string name="_bx_payment_pp_api_err_subscription_not_confirmed"><![CDATA[Subscription wasn't confirmed.]]></string>
+        <string name="_bx_payment_pp_api_msg_captured"><![CDATA[Payment was successfully processed.]]></string>
+        <string name="_bx_payment_pp_api_msg_subscribed"><![CDATA[Thank you! Subscription created. Please, check your email for further instructions.]]></string>
+        <string name="_bx_payment_txt_name_paypal_api"><![CDATA[PayPal]]></string>
+	<string name="_bx_payment_txt_cart_paypal_api"><![CDATA[PayPal]]></string>
+        <string name="_bx_payment_txt_subscribe_paypal_api"><![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[If enabled, users can checkout using Chargebee's hosted pages.]]></string>
+	<string name="_bx_payment_cbee_v3_cpt"><![CDATA[Chargebee]]></string>
+    <string name="_bx_payment_cbee_v3_dsc"><![CDATA[If enabled, users can checkout using Chargebee's drop-in script.]]></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_hidden_cpt"><![CDATA[Hidden]]></string>
+	<string name="_bx_payment_cbee_hidden_dsc"><![CDATA[Hide provider if you don't want to accept new payments but already have active subscriptions.]]></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_check_amount_cpt"><![CDATA[Enable amount checking]]></string>
+	<string name="_bx_payment_cbee_check_amount_dsc"><![CDATA[Enable amount checking for Chargebee Webhooks (recomended). However checking should be disabled when discounts and coupons are used.]]></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_cancellation_email_cpt"><![CDATA[Cancellation Email]]></string>
+        <string name="_bx_payment_cbee_expiration_email_cpt"><![CDATA[Expiration Email]]></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_charged"><![CDATA[Payment was successfully processed.]]></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_cbee_txt_checkout_with_single"><![CDATA[Checkout with {0}]]></string>
+    <string name="_bx_payment_cbee_txt_checkout_with_recurring"><![CDATA[Checkout with {0}]]></string>
+    <string name="_bx_payment_cbee_menu_item_title_manager"><![CDATA[Self-serve Portal]]></string>
+	<string name="_bx_payment_txt_name_chargebee"><![CDATA[Chargebee]]></string>
+	<string name="_bx_payment_txt_name_chargebee_v3"><![CDATA[Chargebee]]></string>
+	<string name="_bx_payment_txt_cart_chargebee"><![CDATA[Chargebee]]></string>
+	<string name="_bx_payment_txt_cart_chargebee_v3"><![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_hidden_cpt"><![CDATA[Hidden]]></string>
+	<string name="_bx_payment_rcrl_hidden_dsc"><![CDATA[Hide provider if you don't want to accept new payments but already have active subscriptions.]]></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_v3_cpt"><![CDATA[Stripe]]></string>
+	<string name="_bx_payment_strp_v3_dsc"><![CDATA[Stripe payment provider with 3D Secure authentication for Strong Customer Authentication (SCA) support. Note, it doesn't allow to use recurring payments with trial period.]]></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_hidden_cpt"><![CDATA[Hidden]]></string>
+	<string name="_bx_payment_strp_hidden_dsc"><![CDATA[Hide provider if you don't want to accept new payments but already have active subscriptions.]]></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_expiration_email_cpt"><![CDATA[Expiration 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>
+    <string name="_bx_payment_txt_name_stripe_v3"><![CDATA[Stripe]]></string>
+    <string name="_bx_payment_txt_cart_stripe_v3"><![CDATA[Stripe]]></string>
+
+    <!-- _bx_payment_aina_mode_live payment provider -->
+    <string name="_bx_payment_aina_cpt"><![CDATA[Apple In-App]]></string>
+    <string name="_bx_payment_aina_dsc"><![CDATA[Apple In-App payment provider]]></string>
+    <string name="_bx_payment_aina_active_cpt"><![CDATA[Active]]></string>
+    <string name="_bx_payment_aina_active_dsc"><![CDATA[Activate(Deactivate) provider.]]></string>
+    <string name="_bx_payment_aina_hidden_cpt"><![CDATA[Hidden]]></string>
+    <string name="_bx_payment_aina_hidden_dsc"><![CDATA[Recommended. The provider should be hidden in WEB because it can be used in mobile app only.]]></string>
+    <string name="_bx_payment_aina_secret_cpt"><![CDATA[Shared Secret]]></string>
+    <string name="_bx_payment_aina_secret_dsc"><![CDATA[It's the app-specific unique code to receive receipts for auto-renewable subscriptions.]]></string>
+    <string name="_bx_payment_aina_notify_url_cpt"><![CDATA[URL for App Store Server Notifications]]></string>
+    <string name="_bx_payment_aina_menu_item_title_cancel"><![CDATA[Cancel]]></string>
+    <string name="_bx_payment_aina_msg_charged"><![CDATA[Payment was successfully processed.]]></string>
+    <string name="_bx_payment_aina_msg_subscribed"><![CDATA[Thank you! Subscription created. Please, check your email for further instructions.]]></string>
+    <string name="_bx_payment_txt_name_apple_in_app"><![CDATA[Apple In-App]]></string>
+    <string name="_bx_payment_txt_cart_apple_in_app"><![CDATA[Apple In-App]]></string>
+</resources>

+ 692 - 0
modules/boonex/payment/updates/13.0.0_13.0.1/source/install/sql/install.sql

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

+ 182 - 0
modules/boonex/payment/updates/13.0.0_13.0.1/source/js/chargebee_v3.js

@@ -0,0 +1,182 @@
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Payment Payment
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+function BxPaymentProviderChargebeeV3(oOptions) {
+    this.init(oOptions);
+}
+
+BxPaymentProviderChargebeeV3.prototype = new BxPaymentMain();
+
+BxPaymentProviderChargebeeV3.prototype.init = function(oOptions) {
+    this._sProvider = oOptions.sProvider;
+    this._sActionsUrl = oOptions.sActionUrl;
+    this._sObjName = oOptions.sObjName == undefined ? 'oPaymentProviderChargebeeV3' : oOptions.sObjName;
+    this._sAnimationEffect = oOptions.sAnimationEffect == undefined ? 'fade' : oOptions.sAnimationEffect;
+    this._iAnimationSpeed = oOptions.iAnimationSpeed == undefined ? 'slow' : oOptions.iAnimationSpeed;
+
+    this._sObjNameCart = oOptions.sObjNameCart == undefined ? '' : oOptions.sObjNameCart;
+    this._iClientId = oOptions.iClientId == undefined ? 0 : oOptions.iClientId;
+    this._iSellerId = oOptions.iSellerId == undefined ? 0 : oOptions.iSellerId;
+
+    //-- For Single payments only.
+    this._aItems = oOptions.aItems == undefined ? {} : oOptions.aItems;
+
+    //-- For Recurring payments only.
+    this._iModuleId  = oOptions.iModuleId == undefined ? 0 : oOptions.iModuleId;
+    this._iItemId  = oOptions.iItemId == undefined ? 0 : oOptions.iItemId;
+    this._sItemName = oOptions.sItemName == undefined ? '' : oOptions.sItemName;
+    this._iItemCount  = oOptions.iItemCount == undefined ? 0 : oOptions.iItemCount;
+    this._sItemAddons  = oOptions.sItemAddons == undefined ? '' : oOptions.sItemAddons;
+    this._sRedirect  = oOptions.sRedirect == undefined ? '' : oOptions.sRedirect;
+    this._sCustom  = oOptions.sCustom == undefined ? '' : oOptions.sCustom;
+
+    this._rHandler = Chargebee.init({
+        site: oOptions.sSite
+    });
+    this._rHandler = Chargebee.getInstance();
+};
+
+BxPaymentProviderChargebeeV3.prototype.checkout = function(oLink) {
+    return this.checkoutWithAddons(oLink);
+};
+
+BxPaymentProviderChargebeeV3.prototype.checkoutWithAddons = function(oLink, mixedAddons) {
+    var $this = this;
+    var oDate = new Date();
+
+    oLink = jQuery(oLink);
+    if(oLink.hasClass('bx-btn-disabled'))
+        return;
+
+    oLink.addClass('bx-btn-disabled');
+
+    this._rHandler.openCheckout({
+        hostedPage: function() {
+            var oParams = {
+                url: $this._sActionsUrl + 'call/' + $this._sProvider + '/get_hosted_page_single/' + $this._iClientId + '/' + $this._iSellerId + '/',
+                dataType: 'json'
+            };
+            if(mixedAddons != undefined)
+                oParams.data = {
+                    addons: mixedAddons
+                };
+
+            return $.post(oParams);
+        },
+        success: function(sHostedPageId) {
+            $this.loadingInPopup(oLink, true);
+
+            var oParams = {
+                seller_id: $this._iSellerId,
+                provider: $this._sProvider,
+                items: $this._aItems,
+                page_id: sHostedPageId,
+                _t: oDate.getTime()
+            };
+
+            $.post(
+                $this._sActionsUrl + 'initialize_checkout_json/',
+                oParams,
+                function(oData){
+                    $this.loadingInPopup(oLink, true);
+
+                    processJsonData(oData);
+                },
+                'json'
+            );
+        },
+        close: function() {
+            oLink.removeClass('bx-btn-disabled');
+        }
+    });
+
+    return false;
+};
+
+
+BxPaymentProviderChargebeeV3.prototype.subscribe = function(oLink) {
+    return this.subscribeWithAddons(oLink);
+};
+
+BxPaymentProviderChargebeeV3.prototype.subscribeWithAddons = function(oLink, mixedAddons) {
+    var $this = this;
+    var oDate = new Date();
+
+    oLink = jQuery(oLink);
+    if(oLink.hasClass('bx-btn-disabled'))
+        return;
+
+    oLink.addClass('bx-btn-disabled');
+
+    this._rHandler.openCheckout({
+        hostedPage: function() {
+            return $.post({
+                url: $this._sActionsUrl + 'call/' + $this._sProvider + '/get_hosted_page_recurring/' + $this._iClientId + '/' + $this._iSellerId + '/' + $this._sItemName + '/',
+                data: {
+                    addons: mixedAddons != undefined ? mixedAddons : $this._sItemAddons
+                }, 
+                dataType: 'json'
+            });
+        },
+        success: function(sHostedPageId) {
+            $this.loadingInPopup(oLink, true);
+
+            var oParams = {
+                seller_id: $this._iSellerId,
+                seller_provider: $this._sProvider,
+                module_id: $this._iModuleId,
+                item_id: $this._iItemId,
+                item_count: $this._iItemCount,
+                item_addons: $this._sItemAddons,
+                redirect: $this._sRedirect,
+                custom: $this._sCustom,
+                page_id: sHostedPageId,
+                _t: oDate.getTime()
+            };
+
+            $.post(
+                $this._sActionsUrl + 'subscribe_json/',
+                oParams,
+                function(oData){
+                    $this.loadingInPopup(oLink, true);
+
+                    processJsonData(oData);
+                },
+                'json'
+            );
+        },
+        close: function() {
+            oLink.removeClass('bx-btn-disabled');
+        }
+    });
+
+    return false;
+};
+
+BxPaymentProviderChargebeeV3.prototype.manage = function(oLink, iPendingId) {
+	var $this = this;
+    var oDate = new Date();
+
+    $(".bx-popup-applied:visible").dolPopupHide();
+
+	this._rHandler.setPortalSession(function() {
+    	return $.post({
+    		url: $this._sActionsUrl + 'call/' + $this._sProvider + '/get_portal/' + iPendingId + '/',
+    		dataType: 'json'
+    	});
+    });
+
+	var cbPortal = this._rHandler.createChargebeePortal();
+	cbPortal.open({});
+
+	return false;
+};
+
+/** @} */

+ 2 - 0
modules/boonex/payment/updates/13.0.0_13.0.1/source/template/cbee_v3_button_single.html

@@ -0,0 +1,2 @@
+<a class="bx-btn bx-def-margin-top-auto" href="__link__" onclick="javascript: return __js_object__.checkout(this)">__caption__</a>
+__js_code__

+ 18 - 0
modules/boonex/payment/updates/13.0.0_13.0.1/source/template/items.html

@@ -0,0 +1,18 @@
+<div id="__html_id__" class="bx-payment-pa-items">
+    <div class="bx-payment-pa-items-cnt">
+        <bx_repeat:items>
+            <div class="bx-payment-pa-item bx-def-margin-thd-top-auto bx-clearfix">
+                <div class="bx-payment-pa-item-chb">__input_hidden____input_checkbox__</div>
+                <div class="bx-payment-pa-item-title">
+                    <div class="bx-payment-pa-item-title-cnt bx-def-padding-sec-leftright">
+                        <bx_if:link>
+                            <a href="__url__" target="_blank" title="__title__">__title__</a>
+                        </bx_if:link>
+                        <bx_if:text>__title__</bx_if:text>
+                    </div>
+                </div>
+                <div class="bx-payment-pa-item-quantity">__input_text__</div>
+            </div>
+        </bx_repeat:items>
+    </div>
+</div>

+ 51 - 0
modules/boonex/persons/updates/13.0.0_13.0.1/install/config.php

@@ -0,0 +1,51 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ */
+
+$aConfig = array(
+    /**
+     * Main Section.
+     */
+    'title' => 'Persons',
+    'version_from' => '13.0.0',
+    'version_to' => '13.0.1',
+    'vendor' => 'BoonEx',
+
+    'compatible_with' => array(
+        '13.0.0-A3'
+    ),
+
+    /**
+     * 'home_dir' and 'home_uri' - should be unique. Don't use spaces in 'home_uri' and the other special chars.
+     */
+    'home_dir' => 'boonex/persons/updates/update_13.0.0_13.0.1/',
+    'home_uri' => 'persons_update_1300_1301',
+
+    'module_dir' => 'boonex/persons/',
+    'module_uri' => 'persons',
+
+    'db_prefix' => 'bx_persons_',
+    'class_prefix' => 'BxPersons',
+
+    /**
+     * Installation/Uninstallation Section.
+     */
+    'install' => array(
+        'execute_sql' => 1,
+        'update_files' => 1,
+        'update_languages' => 1,
+        'clear_db_cache' => 1,
+    ),
+
+    /**
+     * Category for language keys.
+     */
+    'language_category' => 'Persons',
+
+    /**
+     * Files Section
+     */
+    'delete_files' => array(),
+);

+ 47 - 0
modules/boonex/persons/updates/13.0.0_13.0.1/install/installer.php

@@ -0,0 +1,47 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ */
+
+class BxPersonsUpdater extends BxDolStudioUpdater
+{
+    function __construct($aConfig)
+    {
+        parent::__construct($aConfig);
+    }
+
+    public function actionExecuteSql($sOperation)
+    {
+        if($sOperation == 'install') {
+            if(!$this->oDb->isFieldExists('bx_persons_data', 'last_name'))
+                $this->oDb->query("ALTER TABLE `bx_persons_data` ADD `last_name` varchar(255) NOT NULL AFTER `fullname`");
+
+            if(!$this->oDb->isFieldExists('bx_persons_cmts', 'cmt_cf'))
+                $this->oDb->query("ALTER TABLE `bx_persons_cmts` ADD `cmt_cf` int(11) NOT NULL default '1' AFTER `cmt_pinned`");
+
+            if(!$this->oDb->isFieldExists('bx_persons_views_track', 'id'))
+                $this->oDb->query("ALTER TABLE `bx_persons_views_track` ADD `id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT FIRST");
+
+            if(!$this->oDb->isFieldExists('bx_persons_votes', 'id'))
+                $this->oDb->query("ALTER TABLE `bx_persons_votes` ADD `id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT FIRST");
+
+            if(!$this->oDb->isFieldExists('bx_persons_favorites_track', 'id'))
+                $this->oDb->query("ALTER TABLE `bx_persons_favorites_track` ADD `id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT FIRST");
+
+            if(!$this->oDb->isFieldExists('bx_persons_reports', 'id'))
+                $this->oDb->query("ALTER TABLE `bx_persons_reports` ADD `id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT FIRST");
+
+            if(!$this->oDb->isFieldExists('bx_persons_meta_keywords', 'id'))
+                $this->oDb->query("ALTER TABLE `bx_persons_meta_keywords` ADD `id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT FIRST");
+
+            if(!$this->oDb->isFieldExists('bx_persons_meta_mentions', 'id'))
+                $this->oDb->query("ALTER TABLE `bx_persons_meta_mentions` ADD `id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT FIRST");
+
+            if(!$this->oDb->isFieldExists('bx_persons_scores', 'id'))
+                $this->oDb->query("ALTER TABLE `bx_persons_scores` ADD `id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT FIRST");
+        }
+
+        return parent::actionExecuteSql($sOperation);
+    }
+}

+ 16 - 0
modules/boonex/persons/updates/13.0.0_13.0.1/install/langs/en.xml

@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources name="en" flag="gb" title="English">
+	<string_add name="_bx_persons_form_profile_input_sys_last_name"><![CDATA[Last Name]]></string_add>
+	<string_add name="_bx_persons_form_profile_input_last_name"><![CDATA[Last Name]]></string_add>
+	<string_add name="_bx_persons_page_title_browse_familiar"><![CDATA[People You May Know]]></string_add>
+	<string_add name="_bx_persons_page_block_title_profile_friends_mutual"><![CDATA[Mutual Friends]]></string_add>
+	<string_add name="_bx_persons_page_block_title_sys_familiar_profiles"><![CDATA[Familiar People]]></string_add>
+	<string_add name="_bx_persons_page_block_title_familiar_profiles"><![CDATA[People You May Know]]></string_add>
+	<string_add name="_bx_persons_menu_item_title_system_manage_cf"><![CDATA[Manage audience]]></string_add>
+	<string_add name="_bx_persons_menu_item_title_manage_cf"><![CDATA[Manage audience]]></string_add>
+	<string_add name="_bx_persons_grid_action_title_adm_manage_cf"><![CDATA[Manage audience]]></string_add>
+
+	<string_upd name="_bx_persons_form_profile_input_sys_fullname"><![CDATA[Name]]></string_upd>
+	<string_upd name="_bx_persons_form_profile_input_fullname"><![CDATA[Name]]></string_upd>
+	<string_upd name="_bx_persons_form_profile_input_birthday_err"><![CDATA[Age between 18 and 99]]></string_upd>
+</resources>

+ 36 - 0
modules/boonex/persons/updates/13.0.0_13.0.1/install/sql/enable.sql

@@ -0,0 +1,36 @@
+-- PAGES
+DELETE FROM `sys_pages_blocks` WHERE `object`='bx_persons_view_profile' AND `title` IN ('_bx_persons_page_block_title_cover_block', '_bx_persons_page_block_title_profile_friends_mutual');
+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_persons_view_profile', 0, 'bx_persons', '_bx_persons_page_block_title_sys_cover_block', '_bx_persons_page_block_title_cover_block', 3, 2147483647, 'service', 'a:2:{s:6:\"module\";s:10:\"bx_persons\";s:6:\"method\";s:12:\"entity_cover\";}', 0, 0, 1, 0),
+('bx_persons_view_profile', 0, 'bx_persons', '', '_bx_persons_page_block_title_profile_friends_mutual', 11, 2147483647, 'service', 'a:2:{s:6:\"module\";s:10:\"bx_persons\";s:6:\"method\";s:22:\"profile_friends_mutual\";}', 0, 0, 1, 0);
+
+DELETE FROM `sys_pages_blocks` WHERE `object`='' AND `module`='bx_persons' AND `title`='_bx_persons_page_block_title_cover_block';
+
+DELETE FROM `sys_pages_blocks` WHERE `object`='' AND `module`='bx_persons' AND `title`='_bx_persons_page_block_title_familiar_profiles';
+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_persons', '_bx_persons_page_block_title_sys_familiar_profiles', '_bx_persons_page_block_title_familiar_profiles', 11, 2147483647, 'service', 'a:3:{s:6:\"module\";s:10:\"bx_persons\";s:6:\"method\";s:24:\"browse_familiar_profiles\";s:6:\"params\";a:4:{s:10:\"connection\";s:20:\"sys_profiles_friends\";s:9:\"unit_view\";s:4:\"unit\";s:13:\"empty_message\";b:0;s:13:\"ajax_paginate\";b:0;}}', 0, 1, 1, IFNULL(@iBlockOrder, 0) + 1);
+
+
+-- MENUS
+UPDATE `sys_menu_items` SET `onclick`='bx_menu_popup(''sys_set_acl_level'', window, {id:{value:''sys_acl_set_{profile_id}'', force:true}, closeOnOuterClick: false, removeOnClose: true, displayMode: ''box'', cssClass: ''''}, {profile_id: {profile_id}});' WHERE `set_name`='bx_persons_view_actions' AND `name`='profile-set-acl-level';
+
+DELETE FROM `sys_menu_items` WHERE `set_name`='bx_persons_snippet_meta' AND `name`='friends-mutual';
+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_persons_snippet_meta', 'bx_persons', 'friends-mutual', '_sys_menu_item_title_system_sm_friends_mutual', '_sys_menu_item_title_sm_friends_mutual', '', '', '', '', '', 2147483647, 0, 0, 1, 0);
+
+UPDATE `sys_menu_items` SET `collapsed`='0' WHERE `set_name`='sys_profile_followings' AND `name`='persons';
+
+DELETE FROM `sys_menu_items` WHERE `set_name`='bx_persons_menu_manage_tools' AND `name`='manage-cf';
+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_persons_menu_manage_tools', 'bx_persons', 'manage-cf', '_bx_persons_menu_item_title_system_manage_cf', '_bx_persons_menu_item_title_manage_cf', 'javascript:void(0)', 'javascript:{js_object}.onClickManageCf({content_id});', '_self', 'filter', '', 2147483647, 1, 0, 6);
+
+
+-- METATAGS
+UPDATE `sys_objects_metatags` SET `module`='bx_persons' WHERE `object`='bx_persons';
+
+
+-- GRIDS
+DELETE FROM `sys_grid_actions` WHERE `object`='bx_persons_administration' AND `name`='lock_cf';
+INSERT INTO `sys_grid_actions` (`object`, `type`, `name`, `title`, `icon`, `icon_only`, `confirm`, `order`) VALUES
+('bx_persons_administration', 'single', 'lock_cf', '_bx_persons_grid_action_title_adm_lock_cf', 'filter', 1, 0, 5);

+ 4 - 0
modules/boonex/persons/updates/13.0.0_13.0.1/install/sql/install.sql

@@ -0,0 +1,4 @@
+-- FORMS
+DELETE FROM `sys_form_inputs` WHERE `object`='bx_person' AND `name`='last_name';
+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`, `rateable`) VALUES 
+('bx_person', 'bx_persons', 'last_name', '', '', 0, 'text', '_bx_persons_form_profile_input_sys_last_name', '_bx_persons_form_profile_input_last_name', '', 1, 0, 0, '', '', '', '', '', '', 'Xss', '', 1, 0, '');

+ 235 - 0
modules/boonex/persons/updates/13.0.0_13.0.1/source/classes/BxPersonsConfig.php

@@ -0,0 +1,235 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Persons Persons
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+class BxPersonsConfig extends BxBaseModProfileConfig
+{
+    function __construct($aModule)
+    {
+        parent::__construct($aModule);
+
+        $this->_aMenuItems2MethodsSubmenu = array_merge($this->_aMenuItems2MethodsSubmenu, array(
+            'persons-profile-relations' => 'checkAllowedRelationsView',
+            'persons-profile-subscriptions' => 'checkAllowedSubscriptionsView'
+        ));
+
+        $this->_aMenuItems2MethodsActions = array_merge($this->_aMenuItems2MethodsActions, array(
+            'view-persons-profile' => 'checkAllowedView',
+            'edit-persons-profile' => 'checkAllowedEdit',
+            'edit-persons-cover' => 'checkAllowedChangeCover',
+            'delete-persons-profile' => 'checkAllowedDelete',
+        ));
+
+        $this->CNF = array (
+
+            // module icon
+            'ICON' => 'user col-blue3',
+
+            // database tables
+            'TABLE_ENTRIES' => $aModule['db_prefix'] . 'data',
+            'TABLE_ENTRIES_FULLTEXT' => 'search_fields',
+
+            // database fields
+            'FIELD_ID' => 'id',
+            'FIELD_AUTHOR' => 'author',
+            'FIELD_ADDED' => 'added',
+            'FIELD_CHANGED' => 'changed',
+            'FIELD_NAME' => 'fullname',
+            'FIELD_LAST_NAME' => 'last_name',
+            'FIELD_TITLE' => 'fullname',
+            'FIELD_TEXT' => 'description',
+            'FIELD_PICTURE' => 'picture',
+            'FIELD_COVER' => 'cover',
+            'FIELD_BIRTHDAY' => 'birthday',
+            'FIELD_ALLOW_VIEW_TO' => 'allow_view_to',
+            'FIELD_ALLOW_POST_TO' => 'allow_post_to',
+            'FIELD_ALLOW_CONTACT_TO' => 'allow_contact_to',
+            'FIELD_VIEWS' => 'views',
+            'FIELD_VOTES' => 'votes',
+            'FIELD_COMMENTS' => 'comments',
+            'FIELDS_QUICK_SEARCH' => array('fullname', 'last_name'),
+            'FIELD_LOCATION' => 'location',
+            'FIELD_LOCATION_PREFIX' => 'location',
+            'FIELD_LABELS' => 'labels',
+            '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-persons-profile',
+            'URI_VIEW_FRIENDS' => 'persons-profile-friends',
+            'URI_VIEW_FRIEND_REQUESTS' => 'persons-friend-requests',
+            'URI_VIEW_FAVORITES' => 'persons-profile-favorites',
+            'URI_EDIT_ENTRY' => 'edit-persons-profile',
+            'URI_EDIT_COVER' => 'edit-persons-cover',
+            'URI_MANAGE_COMMON' => 'persons-manage',
+            'URI_VIEW_SUBSCRIPTIONS' => 'persons-profile-subscriptions',
+
+            'URL_HOME' => 'page.php?i=persons-home',
+            'URL_CREATE' => 'page.php?i=create-persons-profile',
+            'URL_MANAGE_COMMON' => 'page.php?i=persons-manage',
+            'URL_MANAGE_ADMINISTRATION' => 'page.php?i=persons-administration',
+
+            // some params
+            'PARAM_AUTOAPPROVAL' => 'bx_persons_autoapproval',
+            'PARAM_ENABLE_ACTIVATION_LETTER' => 'bx_persons_enable_profile_activation_letter',
+            'PARAM_DEFAULT_ACL_LEVEL' => 'bx_persons_default_acl_level',
+            'PARAM_NUM_RSS' => 'bx_persons_num_rss',
+            'PARAM_NUM_CONNECTIONS_QUICK' => 'bx_persons_num_connections_quick',
+            'PARAM_SEARCHABLE_FIELDS' => 'bx_persons_searchable_fields',
+            'PARAM_PUBLIC_SBSN' => 'bx_persons_public_subscriptions',
+            'PARAM_PUBLIC_SBSD' => 'bx_persons_public_subscribed_me',
+            'PARAM_REDIRECT_AADD' => 'bx_persons_redirect_aadd',
+            'PARAM_REDIRECT_AADD_CUSTOM_URL' => 'bx_persons_redirect_aadd_custom_url',
+            'PARAM_PER_PAGE_BROWSE_SHOWCASE' => 'bx_persons_per_page_browse_showcase',
+            'PARAM_PER_PAGE_BROWSE_RECOMMENDED' => 'bx_persons_per_page_browse_recommended',
+
+            // objects
+            'OBJECT_STORAGE' => 'bx_persons_pictures',
+            'OBJECT_STORAGE_COVER' => 'bx_persons_pictures',
+            'OBJECT_IMAGES_TRANSCODER_THUMB' => 'bx_persons_thumb',
+            'OBJECT_IMAGES_TRANSCODER_ICON' => 'bx_persons_icon',
+            'OBJECT_IMAGES_TRANSCODER_AVATAR' => 'bx_persons_avatar',
+            'OBJECT_IMAGES_TRANSCODER_AVATAR_BIG' => 'bx_persons_avatar_big',
+            'OBJECT_IMAGES_TRANSCODER_PICTURE' => 'bx_persons_picture',
+            'OBJECT_IMAGES_TRANSCODER_COVER' => 'bx_persons_cover',
+            'OBJECT_IMAGES_TRANSCODER_COVER_THUMB' => 'bx_persons_cover_thumb',
+            'OBJECT_IMAGES_TRANSCODER_GALLERY' => 'bx_persons_gallery',
+            'OBJECT_VIEWS' => 'bx_persons',
+            'OBJECT_VOTES' => 'bx_persons',
+            'OBJECT_SCORES' => 'bx_persons',
+            'OBJECT_FAVORITES' => 'bx_persons',
+            'OBJECT_FEATURED' => 'bx_persons',
+            'OBJECT_COMMENTS' => 'bx_persons',
+            'OBJECT_NOTES' => 'bx_persons_notes',
+            'OBJECT_REPORTS' => 'bx_persons',
+            'OBJECT_METATAGS' => 'bx_persons',
+            'OBJECT_FORM_ENTRY' => 'bx_person',
+            'OBJECT_FORM_ENTRY_DISPLAY_VIEW' => 'bx_person_view',
+            'OBJECT_FORM_ENTRY_DISPLAY_VIEW_FULL' => 'bx_person_view_full', // for "info" tab on view profile page 
+            'OBJECT_FORM_ENTRY_DISPLAY_ADD' => 'bx_person_add',
+            'OBJECT_FORM_ENTRY_DISPLAY_EDIT' => 'bx_person_edit',
+            'OBJECT_FORM_ENTRY_DISPLAY_EDIT_COVER' => 'bx_person_edit_cover',
+            'OBJECT_FORM_ENTRY_DISPLAY_DELETE' => 'bx_person_delete',
+            'OBJECT_MENU_ACTIONS_VIEW_ENTRY' => 'bx_persons_view_actions', // actions menu on view entry page
+            'OBJECT_MENU_ACTIONS_VIEW_ENTRY_MORE' => 'bx_persons_view_actions_more', // actions menu on view entry page for "more" popup
+            'OBJECT_MENU_ACTIONS_VIEW_ENTRY_ALL' => 'bx_persons_view_actions_all', // all actions menu on view entry page
+            'OBJECT_MENU_SUBMENU' => 'bx_persons_submenu', // main module submenu
+            'OBJECT_MENU_SUBMENU_VIEW_ENTRY' => 'bx_persons_view_submenu',  // view entry submenu
+            'OBJECT_MENU_SUBMENU_VIEW_ENTRY_MAIN_SELECTION' => 'persons-home', // first item in view entry submenu from main module submenu
+            'OBJECT_MENU_VIEW_ENTRY_META' => 'bx_persons_view_meta', // meta menu on view entry page
+            'OBJECT_MENU_SNIPPET_META' => 'bx_persons_snippet_meta', // menu for snippet meta info
+            'OBJECT_MENU_MANAGE_TOOLS' => 'bx_persons_menu_manage_tools', //manage menu in content administration tools
+            'OBJECT_PAGE_VIEW_ENTRY' => 'bx_persons_view_profile',
+            'OBJECT_PAGE_VIEW_ENTRY_CLOSED' => 'bx_persons_view_profile_closed',
+            'OBJECT_PRIVACY_VIEW' => 'bx_persons_allow_view_to',
+            'OBJECT_PRIVACY_POST' => 'bx_persons_allow_post_to',
+            'OBJECT_PRIVACY_CONTACT' => 'bx_persons_allow_contact_to',
+            'OBJECT_GRID_ADMINISTRATION' => 'bx_persons_administration',
+            'OBJECT_GRID_COMMON' => 'bx_persons_common',
+            'OBJECT_UPLOADERS_COVER' => array('bx_persons_cover_crop'),
+            'OBJECT_UPLOADERS_PICTURE' => array('bx_persons_picture_crop'),
+            
+            'BADGES_AVALIABLE' => true,
+
+            'EMAIL_FRIEND_REQUEST' => 'bx_persons_friend_request',
+
+            'TRIGGER_MENU_PROFILE_VIEW_SUBMENU' => 'trigger_profile_view_submenu',
+            'TRIGGER_MENU_PROFILE_SNIPPET_META' => 'trigger_profile_snippet_meta',
+            'TRIGGER_MENU_PROFILE_VIEW_ACTIONS' => 'trigger_profile_view_actions',
+        	'TRIGGER_PAGE_VIEW_ENTRY' => 'trigger_page_profile_view_entry',
+
+            // menu items which visibility depends on custom visibility checking
+            'MENU_ITEM_TO_METHOD' => array (
+                'bx_persons_view_submenu' => $this->_aMenuItems2MethodsSubmenu,
+                'bx_persons_view_actions' => $this->_aMenuItems2MethodsActions,
+                'bx_persons_view_actions_more' => $this->_aMenuItems2MethodsActions,
+                'bx_persons_view_actions_all' => $this->_aMenuItems2MethodsActions,
+            ),
+
+            // informer messages
+            'INFORMERS' => array (
+                'status' => array (
+                    'name' => 'bx-persons-status-not-active',
+                    'map' => array (
+                        BX_PROFILE_STATUS_PENDING => '_bx_persons_txt_account_pending',
+                        BX_PROFILE_STATUS_SUSPENDED => '_bx_persons_txt_account_suspended',
+                    ),
+                ),
+                'status_moderation' => array (
+                    'name' => 'bx-persons-status-not-active-moderation',
+                    'map' => array (
+                        BX_PROFILE_STATUS_PENDING => '_bx_persons_txt_account_pending_moderation',
+                        BX_PROFILE_STATUS_SUSPENDED => '_bx_persons_txt_account_suspended_moderation',
+                    ),
+                ),
+            ),
+
+            // some language keys
+            'T' => array (
+                'txt_sample_single' => '_bx_persons_txt_sample_single',
+            	'txt_sample_comment_single' => '_bx_persons_txt_sample_comment_single',
+                'txt_sample_vote_single' => '_bx_persons_txt_sample_vote_single',
+                'txt_sample_score_up_single' => '_bx_persons_txt_sample_score_up_single',
+                'txt_sample_score_down_single' => '_bx_persons_txt_sample_score_down_single',
+            	'txt_sample_pp_single' => '_bx_persons_txt_sample_pp_single',
+            	'txt_sample_pp_single_with_article' => '_bx_persons_txt_sample_pp_single_with_article',
+                'txt_sample_pc_single' => '_bx_persons_txt_sample_pc_single',
+            	'txt_sample_pc_single_with_article' => '_bx_persons_txt_sample_pc_single_with_article',
+            	'txt_sample_pi_action' => '_bx_persons_txt_sample_pi_action',
+            	'txt_sample_pi_action_user' => '_bx_persons_txt_sample_pi_action_user',
+                'txt_N_fans' => '_bx_persons_txt_N_friends',
+            	'txt_ntfs_timeline_post_common' => '_bx_persons_txt_ntfs_timeline_post_common',
+            	'form_field_picture' => '_bx_persons_form_profile_input_picture_search',
+                'form_field_online' => '_bx_persons_form_profile_input_online_search',
+                'menu_item_title_befriend_sent' => '_bx_persons_menu_item_title_befriend_sent',
+                'menu_item_title_unfriend_cancel_request' => '_bx_persons_menu_item_title_unfriend_cancel_request',
+                'menu_item_title_befriend_confirm' => '_bx_persons_menu_item_title_befriend_confirm',
+                'menu_item_title_unfriend_reject_request' => '_bx_persons_menu_item_title_unfriend_reject_request',
+                'menu_item_title_befriend' => '_bx_persons_menu_item_title_befriend',
+                'menu_item_title_unfriend' => '_bx_persons_menu_item_title_unfriend',
+            	'grid_action_err_delete' => '_bx_persons_grid_action_err_delete',
+            	'grid_txt_account_manager' => '_bx_persons_grid_txt_account_manager',
+            	'filter_item_active' => '_bx_persons_grid_filter_item_title_adm_active',
+            	'filter_item_pending' => '_bx_persons_grid_filter_item_title_adm_pending',
+            	'filter_item_suspended' => '_bx_persons_grid_filter_item_title_adm_suspended',
+                'filter_item_unconfirmed' => '_bx_persons_grid_filter_item_title_adm_unconfirmed',
+            	'filter_item_select_one_filter1' => '_bx_persons_grid_filter_item_title_adm_select_one_filter1',
+                'filter_item_select_one_filter2' => '_bx_persons_grid_filter_item_title_adm_select_one_filter2',
+            	'menu_item_manage_my' => '_bx_persons_menu_item_title_manage_my',
+            	'menu_item_manage_all' => '_bx_persons_menu_item_title_manage_all',
+            	'txt_browse_favorites' => '_bx_persons_page_title_browse_favorites',
+                'option_redirect_aadd_profile' => '_bx_persons_option_redirect_aadd_profile',
+            	'option_redirect_aadd_last' => '_bx_persons_option_redirect_aadd_last',
+            	'option_redirect_aadd_custom' => '_bx_persons_option_redirect_aadd_custom',
+                'option_redirect_aadd_homepage' => '_bx_persons_option_redirect_aadd_homepage',
+                'option_activation_on' => '_bx_persons_option_activation_on',
+            	'option_activation_off' => '_bx_persons_option_activation_off',
+            	'option_activation_add' => '_bx_persons_option_activation_add',
+                'option_activation_edit' => '_bx_persons_option_activation_edit'
+            ),
+
+        );
+
+        $this->_aJsClasses = array(
+        	'manage_tools' => 'BxPersonsManageTools'
+        );
+
+        $this->_aJsObjects = array(
+        	'manage_tools' => 'oBxPersonsManageTools'
+        );
+
+        $this->_aGridObjects = array(
+        	'common' => $this->CNF['OBJECT_GRID_COMMON'],
+        	'administration' => $this->CNF['OBJECT_GRID_ADMINISTRATION'],
+        	
+        );
+    }
+}
+
+/** @} */

+ 80 - 0
modules/boonex/persons/updates/13.0.0_13.0.1/source/classes/BxPersonsModule.php

@@ -0,0 +1,80 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Persons Persons
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+/**
+ * Person profiles module.
+ */
+class BxPersonsModule extends BxBaseModProfileModule
+{
+    function __construct(&$aModule)
+    {
+        parent::__construct($aModule);
+
+        $this->_aSearchableNamesExcept[] = $this->_oConfig->CNF['FIELD_AUTHOR'];
+    }
+
+    public function servicePrepareFields ($aFieldsProfile)
+    {
+        $a = parent::_servicePrepareFields($aFieldsProfile, array(), array());
+        if (empty($a['fullname']))
+            $a['fullname'] = $aFieldsProfile['name'];
+        return $a;
+    }
+    
+    /**
+     * @page service Service Calls
+     * @section bx_persons Persons 
+     * @subsection bx_persons-other Other
+     * @subsubsection bx_persons-get_search_options
+     * 
+     * @code bx_srv('bx_persons', 'get_search_options', [...]); @endcode
+     * 
+     * Get options for searchable fields
+     * 
+     * @return array - params or false.
+     * 
+     * @see BxPersonsModule::serviceGetSearchOptions
+     */
+    /** 
+     * @ref bx_persons-get_search_options "get_search_options"
+     */
+    public function serviceGetSearchOptions ($sField, $sFieldType, $sSearchType)
+    {
+        $CNF = $this->_oConfig->CNF;
+        if (isset($CNF['OBJECT_FORM_ENTRY']) && isset($CNF['OBJECT_FORM_ENTRY_DISPLAY_ADD'])){
+            $oForm = BxDolForm::getObjectInstance($CNF['OBJECT_FORM_ENTRY'], $CNF['OBJECT_FORM_ENTRY_DISPLAY_ADD'], $this->_oTemplate);
+            foreach ($oForm->aInputs as $aFld) {
+                if ($aFld['name'] == $sField && $aFld['type'] == $sFieldType && isset($aFld['checker']) && isset($aFld['checker']['params'])){
+                    return $aFld['checker']['params'];
+                }
+            }
+        }
+        
+        if (isset($CNF['OBJECT_FORM_ENTRY']) && isset($CNF['OBJECT_FORM_ENTRY_DISPLAY_EDIT'])){
+            $oForm = BxDolForm::getObjectInstance($CNF['OBJECT_FORM_ENTRY'], $CNF['OBJECT_FORM_ENTRY_DISPLAY_EDIT'], $this->_oTemplate);
+            foreach ($oForm->aInputs as $aFld) {
+                if ($aFld['name'] == $sField && $aFld['type'] == $sFieldType && isset($aFld['checker']) && isset($aFld['checker']['params'])){
+                    return $aFld['checker']['params'];
+                }
+            }
+        }
+        
+        return false;
+    }
+    
+    public function getProfileName ($aContentInfo)
+    {
+        return bx_process_output($aContentInfo[$this->_oConfig->CNF['FIELD_NAME']] . ($aContentInfo[$this->_oConfig->CNF['FIELD_LAST_NAME']] != '' ? ' ' . $aContentInfo[$this->_oConfig->CNF['FIELD_LAST_NAME']] : ''));
+    }
+    
+}
+
+/** @} */

+ 211 - 0
modules/boonex/persons/updates/13.0.0_13.0.1/source/classes/BxPersonsSearchResult.php

@@ -0,0 +1,211 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Persons Persons
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+class BxPersonsSearchResult extends BxBaseModProfileSearchResult
+{
+    function __construct($sMode = '', $aParams = false)
+    {
+        parent::__construct($sMode, $aParams);        
+        
+        $this->aCurrent =  array(
+            'name' => 'bx_persons',
+            'module_name' => 'bx_persons',
+            'object_metatags' => 'bx_persons',
+            'title' => _t('_bx_persons_page_title_browse'),
+            'table' => 'sys_profiles',
+            'tableSearch' => 'bx_persons_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_persons', 'field' => 'type', 'operator' => '='),
+                'owner' => array('value' => '', 'field' => 'author', 'operator' => '=', 'table' => 'bx_persons_data'),
+                'featured' => array('value' => '', 'field' => 'featured', 'operator' => '<>', 'table' => 'bx_persons_data'),
+                'online' => array('value' => '', 'field' => 'date', 'operator' => '>', 'table' => 'sys_sessions'),
+            ),
+            'join' => array (
+                'profile' => array(
+                    'type' => 'INNER',
+                    'table' => 'bx_persons_data',
+                    'mainField' => 'content_id',
+                    'onField' => 'id',
+                    'joinFields' => array('id', 'fullname', 'last_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_persons_per_page_browse'), 'start' => 0),
+            'sorting' => 'active',
+            'rss' => array(
+                'title' => '',
+                'link' => '',
+                'image' => '',
+                'profile' => 0,
+                'fields' => array (
+                    'Guid' => 'link',
+                    'Link' => 'link',
+                    'Title' => 'fullname',
+                    'DateTimeUTS' => 'added',
+                    'Desc' => 'fullname',
+                    'Image' => 'picture',
+                ),
+            ),
+            'ident' => 'id'
+        );
+
+        $this->sFilterName = 'bx_persons_filter';
+        $this->oModule = $this->getMain();
+
+        $CNF = &$this->oModule->_oConfig->CNF;
+        
+        $sSearchFields = getParam($CNF['PARAM_SEARCHABLE_FIELDS']);
+        $this->aCurrent['searchFields'] = !empty($sSearchFields) ? explode(',', $sSearchFields) : '';
+
+        $this->_setAccountConfirmationConditions($aParams);
+
+        switch ($sMode) {
+
+            case 'connections':
+                if ($this->_setConnectionsConditions($aParams)) {
+                    $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_persons_page_title_browse_connections_mutual', $oProfile->getDisplayName(), $oProfile2->getDisplayName());
+                    elseif ((!isset($aParams['type']) || $aParams['type'] != 'common') && $oProfile)
+                        $this->aCurrent['title'] = _t('_bx_persons_page_title_browse_connections', $oProfile->getDisplayName());
+
+                    $this->aCurrent['rss']['link'] = 'modules/?r=persons/rss/' . $sMode . '/' . $aParams['object'] . '/' . $aParams['type'] . '/' . (int)$aParams['profile'] . '/' . (int)$aParams['profile2'] . '/' . (int)$aParams['mutual'];
+                }
+                break;
+
+            case 'familiar':
+                if($this->_setFamiliarConnectionsConditions($aParams)) {
+                    $this->aCurrent['title'] = _t('_bx_persons_page_title_browse_familiar');
+                    unset($this->aCurrent['rss']);
+                }
+                break;
+
+            case 'acl':
+                if ($this->_setAclConditions($aParams)) {
+                    $this->aCurrent['title'] = _t('_bx_persons_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=persons/rss/' . $sMode;
+                $this->aCurrent['title'] = _t('_bx_persons_page_title_browse_recent');
+                $this->aCurrent['sorting'] = 'last';
+                $this->sBrowseUrl = 'page.php?i=persons-home';
+                break;
+
+            case 'featured':
+                $this->sBrowseUrl = BxDolPermalinks::getInstance()->permalink($CNF['URL_HOME']);
+                $this->aCurrent['title'] = _t('_bx_persons_page_title_browse_featured');
+                $this->aCurrent['restriction']['featured']['value'] = '0';
+                $this->aCurrent['rss']['link'] = 'modules/?r=persons/rss/' . $sMode;
+                $this->aCurrent['sorting'] = 'featured';
+                break;
+                
+            case 'recommended':
+                $this->sBrowseUrl = BxDolPermalinks::getInstance()->permalink($CNF['URL_HOME']);
+                $this->aCurrent['title'] = _t('_bx_groups_page_title_browse_recommended');
+                $this->aCurrent['restriction']['featured']['value'] = '0';
+                $this->aCurrent['rss']['link'] = 'modules/?r=groups/rss/' . $sMode;
+                $this->aCurrent['sorting'] = 'recommended';
+                $this->_setConditionsForRecommended();
+                break;    
+            
+            case 'active':
+                $this->aCurrent['rss']['link'] = 'modules/?r=persons/rss/' . $sMode;
+                $this->aCurrent['title'] = _t('_bx_persons_page_title_browse_active');
+                $this->aCurrent['sorting'] = 'active';
+                $this->sBrowseUrl = 'page.php?i=persons-active';
+                break;
+
+            case 'online':
+                $this->aCurrent['rss']['link'] = 'modules/?r=persons/rss/' . $sMode;
+                $this->aCurrent['title'] = _t('_bx_persons_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=persons-online';
+                break;
+
+            case '': // search results
+                $this->sBrowseUrl = BX_DOL_SEARCH_KEYWORD_PAGE;
+                $this->aCurrent['title'] = _t('_bx_persons');
+                unset($this->aCurrent['paginate']['perPage'], $this->aCurrent['rss']);
+                break;
+
+            default:
+                $this->isError = true;
+        }
+
+        $this->sCenterContentUnitSelector = false;
+    }
+
+    function getAlterOrder()
+    {
+        switch ($this->aCurrent['sorting']) {
+            case 'featured':
+                return array('order' => ' ORDER BY `bx_persons_data`.`featured` DESC ');
+            case 'recommended':
+                return array('order' => ' ORDER BY RAND() ');
+            case 'none':
+                return array();
+	        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_persons_data`.`added` DESC ');
+        }
+    }
+
+    function _getPseud ()
+    {
+        return array(
+            'id' => 'id',
+            'fullname' => 'fullname',
+            'added' => 'added',
+            'author' => 'author',
+            'picture' => 'picture',
+        );
+    }
+}
+
+/** @} */

+ 152 - 0
modules/boonex/persons/updates/13.0.0_13.0.1/source/install/config.php

@@ -0,0 +1,152 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Persons Persons
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+$aConfig = array(
+
+    /**
+     * Main Section.
+     */
+    'type' => BX_DOL_MODULE_TYPE_MODULE,
+    'name' => 'bx_persons',
+    'title' => 'Persons',
+    'note' => 'Basic person profiles functionality.',
+    'version' => '13.0.1',
+    'vendor' => 'BoonEx',
+    'help_url' => 'http://feed.una.io/?section={module_name}',
+
+    'compatible_with' => array(
+        '13.0.0-A3'
+    ),
+
+    /**
+     * 'home_dir' and 'home_uri' - should be unique. Don't use spaces in 'home_uri' and the other special chars.
+     */
+    'home_dir' => 'boonex/persons/',
+    'home_uri' => 'persons',
+
+    'db_prefix' => 'bx_persons_',
+    'class_prefix' => 'BxPersons',
+
+    /**
+     * Category for language keys.
+     */
+    'language_category' => 'Persons',
+
+    /**
+     * Connections.
+     */
+    'connections' => array(
+        'sys_profiles_friends' => array ('type' => 'profiles'),
+        'sys_profiles_subscriptions' => array ('type' => 'profiles'),
+        'sys_profiles_relations' => array ('type' => 'profiles'),
+    ),
+
+    /**
+     * Menu triggers.
+     */
+    'menu_triggers' => array(
+        'trigger_profile_view_submenu',
+        'trigger_profile_snippet_meta',
+    	'trigger_profile_view_actions',
+    ),
+
+	/**
+     * Page triggers.
+     */
+    'page_triggers' => array (
+    	'trigger_page_profile_view_entry', 
+    ),
+
+	/**
+     * Storage objects to automatically delete files from upon module uninstallation.
+     * Note. Don't add storage objects used in transcoder objects.
+     */
+    'storages' => array(
+    	'bx_persons_pictures'
+    ),
+
+	/**
+     * Transcoders.
+     */
+    'transcoders' => array(
+    	'bx_persons_icon',
+    	'bx_persons_thumb',
+    	'bx_persons_avatar',
+        'bx_persons_avatar_big',
+    	'bx_persons_picture',
+    	'bx_persons_cover',
+    	'bx_persons_cover_thumb',
+        'bx_persons_gallery'
+    ),
+
+    /**
+     * Extended Search Forms.
+     */
+    'esearches' => array(
+        'bx_persons',
+    	'bx_persons_cmts',
+    ),
+
+    /**
+     * Installation/Uninstallation Section.
+     */
+    'install' => array(
+        'execute_sql' => 1,
+        'update_languages' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'uninstall' => array (
+    	'process_esearches' => 1,
+        'execute_sql' => 1,
+        'update_languages' => 1,
+    	'process_connections' => 1,
+    	'process_deleted_profiles' => 1,
+    	'update_relations' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'enable' => array(
+        'execute_sql' => 1,
+    	'update_relations' => 1,
+        'clear_db_cache' => 1,
+    ),
+	'enable_success' => array(
+    	'process_menu_triggers' => 1,
+    	'process_page_triggers' => 1,
+    	'process_esearches' => 1,
+    	'register_transcoders' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'disable' => array (
+        'execute_sql' => 1,
+    	'unregister_transcoders' => 1,
+    	'update_relations' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'disable_failed' => array (
+    	'register_transcoders' => 1,
+    	'clear_db_cache' => 1,
+    ),
+
+    /**
+     * Dependencies Section
+     */
+    'dependencies' => array(),
+
+    /**
+     * Connections Section
+     */
+    'relations' => array(
+    	'bx_timeline',
+        'bx_notifications',
+    ),
+);
+
+/** @} */

+ 359 - 0
modules/boonex/persons/updates/13.0.0_13.0.1/source/install/langs/en.xml

@@ -0,0 +1,359 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources name="en" flag="gb" title="English">
+
+	<string name="_bx_persons"><![CDATA[Persons]]></string>
+	<string name="_bx_persons_cmts"><![CDATA[Persons' Comments]]></string>
+
+	<string name="_bx_persons_option_autoapproval"><![CDATA[Activate all persons automatically]]></string>
+	<string name="_bx_persons_option_default_acl_level"><![CDATA[Default member's level to assign after person's profile creation]]></string>
+  <string name="_bx_persons_option_enable_profile_activation_letter"><![CDATA[Enable profile activation letter]]></string>
+  <string name="_bx_persons_option_redirect_aadd"><![CDATA[Redirect after person's profile creation to]]></string>
+	<string name="_bx_persons_option_redirect_aadd_profile"><![CDATA[Profile Page]]></string>
+	<string name="_bx_persons_option_redirect_aadd_last"><![CDATA[Last Page]]></string>
+	<string name="_bx_persons_option_redirect_aadd_custom"><![CDATA[Custom Page]]></string>
+  <string name="_bx_persons_option_redirect_aadd_homepage"><![CDATA[Homepage]]></string>
+	<string name="_bx_persons_option_redirect_aadd_custom_url"><![CDATA[URL for 'Custom Page' redirect]]></string>
+  <string name="_bx_persons_option_activation_on"><![CDATA[After creation & after editing]]></string>
+  <string name="_bx_persons_option_activation_add"><![CDATA[After creation only]]></string>
+  <string name="_bx_persons_option_activation_edit"><![CDATA[After editing only]]></string>
+  <string name="_bx_persons_option_activation_off"><![CDATA[Manual activation]]></string>
+	<string name="_bx_persons_option_num_connections_quick"><![CDATA[Number of items in friends block]]></string>
+	<string name="_bx_persons_option_per_page_browse"><![CDATA[Number of items per page]]></string>
+	<string name="_bx_persons_option_num_rss"><![CDATA[Number of items in RSS feed]]></string>
+	<string name="_bx_persons_option_searchable_fields"><![CDATA[Searchable fields for keyword search]]></string>
+    <string name="_bx_persons_option_public_subscriptions"><![CDATA[Public following list]]></string>
+    <string name="_bx_persons_option_public_subscribed_me"><![CDATA[Public followers list]]></string>
+
+	<string name="_bx_persons_form_profile"><![CDATA[Persons]]></string>
+	<string name="_bx_persons_form_profile_display_add"><![CDATA[Add Person]]></string>
+	<string name="_bx_persons_form_profile_display_edit"><![CDATA[Edit Person]]></string>
+	<string name="_bx_persons_form_profile_display_edit_cover"><![CDATA[Edit Cover]]></string>
+	<string name="_bx_persons_form_profile_display_delete"><![CDATA[Delete Person]]></string>
+	<string name="_bx_persons_form_profile_display_view"><![CDATA[View Person]]></string>
+	<string name="_bx_persons_form_profile_display_view_full"><![CDATA[Full View Person]]></string>
+    <string name="_bx_persons_form_profile_input_sys_do_submit"><![CDATA[Submit]]></string>
+    <string name="_bx_persons_form_profile_input_submit"><![CDATA[Submit]]></string>
+    <string name="_bx_persons_form_profile_input_sys_allow_view_to"><![CDATA[Visible to]]></string>
+    <string name="_bx_persons_form_profile_input_allow_view_to"><![CDATA[Visible to]]></string>
+    <string name="_bx_persons_form_profile_input_sys_allow_post_to"><![CDATA[Who can post to my profile]]></string>
+    <string name="_bx_persons_form_profile_input_allow_post_to"><![CDATA[Who can post to my profile]]></string>
+    <string name="_bx_persons_form_profile_input_sys_allow_contact_to"><![CDATA[Who can contact me]]></string>
+    <string name="_bx_persons_form_profile_input_allow_contact_to"><![CDATA[Who can contact me]]></string>
+	<string name="_bx_persons_form_profile_input_sys_fullname"><![CDATA[Name]]></string>
+	<string name="_bx_persons_form_profile_input_fullname"><![CDATA[Name]]></string>
+    <string name="_bx_persons_form_profile_input_sys_last_name"><![CDATA[Last Name]]></string>
+	<string name="_bx_persons_form_profile_input_last_name"><![CDATA[Last Name]]></string>
+	<string name="_bx_persons_form_profile_input_fullname_err"><![CDATA[Profile name is mandatory and and cannot start with @]]></string>
+	<string name="_bx_persons_form_profile_input_sys_desc"><![CDATA[Description]]></string>
+	<string name="_bx_persons_form_profile_input_desc"><![CDATA[Description]]></string>
+	<string name="_bx_persons_form_profile_input_sys_picture"><![CDATA[Profile Picture]]></string>
+	<string name="_bx_persons_form_profile_input_picture"><![CDATA[Upload a profile picture]]></string>
+	<string name="_bx_persons_form_profile_input_picture_err"><![CDATA[Profile picture is mandatory.]]></string>
+	<string name="_bx_persons_form_profile_input_picture_search"><![CDATA[With photo]]></string>
+	<string name="_bx_persons_form_profile_input_online_search"><![CDATA[Online only]]></string>
+	<string name="_bx_persons_form_profile_input_sys_cover"><![CDATA[Cover Picture]]></string>
+	<string name="_bx_persons_form_profile_input_cover"><![CDATA[Upload New Cover Picture]]></string>
+	<string name="_bx_persons_form_profile_input_sys_delete_confirm"><![CDATA[Delete confirmation]]></string>
+	<string name="_bx_persons_form_profile_input_delete_confirm"><![CDATA[I am sure I want to delete this profile]]></string>
+	<string name="_bx_persons_form_profile_input_delete_confirm_info"><![CDATA[This action can not be undone.]]></string>
+	<string name="_bx_persons_form_profile_input_delete_confirm_error"><![CDATA[Please check this checkbox if you really want to delete your profile.]]></string>
+    <string name="_bx_persons_form_profile_input_sys_birthday"><![CDATA[Birthday]]></string>
+    <string name="_bx_persons_form_profile_input_birthday_err"><![CDATA[Age between 18 and 99]]></string>
+    <string name="_bx_persons_form_profile_input_birthday"><![CDATA[Birthday]]></string>
+    <string name="_bx_persons_form_profile_input_sys_gender"><![CDATA[Gender]]></string>
+    <string name="_bx_persons_form_profile_input_gender"><![CDATA[Gender]]></string>
+    <string name="_bx_persons_form_profile_input_sys_profile_email"><![CDATA[Email]]></string>
+    <string name="_bx_persons_form_profile_input_profile_email"><![CDATA[Email]]></string>
+    <string name="_bx_persons_form_profile_input_sys_profile_status"><![CDATA[Status]]></string>
+    <string name="_bx_persons_form_profile_input_profile_status"><![CDATA[Status]]></string>
+    <string name="_bx_persons_form_profile_input_sys_profile_ip"><![CDATA[IP]]></string>
+    <string name="_bx_persons_form_profile_input_profile_ip"><![CDATA[IP]]></string>
+    <string name="_bx_persons_form_profile_input_sys_skills"><![CDATA[Skills]]></string>
+    <string name="_bx_persons_form_profile_input_skills"><![CDATA[Skills]]></string>
+    <string name="_bx_persons_form_profile_input_sys_date_added"><![CDATA[Added]]></string>
+    <string name="_bx_persons_form_profile_input_date_added"><![CDATA[Added]]></string>
+    <string name="_bx_persons_form_profile_input_sys_date_changed"><![CDATA[Updated]]></string>
+    <string name="_bx_persons_form_profile_input_date_changed"><![CDATA[Updated]]></string>
+    <string name="_bx_persons_form_profile_input_sys_friends_count"><![CDATA[Friends count]]></string>
+    <string name="_bx_persons_form_profile_input_friends_count"><![CDATA[Friends count]]></string>
+    <string name="_bx_persons_form_profile_input_sys_followers_count"><![CDATA[Followers count]]></string>
+    <string name="_bx_persons_form_profile_input_followers_count"><![CDATA[Followers count]]></string>
+
+  <string name="_bx_persons_skills_form_profile"><![CDATA[Skills]]></string>
+  <string name="_bx_persons_skills_form_profile_display_add"><![CDATA[Add Skill]]></string>
+  <string name="_bx_persons_skills_form_profile_display_view"><![CDATA[View Skill]]></string>
+  <string name="_bx_persons_skills_form_profile_input_sys_skill_name"><![CDATA[Name]]></string>
+  <string name="_bx_persons_skills_form_profile_input_skill_name"><![CDATA[Name]]></string>
+  <string name="_bx_persons_skills_form_profile_input_skill_name_err"><![CDATA[This information is essential. Please, fill in this field.]]></string>
+
+	<string name="_bx_persons_acl_action_create_profile"><![CDATA[Create Person's Profile]]></string>
+	<string name="_bx_persons_acl_action_delete_profile"><![CDATA[Delete Person's Profile]]></string>
+	<string name="_bx_persons_acl_action_view_profile"><![CDATA[View Person's Profile]]></string>
+	<string name="_bx_persons_acl_action_edit_any_profile"><![CDATA[Edit Any Person's Profile]]></string>
+	<string name="_bx_persons_acl_action_delete_any_profile"><![CDATA[Delete Any Person's Profile]]></string>
+
+	<string name="_bx_persons_page_title_sys_create_profile"><![CDATA[Create a Profile - Person]]></string>
+	<string name="_bx_persons_page_title_create_profile"><![CDATA[Create a Profile - Person]]></string>
+	<string name="_bx_persons_page_title_sys_edit_profile"><![CDATA[Edit Profile]]></string>
+	<string name="_bx_persons_page_title_edit_profile"><![CDATA[Edit Profile]]></string>
+	<string name="_bx_persons_page_title_sys_edit_profile_cover"><![CDATA[Edit Cover]]></string>
+	<string name="_bx_persons_page_title_edit_profile_cover"><![CDATA[Edit Cover]]></string>
+	<string name="_bx_persons_page_title_sys_delete_profile"><![CDATA[Delete Profile]]></string>
+	<string name="_bx_persons_page_title_delete_profile"><![CDATA[Delete Profile]]></string>
+    <string name="_bx_persons_page_title_sys_view_profile"><![CDATA[View Profile]]></string>
+    <string name="_bx_persons_page_title_sys_view_profile_closed"><![CDATA[View Profile with Limited Visibility]]></string>
+	<string name="_bx_persons_page_title_view_profile"><![CDATA[{display_name}]]></string>
+	<string name="_bx_persons_page_title_browse"><![CDATA[People]]></string>
+	<string name="_bx_persons_page_title_browse_featured"><![CDATA[Featured People]]></string>
+	<string name="_bx_persons_page_title_browse_active"><![CDATA[Active People]]></string>
+	<string name="_bx_persons_page_title_browse_online"><![CDATA[Online People]]></string>
+	<string name="_bx_persons_page_title_browse_recent"><![CDATA[New People]]></string>
+	<string name="_bx_persons_page_title_browse_connections"><![CDATA[{0} connections]]></string>
+	<string name="_bx_persons_page_title_browse_connections_mutual"><![CDATA[{0} and {1} mutual connections]]></string>
+        <string name="_bx_persons_page_title_browse_familiar"><![CDATA[People You May Know]]></string>
+	<string name="_bx_persons_page_title_browse_favorites"><![CDATA[{0} favorites]]></string>
+	<string name="_bx_persons_page_title_browse_by_acl"><![CDATA[{0} People]]></string>
+	<string name="_bx_persons_page_title_browse_by_cmts"><![CDATA[People's Comments]]></string>
+	<string name="_bx_persons_page_title_sys_profile_favorites"><![CDATA[Favorite persons]]></string>
+	<string name="_bx_persons_page_title_profile_favorites"><![CDATA[Favorite persons]]></string>
+	<string name="_bx_persons_page_title_sys_profile_friends"><![CDATA[Friends]]></string>
+	<string name="_bx_persons_page_title_profile_friends"><![CDATA[Friends]]></string>
+	<string name="_bx_persons_page_title_sys_friend_requests"><![CDATA[Friend Requests]]></string>
+	<string name="_bx_persons_page_title_friend_requests"><![CDATA[Friend Requests]]></string>
+	<string name="_bx_persons_page_title_sys_profile_subscriptions"><![CDATA[Following]]></string>
+    <string name="_bx_persons_page_title_profile_subscriptions"><![CDATA[Following & Followers]]></string>
+    <string name="_bx_persons_page_title_sys_profile_relations"><![CDATA[Relationships]]></string>
+    <string name="_bx_persons_page_title_profile_relations"><![CDATA[Relationships]]></string>
+    <string name="_bx_persons_page_title_sys_profile_comments"><![CDATA[Comments]]></string>
+    <string name="_bx_persons_page_title_profile_comments"><![CDATA[Comments]]></string>
+	<string name="_bx_persons_page_title_sys_profile_info"><![CDATA[Profile Info]]></string>
+	<string name="_bx_persons_page_title_profile_info"><![CDATA[Info about {display_name}]]></string>
+	<string name="_bx_persons_page_title_sys_recent"><![CDATA[New People]]></string>
+	<string name="_bx_persons_page_title_recent"><![CDATA[New People]]></string>
+	<string name="_bx_persons_page_title_sys_manage"><![CDATA[Manage Own People]]></string>
+	<string name="_bx_persons_page_title_sys_manage_administration"><![CDATA[Manage All People]]></string>
+	<string name="_bx_persons_page_title_manage"><![CDATA[Manage People]]></string>
+	<string name="_bx_persons_page_title_sys_active"><![CDATA[Active People]]></string>
+	<string name="_bx_persons_page_title_active"><![CDATA[Active People]]></string>
+	<string name="_bx_persons_page_title_sys_online"><![CDATA[Online People]]></string>
+	<string name="_bx_persons_page_title_online"><![CDATA[Online People]]></string>
+	<string name="_bx_persons_page_title_sys_entries_search"><![CDATA[Search]]></string>
+    <string name="_bx_persons_page_title_entries_search"><![CDATA[Search]]></string>
+
+    <string name="_bx_persons_page_block_title_profile_private"><![CDATA[Private Profile]]></string>
+    <string name="_bx_persons_page_block_title_choose_type"><![CDATA[Choose Profile Type]]></string>
+    <string name="_bx_persons_page_block_title_create_profile"><![CDATA[Create a Profile - Person]]></string>
+    <string name="_bx_persons_page_block_title_edit_profile"><![CDATA[Edit Profile]]></string>
+    <string name="_bx_persons_page_block_title_edit_profile_cover"><![CDATA[Edit Cover]]></string>
+    <string name="_bx_persons_page_block_title_delete_profile"><![CDATA[Delete Profile]]></string>
+    <string name="_bx_persons_page_block_title_profile_all_actions"><![CDATA[All Actions]]></string>
+    <string name="_bx_persons_page_block_title_profile_info_link"><![CDATA[About <a href="{profile_link}">{display_name}</a>]]></string>
+    <string name="_bx_persons_page_block_title_profile_info"><![CDATA[Info]]></string>
+    <string name="_bx_persons_page_block_title_system_profile_info"><![CDATA[Info]]></string>
+    <string name="_bx_persons_page_block_title_profile_membership"><![CDATA[Membership]]></string>
+    <string name="_bx_persons_page_block_title_system_profile_membership"><![CDATA[Membership]]></string>
+    <string name="_bx_persons_page_block_title_profile_description"><![CDATA[Description]]></string>
+    <string name="_bx_persons_page_block_title_profile_favorites"><![CDATA[Favorite persons]]></string>
+    <string name="_bx_persons_page_block_title_system_profile_favorites"><![CDATA[Favorite persons]]></string>
+    <string name="_bx_persons_page_block_title_profile_friends_link"><![CDATA[Friends of <a href="{profile_link}">{display_name}</a>]]></string>
+    <string name="_bx_persons_page_block_title_profile_friends"><![CDATA[Friends]]></string>
+    <string name="_bx_persons_page_block_title_profile_friends_mutual"><![CDATA[Mutual Friends]]></string>
+    <string name="_bx_persons_page_block_title_system_profile_friends"><![CDATA[Friends]]></string>
+    <string name="_bx_persons_page_block_title_friend_requests_link"><![CDATA[Friend Requests for <a href="{profile_link}">{display_name}</a>]]></string>
+    <string name="_bx_persons_page_block_title_system_friend_requests"><![CDATA[Friend Requests]]></string>
+    <string name="_bx_persons_page_block_title_profile_location"><![CDATA[Location]]></string>
+    <string name="_bx_persons_page_block_title_system_profile_subscriptions"><![CDATA[Following]]></string>
+    <string name="_bx_persons_page_block_title_profile_subscriptions"><![CDATA[Following]]></string>
+    <string name="_bx_persons_page_block_title_system_profile_subscribed_me"><![CDATA[Followers]]></string>
+    <string name="_bx_persons_page_block_title_profile_subscribed_me"><![CDATA[Followers]]></string>
+    <string name="_bx_persons_page_block_title_system_profile_relations"><![CDATA[Relationships]]></string>
+    <string name="_bx_persons_page_block_title_profile_relations"><![CDATA[Relationships]]></string>
+    <string name="_bx_persons_page_block_title_system_profile_related_me"><![CDATA[Relationships with Me]]></string>
+    <string name="_bx_persons_page_block_title_profile_related_me"><![CDATA[Relationships with Me]]></string>
+    <string name="_bx_persons_page_block_title_profile_comments"><![CDATA[Comments]]></string>
+    <string name="_bx_persons_page_block_title_entry_reports"><![CDATA[Reports]]></string>
+    <string name="_bx_persons_page_block_title_profile_comments_link"><![CDATA[Comments to <a href="{entry_link}">{title}</a>]]></string>
+    <string name="_bx_persons_page_block_title_featured_profiles"><![CDATA[Featured People]]></string>
+    <string name="_bx_persons_page_block_title_profile_actions"><![CDATA[Actions]]></string>
+    <string name="_bx_persons_page_block_title_profile_calendar"><![CDATA[Calendar]]></string>
+    <string name="_bx_persons_page_block_title_latest_profiles"><![CDATA[New People]]></string>
+    <string name="_bx_persons_page_block_title_system_manage"><![CDATA[Manage Own People]]></string>
+    <string name="_bx_persons_page_block_title_system_manage_administration"><![CDATA[Manage All People]]></string>
+    <string name="_bx_persons_page_block_title_manage"><![CDATA[Manage People]]></string>
+    <string name="_bx_persons_page_block_title_sys_active_profiles"><![CDATA[Active People]]></string>
+    <string name="_bx_persons_page_block_title_active_profiles"><![CDATA[Active People]]></string>
+    <string name="_bx_persons_page_block_title_online_profiles"><![CDATA[Online People]]></string>
+    <string name="_bx_persons_page_block_title_sys_familiar_profiles"><![CDATA[Familiar People]]></string>
+    <string name="_bx_persons_page_block_title_familiar_profiles"><![CDATA[People You May Know]]></string>
+    <string name="_bx_persons_page_block_title_search_form"><![CDATA[Search Form]]></string>
+    <string name="_bx_persons_page_block_title_search_results"><![CDATA[Search Results]]></string>
+    <string name="_bx_persons_page_block_title_search_form_cmts"><![CDATA[Comments Search Form]]></string>
+    <string name="_bx_persons_page_block_title_search_results_cmts"><![CDATA[Comments Search Results]]></string>
+    <string name="_bx_persons_page_block_title_sys_featured_entries_view_showcase"><![CDATA[Featured People (Showcase View)]]></string>
+    <string name="_bx_persons_page_block_title_featured_entries_view_showcase"><![CDATA[Featured People]]></string>
+    <string name="_bx_persons_page_block_title_sys_recommended_entries_view_showcase"><![CDATA[Recommended People (Showcase View)]]></string>
+    <string name="_bx_persons_page_block_title_recommended_entries_view_showcase"><![CDATA[Recommended People]]></string>
+    <string name="_bx_persons_page_block_title_sys_active_entries_view_showcase"><![CDATA[Active People (Showcase View)]]></string>
+    <string name="_bx_persons_page_block_title_active_entries_view_showcase"><![CDATA[Active People]]></string>
+	
+	<string name="_bx_persons_page_block_title_sys_cover_block"><![CDATA[Cover]]></string>
+    <string name="_bx_persons_page_block_title_cover_block"><![CDATA[Cover]]></string>
+
+    <string name="_bx_persons_menu_title_submenu"><![CDATA[Persons Submenu]]></string>
+    <string name="_bx_persons_menu_set_title_submenu"><![CDATA[Persons Submenu]]></string>
+    <string name="_bx_persons_menu_set_title_view_profile_actions"><![CDATA[Person Actions]]></string>
+    <string name="_bx_persons_menu_title_view_profile_actions"><![CDATA[Person Actions]]></string>
+    <string name="_bx_persons_menu_set_title_view_profile_actions_more"><![CDATA[Person More Actions]]></string>
+    <string name="_bx_persons_menu_title_view_profile_actions_more"><![CDATA[Person More Actions]]></string>
+    <string name="_bx_persons_menu_title_view_profile_meta"><![CDATA[Person Meta]]></string>
+    <string name="_bx_persons_menu_set_title_view_profile_meta"><![CDATA[Person Meta]]></string>
+    <string name="_bx_persons_menu_set_title_view_profile_submenu"><![CDATA[View Person Submenu]]></string>
+    <string name="_bx_persons_menu_title_view_profile_submenu"><![CDATA[View Person Submenu]]></string>
+    <string name="_bx_persons_menu_set_title_manage_tools"><![CDATA[Manage Tools Submenu]]></string>
+    <string name="_bx_persons_menu_title_manage_tools"><![CDATA[Manage Tools Submenu]]></string>
+    <string name="_bx_persons_menu_item_title_system_delete"><![CDATA[Delete]]></string>
+    <string name="_bx_persons_menu_item_title_delete"><![CDATA[Delete]]></string>
+    <string name="_bx_persons_menu_item_title_system_delete_with_content"><![CDATA[Delete With Content]]></string>
+    <string name="_bx_persons_menu_item_title_delete_with_content"><![CDATA[Delete With Content]]></string>
+    <string name="_bx_persons_menu_item_title_system_clear_reports"><![CDATA[Clear reports]]></string>
+    <string name="_bx_persons_menu_item_title_clear_reports"><![CDATA[Clear reports]]></string>
+    <string name="_bx_persons_menu_item_title_system_manage_cf"><![CDATA[Manage audience]]></string>
+    <string name="_bx_persons_menu_item_title_manage_cf"><![CDATA[Manage audience]]></string>
+    <string name="_bx_persons_menu_item_title_system_edit_cover"><![CDATA[Edit Cover]]></string>
+    <string name="_bx_persons_menu_item_title_edit_cover"><![CDATA[Edit Cover]]></string>
+    <string name="_bx_persons_menu_item_title_system_edit_profile"><![CDATA[Edit Person]]></string>
+    <string name="_bx_persons_menu_item_title_edit_profile"><![CDATA[Edit Profile]]></string>
+    <string name="_bx_persons_menu_item_title_system_delete_profile"><![CDATA[Delete Person]]></string>
+    <string name="_bx_persons_menu_item_title_delete_profile"><![CDATA[Delete Profile]]></string>
+    <string name="_bx_persons_menu_item_title_system_delete_account"><![CDATA[Delete Account]]></string>
+    <string name="_bx_persons_menu_item_title_delete_account"><![CDATA[Delete Account]]></string>
+    <string name="_bx_persons_menu_item_title_system_delete_account_content"><![CDATA[Delete Account with Content]]></string>
+    <string name="_bx_persons_menu_item_title_delete_account_content"><![CDATA[Delete Account with Content]]></string>
+    <string name="_bx_persons_menu_item_title_system_profile_type"><![CDATA[Person]]></string>
+    <string name="_bx_persons_menu_item_title_profile_type"><![CDATA[Person]]></string>
+    <string name="_bx_persons_menu_item_title_system_create_profile"><![CDATA[Person]]></string>
+    <string name="_bx_persons_menu_item_title_create_profile"><![CDATA[Person]]></string>
+    <string name="_bx_persons_menu_item_title_system_view_profile_friends"><![CDATA[Friends]]></string>
+    <string name="_bx_persons_menu_item_title_view_profile_friends"><![CDATA[Friends]]></string>
+    <string name="_bx_persons_menu_item_title_system_view_profile_relations"><![CDATA[Relationships]]></string>
+    <string name="_bx_persons_menu_item_title_view_profile_relations"><![CDATA[Relationships]]></string>
+    <string name="_bx_persons_menu_item_title_system_view_profile_subscriptions"><![CDATA[Following]]></string>
+    <string name="_bx_persons_menu_item_title_view_profile_subscriptions"><![CDATA[Following]]></string>
+    <string name="_bx_persons_menu_item_title_system_view_profile_comments"><![CDATA[Comments]]></string>
+    <string name="_bx_persons_menu_item_title_view_profile_comments"><![CDATA[Comments]]></string>
+    <string name="_bx_persons_menu_item_title_system_view_profile_info"><![CDATA[Info]]></string>
+    <string name="_bx_persons_menu_item_title_view_profile_info"><![CDATA[Info]]></string>
+    <string name="_bx_persons_menu_item_title_system_view_profile_view"><![CDATA[Profile]]></string>
+    <string name="_bx_persons_menu_item_title_view_profile_view"><![CDATA[Profile]]></string>
+    <string name="_bx_persons_menu_item_title_system_view_profile_more_auto"><![CDATA[More]]></string>
+    <string name="_bx_persons_menu_item_title_view_profile_more_auto"><![CDATA[More]]></string>
+    <string name="_bx_persons_menu_item_title_system_befriend"><![CDATA[Add friend]]></string>
+    <string name="_bx_persons_menu_item_title_befriend"><![CDATA[Add friend]]></string>
+    <string name="_bx_persons_menu_item_title_befriend_sent"><![CDATA[Add friend (requested)]]></string>
+    <string name="_bx_persons_menu_item_title_befriend_confirm"><![CDATA[Accept friend request]]></string>
+    <string name="_bx_persons_menu_item_title_system_unfriend"><![CDATA[Unfriend]]></string>
+    <string name="_bx_persons_menu_item_title_unfriend"><![CDATA[Unfriend]]></string>
+    <string name="_bx_persons_menu_item_title_unfriend_cancel_request"><![CDATA[Cancel friend request]]></string>
+    <string name="_bx_persons_menu_item_title_unfriend_reject_request"><![CDATA[Reject friend request]]></string>
+    <string name="_bx_persons_menu_item_title_system_subscribe"><![CDATA[Follow]]></string>
+    <string name="_bx_persons_menu_item_title_subscribe"><![CDATA[Follow]]></string>
+    <string name="_bx_persons_menu_item_title_system_unsubscribe"><![CDATA[Unfollow]]></string>
+    <string name="_bx_persons_menu_item_title_unsubscribe"><![CDATA[Unfollow]]></string>
+    <string name="_bx_persons_menu_item_title_system_relation_add"><![CDATA[Add Relationship]]></string>
+    <string name="_bx_persons_menu_item_title_relation_add"><![CDATA[Add Relationship]]></string>
+    <string name="_bx_persons_menu_item_title_system_relation_delete"><![CDATA[Remove Relationship]]></string>
+    <string name="_bx_persons_menu_item_title_relation_delete"><![CDATA[Remove Relationship]]></string>
+    <string name="_bx_persons_menu_item_title_system_more_actions"><![CDATA[More Actions]]></string>
+    <string name="_bx_persons_menu_item_title_more_actions"><![CDATA[]]></string>
+    <string name="_bx_persons_menu_item_title_system_friends"><![CDATA[Friends]]></string>
+    <string name="_bx_persons_menu_item_title_friends"><![CDATA[Friends]]></string>
+    <string name="_bx_persons_menu_item_title_system_relations"><![CDATA[Relationships]]></string>
+    <string name="_bx_persons_menu_item_title_relations"><![CDATA[Relationships]]></string>
+    <string name="_bx_persons_menu_item_title_system_friend_requests"><![CDATA[Friend requests number]]></string>
+    <string name="_bx_persons_menu_item_title_friend_requests"><![CDATA[Friend requests]]></string>
+    <string name="_bx_persons_menu_item_title_system_manage_my_profiles"><![CDATA[My profiles]]></string>
+    <string name="_bx_persons_menu_item_title_manage_my_profiles"><![CDATA[Profiles]]></string>
+    <string name="_bx_persons_menu_item_title_system_favorites"><![CDATA[Favorite Persons]]></string>
+    <string name="_bx_persons_menu_item_title_favorites"><![CDATA[Favorite persons]]></string>    
+    <string name="_bx_persons_menu_item_title_system_subscriptions"><![CDATA[Following]]></string>
+    <string name="_bx_persons_menu_item_title_subscriptions"><![CDATA[Following]]></string>
+    <string name="_bx_persons_menu_item_title_system_subscribed_me"><![CDATA[Followers]]></string>
+    <string name="_bx_persons_menu_item_title_subscribed_me"><![CDATA[Followers]]></string>
+    <string name="_bx_persons_menu_item_title_system_relations"><![CDATA[Relationships]]></string>
+    <string name="_bx_persons_menu_item_title_relations"><![CDATA[Relationships]]></string>
+    <string name="_bx_persons_menu_item_title_system_related_me"><![CDATA[Relationships with Me]]></string>
+    <string name="_bx_persons_menu_item_title_related_me"><![CDATA[Relationships with Me]]></string>
+    <string name="_bx_persons_menu_item_title_system_followings"><![CDATA[Persons]]></string>
+    <string name="_bx_persons_menu_item_title_followings"><![CDATA[Persons]]></string>
+    <string name="_bx_persons_menu_item_title_system_entries_recent"><![CDATA[New]]></string>
+    <string name="_bx_persons_menu_item_title_entries_recent"><![CDATA[New]]></string>
+    <string name="_bx_persons_menu_item_title_system_entries_search"><![CDATA[Search]]></string>
+    <string name="_bx_persons_menu_item_title_entries_search"><![CDATA[Search]]></string>
+    <string name="_bx_persons_menu_item_title_system_entries_manage"><![CDATA[Manage]]></string>
+    <string name="_bx_persons_menu_item_title_entries_manage"><![CDATA[Manage]]></string>
+    <string name="_bx_persons_menu_item_title_system_entries_home"><![CDATA[Persons]]></string>
+    <string name="_bx_persons_menu_item_title_entries_home"><![CDATA[People]]></string>
+	<string name="_bx_persons_menu_item_title_system_admt_persons"><![CDATA[Profiles]]></string>
+	<string name="_bx_persons_menu_item_title_admt_persons"><![CDATA[Profiles]]></string>
+	<string name="_bx_persons_menu_item_title_manage_my"><![CDATA[My Profiles]]></string>
+	<string name="_bx_persons_menu_item_title_manage_all"><![CDATA[All Profiles]]></string>   
+	<string name="_bx_persons_menu_item_title_system_entries_active"><![CDATA[Active]]></string>
+	<string name="_bx_persons_menu_item_title_entries_active"><![CDATA[Active]]></string>
+	<string name="_bx_persons_menu_item_title_system_entries_online"><![CDATA[Online]]></string>
+	<string name="_bx_persons_menu_item_title_entries_online"><![CDATA[Online]]></string>
+
+    <string name="_bx_persons_grid_filter_item_title_adm_select_one_filter1"><![CDATA[All Statuses]]></string>
+    <string name="_bx_persons_grid_filter_item_title_adm_select_one_filter2"><![CDATA[All]]></string>
+    <string name="_bx_persons_grid_filter_item_title_adm_active"><![CDATA[Active]]></string>
+    <string name="_bx_persons_grid_filter_item_title_adm_pending"><![CDATA[Pending]]></string>
+    <string name="_bx_persons_grid_filter_item_title_adm_suspended"><![CDATA[Suspended]]></string>
+    <string name="_bx_persons_grid_filter_item_title_adm_unconfirmed"><![CDATA[Unconfirmed]]></string>
+    <string name="_bx_persons_grid_column_title_adm_active"><![CDATA[Active]]></string>
+    <string name="_bx_persons_grid_column_title_adm_fullname"><![CDATA[Name]]></string>
+    <string name="_bx_persons_grid_column_title_adm_last_online"><![CDATA[Last Logged]]></string>
+    <string name="_bx_persons_grid_column_title_adm_account"><![CDATA[Account]]></string>
+    <string name="_bx_persons_grid_action_title_adm_delete"><![CDATA[Delete]]></string>
+    <string name="_bx_persons_grid_action_title_adm_delete_with_content"><![CDATA[Delete With Content]]></string>
+    <string name="_bx_persons_grid_action_title_adm_clear_reports"><![CDATA[Clear reports]]></string>
+    <string name="_bx_persons_grid_action_title_adm_set_acl_level"><![CDATA[Set Membership]]></string>
+    <string name="_bx_persons_grid_action_title_adm_more_actions"><![CDATA[More Actions]]></string>
+    <string name="_bx_persons_grid_action_title_adm_audit_content"><![CDATA[Audit actions with profile]]></string>
+    <string name="_bx_persons_grid_action_title_adm_audit_profile"><![CDATA[Audit profile actions]]></string>
+    <string name="_bx_persons_grid_action_title_adm_manage_cf"><![CDATA[Manage audience]]></string>
+    
+    <string name="_bx_persons_grid_action_err_delete"><![CDATA[Cannot delete the selected person(s).]]></string>
+    <string name="_bx_persons_grid_txt_account_manager"><![CDATA[Redirect to manage account.]]></string>
+
+    <string name="_bx_persons_chart_growth"><![CDATA[Persons: Growth]]></string>
+    <string name="_bx_persons_chart_growth_speed"><![CDATA[Persons: Growth Speed]]></string>
+
+    <string name="_bx_persons_search_extended"><![CDATA[Persons Search]]></string>
+    <string name="_bx_persons_search_extended_cmts"><![CDATA[Persons Comments Search]]></string>
+
+    <string name="_bx_persons_alert_action_profile_cover_changed"><![CDATA[cover changed]]></string>
+    <string name="_bx_persons_alert_action_profile_picture_changed"><![CDATA[picture changed]]></string>
+
+    <string name="_bx_persons_txt_account_pending"><![CDATA[This profile is pending approval, please wait until it is activated.]]></string>
+    <string name="_bx_persons_txt_account_pending_moderation"><![CDATA[This <a href="{0}">profile</a> is pending approval.]]></string>
+    <string name="_bx_persons_txt_account_suspended"><![CDATA[This profile is suspended.]]></string>
+    <string name="_bx_persons_txt_account_suspended_moderation"><![CDATA[This <a href="{0}">profile</a> is suspended.]]></string>
+    <string name="_bx_persons_txt_N_friends"><![CDATA[{0} friends]]></string>
+    <string name="_bx_persons_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> profile timeline]]></string>
+    <string name="_bx_persons_txt_sample_single"><![CDATA[person]]></string>
+    <string name="_bx_persons_txt_sample_comment_single"><![CDATA[comment to person]]></string>
+    <string name="_bx_persons_txt_sample_vote_single"><![CDATA[vote to person]]></string>
+    <string name="_bx_persons_txt_sample_score_up_single"><![CDATA[score up vote to person]]></string>
+    <string name="_bx_persons_txt_sample_score_down_single"><![CDATA[score down vote to person]]></string>
+    <string name="_bx_persons_txt_sample_pp_single"><![CDATA[profile picture]]></string>
+    <string name="_bx_persons_txt_sample_pp_single_with_article"><![CDATA[a profile picture]]></string>
+    <string name="_bx_persons_txt_sample_pc_single"><![CDATA[profile cover]]></string>
+    <string name="_bx_persons_txt_sample_pc_single_with_article"><![CDATA[a profile cover]]></string>
+    <string name="_bx_persons_txt_sample_pi_action"><![CDATA[changed {0}]]></string>
+    <string name="_bx_persons_txt_sample_pi_action_user"><![CDATA[{0} changed {1}]]></string>
+
+    <string name="_bx_persons_email_friend_request"><![CDATA[Friend request]]></string>
+    <string name="_bx_persons_email_friend_request_subject"><![CDATA[Friendship Request]]></string>
+    <string name="_bx_persons_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>
+</resources>

+ 566 - 0
modules/boonex/persons/updates/13.0.0_13.0.1/source/install/sql/enable.sql

@@ -0,0 +1,566 @@
+
+-- 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_persons', '_bx_persons', 'bx_persons@modules/boonex/persons/|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_persons', '_bx_persons', 1);
+SET @iCategId = LAST_INSERT_ID();
+
+INSERT INTO `sys_options` (`name`, `value`, `category_id`, `caption`, `type`, `extra`, `check`, `check_error`, `order`) VALUES
+('bx_persons_autoapproval', 'on', @iCategId, '_bx_persons_option_autoapproval', 'select', 'a:2:{s:6:"module";s:10:"bx_persons";s:6:"method";s:22:"get_options_activation";}', '', '', 1),
+('bx_persons_default_acl_level', '3', @iCategId, '_bx_persons_option_default_acl_level', 'select', 'a:4:{s:6:"module";s:6:"system";s:6:"method";s:15:"get_memberships";s:6:"params";a:4:{s:11:"purchasable";b:0;s:6:"active";b:1;s:9:"translate";b:1;s:22:"filter_out_auto_levels";b:1;}s:5:"class";s:16:"TemplAclServices";}', '', '', 2),
+('bx_persons_redirect_aadd', 'profile', @iCategId, '_bx_persons_option_redirect_aadd', 'select', 'a:2:{s:6:"module";s:10:"bx_persons";s:6:"method";s:30:"get_options_redirect_after_add";}', '', '', 3),
+('bx_persons_redirect_aadd_custom_url', '', @iCategId, '_bx_persons_option_redirect_aadd_custom_url', 'digit', '', '', '', 4),
+('bx_persons_num_connections_quick', '6', @iCategId, '_bx_persons_option_num_connections_quick', 'digit', '', '', '', 10),
+('bx_persons_per_page_browse', '24', @iCategId, '_bx_persons_option_per_page_browse', 'digit', '', '', '', 11),
+('bx_persons_num_rss', '10', @iCategId, '_bx_persons_option_num_rss', 'digit', '', '', '', 12),
+('bx_persons_per_page_browse_showcase', '32', @iCategId, '_sys_option_per_page_browse_showcase', 'digit', '', '', '', 15),
+('bx_persons_per_page_browse_recommended', '10', @iCategId, '_sys_option_per_page_browse_recommended', 'digit', '', '', '', 16),
+('bx_persons_searchable_fields', 'fullname,description', @iCategId, '_bx_persons_option_searchable_fields', 'list', 'a:2:{s:6:"module";s:10:"bx_persons";s:6:"method";s:21:"get_searchable_fields";}', '', '', 20),
+('bx_persons_public_subscriptions', '', @iCategId, '_bx_persons_option_public_subscriptions', 'checkbox', '', '', '', 30),
+('bx_persons_public_subscribed_me', '', @iCategId, '_bx_persons_option_public_subscribed_me', 'checkbox', '', '', '', 31),
+('bx_persons_enable_profile_activation_letter', 'on', @iCategId, '_bx_persons_option_enable_profile_activation_letter', 'checkbox', '', '', '', 32);
+
+-- 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_persons_create_profile', 'create-persons-profile', '_bx_persons_page_title_sys_create_profile', '_bx_persons_page_title_create_profile', 'bx_persons', 5, 2147483647, 1, 'page.php?i=create-persons-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_persons_create_profile', 1, 'bx_persons', '_bx_persons_page_block_title_choose_type', 11, 2147483647, 'menu', 'sys_add_profile_vertical', 0, 1, 0, 0),
+('bx_persons_create_profile', 1, 'bx_persons', '_bx_persons_page_block_title_create_profile', 11, 2147483647, 'service', 'a:2:{s:6:\"module\";s:10:\"bx_persons\";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_persons_view_profile', 'view-persons-profile', '_bx_persons_page_title_sys_view_profile', '_bx_persons_page_title_view_profile', 'bx_persons', 7, 2147483647, 1, 'page.php?i=view-persons-profile', '', '', '', 0, 1, 0, 'BxPersonsPageEntry', 'modules/boonex/persons/classes/BxPersonsPageEntry.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_persons_view_profile', 0, 'bx_persons', '_bx_persons_page_block_title_sys_cover_block', '_bx_persons_page_block_title_cover_block', 3, 2147483647, 'service', 'a:2:{s:6:\"module\";s:10:\"bx_persons\";s:6:\"method\";s:12:\"entity_cover\";}', 0, 0, 1, 0),
+('bx_persons_view_profile', 0, 'bx_persons', '', '_bx_persons_page_block_title_profile_friends_mutual', 11, 2147483647, 'service', 'a:2:{s:6:\"module\";s:10:\"bx_persons\";s:6:\"method\";s:22:\"profile_friends_mutual\";}', 0, 0, 1, 0),
+('bx_persons_view_profile', 2, 'bx_persons', '', '_bx_persons_page_block_title_profile_subscriptions', 11, 2147483647, 'service', 'a:2:{s:6:\"module\";s:10:\"bx_persons\";s:6:\"method\";s:21:\"profile_subscriptions\";}', 0, 1, 0, 0),
+('bx_persons_view_profile', 2, 'bx_persons', '', '_bx_persons_page_block_title_profile_subscribed_me', 11, 2147483647, 'service', 'a:2:{s:6:\"module\";s:10:\"bx_persons\";s:6:\"method\";s:21:\"profile_subscribed_me\";}', 0, 1, 0, 0),
+('bx_persons_view_profile', 2, 'bx_persons', '', '_bx_persons_page_block_title_profile_related_me', 11, 2147483647, 'service', 'a:2:{s:6:"module";s:10:"bx_persons";s:6:"method";s:18:"profile_related_me";}', 0, 1, 0, 0),
+('bx_persons_view_profile', 2, 'bx_persons', '', '_bx_persons_page_block_title_profile_comments', 11, 2147483647, 'service', 'a:2:{s:6:\"module\";s:10:\"bx_persons\";s:6:\"method\";s:15:\"entity_comments\";}', 0, 0, 0, 0),
+('bx_persons_view_profile', 2, 'bx_persons', '', '_bx_persons_page_block_title_profile_description', 13, 2147483647, 'service', 'a:2:{s:6:\"module\";s:10:\"bx_persons\";s:6:\"method\";s:17:\"entity_text_block\";}', 0, 0, 1, 1),
+('bx_persons_view_profile', 2, 'bx_persons', '', '_bx_persons_page_block_title_profile_friends', 11, 2147483647, 'service', 'a:2:{s:6:\"module\";s:10:\"bx_persons\";s:6:\"method\";s:15:\"profile_friends\";}', 0, 1, 1, 2),
+('bx_persons_view_profile', 2, 'bx_persons', '', '_bx_persons_page_block_title_profile_relations', 11, 2147483647, 'service', 'a:2:{s:6:"module";s:10:"bx_persons";s:6:"method";s:17:"profile_relations";}', 0, 1, 1, 3),
+('bx_persons_view_profile', 2, 'bx_persons', '', '_bx_persons_page_block_title_profile_calendar', 13, 2147483647, 'service', 'a:2:{s:6:\"module\";s:10:\"bx_persons\";s:6:\"method\";s:15:\"entity_calendar\";}', 0, 0, 0, 4),
+('bx_persons_view_profile', 3, 'bx_persons', '', '_bx_persons_page_block_title_profile_location', 13, 2147483647, 'service', 'a:2:{s:6:\"module\";s:10:\"bx_persons\";s:6:\"method\";s:15:\"entity_location\";}', 0, 0, 0, 0),
+('bx_persons_view_profile', 3, 'bx_persons', '', '_bx_persons_page_block_title_profile_info', 11, 2147483647, 'service', 'a:2:{s:6:\"module\";s:10:\"bx_persons\";s:6:\"method\";s:11:\"entity_info\";}', 0, 0, 1, 1),
+('bx_persons_view_profile', 3, 'bx_persons', '', '_bx_persons_page_block_title_profile_all_actions', 13, 2147483647, 'service', 'a:2:{s:6:"module";s:10:"bx_persons";s:6:"method";s:18:"entity_all_actions";}', 0, 0, 0, 0),
+('bx_persons_view_profile', 3, 'bx_persons', '', '_bx_persons_page_block_title_profile_membership', 11, 2147483647, 'service', 'a:2:{s:6:\"module\";s:10:\"bx_persons\";s:6:\"method\";s:18:\"profile_membership\";}', 0, 0, 1, 2),
+('bx_persons_view_profile', 3, 'bx_persons', '', '_bx_persons_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:10:\"bx_persons\";i:1;s:12:\"{content_id}\";}s:5:\"class\";s:20:\"TemplServiceMetatags\";}', 0, 0, 1, 3),
+('bx_persons_view_profile', 2, 'bx_persons', '', '_bx_persons_page_block_title_entry_reports', 11, 2147483647, 'service', 'a:2:{s:6:\"module\";s:10:\"bx_persons\";s:6:\"method\";s:14:\"entity_reports\";}', 0, 0, 1, 6);
+
+-- 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_persons_view_profile_closed', 'view-person-profile-closed', '_bx_persons_page_title_sys_view_profile_closed', '_bx_persons_page_title_view_profile', 'bx_persons', 10, 2147483647, 1, 'page.php?i=view-person-profile', '', '', '', 0, 1, 0, 'BxPersonsPageEntry', 'modules/boonex/persons/classes/BxPersonsPageEntry.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_persons_view_profile_closed', 1, 'bx_persons', '', '_bx_persons_page_block_title_profile_private', 11, 2147483647, 'service', 'a:2:{s:6:\"module\";s:10:\"bx_persons\";s:6:\"method\";s:19:\"private_profile_msg\";}', 0, 1, 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_persons_edit_profile', 'edit-persons-profile', '_bx_persons_page_title_sys_edit_profile', '_bx_persons_page_title_edit_profile', 'bx_persons', 5, 2147483647, 1, 'page.php?i=edit-persons-profile', '', '', '', 0, 1, 0, 'BxPersonsPageEntry', 'modules/boonex/persons/classes/BxPersonsPageEntry.php');
+
+INSERT INTO `sys_pages_blocks`(`object`, `cell_id`, `module`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `order`) VALUES 
+('bx_persons_edit_profile', 1, 'bx_persons', '_bx_persons_page_block_title_edit_profile', 11, 2147483647, 'service', 'a:2:{s:6:\"module\";s:10:\"bx_persons\";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_persons_edit_profile_cover', 'edit-persons-cover', '_bx_persons_page_title_sys_edit_profile_cover', '_bx_persons_page_title_edit_profile_cover', 'bx_persons', 5, 2147483647, 1, 'page.php?i=edit-persons-cover', '', '', '', 0, 1, 0, 'BxPersonsPageEntry', 'modules/boonex/persons/classes/BxPersonsPageEntry.php');
+
+INSERT INTO `sys_pages_blocks`(`object`, `cell_id`, `module`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `order`) VALUES 
+('bx_persons_edit_profile_cover', 1, 'bx_persons', '_bx_persons_page_block_title_edit_profile_cover', 11, 2147483647, 'service', 'a:2:{s:6:\"module\";s:10:\"bx_persons\";s:6:\"method\";s:17:\"entity_edit_cover\";}', 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_persons_delete_profile', 'delete-persons-profile', '_bx_persons_page_title_sys_delete_profile', '_bx_persons_page_title_delete_profile', 'bx_persons', 5, 2147483647, 1, 'page.php?i=delete-persons-profile', '', '', '', 0, 1, 0, 'BxPersonsPageEntry', 'modules/boonex/persons/classes/BxPersonsPageEntry.php');
+
+INSERT INTO `sys_pages_blocks`(`object`, `cell_id`, `module`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `order`) VALUES 
+('bx_persons_delete_profile', 1, 'bx_persons', '_bx_persons_page_block_title_delete_profile', 11, 2147483647, 'service', 'a:2:{s:6:\"module\";s:10:\"bx_persons\";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_persons_profile_info', 'persons-profile-info', '_bx_persons_page_title_sys_profile_info', '_bx_persons_page_title_profile_info', 'bx_persons', 5, 2147483647, 1, 'page.php?i=persons-profile-info', '', '', '', 0, 1, 0, 'BxPersonsPageEntry', 'modules/boonex/persons/classes/BxPersonsPageEntry.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_persons_profile_info', 1, 'bx_persons', '_bx_persons_page_block_title_system_profile_info', '_bx_persons_page_block_title_profile_info_link', 11, 2147483647, 'service', 'a:2:{s:6:\"module\";s:10:\"bx_persons\";s:6:\"method\";s:16:\"entity_info_full\";}', 0, 0, 1, 1),
+('bx_persons_profile_info', 1, 'bx_persons', '', '_bx_persons_page_block_title_profile_description', 13, 2147483647, 'service', 'a:2:{s:6:\"module\";s:10:\"bx_persons\";s:6:\"method\";s:17:\"entity_text_block\";}', 0, 0, 1, 2);
+
+-- 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_persons_profile_friends', 'persons-profile-friends', '_bx_persons_page_title_sys_profile_friends', '_bx_persons_page_title_profile_friends', 'bx_persons', 5, 2147483647, 1, 'page.php?i=persons-profile-friends', '', '', '', 0, 1, 0, 'BxPersonsPageEntry', 'modules/boonex/persons/classes/BxPersonsPageEntry.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_persons_profile_friends', 1, 'bx_persons', '_bx_persons_page_block_title_system_profile_friends', '_bx_persons_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_persons_friend_requests', 'persons-friend-requests', '_bx_persons_page_title_sys_friend_requests', '_bx_persons_page_title_friend_requests', 'bx_persons', 5, 2147483647, 1, 'page.php?i=persons-friend-requests', '', '', '', 0, 1, 0, 'BxPersonsPageEntry', 'modules/boonex/persons/classes/BxPersonsPageEntry.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_persons_friend_requests', 1, 'bx_persons', '_bx_persons_page_block_title_system_friend_requests', '_bx_persons_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_persons_profile_favorites', 'persons-profile-favorites', '_bx_persons_page_title_sys_profile_favorites', '_bx_persons_page_title_profile_favorites', 'bx_persons', 5, 2147483647, 1, 'page.php?i=persons-profile-favorites', '', '', '', 0, 1, 0, 'BxPersonsPageBrowse', 'modules/boonex/persons/classes/BxPersonsPageBrowse.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_persons_profile_favorites', 1, 'bx_persons', '_bx_persons_page_block_title_system_profile_favorites', '_bx_persons_page_block_title_profile_favorites', 11, 2147483647, 'service', 'a:2:{s:6:"module";s:10:"bx_persons";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_persons_profile_subscriptions', 'persons-profile-subscriptions', '_bx_persons_page_title_sys_profile_subscriptions', '_bx_persons_page_title_profile_subscriptions', 'bx_persons', 5, 2147483647, 1, 'page.php?i=persons-profile-subscriptions', '', '', '', 0, 1, 0, 'BxPersonsPageEntry', 'modules/boonex/persons/classes/BxPersonsPageEntry.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_persons_profile_subscriptions', 1, 'bx_persons', '_bx_persons_page_block_title_system_profile_subscriptions', '_bx_persons_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_persons_profile_subscriptions', 1, 'bx_persons', '_bx_persons_page_block_title_system_profile_subscribed_me', '_bx_persons_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: profile relations
+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_persons_profile_relations', 'persons-profile-relations', '_bx_persons_page_title_sys_profile_relations', '_bx_persons_page_title_profile_relations', 'bx_persons', 5, 2147483647, 1, 'page.php?i=persons-profile-relations', '', '', '', 0, 1, 0, 'BxPersonsPageEntry', 'modules/boonex/persons/classes/BxPersonsPageEntry.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_persons_profile_relations', 1, 'bx_persons', '_bx_persons_page_block_title_system_profile_relations', '_bx_persons_page_block_title_profile_relations', 11, 2147483647, 'service', 'a:3:{s:6:"module";s:6:"system";s:6:"method";s:15:"relations_table";s:5:"class";s:23:"TemplServiceConnections";}', 0, 0, 1, 1),
+('bx_persons_profile_relations', 1, 'bx_persons', '_bx_persons_page_block_title_system_profile_related_me', '_bx_persons_page_block_title_profile_related_me', 11, 2147483647, 'service', 'a:3:{s:6:"module";s:6:"system";s:6:"method";s:16:"related_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_persons_profile_comments', '_bx_persons_page_title_sys_profile_comments', '_bx_persons_page_title_profile_comments', 'bx_persons', 5, 2147483647, 1, 'persons-profile-comments', '', '', '', '', 0, 1, 0, 'BxPersonsPageEntry', 'modules/boonex/persons/classes/BxPersonsPageEntry.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_persons_profile_comments', 1, 'bx_persons', '_bx_persons_page_block_title_profile_comments', '_bx_persons_page_block_title_profile_comments_link', 11, 2147483647, 'service', 'a:2:{s:6:\"module\";s:10:\"bx_persons\";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_persons_home', '_bx_persons_page_title_sys_recent', '_bx_persons_page_title_recent', 'bx_persons', 5, 2147483647, 1, 'persons-home', 'page.php?i=persons-home', '', '', '', 0, 1, 0, 'BxPersonsPageBrowse', 'modules/boonex/persons/classes/BxPersonsPageBrowse.php');
+
+INSERT INTO `sys_pages_blocks`(`object`, `cell_id`, `module`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `order`) VALUES
+('bx_persons_home', 1, 'bx_persons', '_bx_persons_page_block_title_featured_profiles', 11, 2147483647, 'service', 'a:3:{s:6:"module";s:10:"bx_persons";s:6:"method";s:15:"browse_featured";s:6:"params";a:1:{i:0;s:7:"gallery";}}', 0, 1, 0),
+('bx_persons_home', 1, 'bx_persons', '_bx_persons_page_block_title_latest_profiles', 11, 2147483647, 'service', 'a:3:{s:6:\"module\";s:10:\"bx_persons\";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_persons_active', '_bx_persons_page_title_sys_active', '_bx_persons_page_title_active', 'bx_persons', 5, 2147483647, 1, 'persons-active', 'page.php?i=persons-active', '', '', '', 0, 1, 0, 'BxPersonsPageBrowse', 'modules/boonex/persons/classes/BxPersonsPageBrowse.php');
+
+INSERT INTO `sys_pages_blocks`(`object`, `cell_id`, `module`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `order`) VALUES 
+('bx_persons_active', 1, 'bx_persons', '_bx_persons_page_block_title_active_profiles', 11, 2147483647, 'service', 'a:3:{s:6:"module";s:10:"bx_persons";s:6:"method";s:22:"browse_active_profiles";s:6:"params";a:2:{s:9:"unit_view";s:7:"gallery";s:13:"empty_message";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_persons_online', '_bx_persons_page_title_sys_online', '_bx_persons_page_title_online', 'bx_persons', 5, 2147483647, 1, 'persons-online', 'page.php?i=persons-online', '', '', '', 0, 1, 0, 'BxPersonsPageBrowse', 'modules/boonex/persons/classes/BxPersonsPageBrowse.php');
+
+INSERT INTO `sys_pages_blocks`(`object`, `cell_id`, `module`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `order`) VALUES 
+('bx_persons_online', 1, 'bx_persons', '_bx_persons_page_block_title_online_profiles', 11, 2147483647, 'service', 'a:3:{s:6:\"module\";s:10:\"bx_persons\";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_persons_search', '_bx_persons_page_title_sys_entries_search', '_bx_persons_page_title_entries_search', 'bx_persons', 5, 2147483647, 1, 'persons-search', 'page.php?i=persons-search', '', '', '', 0, 1, 0, 'BxPersonsPageBrowse', 'modules/boonex/persons/classes/BxPersonsPageBrowse.php');
+
+INSERT INTO `sys_pages_blocks`(`object`, `cell_id`, `module`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `active`, `order`) VALUES 
+('bx_persons_search', 1, 'bx_persons', '_bx_persons_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:10:"bx_persons";}}s:5:"class";s:27:"TemplSearchExtendedServices";}', 0, 1, 1, 1),
+('bx_persons_search', 1, 'bx_persons', '_bx_persons_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:10:"bx_persons";s:10:"show_empty";b:1;}}s:5:"class";s:27:"TemplSearchExtendedServices";}', 0, 1, 1, 2),
+('bx_persons_search', 1, 'bx_persons', '_bx_persons_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:15:"bx_persons_cmts";}}s:5:"class";s:27:"TemplSearchExtendedServices";}', 0, 1, 0, 3),
+('bx_persons_search', 1, 'bx_persons', '_bx_persons_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:15:"bx_persons_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_persons_manage', '_bx_persons_page_title_sys_manage', '_bx_persons_page_title_manage', 'bx_persons', 5, 2147483647, 1, 'persons-manage', 'page.php?i=persons-manage', '', '', '', 0, 1, 0, 'BxPersonsPageBrowse', 'modules/boonex/persons/classes/BxPersonsPageBrowse.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_persons_manage', 1, 'bx_persons', '_bx_persons_page_block_title_system_manage', '_bx_persons_page_block_title_manage', 11, 2147483647, 'service', 'a:2:{s:6:\"module\";s:10:\"bx_persons\";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_persons_administration', '_bx_persons_page_title_sys_manage_administration', '_bx_persons_page_title_manage', 'bx_persons', 5, 192, 1, 'persons-administration', 'page.php?i=persons-administration', '', '', '', 0, 1, 0, 'BxPersonsPageBrowse', 'modules/boonex/persons/classes/BxPersonsPageBrowse.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_persons_administration', 1, 'bx_persons', '_bx_persons_page_block_title_system_manage_administration', '_bx_persons_page_block_title_manage', 11, 192, 'service', 'a:3:{s:6:\"module\";s:10:\"bx_persons\";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_system`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `active`, `order`) VALUES
+('sys_home', 1, 'bx_persons', '' , '_bx_persons_page_block_title_latest_profiles', 11, 2147483647, 'service', 'a:2:{s:6:"module";s:10:"bx_persons";s:6:"method";s:22:"browse_recent_profiles";}', 1, 0, 0, IFNULL(@iBlockOrder, 0) + 1),
+('sys_home', 1, 'bx_persons', '_bx_persons_page_block_title_sys_recommended_entries_view_showcase', '_bx_persons_page_block_title_recommended_entries_view_showcase', 11, 2147483647, 'service', 'a:3:{s:6:\"module\";s:10:\"bx_persons\";s:6:\"method\";s:18:\"browse_recommended\";s:6:\"params\";a:3:{s:9:\"unit_view\";s:8:\"showcase\";s:13:\"empty_message\";b:0;s:13:\"ajax_paginate\";b:0;}}', 1, 0, 0, IFNULL(@iBlockOrder, 0) + 2);
+
+-- 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_persons', '_bx_persons_page_block_title_sys_featured_entries_view_showcase', '_bx_persons_page_block_title_featured_entries_view_showcase', 11, 2147483647, 'service', 'a:3:{s:6:\"module\";s:10:\"bx_persons\";s:6:\"method\";s:15:\"browse_featured\";s:6:\"params\";a:3:{s:9:\"unit_view\";s:8:\"showcase\";s:13:\"empty_message\";b:0;s:13:\"ajax_paginate\";b:0;}}', 0, 1, 1, IFNULL(@iBlockOrder, 0) + 1),
+('', 0, 'bx_persons', '_bx_persons_page_block_title_sys_recommended_entries_view_showcase', '_bx_persons_page_block_title_recommended_entries_view_showcase', 11, 2147483647, 'service', 'a:3:{s:6:\"module\";s:10:\"bx_persons\";s:6:\"method\";s:18:\"browse_recommended\";s:6:\"params\";a:3:{s:9:\"unit_view\";s:8:\"showcase\";s:13:\"empty_message\";b:0;s:13:\"ajax_paginate\";b:0;}}', 0, 1, 1, IFNULL(@iBlockOrder, 0) + 2),
+('', 0, 'bx_persons', '_bx_persons_page_block_title_sys_active_entries_view_showcase', '_bx_persons_page_block_title_active_entries_view_showcase', 11, 2147483647, 'service', 'a:3:{s:6:\"module\";s:10:\"bx_persons\";s:6:\"method\";s:22:\"browse_active_profiles\";s:6:\"params\";a:3:{s:9:\"unit_view\";s:16:\"showcase_wo_info\";s:13:\"empty_message\";b:0;s:13:\"ajax_paginate\";b:0;}}', 0, 1, 1, IFNULL(@iBlockOrder, 0) + 3),
+('', 0, 'bx_persons', '_bx_persons_page_block_title_sys_active_profiles', '_bx_persons_page_block_title_active_profiles', 11, 2147483647, 'service', 'a:3:{s:6:\"module\";s:10:\"bx_persons\";s:6:\"method\";s:22:\"browse_active_profiles\";s:6:\"params\";a:3:{s:9:\"unit_view\";s:12:\"unit_wo_info\";s:13:\"empty_message\";b:0;s:13:\"ajax_paginate\";b:0;}}', 0, 1, 1, IFNULL(@iBlockOrder, 0) + 4),
+('', 0, 'bx_persons', '_bx_persons_page_block_title_sys_familiar_profiles', '_bx_persons_page_block_title_familiar_profiles', 11, 2147483647, 'service', 'a:3:{s:6:\"module\";s:10:\"bx_persons\";s:6:\"method\";s:24:\"browse_familiar_profiles\";s:6:\"params\";a:4:{s:10:\"connection\";s:20:\"sys_profiles_friends\";s:9:\"unit_view\";s:4:\"unit\";s:13:\"empty_message\";b:0;s:13:\"ajax_paginate\";b:0;}}', 0, 1, 1, IFNULL(@iBlockOrder, 0) + 5);
+
+-- MENU
+
+-- MENU: add to site menu
+
+SET @iSiteMenuOrder = (SELECT `order` FROM `sys_menu_items` WHERE `set_name` = 'sys_site' AND `active` = 1 AND `order` < 9999 ORDER BY `order` DESC LIMIT 1);
+INSERT INTO `sys_menu_items` (`set_name`, `module`, `name`, `title_system`, `title`, `link`, `onclick`, `target`, `icon`, `submenu_object`, `visible_for_levels`, `active`, `copyable`, `order`) VALUES 
+('sys_site', 'bx_persons', 'persons-home', '_bx_persons_menu_item_title_system_entries_home', '_bx_persons_menu_item_title_entries_home', 'page.php?i=persons-home', '', '', 'user col-blue3', 'bx_persons_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_persons', 'persons-home', '_bx_persons_menu_item_title_system_entries_home', '_bx_persons_menu_item_title_entries_home', 'page.php?i=persons-home', '', '', 'user col-blue3', 'bx_persons_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_persons', 'create-person-profile', '_bx_persons_menu_item_title_system_profile_type', '_bx_persons_menu_item_title_profile_type', 'page.php?i=create-persons-profile', '', '', 'user', '', 2147483647, 1, 1, IFNULL(@iCreateProfileMenuOrder, 0) + 1);
+
+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_persons', 'create-persons-profile', '_bx_persons_menu_item_title_system_create_profile', '_bx_persons_menu_item_title_create_profile', 'page.php?i=create-persons-profile', '', '', 'user col-blue3', '', 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_persons_view_actions', '_bx_persons_menu_title_view_profile_actions', 'bx_persons_view_actions', 'bx_persons', 9, 0, 1, 'BxPersonsMenuViewActions', 'modules/boonex/persons/classes/BxPersonsMenuViewActions.php');
+
+INSERT INTO `sys_menu_sets`(`set_name`, `module`, `title`, `deletable`) VALUES 
+('bx_persons_view_actions', 'bx_persons', '_bx_persons_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`, `visibility_custom`, `active`, `copyable`, `order`) VALUES 
+('bx_persons_view_actions', 'bx_persons', 'profile-friend-add', '_bx_persons_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, 10),
+('bx_persons_view_actions', 'bx_persons', 'profile-relation-add', '_bx_persons_menu_item_title_system_relation_add', '_bx_persons_menu_item_title_relation_add', 'javascript:void(0)', 'bx_menu_popup(''sys_add_relation'', window, {}, {profile_id: {profile_id}});', '', 'sync', '', 0, 2147483647, '', 1, 0, 15),
+('bx_persons_view_actions', 'bx_persons', 'profile-subscribe-add', '_bx_persons_menu_item_title_system_subscribe', '_bx_persons_menu_item_title_subscribe', 'javascript:void(0)', 'bx_conn_action(this, \'sys_profiles_subscriptions\', \'add\', \'{profile_id}\')', '', 'check', '', 0, 2147483647, '', 1, 0, 20),
+('bx_persons_view_actions', 'bx_persons', '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, {id:{value:''sys_acl_set_{profile_id}'', force:true}, closeOnOuterClick: false, removeOnClose: true, displayMode: ''box'', cssClass: ''''}, {profile_id: {profile_id}});', '', 'certificate', '', 0, 2147483647, '', 1, 0, 30),
+('bx_persons_view_actions', 'bx_persons', 'profile-set-badges', '_sys_menu_item_title_system_set_badges', '_sys_menu_item_title_set_badges', 'javascript:void(0)', 'bx_menu_popup(''sys_set_badges'', window, {}, {module: ''bx_persons'', content_id: {content_id}});', '', 'check-circle', '', 0, 192, 'a:2:{s:6:"module";s:10:"bx_persons";s:6:"method";s:19:"is_badges_avaliable";}', 1, 0, 30),
+('bx_persons_view_actions', 'bx_persons', 'profile-actions-more', '_bx_persons_menu_item_title_system_more_actions', '_bx_persons_menu_item_title_more_actions', 'javascript:void(0)', 'bx_menu_popup(''bx_persons_view_actions_more'', this, {}, {profile_id:{profile_id}});', '', 'cog', 'bx_persons_view_actions_more', 1, 2147483647, '', 1, 0, 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_persons_view_actions_more', '_bx_persons_menu_title_view_profile_actions_more', 'bx_persons_view_actions_more', 'bx_persons', 6, 0, 1, 'BxPersonsMenuViewActions', 'modules/boonex/persons/classes/BxPersonsMenuViewActions.php');
+
+INSERT INTO `sys_menu_sets`(`set_name`, `module`, `title`, `deletable`) VALUES 
+('bx_persons_view_actions_more', 'bx_persons', '_bx_persons_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_persons_view_actions_more', 'bx_persons', 'profile-friend-remove', '_bx_persons_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_persons_view_actions_more', 'bx_persons', 'profile-relation-remove', '_bx_persons_menu_item_title_system_relation_delete', '_bx_persons_menu_item_title_relation_delete', 'javascript:void(0)', 'bx_conn_action(this, \'sys_profiles_relations\', \'remove\', \'{profile_id}\')', '', 'sync', '', 2147483647, 1, 0, 15),
+('bx_persons_view_actions_more', 'bx_persons', 'profile-subscribe-remove', '_bx_persons_menu_item_title_system_unsubscribe', '_bx_persons_menu_item_title_unsubscribe', 'javascript:void(0)', 'bx_conn_action(this, \'sys_profiles_subscriptions\', \'remove\', \'{profile_id}\')', '', 'check', '', 2147483647, 1, 0, 20),
+('bx_persons_view_actions_more', 'bx_persons', 'edit-persons-cover', '_bx_persons_menu_item_title_system_edit_cover', '_bx_persons_menu_item_title_edit_cover', 'page.php?i=edit-persons-cover&id={content_id}', '', '', 'edit', '', 2147483647, 1, 0, 25),
+('bx_persons_view_actions_more', 'bx_persons', 'edit-persons-profile', '_bx_persons_menu_item_title_system_edit_profile', '_bx_persons_menu_item_title_edit_profile', 'page.php?i=edit-persons-profile&id={content_id}', '', '', 'pencil-alt', '', 2147483647, 1, 0, 30),
+('bx_persons_view_actions_more', 'bx_persons', 'delete-persons-profile', '_bx_persons_menu_item_title_system_delete_profile', '_bx_persons_menu_item_title_delete_profile', 'page.php?i=delete-persons-profile&id={content_id}', '', '', 'remove', '', 2147483647, 1, 0, 40),
+('bx_persons_view_actions_more', 'bx_persons', 'delete-persons-account', '_bx_persons_menu_item_title_system_delete_account', '_bx_persons_menu_item_title_delete_account', 'page.php?i=account-settings-delete&id={account_id}', '', '', 'user-times', '', 128, 1, 0, 50),
+('bx_persons_view_actions_more', 'bx_persons', 'delete-persons-account-content', '_bx_persons_menu_item_title_system_delete_account_content', '_bx_persons_menu_item_title_delete_account_content', 'page.php?i=account-settings-delete&id={account_id}&content=1', '', '', 'trash', '', 128, 1, 0, 60);
+
+-- MENU: all 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_persons_view_actions_all', '_sys_menu_title_view_actions', 'bx_persons_view_actions_all', 'bx_persons', 15, 0, 1, 'BxPersonsMenuViewActionsAll', 'modules/boonex/persons/classes/BxPersonsMenuViewActionsAll.php');
+
+INSERT INTO `sys_menu_sets`(`set_name`, `module`, `title`, `deletable`) VALUES 
+('bx_persons_view_actions_all', 'bx_persons', '_sys_menu_set_title_view_actions', 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`, `visibility_custom`, `active`, `copyable`, `order`) VALUES 
+('bx_persons_view_actions_all', 'bx_persons', 'profile-friend-add', '_bx_persons_menu_item_title_system_befriend', '', '', '', '', '', '', '', 0, 2147483647, '', 1, 0, 10),
+('bx_persons_view_actions_all', 'bx_persons', 'profile-friend-remove', '_bx_persons_menu_item_title_system_unfriend', '', '', '', '', '', '', '', 0, 2147483647, '', 1, 0, 20),
+('bx_persons_view_actions_all', 'bx_persons', 'profile-relation-add', '_bx_persons_menu_item_title_system_relation_add', '', '', '', '', '', '', '', 0, 2147483647, '', 1, 0, 23),
+('bx_persons_view_actions_all', 'bx_persons', 'profile-relation-remove', '_bx_persons_menu_item_title_system_relation_delete', '', '', '', '', '', '', '', 0, 2147483647, '', 1, 0, 27),
+('bx_persons_view_actions_all', 'bx_persons', 'profile-subscribe-add', '_bx_persons_menu_item_title_system_subscribe', '', '', '', '', '', '', '', 0, 2147483647, '', 1, 0, 30),
+('bx_persons_view_actions_all', 'bx_persons', 'profile-subscribe-remove', '_bx_persons_menu_item_title_system_unsubscribe', '', '', '', '', '', '', '', 0, 2147483647, '', 1, 0, 40),
+('bx_persons_view_actions_all', 'bx_persons', 'profile-set-acl-level', '_sys_menu_item_title_system_set_acl_level', '', '', '', '', '', '', '', 0, 2147483647, '', 1, 0, 50),
+('bx_persons_view_actions_all', 'bx_persons', 'profile-set-badges', '_sys_menu_item_title_system_set_badges', '', '', '', '', '', '', '', 0, 192, 'a:2:{s:6:"module";s:10:"bx_persons";s:6:"method";s:19:"is_badges_avaliable";}', 1, 0, 60),
+('bx_persons_view_actions_all', 'bx_persons', 'comment', '_sys_menu_item_title_system_va_comment', '', '', '', '', '', '', '', 0, 2147483647, '', 0, 0, 200),
+('bx_persons_view_actions_all', 'bx_persons', 'view', '_sys_menu_item_title_system_va_view', '', '', '', '', '', '', '', 0, 2147483647, '', 0, 0, 210),
+('bx_persons_view_actions_all', 'bx_persons', 'vote', '_sys_menu_item_title_system_va_vote', '', '', '', '', '', '', '', 0, 2147483647, '', 1, 0, 215),
+('bx_persons_view_actions_all', 'bx_persons', 'score', '_sys_menu_item_title_system_va_score', '', '', '', '', '', '', '', 0, 2147483647, '', 1, 0, 220),
+('bx_persons_view_actions_all', 'bx_persons', 'favorite', '_sys_menu_item_title_system_va_favorite', '', '', '', '', '', '', '', 0, 2147483647, '', 1, 0, 230),
+('bx_persons_view_actions_all', 'bx_persons', 'feature', '_sys_menu_item_title_system_va_feature', '', '', '', '', '', '', '', 0, 2147483647, '', 1, 0, 240),
+('bx_persons_view_actions_all', 'bx_persons', 'report', '_sys_menu_item_title_system_va_report', '', '', '', '', '', '', '', 0, 2147483647, '', 1, 0, 250),
+('bx_persons_view_actions_all', 'bx_persons', 'notes', '_sys_menu_item_title_system_va_notes', '_sys_menu_item_title_va_notes', 'javascript:void(0)', 'javascript:bx_get_notes(this,  ''{module_uri}'', {content_id});', '', 'exclamation-triangle', '', '', 0, 2147483647, '', 1, 0, 280),
+('bx_persons_view_actions_all', 'bx_persons', 'audit', '_sys_menu_item_title_system_va_audit', '_sys_menu_item_title_va_audit', 'page.php?i=dashboard-audit&module=bx_persons&content_id={content_id}', '', '', 'history', '', '', 0, 192, '', 1, 0, 290),
+('bx_persons_view_actions_all', 'bx_persons', 'edit-persons-cover', '_bx_persons_menu_item_title_system_edit_cover', '', '', '', '', '', '', '', 0, 2147483647, '', 1, 0, 400),
+('bx_persons_view_actions_all', 'bx_persons', 'edit-persons-profile', '_bx_persons_menu_item_title_system_edit_profile', '', '', '', '', '', '', '', 0, 2147483647, '', 1, 0, 410),
+('bx_persons_view_actions_all', 'bx_persons', 'delete-persons-profile', '_bx_persons_menu_item_title_system_delete_profile', '', '', '', '', '', '', '', 0, 2147483647, '', 1, 0, 420),
+('bx_persons_view_actions_all', 'bx_persons', 'delete-persons-account', '_bx_persons_menu_item_title_system_delete_account', '', '', '', '', '', '', '', 0, 128, '', 1, 0, 430),
+('bx_persons_view_actions_all', 'bx_persons', 'delete-persons-account-content', '_bx_persons_menu_item_title_system_delete_account_content', '', '', '', '', '', '', '', 0, 128, '', 1, 0, 440),
+('bx_persons_view_actions_all', 'bx_persons', 'more-auto', '_sys_menu_item_title_system_va_more_auto', '_sys_menu_item_title_va_more_auto', 'javascript:void(0)', '', '', 'ellipsis-v', '', '', 0, 2147483647, '', 1, 0, 9999);
+
+-- MENU: meta (counters) 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_persons_view_meta', '_bx_persons_menu_title_view_profile_meta', 'bx_persons_view_meta', 'bx_persons', 15, 0, 1, 'BxPersonsMenuViewMeta', 'modules/boonex/persons/classes/BxPersonsMenuViewMeta.php');
+
+INSERT INTO `sys_menu_sets`(`set_name`, `module`, `title`, `deletable`) VALUES 
+('bx_persons_view_meta', 'bx_persons', '_bx_persons_menu_set_title_view_profile_meta', 0);
+
+INSERT INTO `sys_menu_items`(`set_name`, `module`, `name`, `title_system`, `title`, `link`, `onclick`, `target`, `icon`, `submenu_object`, `submenu_popup`, `visible_for_levels`, `visibility_custom`, `active`, `copyable`, `order`) VALUES 
+('bx_persons_view_meta', 'bx_persons', 'membership', '_sys_menu_item_title_system_vm_membership', '_sys_menu_item_title_vm_membership', '', '', '', '', '', 0, 2147483647, '', 1, 0, 10),
+('bx_persons_view_meta', 'bx_persons', 'badges', '_sys_menu_item_title_system_vm_badges', '_sys_menu_item_title_vm_badges', '', '', '', '', '', 0, 2147483647, '', 1, 0, 20),
+('bx_persons_view_meta', 'bx_persons', 'views', '_sys_menu_item_title_system_sm_views', '_sys_menu_item_title_sm_views', '', '', '', '', '', 0, 2147483647, '', 1, 0, 30),
+('bx_persons_view_meta', 'bx_persons', 'votes', '_sys_menu_item_title_system_sm_votes', '_sys_menu_item_title_sm_votes', '', '', '', '', '', 0, 2147483647, '', 1, 0, 40),
+('bx_persons_view_meta', 'bx_persons', 'comments', '_sys_menu_item_title_system_sm_comments', '_sys_menu_item_title_sm_comments', '', '', '', '', '', 0, 2147483647, '', 1, 0, 50);
+
+-- 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_persons_submenu', '_bx_persons_menu_title_submenu', 'bx_persons_submenu', 'bx_persons', 8, 0, 1, '', '');
+
+INSERT INTO `sys_menu_sets`(`set_name`, `module`, `title`, `deletable`) VALUES 
+('bx_persons_submenu', 'bx_persons', '_bx_persons_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_persons_submenu', 'bx_persons', 'persons-home', '_bx_persons_menu_item_title_system_entries_recent', '_bx_persons_menu_item_title_entries_recent', 'page.php?i=persons-home', '', '', '', '', 2147483647, 1, 1, 1),
+('bx_persons_submenu', 'bx_persons', 'persons-active', '_bx_persons_menu_item_title_system_entries_active', '_bx_persons_menu_item_title_entries_active', 'page.php?i=persons-active', '', '', '', '', 2147483647, 1, 1, 2),
+('bx_persons_submenu', 'bx_persons', 'persons-online', '_bx_persons_menu_item_title_system_entries_online', '_bx_persons_menu_item_title_entries_online', 'page.php?i=persons-online', '', '', '', '', 2147483647, 1, 1, 3),
+('bx_persons_submenu', 'bx_persons', 'persons-search', '_bx_persons_menu_item_title_system_entries_search', '_bx_persons_menu_item_title_entries_search', 'page.php?i=persons-search', '', '', '', '', 2147483647, 1, 1, 4),
+('bx_persons_submenu', 'bx_persons', 'persons-manage', '_bx_persons_menu_item_title_system_entries_manage', '_bx_persons_menu_item_title_entries_manage', 'page.php?i=persons-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_persons_view_submenu', '_bx_persons_menu_title_view_profile_submenu', 'bx_persons_view_submenu', 'bx_persons', 18, 0, 1, 'BxPersonsMenuView', 'modules/boonex/persons/classes/BxPersonsMenuView.php');
+
+INSERT INTO `sys_menu_sets`(`set_name`, `module`, `title`, `deletable`) VALUES 
+('bx_persons_view_submenu', 'bx_persons', '_bx_persons_menu_set_title_view_profile_submenu', 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`, `order`) VALUES 
+('bx_persons_view_submenu', 'bx_persons', 'view-persons-profile', '_bx_persons_menu_item_title_system_view_profile_view', '_bx_persons_menu_item_title_view_profile_view', 'page.php?i=view-persons-profile&id={content_id}', '', '', 'user col-blue3', '', '', 0, 2147483647, 1, 0, 1),
+('bx_persons_view_submenu', 'bx_persons', 'persons-profile-info', '_bx_persons_menu_item_title_system_view_profile_info', '_bx_persons_menu_item_title_view_profile_info', 'page.php?i=persons-profile-info&id={content_id}', '', '', 'info-circle col-gray', '', '', 0, 2147483647, 1, 0, 2),
+('bx_persons_view_submenu', 'bx_persons', 'persons-profile-friends', '_bx_persons_menu_item_title_system_view_profile_friends', '_bx_persons_menu_item_title_view_profile_friends', 'page.php?i=persons-profile-friends&profile_id={profile_id}', '', '', 'users col-blue3', '', '', 0, 2147483647, 1, 0, 3),
+('bx_persons_view_submenu', 'bx_persons', 'persons-profile-relations', '_bx_persons_menu_item_title_system_view_profile_relations', '_bx_persons_menu_item_title_view_profile_relations', 'page.php?i=persons-profile-relations&profile_id={profile_id}', '', '', 'sync col-blue3', '', '', 0, 2147483647, 1, 0, 4),
+('bx_persons_view_submenu', 'bx_persons', 'persons-profile-subscriptions', '_bx_persons_menu_item_title_system_view_profile_subscriptions', '_bx_persons_menu_item_title_view_profile_subscriptions', 'page.php?i=persons-profile-subscriptions&profile_id={profile_id}', '', '', 'check col-blue3', '', '', 0, 2147483647, 1, 0, 5),
+('bx_persons_view_submenu', 'bx_persons', 'persons-profile-comments', '_bx_persons_menu_item_title_system_view_profile_comments', '_bx_persons_menu_item_title_view_profile_comments', 'page.php?i=persons-profile-comments&id={content_id}', '', '', '', '', '', 0, 2147483647, 0, 0, 6),
+('bx_persons_view_submenu', 'bx_persons', 'more-auto', '_bx_persons_menu_item_title_system_view_profile_more_auto', '_bx_persons_menu_item_title_view_profile_more_auto', 'javascript:void(0)', '', '', 'ellipsis-v', '', '', 0, 2147483647, 1, 0, 9999);
+
+-- 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_persons_snippet_meta', '_sys_menu_title_snippet_meta', 'bx_persons_snippet_meta', 'bx_persons', 15, 0, 1, 'BxPersonsMenuSnippetMeta', 'modules/boonex/persons/classes/BxPersonsMenuSnippetMeta.php');
+
+INSERT INTO `sys_menu_sets`(`set_name`, `module`, `title`, `deletable`) VALUES 
+('bx_persons_snippet_meta', 'bx_persons', '_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_persons_snippet_meta', 'bx_persons', 'friends-mutual', '_sys_menu_item_title_system_sm_friends_mutual', '_sys_menu_item_title_sm_friends_mutual', '', '', '', '', '', 2147483647, 0, 0, 1, 0),
+('bx_persons_snippet_meta', 'bx_persons', 'date', '_sys_menu_item_title_system_sm_date', '_sys_menu_item_title_sm_date', '', '', '', '', '', 2147483647, 0, 0, 1, 1),
+('bx_persons_snippet_meta', 'bx_persons', 'tags', '_sys_menu_item_title_system_sm_tags', '_sys_menu_item_title_sm_tags', '', '', '', '', '', 2147483647, 0, 0, 1, 2),
+('bx_persons_snippet_meta', 'bx_persons', 'views', '_sys_menu_item_title_system_sm_views', '_sys_menu_item_title_sm_views', '', '', '', '', '', 2147483647, 0, 0, 1, 3),
+('bx_persons_snippet_meta', 'bx_persons', 'comments', '_sys_menu_item_title_system_sm_comments', '_sys_menu_item_title_sm_comments', '', '', '', '', '', 2147483647, 0, 0, 1, 4),
+('bx_persons_snippet_meta', 'bx_persons', 'friends', '_sys_menu_item_title_system_sm_friends', '_sys_menu_item_title_sm_friends', '', '', '', '', '', 2147483647, 1, 0, 1, 5),
+('bx_persons_snippet_meta', 'bx_persons', 'subscribers', '_sys_menu_item_title_system_sm_subscribers', '_sys_menu_item_title_sm_subscribers', '', '', '', '', '', 2147483647, 1, 0, 1, 6),
+('bx_persons_snippet_meta', 'bx_persons', 'membership', '_sys_menu_item_title_system_sm_membership', '_sys_menu_item_title_sm_membership', '', '', '', '', '', 2147483647, 0, 0, 1, 7),
+('bx_persons_snippet_meta', 'bx_persons', 'nl', '_sys_menu_item_title_system_sm_nl', '_sys_menu_item_title_sm_nl', '', '', '', '', '', 2147483647, 1, 0, 1, 8),
+('bx_persons_snippet_meta', 'bx_persons', 'befriend', '_sys_menu_item_title_system_sm_befriend', '_sys_menu_item_title_sm_befriend', '', '', '', '', '', 2147483647, 1, 0, 1, 9),
+('bx_persons_snippet_meta', 'bx_persons', 'unfriend', '_sys_menu_item_title_system_sm_unfriend', '_sys_menu_item_title_sm_unfriend', '', '', '', '', '', 2147483647, 0, 0, 1, 10),
+('bx_persons_snippet_meta', 'bx_persons', 'subscribe', '_sys_menu_item_title_system_sm_subscribe', '_sys_menu_item_title_sm_subscribe', '', '', '', '', '', 2147483647, 1, 0, 1, 11),
+('bx_persons_snippet_meta', 'bx_persons', 'unsubscribe', '_sys_menu_item_title_system_sm_unsubscribe', '_sys_menu_item_title_sm_unsubscribe', '', '', '', '', '', 2147483647, 0, 0, 1, 12);
+
+-- MENU: notifications menu in account popup
+SET @iNotifMenuOrder = (SELECT IFNULL(MAX(`order`), 0) 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`, `visibility_custom`, `active`, `copyable`, `order`) VALUES
+('sys_account_notifications', 'bx_persons', 'notifications-friend-requests', '_bx_persons_menu_item_title_system_friends', '_bx_persons_menu_item_title_friends', 'page.php?i=persons-profile-friends&profile_id={member_id}', '', '', 'users col-blue3', '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_account_notifications', 'bx_persons', 'notifications-relation-requests', '_bx_persons_menu_item_title_system_relations', '_bx_persons_menu_item_title_relations', 'page.php?i=persons-profile-relations&profile_id={member_id}', '', '', 'sync col-blue3', '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:22:"sys_profiles_relations";}s:5:"class";s:23:"TemplServiceConnections";}', '', 2147483646, 'a:2:{s:6:"module";s:10:"bx_persons";s:6:"method";s:19:"is_enable_relations";}', 1, 0, @iNotifMenuOrder + 2);
+
+-- 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_persons', 'profile-stats-friend-requests', '_bx_persons_menu_item_title_system_friend_requests', '_bx_persons_menu_item_title_friend_requests', 'page.php?i=persons-profile-friends&profile_id={member_id}', '', '', 'users col-blue3', '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_persons', 'profile-stats-manage-profiles', '_bx_persons_menu_item_title_system_manage_my_profiles', '_bx_persons_menu_item_title_manage_my_profiles', 'page.php?i=persons-manage', '', '_self', 'users col-blue3', 'a:2:{s:6:"module";s:10:"bx_persons";s:6:"method";s:41:"get_menu_addon_manage_tools_profile_stats";}', '', 2147483646, 1, 0, @iNotifMenuOrder + 2),
+('sys_profile_stats', 'bx_persons', 'profile-stats-favorite-persons', '_bx_persons_menu_item_title_system_favorites', '_bx_persons_menu_item_title_favorites', 'page.php?i=persons-profile-favorites&profile_id={member_id}', '', '', 'star col-blue3', 'a:2:{s:6:"module";s:10:"bx_persons";s:6:"method";s:38:"get_menu_addon_favorites_profile_stats";}', '', 2147483646, 1, 0, @iNotifMenuOrder + 3),
+('sys_profile_stats', 'bx_persons', 'profile-stats-subscriptions', '_bx_persons_menu_item_title_system_subscriptions', '_bx_persons_menu_item_title_subscriptions', 'page.php?i=persons-profile-subscriptions&profile_id={member_id}#subscriptions', '', '_self', 'rss col-blue3', '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_persons', 'profile-stats-subscribed-me', '_bx_persons_menu_item_title_system_subscribed_me', '_bx_persons_menu_item_title_subscribed_me', 'page.php?i=persons-profile-subscriptions&profile_id={member_id}#subscribers', '', '_self', 'rss col-blue3', '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),
+('sys_profile_stats', 'bx_persons', 'profile-stats-relations', '_bx_persons_menu_item_title_system_relations', '_bx_persons_menu_item_title_relations', 'page.php?i=persons-profile-relations&profile_id={member_id}#relations', '', '_self', 'sync col-blue3', 'a:4:{s:6:"module";s:6:"system";s:6:"method";s:25:"get_connected_content_num";s:6:"params";a:3:{i:0;s:22:"sys_profiles_relations";i:1;i:0;i:2;i:1;}s:5:"class";s:23:"TemplServiceConnections";}', '', 2147483646, 1, 0, @iNotifMenuOrder + 6),
+('sys_profile_stats', 'bx_persons', 'profile-stats-related-me', '_bx_persons_menu_item_title_system_related_me', '_bx_persons_menu_item_title_related_me', 'page.php?i=persons-profile-relations&profile_id={member_id}#related-me', '', '_self', 'sync col-blue3', 'a:4:{s:6:"module";s:6:"system";s:6:"method";s:28:"get_connected_initiators_num";s:6:"params";a:3:{i:0;s:22:"sys_profiles_relations";i:1;i:0;i:2;i:1;}s:5:"class";s:23:"TemplServiceConnections";}', '', 2147483646, 1, 0, @iNotifMenuOrder + 7);
+
+-- MENU: profile followings
+SET @iFollowingsMenuOrder = (SELECT IFNULL(MAX(`order`), 0) FROM `sys_menu_items` WHERE `set_name`='sys_profile_followings' LIMIT 1);
+INSERT INTO `sys_menu_items`(`set_name`, `module`, `name`, `title_system`, `title`, `link`, `onclick`, `target`, `icon`, `addon`, `submenu_object`, `visible_for_levels`, `collapsed`, `active`, `copyable`, `order`) VALUES 
+('sys_profile_followings', 'bx_persons', 'persons', '_bx_persons_menu_item_title_system_followings', '_bx_persons_menu_item_title_followings', 'javascript:void(0)', '', '_self', 'users col-blue3', '', '', 2147483647, 0, 1, 0, @iFollowingsMenuOrder + 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_persons_menu_manage_tools', '_bx_persons_menu_title_manage_tools', 'bx_persons_menu_manage_tools', 'bx_persons', 6, 0, 1, 'BxPersonsMenuManageTools', 'modules/boonex/persons/classes/BxPersonsMenuManageTools.php');
+
+INSERT INTO `sys_menu_sets`(`set_name`, `module`, `title`, `deletable`) VALUES 
+('bx_persons_menu_manage_tools', 'bx_persons', '_bx_persons_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_persons_menu_manage_tools', 'bx_persons', 'clear-reports', '_bx_persons_menu_item_title_system_clear_reports', '_bx_persons_menu_item_title_clear_reports', 'javascript:void(0)', 'javascript:{js_object}.onClickClearReports({content_id});', '_self', 'eraser', '', 2147483647, 1, 0, 1),
+('bx_persons_menu_manage_tools', 'bx_persons', 'manage-cf', '_bx_persons_menu_item_title_system_manage_cf', '_bx_persons_menu_item_title_manage_cf', 'javascript:void(0)', 'javascript:{js_object}.onClickManageCf({content_id});', '_self', 'filter', '', 2147483647, 1, 0, 6),
+('bx_persons_menu_manage_tools', 'bx_persons', 'delete', '_bx_persons_menu_item_title_system_delete', '_bx_persons_menu_item_title_delete', 'javascript:void(0)', 'javascript:{js_object}.onClickDelete({content_id});', '_self', 'far trash-alt', '', 2147483647, 1, 0, 98),
+('bx_persons_menu_manage_tools', 'bx_persons', 'delete-with-content', '_bx_persons_menu_item_title_system_delete_with_content', '_bx_persons_menu_item_title_delete_with_content', 'javascript:void(0)', 'javascript:{js_object}.onClickDeleteWithContent({content_id});', '_self', 'far trash-alt', '', 2147483647, 1, 0, 99);
+
+-- 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_persons', 'persons-administration', '_bx_persons_menu_item_title_system_admt_persons', '_bx_persons_menu_item_title_admt_persons', 'page.php?i=persons-administration', '', '_self', 'user', 'a:2:{s:6:"module";s:10:"bx_persons";s:6:"method";s:27:"get_menu_addon_manage_tools";}', '', 192, 1, 0, @iManageMenuOrder + 1);
+
+
+-- ACL
+INSERT INTO `sys_acl_actions` (`Module`, `Name`, `AdditionalParamName`, `Title`, `Desc`, `Countable`, `DisabledForLevels`) VALUES
+('bx_persons', 'create entry', NULL, '_bx_persons_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_persons', 'delete entry', NULL, '_bx_persons_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_persons', 'view entry', NULL, '_bx_persons_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_persons', 'edit any entry', NULL, '_bx_persons_acl_action_edit_any_profile', '', 1, 3);
+SET @iIdActionProfileEditAny = LAST_INSERT_ID();
+
+INSERT INTO `sys_acl_actions` (`Module`, `Name`, `AdditionalParamName`, `Title`, `Desc`, `Countable`, `DisabledForLevels`) VALUES
+('bx_persons', 'delete any entry', NULL, '_bx_persons_acl_action_delete_any_profile', '', 1, 3);
+SET @iIdActionProfileDeleteAny = 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),
+
+-- any profile delete
+(@iAdministrator, @iIdActionProfileDeleteAny);
+
+-- METATAGS
+INSERT INTO `sys_objects_metatags` (`object`, `module`, `table_keywords`, `table_locations`, `table_mentions`, `override_class_name`, `override_class_file`) VALUES
+('bx_persons', 'bx_persons', 'bx_persons_meta_keywords', 'bx_persons_meta_locations', 'bx_persons_meta_mentions', '', '');
+
+-- SEARCH
+SET @iSearchOrder = (SELECT IFNULL(MAX(`Order`), 0) FROM `sys_objects_search`);
+INSERT INTO `sys_objects_search` (`ObjectName`, `Title`, `Order`, `ClassName`, `ClassPath`) VALUES
+('bx_persons', '_bx_persons', @iSearchOrder + 1, 'BxPersonsSearchResult', 'modules/boonex/persons/classes/BxPersonsSearchResult.php'),
+('bx_persons_cmts', '_bx_persons_cmts', @iSearchOrder + 2, 'BxPersonsCmtsSearchResult', 'modules/boonex/persons/classes/BxPersonsCmtsSearchResult.php');
+
+-- STATS
+SET @iMaxOrderStats = (SELECT IFNULL(MAX(`order`), 0) FROM `sys_statistics`);
+INSERT INTO `sys_statistics` (`module`, `name`, `title`, `link`, `icon`, `query`, `order`) VALUES 
+('bx_persons', 'bx_persons', '_bx_persons', 'page.php?i=persons-home', 'user col-blue3', 'SELECT COUNT(*) FROM `bx_persons_data` AS `td` LEFT JOIN `sys_profiles` AS `tp` ON `td`.`id` = `tp`.`content_id` AND `tp`.`type`=''bx_persons'' 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_persons_growth', '_bx_persons_chart_growth', 'bx_persons_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_persons'' WHERE 1 AND `tp`.`status`=''active'' {where_inteval} GROUP BY `period` ORDER BY {table}.{field_date} ASC', 1, @iMaxOrderCharts + 1, 'BxDolChartGrowth', ''),
+('bx_persons_growth_speed', '_bx_persons_chart_growth_speed', 'bx_persons_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_persons'' WHERE 1 AND `tp`.`status`=''active'' {where_inteval} GROUP BY `period` ORDER BY {table}.{field_date} ASC', 1, @iMaxOrderCharts + 2, 'BxDolChartGrowthSpeed', '');
+
+-- 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_persons_administration', 'Sql', 'SELECT `td`.*, `ta`.`email` AS `account`, `ta`.`logged` AS `last_online`, `tp`.`status` AS `status`, `tp`.`id` as `profile_id` FROM `bx_persons_data` AS `td` LEFT JOIN `sys_profiles` AS `tp` ON `td`.`id`=`tp`.`content_id` AND `tp`.`type`=''bx_persons'' LEFT JOIN `sys_accounts` AS `ta` ON `tp`.`account_id`=`ta`.`id` WHERE 1 ', 'bx_persons_data', 'id', 'last_online', 'status', '', 20, NULL, 'start', '', 'fullname,email', '', 'like', 'reports', '', 192, 'BxPersonsGridAdministration', 'modules/boonex/persons/classes/BxPersonsGridAdministration.php'),
+('bx_persons_common', 'Sql', 'SELECT `td`.*, `ta`.`email` AS `account`, `ta`.`logged` AS `last_online`, `tp`.`status` AS `status` FROM `bx_persons_data` AS `td` LEFT JOIN `sys_profiles` AS `tp` ON `td`.`id`=`tp`.`content_id` AND `tp`.`type`=''bx_persons'' LEFT JOIN `sys_accounts` AS `ta` ON `tp`.`account_id`=`ta`.`id` WHERE 1 ', 'bx_persons_data', 'id', 'last_online', 'status', '', 20, NULL, 'start', '', 'fullname', '', 'like', '', '', 2147483647, 'BxPersonsGridCommon', 'modules/boonex/persons/classes/BxPersonsGridCommon.php');
+
+INSERT INTO `sys_grid_fields` (`object`, `name`, `title`, `width`, `translatable`, `chars_limit`, `params`, `order`) VALUES
+('bx_persons_administration', 'checkbox', '_sys_select', '2%', 0, '', '', 1),
+('bx_persons_administration', 'switcher', '_bx_persons_grid_column_title_adm_active', '8%', 0, '', '', 2),
+('bx_persons_administration', 'reports', '_sys_txt_reports_title', '5%', 0, '', '', 3),
+('bx_persons_administration', 'fullname', '_bx_persons_grid_column_title_adm_fullname', '25%', 0, '', '', 4),
+('bx_persons_administration', 'last_online', '_bx_persons_grid_column_title_adm_last_online', '20%', 1, '25', '', 5),
+('bx_persons_administration', 'account', '_bx_persons_grid_column_title_adm_account', '20%', 0, '25', '', 6),
+('bx_persons_administration', 'actions', '', '20%', 0, '', '', 7),
+('bx_persons_common', 'checkbox', '_sys_select', '2%', 0, '', '', 1),
+('bx_persons_common', 'fullname', '_bx_persons_grid_column_title_adm_fullname', '48%', 0, '', '', 2),
+('bx_persons_common', 'last_online', '_bx_persons_grid_column_title_adm_last_online', '30%', 1, '25', '', 3),
+('bx_persons_common', 'actions', '', '20%', 0, '', '', 4);
+
+INSERT INTO `sys_grid_actions` (`object`, `type`, `name`, `title`, `icon`, `icon_only`, `confirm`, `order`) VALUES
+('bx_persons_administration', 'bulk', 'set_acl_level', '_bx_persons_grid_action_title_adm_set_acl_level', '', 0, 0, 1),
+('bx_persons_administration', 'bulk', 'delete', '_bx_persons_grid_action_title_adm_delete', '', 0, 1, 2),
+('bx_persons_administration', 'bulk', 'delete_with_content', '_bx_persons_grid_action_title_adm_delete_with_content', '', 0, 1, 3),
+('bx_persons_administration', 'bulk', 'clear_reports', '_bx_persons_grid_action_title_adm_clear_reports', '', 0, 1, 4),
+('bx_persons_administration', 'single', 'set_acl_level', '_bx_persons_grid_action_title_adm_set_acl_level', 'certificate', 1, 0, 1),
+('bx_persons_administration', 'single', 'settings', '_bx_persons_grid_action_title_adm_more_actions', 'cog', 1, 0, 2),
+('bx_persons_administration', 'single', 'audit_content', '_bx_persons_grid_action_title_adm_audit_content', 'search', 1, 0, 3),
+('bx_persons_administration', 'single', 'audit_profile', '_bx_persons_grid_action_title_adm_audit_profile', 'search-location', 1, 0, 4),
+('bx_persons_administration', 'single', 'lock_cf', '_bx_persons_grid_action_title_adm_lock_cf', 'filter', 1, 0, 5),
+
+('bx_persons_common', 'bulk', 'delete', '_bx_persons_grid_action_title_adm_delete', '', 0, 1, 1),
+('bx_persons_common', 'bulk', 'delete_with_content', '_bx_persons_grid_action_title_adm_delete_with_content', '', 0, 1, 2),
+('bx_persons_common', 'single', 'settings', '_bx_persons_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_persons_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:10:"bx_persons";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_persons', 'BxPersonsAlertsResponse', 'modules/boonex/persons/classes/BxPersonsAlertsResponse.php', '');
+SET @iHandler := LAST_INSERT_ID();
+
+INSERT INTO `sys_alerts` (`unit`, `action`, `handler_id`) VALUES
+('system', 'save_setting', @iHandler),
+('sys_profiles_friends', 'connection_added', @iHandler),
+('bx_timeline', 'post_common', @iHandler),
+('bx_persons_pictures', 'file_deleted', @iHandler),
+('bx_persons', 'timeline_view', @iHandler),
+('bx_persons', 'timeline_post', @iHandler),
+('bx_persons', 'timeline_delete', @iHandler),
+('bx_persons', 'timeline_comment', @iHandler),
+('bx_persons', 'timeline_vote', @iHandler),
+('bx_persons', 'timeline_score', @iHandler),
+('bx_persons', 'timeline_report', @iHandler),
+('bx_persons', 'timeline_repost', @iHandler),
+('bx_persons', 'timeline_pin', @iHandler),
+('bx_persons', 'timeline_promote', @iHandler);
+
+-- PRIVACY 
+INSERT INTO `sys_objects_privacy` (`object`, `module`, `action`, `title`, `default_group`, `spaces`, `table`, `table_field_id`, `table_field_author`, `override_class_name`, `override_class_file`) VALUES
+('bx_persons_allow_view_to', 'bx_persons', 'view', '_bx_persons_form_profile_input_allow_view_to', '3', '', 'bx_persons_data', 'id', 'author', 'BxPersonsPrivacy', 'modules/boonex/persons/classes/BxPersonsPrivacy.php'),
+('bx_persons_allow_post_to', 'bx_persons', 'post', '_bx_persons_form_profile_input_allow_post_to', '5', '', 'bx_persons_data', 'id', 'author', 'BxPersonsPrivacyPost', 'modules/boonex/persons/classes/BxPersonsPrivacyPost.php'),
+('bx_persons_allow_contact_to', 'bx_persons', 'contact', '_bx_persons_form_profile_input_allow_contact_to', '3', '', 'bx_persons_data', 'id', 'author', 'BxPersonsPrivacyContact', 'modules/boonex/persons/classes/BxPersonsPrivacyContact.php');
+
+-- EMAIL TEMPLATES
+INSERT INTO `sys_email_templates` (`Module`, `NameSystem`, `Name`, `Subject`, `Body`) VALUES
+('bx_persons', '_bx_persons_email_friend_request', 'bx_persons_friend_request', '_bx_persons_email_friend_request_subject', '_bx_persons_email_friend_request_body');
+
+-- UPLOADERS
+INSERT INTO `sys_objects_uploader` (`object`, `active`, `override_class_name`, `override_class_file`) VALUES
+('bx_persons_cover_crop', 1, 'BxPersonsUploaderCoverCrop', 'modules/boonex/persons/classes/BxPersonsUploaderCoverCrop.php'),
+('bx_persons_picture_crop', 1, 'BxPersonsUploaderPictureCrop', 'modules/boonex/persons/classes/BxPersonsUploaderPictureCrop.php');

+ 416 - 0
modules/boonex/persons/updates/13.0.0_13.0.1/source/install/sql/install.sql

@@ -0,0 +1,416 @@
+
+SET @sStorageEngine = (SELECT `value` FROM `sys_options` WHERE `name` = 'sys_storage_default');
+
+-- TABLE: PROFILES
+CREATE TABLE IF NOT EXISTS `bx_persons_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,
+  `fullname` varchar(255) NOT NULL,
+  `last_name` varchar(255) NOT NULL,
+  `description` text NOT NULL,
+  `gender` varchar(255) DEFAULT NULL,
+  `birthday` date DEFAULT NULL,
+  `labels` text NOT NULL,
+  `location` text NOT NULL,
+  `views` int(11) NOT NULL default '0',
+  `rate` float NOT NULL default '0',
+  `votes` int(11) NOT NULL default '0',
+  `score` int(11) NOT NULL default '0',
+  `sc_up` int(11) NOT NULL default '0',
+  `sc_down` int(11) NOT NULL default '0',
+  `favorites` int(11) NOT NULL default '0',
+  `comments` int(11) NOT NULL default '0',
+  `reports` int(11) NOT NULL default '0',
+  `featured` int(11) NOT NULL default '0',
+  `allow_view_to` varchar(16) NOT NULL DEFAULT '3',
+  `allow_post_to` varchar(16) NOT NULL DEFAULT '5',
+  `allow_contact_to` varchar(16) NOT NULL DEFAULT '3',
+  PRIMARY KEY (`id`),
+  FULLTEXT KEY `search_fields` (`fullname`,`description`)
+);
+
+-- TABLE: STORAGES & TRANSCODERS
+CREATE TABLE IF NOT EXISTS `bx_persons_pictures` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `profile_id` int(10) unsigned NOT NULL,
+  `remote_id` varchar(128) NOT NULL,
+  `path` varchar(255) NOT NULL,
+  `file_name` varchar(255) NOT NULL,
+  `mime_type` varchar(128) NOT NULL,
+  `ext` varchar(32) NOT NULL,
+  `size` bigint(20) NOT NULL,
+  `added` int(11) NOT NULL,
+  `modified` int(11) NOT NULL,
+  `private` int(11) NOT NULL,
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `remote_id` (`remote_id`)
+);
+
+CREATE TABLE IF NOT EXISTS `bx_persons_pictures_resized` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `profile_id` int(10) unsigned NOT NULL,
+  `remote_id` varchar(128) NOT NULL,
+  `path` varchar(255) NOT NULL,
+  `file_name` varchar(255) NOT NULL,
+  `mime_type` varchar(128) NOT NULL,
+  `ext` varchar(32) NOT NULL,
+  `size` bigint(20) NOT NULL,
+  `added` int(11) NOT NULL,
+  `modified` int(11) NOT NULL,
+  `private` int(11) NOT NULL,
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `remote_id` (`remote_id`)
+);
+
+-- TABLE: comments
+CREATE TABLE IF NOT EXISTS `bx_persons_cmts` (
+  `cmt_id` int(11) NOT NULL AUTO_INCREMENT,
+  `cmt_parent_id` int(11) NOT NULL DEFAULT '0',
+  `cmt_vparent_id` int(11) NOT NULL DEFAULT '0',
+  `cmt_object_id` int(11) NOT NULL DEFAULT '0',
+  `cmt_author_id` int(11) NOT NULL DEFAULT '0',
+  `cmt_level` int(11) NOT NULL DEFAULT '0',
+  `cmt_text` text NOT NULL,
+  `cmt_mood` tinyint(4) NOT NULL DEFAULT '0',
+  `cmt_rate` int(11) NOT NULL DEFAULT '0',
+  `cmt_rate_count` int(11) NOT NULL DEFAULT '0',
+  `cmt_time` int(11) unsigned NOT NULL DEFAULT '0',
+  `cmt_replies` int(11) NOT NULL DEFAULT '0',
+  `cmt_pinned` int(11) NOT NULL default '0',
+  `cmt_cf` int(11) NOT NULL default '1',
+  PRIMARY KEY (`cmt_id`),
+  KEY `cmt_object_id` (`cmt_object_id`,`cmt_parent_id`),
+  FULLTEXT KEY `search_fields` (`cmt_text`)
+);
+
+CREATE TABLE IF NOT EXISTS `bx_persons_cmts_notes` (
+  `cmt_id` int(11) NOT NULL AUTO_INCREMENT,
+  `cmt_parent_id` int(11) NOT NULL DEFAULT '0',
+  `cmt_vparent_id` int(11) NOT NULL DEFAULT '0',
+  `cmt_object_id` int(11) NOT NULL DEFAULT '0',
+  `cmt_author_id` int(11) NOT NULL DEFAULT '0',
+  `cmt_level` int(11) NOT NULL DEFAULT '0',
+  `cmt_text` text NOT NULL,
+  `cmt_mood` tinyint(4) NOT NULL DEFAULT '0',
+  `cmt_rate` int(11) NOT NULL DEFAULT '0',
+  `cmt_rate_count` int(11) NOT NULL DEFAULT '0',
+  `cmt_time` int(11) unsigned NOT NULL DEFAULT '0',
+  `cmt_replies` int(11) NOT NULL DEFAULT '0',
+  `cmt_pinned` int(11) NOT NULL default '0',
+  PRIMARY KEY (`cmt_id`),
+  KEY `cmt_object_id` (`cmt_object_id`,`cmt_parent_id`),
+  FULLTEXT KEY `search_fields` (`cmt_text`)
+);
+
+-- TABLE: VIEWS
+CREATE TABLE IF NOT EXISTS `bx_persons_views_track` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `object_id` int(11) NOT NULL default '0',
+  `viewer_id` int(11) NOT NULL default '0',
+  `viewer_nip` int(11) unsigned NOT NULL default '0',
+  `date` int(11) NOT NULL default '0',
+  PRIMARY KEY (`id`),
+  KEY `id` (`object_id`,`viewer_id`,`viewer_nip`)
+);
+
+-- TABLE: VOTES
+CREATE TABLE IF NOT EXISTS `bx_persons_votes` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `object_id` int(11) NOT NULL default '0',
+  `count` int(11) NOT NULL default '0',
+  `sum` int(11) NOT NULL default '0',
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `object_id` (`object_id`)
+);
+
+CREATE TABLE IF NOT EXISTS `bx_persons_votes_track` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `object_id` int(11) NOT NULL default '0',
+  `author_id` int(11) NOT NULL default '0',
+  `author_nip` int(11) unsigned NOT NULL default '0',
+  `value` tinyint(4) NOT NULL default '0',
+  `date` int(11) NOT NULL default '0',
+  PRIMARY KEY (`id`),
+  KEY `vote` (`object_id`, `author_nip`)
+);
+
+-- TABLE: favorites
+CREATE TABLE IF NOT EXISTS `bx_persons_favorites_track` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `object_id` int(11) NOT NULL default '0',
+  `author_id` int(11) NOT NULL default '0',
+  `date` int(11) NOT NULL default '0',
+  PRIMARY KEY (`id`),
+  KEY `id` (`object_id`,`author_id`)
+);
+
+-- TABLE: reports
+CREATE TABLE IF NOT EXISTS `bx_persons_reports` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `object_id` int(11) NOT NULL default '0',
+  `count` int(11) NOT NULL default '0',
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `object_id` (`object_id`)
+);
+
+CREATE TABLE IF NOT EXISTS `bx_persons_reports_track` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `object_id` int(11) NOT NULL default '0',
+  `author_id` int(11) NOT NULL default '0',
+  `author_nip` int(11) unsigned NOT NULL default '0',
+  `type` varchar(32) NOT NULL default '',
+  `text` text NOT NULL default '',
+  `date` int(11) NOT NULL default '0',
+  `checked_by` int(11) NOT NULL default '0',
+  `status` tinyint(11) NOT NULL default '0',
+  PRIMARY KEY (`id`),
+  KEY `report` (`object_id`, `author_nip`)
+);
+
+-- TABLE: metas
+CREATE TABLE IF NOT EXISTS `bx_persons_meta_keywords` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `object_id` int(10) unsigned NOT NULL,
+  `keyword` varchar(255) NOT NULL,
+  PRIMARY KEY (`id`),
+  KEY `object_id` (`object_id`),
+  KEY `keyword` (`keyword`)
+);
+
+CREATE TABLE IF NOT EXISTS `bx_persons_meta_locations` (
+  `object_id` int(10) unsigned NOT NULL,
+  `lat` double NOT NULL,
+  `lng` double NOT NULL,
+  `country` varchar(2) NOT NULL,
+  `state` varchar(255) NOT NULL,
+  `city` varchar(255) NOT NULL,
+  `zip` varchar(255) NOT NULL,
+  `street` varchar(255) NOT NULL,
+  `street_number` varchar(255) NOT NULL,
+  PRIMARY KEY (`object_id`),
+  KEY `country_state_city` (`country`,`state`(8),`city`(8))
+);
+
+CREATE TABLE `bx_persons_meta_mentions` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `object_id` int(10) unsigned NOT NULL,
+  `profile_id` int(10) unsigned NOT NULL,
+  PRIMARY KEY (`id`),
+  KEY `object_id` (`object_id`),
+  KEY `profile_id` (`profile_id`)
+);
+
+-- TABLE: scores
+CREATE TABLE IF NOT EXISTS `bx_persons_scores` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `object_id` int(11) NOT NULL default '0',
+  `count_up` int(11) NOT NULL default '0',
+  `count_down` int(11) NOT NULL default '0',
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `object_id` (`object_id`)
+);
+
+CREATE TABLE IF NOT EXISTS `bx_persons_scores_track` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `object_id` int(11) NOT NULL default '0',
+  `author_id` int(11) NOT NULL default '0',
+  `author_nip` int(11) unsigned NOT NULL default '0',
+  `type` varchar(8) NOT NULL default '',
+  `date` int(11) NOT NULL default '0',
+  PRIMARY KEY (`id`),
+  KEY `vote` (`object_id`, `author_nip`)
+);
+
+CREATE TABLE `bx_persons_skills` (
+  `skill_id` int(11) NOT NULL AUTO_INCREMENT,
+  `skill_name` varchar(500) DEFAULT NULL,
+  `content_id` int(11) NOT NULL,
+  PRIMARY KEY (`skill_id`),
+  KEY `content_id` (`content_id`)
+);
+
+
+-- 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_persons_pictures', @sStorageEngine, '', 360, 2592000, 3, 'bx_persons_pictures', 'allow-deny', 'jpg,jpeg,jpe,gif,png', '', 0, 0, 0, 0, 0, 0),
+('bx_persons_pictures_resized', @sStorageEngine, '', 360, 2592000, 3, 'bx_persons_pictures_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_persons_icon', 'bx_persons_pictures_resized', 'Storage', 'a:1:{s:6:"object";s:19:"bx_persons_pictures";}', 'no', '1', '2592000', '0'),
+('bx_persons_thumb', 'bx_persons_pictures_resized', 'Storage', 'a:1:{s:6:"object";s:19:"bx_persons_pictures";}', 'no', '1', '2592000', '0'),
+('bx_persons_avatar', 'bx_persons_pictures_resized', 'Storage', 'a:1:{s:6:"object";s:19:"bx_persons_pictures";}', 'no', '1', '2592000', '0'),
+('bx_persons_avatar_big', 'bx_persons_pictures_resized', 'Storage', 'a:1:{s:6:"object";s:19:"bx_persons_pictures";}', 'no', '1', '2592000', '0'),
+('bx_persons_picture', 'bx_persons_pictures_resized', 'Storage', 'a:1:{s:6:"object";s:19:"bx_persons_pictures";}', 'no', '1', '2592000', '0'),
+('bx_persons_cover', 'bx_persons_pictures_resized', 'Storage', 'a:1:{s:6:"object";s:19:"bx_persons_pictures";}', 'no', '1', '2592000', '0'),
+('bx_persons_cover_thumb', 'bx_persons_pictures_resized', 'Storage', 'a:1:{s:6:"object";s:19:"bx_persons_pictures";}', 'no', '1', '2592000', '0'),
+('bx_persons_gallery', 'bx_persons_pictures_resized', 'Storage', 'a:1:{s:6:"object";s:19:"bx_persons_pictures";}', 'no', '1', '2592000', '0');
+
+INSERT INTO `sys_transcoder_filters` (`transcoder_object`, `filter`, `filter_params`, `order`) VALUES 
+('bx_persons_icon', 'Resize', 'a:3:{s:1:"w";s:2:"30";s:1:"h";s:2:"30";s:13:"square_resize";s:1:"1";}', '0'),
+('bx_persons_thumb', 'Resize', 'a:3:{s:1:"w";s:2:"50";s:1:"h";s:2:"50";s:13:"square_resize";s:1:"1";}', '0'),
+('bx_persons_avatar', 'Resize', 'a:3:{s:1:"w";s:3:"100";s:1:"h";s:3:"100";s:13:"square_resize";s:1:"1";}', '0'),
+('bx_persons_avatar_big', 'Resize', 'a:3:{s:1:"w";s:3:"200";s:1:"h";s:3:"200";s:13:"square_resize";s:1:"1";}', '0'),
+('bx_persons_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_persons_cover', 'Resize', 'a:2:{s:1:"w";s:3:"960";s:1:"h";s:3:"480";}', '0'),
+('bx_persons_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_persons_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`, `parent_form`) VALUES 
+('bx_person', 'bx_persons', '_bx_persons_form_profile', '', 'a:1:{s:7:\"enctype\";s:19:\"multipart/form-data\";}', 'bx_persons_data', 'id', '', '', 'do_submit', '', 0, 1, 'BxPersonsFormEntry', 'modules/boonex/persons/classes/BxPersonsFormEntry.php', ''),
+('bx_person_skills', 'bx_persons', '_bx_persons_skills_form_profile', '', 'a:1:{s:7:\"enctype\";s:19:\"multipart/form-data\";}', 'bx_persons_skills', 'skill_id', '', '', 'do_submit', '', 0, 1, 'BxDolFormNested', 'inc/classes/BxDolFormNested.php', 'bx_person');
+
+INSERT INTO `sys_form_displays`(`object`, `display_name`, `module`, `view_mode`, `title`) VALUES 
+('bx_person', 'bx_person_add', 'bx_persons', 0, '_bx_persons_form_profile_display_add'),
+('bx_person', 'bx_person_delete', 'bx_persons', 0, '_bx_persons_form_profile_display_delete'),
+('bx_person', 'bx_person_edit', 'bx_persons', 0, '_bx_persons_form_profile_display_edit'),
+('bx_person', 'bx_person_edit_cover', 'bx_persons', 0, '_bx_persons_form_profile_display_edit_cover'),
+('bx_person', 'bx_person_view', 'bx_persons', 1, '_bx_persons_form_profile_display_view'),
+('bx_person', 'bx_person_view_full', 'bx_persons', 1, '_bx_persons_form_profile_display_view_full'),
+('bx_person_skills', 'bx_person_skills', 'bx_persons', 0, '_bx_persons_skills_form_profile_display_add'),
+('bx_person_skills', 'bx_person_skills_view', 'bx_persons', 1, '_bx_persons_skills_form_profile_display_view');
+
+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`, `rateable`) VALUES 
+('bx_person', 'bx_persons', 'allow_view_to', 3, '', 0, 'custom', '_bx_persons_form_profile_input_sys_allow_view_to', '_bx_persons_form_profile_input_allow_view_to', '', 0, 0, 0, '', '', '', '', '', '', '', '', 1, 0, ''),
+('bx_person', 'bx_persons', 'allow_post_to', 5, '', 0, 'custom', '_bx_persons_form_profile_input_sys_allow_post_to', '_bx_persons_form_profile_input_allow_post_to', '', 0, 0, 0, '', '', '', '', '', '', '', '', 1, 0, ''),
+('bx_person', 'bx_persons', 'allow_contact_to', 3, '', 0, 'custom', '_bx_persons_form_profile_input_sys_allow_contact_to', '_bx_persons_form_profile_input_allow_contact_to', '', 0, 0, 0, '', '', '', '', '', '', '', '', 1, 0, ''),
+('bx_person', 'bx_persons', 'delete_confirm', 1, '', 0, 'checkbox', '_bx_persons_form_profile_input_sys_delete_confirm', '_bx_persons_form_profile_input_delete_confirm', '_bx_persons_form_profile_input_delete_confirm_info', 1, 0, 0, '', '', '', 'Avail', '', '_bx_persons_form_profile_input_delete_confirm_error', '', '', 1, 0, ''),
+('bx_person', 'bx_persons', 'do_submit', '_bx_persons_form_profile_input_submit', '', 0, 'submit', '_bx_persons_form_profile_input_sys_do_submit', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 1, 0, ''),
+('bx_person', 'bx_persons', 'description', '', '', 0, 'textarea', '_bx_persons_form_profile_input_sys_desc', '_bx_persons_form_profile_input_desc', '', 0, 0, 1, '', '', '', '', '', '', 'XssHtml', '', 1, 1, ''),
+('bx_person', 'bx_persons', 'fullname', '', '', 0, 'text', '_bx_persons_form_profile_input_sys_fullname', '_bx_persons_form_profile_input_fullname', '', 1, 0, 0, '', '', '', 'ProfileName', '', '_bx_persons_form_profile_input_fullname_err', 'Xss', '', 1, 0, ''),
+('bx_person', 'bx_persons', 'last_name', '', '', 0, 'text', '_bx_persons_form_profile_input_sys_last_name', '_bx_persons_form_profile_input_last_name', '', 1, 0, 0, '', '', '', '', '', '', 'Xss', '', 1, 0, ''),
+('bx_person', 'bx_persons', 'cover', 'a:1:{i:0;s:21:"bx_persons_cover_crop";}', 'a:1:{s:21:"bx_persons_cover_crop";s:24:"_sys_uploader_crop_title";}', 0, 'files', '_bx_persons_form_profile_input_sys_cover', '_bx_persons_form_profile_input_cover', '', 0, 0, 0, '', '', '', '', '', '', '', '', 1, 0, ''),
+('bx_person', 'bx_persons', 'picture', 'a:1:{i:0;s:23:"bx_persons_picture_crop";}', 'a:1:{s:23:"bx_persons_picture_crop";s:24:"_sys_uploader_crop_title";}', 0, 'files', '_bx_persons_form_profile_input_sys_picture', '_bx_persons_form_profile_input_picture', '', 0, 0, 0, '', '', '', '', '', '_bx_persons_form_profile_input_picture_err', '', '', 1, 0, ''),
+('bx_person', 'bx_persons', 'location', '', '', 0, 'location', '_sys_form_input_sys_location', '_sys_form_input_location', '', 0, 0, 0, '', '', '', '', '', '', '', '', 1, 0, ''),
+('bx_person', 'bx_persons', 'birthday', '0', '', 0, 'datepicker', '_bx_persons_form_profile_input_sys_birthday', '_bx_persons_form_profile_input_birthday', '', 1, 0, 0, '', '', '', 'date_range', 'a:3:{s:3:"min";i:18;s:3:"max";i:99;s:8:"required";b:0;}', '_bx_persons_form_profile_input_birthday_err', 'Date', '', 1, 0, ''),
+('bx_person', 'bx_persons', 'gender', '', '#!Sex', 0, 'select', '_bx_persons_form_profile_input_sys_gender', '_bx_persons_form_profile_input_gender', '', 0, 0, 0, '', '', '', '', '', '', 'Xss', '', 1, 0, ''),
+('bx_person', 'bx_persons', 'profile_email', '', '', 0, 'text', '_bx_persons_form_profile_input_sys_profile_email', '_bx_persons_form_profile_input_profile_email', '', 0, 0, 0, '', '', '', '', '', '', 'Xss', '', 0, 0, ''),
+('bx_person', 'bx_persons', 'profile_status', '', '', 0, 'text', '_bx_persons_form_profile_input_sys_profile_status', '_bx_persons_form_profile_input_profile_status', '', 0, 0, 0, '', '', '', '', '', '', 'Xss', '', 0, 0, ''),
+('bx_person', 'bx_persons', 'profile_ip', '', '', 0, 'text', '_bx_persons_form_profile_input_sys_profile_ip', '_bx_persons_form_profile_input_profile_ip', '', 0, 0, 0, '', '', '', '', '', '', 'Xss', '', 0, 0, ''),
+('bx_person', 'bx_persons', 'labels', '', '', 0, 'custom', '_sys_form_input_sys_labels', '_sys_form_input_labels', '', 0, 0, 0, '', '', '', '', '', '', '', '', 1, 0, ''),
+('bx_person', 'bx_persons', 'skills', 'bx_person_skills', '', 0, 'nested_form', '_bx_persons_form_profile_input_sys_skills', '_bx_persons_form_profile_input_skills', '', 0, 0, 0, '', '', '', '', '', '', '', '', 1, 0, 'sys_form_fields_votes'),
+('bx_person', 'bx_persons', 'added', '', '', 0, 'datetime', '_bx_persons_form_profile_input_sys_date_added', '_bx_persons_form_profile_input_date_added', '', 0, 0, 0, '', '', '', '', '', '', '', '', 1, 0, ''),
+('bx_person', 'bx_persons', 'changed', '', '', 0, 'datetime', '_bx_persons_form_profile_input_sys_date_changed', '_bx_persons_form_profile_input_date_changed', '', 0, 0, 0, '', '', '', '', '', '', '', '', 1, 0, ''),
+('bx_person', 'bx_persons', 'friends_count', '', '', 0, 'text', '_bx_persons_form_profile_input_sys_friends_count', '_bx_persons_form_profile_input_friends_count', '', 0, 0, 0, '', '', '', '', '', '', '', '', 1, 0, ''),
+('bx_person', 'bx_persons', 'followers_count', '', '', 0, 'text', '_bx_persons_form_profile_input_sys_followers_count', '_bx_persons_form_profile_input_followers_count', '', 0, 0, 0, '', '', '', '', '', '', '', '', 1, 0, ''),
+('bx_person_skills', 'bx_persons', 'skill_name', '', '', 0, 'text', '_bx_persons_skills_form_profile_input_sys_skill_name', '_bx_persons_skills_form_profile_input_skill_name', '', 1, 0, 0, '', '', '', 'Avail', '', '_bx_persons_skills_form_profile_input_skill_name_err', 'Xss', '', 1, 0, '');
+
+INSERT INTO `sys_form_display_inputs`(`display_name`, `input_name`, `visible_for_levels`, `active`, `order`) VALUES 
+('bx_person_add', 'picture', 2147483647, 1, 1),
+('bx_person_add', 'gender', 2147483647, 1, 2),
+('bx_person_add', 'birthday', 2147483647, 1, 3),
+('bx_person_add', 'fullname', 2147483647, 1, 4),
+('bx_person_add', 'last_name', 2147483647, 0, 5),
+('bx_person_add', 'description', 2147483647, 1, 6),
+('bx_person_add', 'location', 2147483647, 1, 7),
+('bx_person_add', 'allow_view_to', 2147483647, 1, 8),
+('bx_person_add', 'allow_post_to', 2147483647, 1, 9),
+('bx_person_add', 'allow_contact_to', 2147483647, 1, 10),
+('bx_person_add', 'do_submit', 2147483647, 1, 11),
+
+('bx_person_delete', 'cover', 2147483647, 0, 0),
+('bx_person_delete', 'picture', 2147483647, 0, 0),
+('bx_person_delete', 'delete_confirm', 2147483647, 1, 0),
+('bx_person_delete', 'do_submit', 2147483647, 1, 1),
+('bx_person_delete', 'fullname', 2147483647, 0, 2),
+
+('bx_person_edit', 'picture', 2147483647, 1, 1),
+('bx_person_edit', 'gender', 2147483647, 1, 2),
+('bx_person_edit', 'birthday', 2147483647, 1, 3),
+('bx_person_edit', 'fullname', 2147483647, 1, 4),
+('bx_person_edit', 'last_name', 2147483647, 0, 5),
+('bx_person_edit', 'description', 2147483647, 1, 6),
+('bx_person_edit', 'location', 2147483647, 1, 7),
+('bx_person_edit', 'allow_view_to', 2147483647, 1, 8),
+('bx_person_edit', 'allow_post_to', 2147483647, 1, 9),
+('bx_person_edit', 'allow_contact_to', 2147483647, 1, 10),
+('bx_person_edit', 'do_submit', 2147483647, 1, 11),
+
+('bx_person_edit_cover', 'delete_confirm', 2147483647, 0, 1),
+('bx_person_edit_cover', 'fullname', 2147483647, 0, 2),
+('bx_person_edit_cover', 'picture', 2147483647, 0, 3),
+('bx_person_edit_cover', 'cover', 2147483647, 1, 7),
+('bx_person_edit_cover', 'do_submit', 2147483647, 1, 8),
+
+('bx_person_view', 'gender', 2147483647, 1, 1),
+('bx_person_view', 'birthday', 2147483647, 1, 2),
+('bx_person_view', 'fullname', 2147483647, 1, 3),
+('bx_person_view', 'last_name', 2147483647, 0, 4),
+('bx_person_view', 'profile_email', 192, 1, 5),
+('bx_person_view', 'profile_status', 192, 1, 6),
+('bx_person_view', 'profile_ip', 192, 1, 7),
+('bx_person_view', 'added', 192, 1, 8),
+('bx_person_view', 'changed', 192, 1, 9),
+('bx_person_view', 'friends_count', 2147483647, 1, 10),
+('bx_person_view', 'followers_count', 2147483647, 1, 11),
+
+('bx_person_view_full', 'gender', 2147483647, 1, 1),
+('bx_person_view_full', 'birthday', 2147483647, 1, 2),
+('bx_person_view_full', 'fullname', 2147483647, 1, 3),
+('bx_person_view_full', 'last_name', 2147483647, 0, 4),
+('bx_person_view_full', 'description', 2147483647, 0, 5),
+('bx_person_view_full', 'profile_email', 192, 1, 6),
+('bx_person_view_full', 'profile_status', 192, 1, 7),
+
+('bx_person_skills', 'skill_name', 2147483647, 1, 1),
+('bx_person_skills_view', 'skill_name', 2147483647, 1, 1);
+
+-- COMMENTS
+INSERT INTO `sys_objects_cmts` (`Name`, `Module`, `Table`, `CharsPostMin`, `CharsPostMax`, `CharsDisplayMax`, `Html`, `PerView`, `PerViewReplies`, `BrowseType`, `IsBrowseSwitch`, `PostFormPosition`, `NumberOfLevels`, `IsDisplaySwitch`, `IsRatable`, `ViewingThreshold`, `IsOn`, `RootStylePrefix`, `BaseUrl`, `ObjectVote`, `TriggerTable`, `TriggerFieldId`, `TriggerFieldAuthor`, `TriggerFieldTitle`, `TriggerFieldComments`, `ClassName`, `ClassFile`) VALUES
+('bx_persons', 'bx_persons', 'bx_persons_cmts', 1, 5000, 1000, 3, 5, 3, 'tail', 1, 'bottom', 1, 1, 1, -3, 1, 'cmt', 'page.php?i=view-persons-profile&id={object_id}', '', 'bx_persons_data', 'id', 'author', 'fullname', 'comments', 'BxPersonsCmts', 'modules/boonex/persons/classes/BxPersonsCmts.php'),
+('bx_persons_notes', 'bx_persons', 'bx_persons_cmts_notes', 1, 5000, 1000, 0, 5, 3, 'tail', 1, 'bottom', 1, 1, 1, -3, 1, 'cmt', 'page.php?i=view-post&id={object_id}', '', 'bx_persons_data', 'id', 'author', 'fullname', '', 'BxTemplCmtsNotes', '');
+
+-- VIEWS
+INSERT INTO `sys_objects_view` (`name`, `module`, `table_track`, `period`, `is_on`, `trigger_table`, `trigger_field_id`, `trigger_field_author`, `trigger_field_count`, `class_name`, `class_file`) VALUES 
+('bx_persons', 'bx_persons', 'bx_persons_views_track', '86400', '1', 'bx_persons_data', 'id', 'author', 'views', '', '');
+
+-- VOTES
+INSERT INTO `sys_objects_vote` (`Name`, `TableMain`, `TableTrack`, `PostTimeout`, `MinValue`, `MaxValue`, `IsUndo`, `IsOn`, `TriggerTable`, `TriggerFieldId`, `TriggerFieldAuthor`, `TriggerFieldRate`, `TriggerFieldRateCount`, `ClassName`, `ClassFile`) VALUES 
+('bx_persons', 'bx_persons_votes', 'bx_persons_votes_track', '604800', '1', '1', '0', '1', 'bx_persons_data', 'id', '', 'rate', 'votes', 'BxPersonsVote', 'modules/boonex/persons/classes/BxPersonsVote.php');
+
+-- SCORES
+INSERT INTO `sys_objects_score` (`name`, `module`, `table_main`, `table_track`, `post_timeout`, `is_on`, `trigger_table`, `trigger_field_id`, `trigger_field_author`, `trigger_field_score`, `trigger_field_cup`, `trigger_field_cdown`, `class_name`, `class_file`) VALUES 
+('bx_persons', 'bx_persons', 'bx_persons_scores', 'bx_persons_scores_track', '604800', '0', 'bx_persons_data', 'id', 'author', 'score', 'sc_up', 'sc_down', '', '');
+
+-- 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_persons', 'bx_persons_favorites_track', '1', '1', '0', 'page.php?i=view-persons-profile&id={object_id}', 'bx_persons_data', 'id', 'author', 'favorites', 'BxPersonsFavorite', 'modules/boonex/persons/classes/BxPersonsFavorite.php');
+
+-- FEATURED
+INSERT INTO `sys_objects_feature` (`name`, `module`, `is_on`, `is_undo`, `base_url`, `trigger_table`, `trigger_field_id`, `trigger_field_author`, `trigger_field_flag`, `class_name`, `class_file`) VALUES 
+('bx_persons', 'bx_persons', '1', '1', 'page.php?i=view-persons-profile&id={object_id}', 'bx_persons_data', 'id', 'author', 'featured', '', '');
+
+-- REPORTS
+INSERT INTO `sys_objects_report` (`name`, `module`, `table_main`, `table_track`, `is_on`, `base_url`, `object_comment`, `trigger_table`, `trigger_field_id`, `trigger_field_author`, `trigger_field_count`, `class_name`, `class_file`) VALUES 
+('bx_persons', 'bx_persons', 'bx_persons_reports', 'bx_persons_reports_track', '1', 'page.php?i=view-persons-profile&id={object_id}', 'bx_persons_notes', 'bx_persons_data', 'id', 'author', 'reports', 'BxPersonsReport', 'modules/boonex/persons/classes/BxPersonsReport.php');
+
+-- 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_persons', '_bx_persons', 'bx_persons', 'added', 'edited', 'deleted', '', ''),
+('bx_persons_cmts', '_bx_persons_cmts', 'bx_persons', 'commentPost', 'commentUpdated', 'commentRemoved', 'BxDolContentInfoCmts', '');
+
+INSERT INTO `sys_content_info_grids` (`object`, `grid_object`, `grid_field_id`, `condition`, `selection`) VALUES
+('bx_persons', 'bx_persons_administration', 'td`.`id', '', ''),
+('bx_persons', 'bx_persons_common', 'td`.`id', '', '');
+
+-- SEARCH EXTENDED
+INSERT INTO `sys_objects_search_extended` (`object`, `object_content_info`, `module`, `title`, `active`, `class_name`, `class_file`) VALUES
+('bx_persons', 'bx_persons', 'bx_persons', '_bx_persons_search_extended', 1, '', ''),
+('bx_persons_cmts', 'bx_persons_cmts', 'bx_persons', '_bx_persons_search_extended_cmts', 1, 'BxTemplSearchExtendedCmts', '');
+
+-- STUDIO PAGE & WIDGET
+INSERT INTO `sys_std_pages`(`index`, `name`, `header`, `caption`, `icon`) VALUES
+(3, 'bx_persons', '_bx_persons', '_bx_persons', 'bx_persons@modules/boonex/persons/|std-icon.svg');
+SET @iPageId = LAST_INSERT_ID();
+
+SET @iParentPageId = (SELECT `id` FROM `sys_std_pages` WHERE `name` = 'home');
+SET @iParentPageOrder = (SELECT MAX(`order`) FROM `sys_std_pages_widgets` WHERE `page_id` = @iParentPageId);
+INSERT INTO `sys_std_widgets` (`page_id`, `module`, `type`, `url`, `click`, `icon`, `caption`, `cnt_notices`, `cnt_actions`) VALUES
+(@iPageId, 'bx_persons', 'users', '{url_studio}module.php?name=bx_persons', '', 'bx_persons@modules/boonex/persons/|std-icon.svg', '_bx_persons', '', '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));
+

Certains fichiers n'ont pas été affichés car il y a eu trop de fichiers modifiés dans ce diff